We are trying to automate the deployment of Azure Function app with Azure API Management so that when there is a schema change, we don't have to manually update the APIM with the functionApp schema changes.
Our API Management and Function App are inside different resource groups, but inside the same subscription. I have a main.bicep
file withe following relevant parts.
targetScope = 'resourceGroup'
parameter definitions
Modules defined inside the bicep file like this
module functionapp 'modules/funcapp.bicep' = {
name: 'funappDeploy'
params: {
tags: tags
location: location
application: application
environment: environment
instrumentationKey: appinsight.outputs.instrumentationKey
storageAccountName: storageaccount.outputs.storageAccountName
functionSubNetId: networking.outputs.functionSubnetId
appInsightsConSting: appinsight.outputs.appInsightsConSting
}
}
And my problematic api management definition below inside the main.bicep
:
module apimanagement 'modules/apimanagement.bicep' = {
name: 'apimdeploy'
params: {
application: application
environment: environment
}
}
API Management resource already exists, and API's including my relevant API is deployed inside. This was done early without automation.
And here is my apimanagement.bicep
:
targetScope = 'resourceGroup'
param environment string
param application string = 'gcob-ncino'
var apimName = 'apim-rxx-${application}-${environment}'
var resourceGroupName = 'rg-rxx-apim-${application}-${environment}'
resource apiManagement 'Microsoft.ApiManagement/service@2024-05-01' existing = {
name: apimName
scope: resourceGroup(resourceGroupName)
}
resource apimApi 'Microsoft.ApiManagement/service/apis@2024-05-01' = {
name: 'yourApimApiName'
parent: apiManagement
properties: {
name: 'risk-rating' // This is the API name within APIM
path: '/' // The base path for this API
displayName: 'risk-rating'
}
}
resource apimBackend 'Microsoft.ApiManagement/service/backends@2024-05-01' = {
name: 'my-function-app'
parent: apiManagement
properties: {
protocol: 'https' // Or https
url: 'azfun-my-dev.azurewebsites.net'
}
}
resource apimApiBackendLink 'Microsoft.ApiManagement/service/apis/backends@2021-08-01' = {
name: 'my-function-app-link'
parent: apimApi
properties: {
backendId: apimBackend.id
}
}
While deploying through the Azure DevOps, I see this error in the pipeline:
A resource's computed scope must match that of the Bicep file for it to be deployable. This resource's scope is computed from the "scope" property value assigned to ancestor resource "apiManagement". You must use modules to deploy resources to a different scope. [https://aka.ms/bicep/core-diagnostics#BCP165]
Can someone suggest how to fix this problem?
Thanks DD
The error you’re encountering is BCP165 because your apimanagement.bicep
file sets a resourceGroup(resourceGroupName)
scope for an existing resource (apiManagement
), but you're deploying it from a Bicep file that already targets a different resource group.
To resolve the issue, split the logic into separate modules and use scoped deployments. You can create a separate Bicep module for all API Management operations (e.g., apim-api.bicep
) and deploy that module with the correct scope, targeting the resource group where the API Management instance exists.
main.bicep
targetScope = 'subscription'
param location string = 'eastus'
module funcappModule './modules/funcapp.bicep' = {
name: 'deployFuncApp'
scope: resourceGroup('rg-functions')
params: {
location: location
functionAppName: 'func-demo-lab'
storageAccountName: 'funcdemosa123'
}
}
module apimApiModule './modules/apim-api.bicep' = {
name: 'deployApimApi'
scope: resourceGroup('rg-apim')
params: {
apimName: 'apim-demo-lab1'
apiName: 'lab-api'
functionAppUrl: funcappModule.outputs.functionAppUrl
backendName: 'lab-api-backend'
}
}
modules/apim-api.bicep
param apimName string
param apiName string
param functionAppUrl string
resource apim 'Microsoft.ApiManagement/service@2021-08-01' existing = {
name: apimName
}
resource backend 'Microsoft.ApiManagement/service/backends@2021-08-01' = {
name: 'functionapp-backend'
parent: apim
properties: {
protocol: 'https'
url: functionAppUrl
}
}
resource api 'Microsoft.ApiManagement/service/apis@2021-08-01' = {
name: apiName
parent: apim
properties: {
displayName: apiName
path: apiName
protocols: [ 'https' ]
}
}
resource apiBackend 'Microsoft.ApiManagement/service/apis/backends@2021-08-01' = {
name: 'functionapp-backend-link'
parent: api
properties: {
backendId: backend.id
}
}
modules/funcapp.bicep
param location string
param functionAppName string
param storageAccountName string
resource sa 'Microsoft.Storage/storageAccounts@2022-09-01' = {
name: storageAccountName
location: location
sku: { name: 'Standard_LRS' }
kind: 'StorageV2'
}
resource app 'Microsoft.Web/sites@2022-03-01' = {
name: functionAppName
location: location
kind: 'functionapp'
properties: {
serverFarmId: ''
siteConfig: {
appSettings: [
{
name: 'AzureWebJobsStorage'
value: sa.properties.primaryEndpoints.blob
}
]
}
}
}
output functionAppUrl string = 'https://${app.name}.azurewebsites.net'
After running the code , The backend lab-api-backend is registered and points to the Function App URL and The API lab-api is listed under the APIs section in APIM
Output: