I have the following bicep module:
// fails if set-backend-service and set-body are used together
// var apiOperationPolicy = format('''
// <policies>
// <inbound>
// <base />
// <rewrite-uri template="/" />
// <set-backend-service base-url="{0}" />
// <set-body>
// <value>@{
// var body = context.Request.Body.As<JObject>();
// body["source"] = body["operation"];
// return body.ToString();
// }</value>
// </set-body>
// </inbound>
// <backend>
// <base />
// </backend>
// <outbound>
// <base />
// </outbound>
// <on-error>
// <base />
// </on-error>
// </policies>
// ''', formattedBasePath)
//works if only set-body
// var apiOperationPolicy = '''
// <policies>
// <inbound>
// <base />
// <rewrite-uri template="/" />
// <set-body>
// <value>@{
// var body = context.Request.Body.As<JObject>();
// body["source"] = body["operation"];
// return body.ToString();
// }</value>
// </set-body>
// </inbound>
// <backend>
// <base />
// </backend>
// <outbound>
// <base />
// </outbound>
// <on-error>
// <base />
// </on-error>
// </policies>
// '''
//works if only set-backend-service is used
var apiOperationPolicy = format('''
<policies>
<inbound>
<base />
<rewrite-uri template="/" />
<set-backend-service base-url="{0}" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
''', formattedBasePath)
resource apiOperationPolicyResource 'Microsoft.ApiManagement/service/apis/operations/policies@2022-04-01-preview' = {
parent: apiOperation
name: 'policy'
properties: {
value: apiOperationPolicy
format: 'rawxml'
}
}
If I try setting both policies then I get the following error:
ERROR: InvalidTemplate - Deployment template validation failed: 'The template variable 'apiOperationPolicy' is not valid: Unable to evaluate language function 'format': the format is invalid: 'Input string was not in a correct format.'
Does anyone know the reason for this?
ERROR: InvalidTemplate - Deployment template validation failed: 'The template variable 'apiOperationPolicy' is not valid: Unable to evaluate language function 'format': the format is invalid: 'Input string was not in a correct format.'
I also received the same error when I tried in my environment previously. The below workaround I have used to resolve the issue and worked as expected.
Basically, the purpose of the placeholder you are using is. it will be replaced by the formatted base path URL later after deployment. So, rather than using {0}
as a placeholder try using a placeholder called __BASE_URL__
to avoid the conflicts of input format as there is a chance of getting parsing errors when bicep reads multiline structure of XML.
After passing it, use replace()
function available in policy for replacing and substituting the placeholder with the actual URL stored in formatted base path.
param formattedBasePath string = 'https://google.com'
var apiOperationPolicy = '''
<policies>
<inbound>
<base />
<rewrite-uri template="/" />
<set-backend-service base-url="__BASE_URL__" />
<set-body>
<value>@{
var body = context.Request.Body.As<JObject>();
body["source"] = body["operation"];
return body.ToString();
}</value>
</set-body>
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
'''
Using replace() function:
var replacepolicy = replace(apiOperationPolicy, '__BASE_URL__', formattedBasePath)
resource apiManagementService 'Microsoft.ApiManagement/service@2023-05-01-preview' existing = {
name: 'newapimjah'
}
resource api 'Microsoft.ApiManagement/service/apis@2020-12-01' existing = {
parent: apiManagementService
name:'apinewjah'
}
resource apiOperation 'Microsoft.ApiManagement/service/apis/operations@2023-09-01-preview' existing = {
name: 'firstop'
parent: api
}
resource apiOperationPolicyResource 'Microsoft.ApiManagement/service/apis/operations/policies@2022-04-01-preview' = {
parent: apiOperation
name: 'policy'
properties: {
value: replacepolicy
format: 'rawxml'
}
}
Deployment succeeded: