Reputation: 1994
I'm creating my azure Container Registry and my Azure Instance using modules. After creating those I want to assign the permission such that the Azure Container Instance can pull images.
main.bicep:
module dockerContainerRegistry 'modules/dockerContainerRegistry.bicep' = {
name: 'deploy_dockerContainerRegistry'
scope: resourceGroup
[...]
dependsOn: [
network
]
}
module dockerContainerInstance 'modules/dockerContainerGroups.bicep' = {
name: 'deploy_dockerContainerInstance'
scope: resourceGroup
[...]
dependsOn: [
network
dockerContainerRegistry
]
}
// roleDefinitionId is the ID found here for AcrPull: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#acrpull
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup.id, dockerContainerRegistry, 'AcrPullSystemAssigned')
scope: container
properties: {
principalId: dockerContainerInstance.outputs.containerManagedIdentity
principalType: 'ServicePrincipal'
// acrPullDefinitionId has a value of 7f951dda-4ed3-4680-a7ca-43fe172d538d
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
}
dependsOn: [
dockerContainerInstance,
dockerContainerRegistry
]
}
But it always fails with something like:
Error BCP036: The property "scope" expected a value of type "resource | tenant" but the provided value is of type "string"
I also tried diffrent methods to get the resource of dockerContainerInstance
or dockerContainerRegistry
with
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup.id, dockerContainerRegistry, 'AcrPullSystemAssigned')
scope: '/subscriptions/${subscription().subscriptionId}/resourceGroups/${resourceGroup.name}/providers/Microsoft.ContainerInstance/containerGroups/${dockerContainerInstance.name}'
[...]
or
resource registry 'Microsoft.ContainerRegistry/registries@2021-06-01-preview' existing = {
name: dockerContainerRegistryName
}
but the error message is still the same.
I also tried to assign the permissions in an own module with:
dockerRolePullAssignment.bicep:
@description('The resourcegroup which contains the resources')
param targetResourceGroup string
@description('The name of the container registry')
param dockerContainerRegistryName string
@description('The name of the azure container instance')
param dockerContainerInstanceName string
@description('The principal ID of the Azure Container Instance')
param dockerContainerInstanceNamePrincipalId string
resource dockerContainerRegistry 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' existing = {
name: dockerContainerRegistryName
scope: resourceGroup(targetResourceGroup)
}
resource dockerContainerInstance 'Microsoft.ContainerInstance/containerGroups@2022-10-01-preview' existing = {
name: dockerContainerInstanceName
scope: resourceGroup(targetResourceGroup)
}
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2020-04-01-preview' = {
name: guid(dockerContainerRegistry.id, 'AcrPull')
scope: dockerContainerRegistry
properties: {
roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d') // AcrPull role
principalId: dockerContainerInstanceNamePrincipalId
}
}
But this fails with:
dockerRolePullAssignment.bicep(28,10) : Error BCP139: A resource's scope must match the scope of the Bicep file for it to be deployable. You must use modules to deploy resources to a different scope.
I also looked up the following examples: https://azureossd.github.io/2023/01/03/Using-Managed-Identity-and-Bicep-to-pull-images-with-Azure-Container-Apps/ and an other SO but they do not use modules. Is it possible that this is not achievable with modules?
Upvotes: 1
Views: 592
Reputation: 1506
Hi @Briefkasten sorry for the late response, really busy these days, I re-wrote a new sample based on the code you provided to clarify the behavior of scope. just copy and paste into local and run yourself. hope this can help.
network.bicep
@description('Location for all resources.')
param location string
var virtualNetworkName = 'vNet'
var subnetName = 'backendSubnet'
resource virtualNetwork 'Microsoft.Network/virtualNetworks@2021-05-01' = {
name: virtualNetworkName
location: location
properties: {
addressSpace: {
addressPrefixes: [
'10.0.0.0/16'
]
}
subnets: [
{
name: subnetName
properties: {
addressPrefix: '10.0.2.0/24'
delegations: [
{
name: 'CloudShellDelegation'
properties: {
serviceName: 'Microsoft.ContainerInstance/containerGroups'
}
}
]
}
}
]
}
}
output subnetId string = virtualNetwork.properties.subnets[0].id
dockerContainerGroups.bicep
@description('Name for the container group')
param name string = 'acilinuxpublicipcontainergroup'
@description('Location for all resources.')
param location string
@description('Container image to deploy. Should be of the form repoName/imagename:tag for images stored in public Docker Hub, or a fully qualified URI for other registries. Images from private registries require additional registry credentials.')
param image string = 'mcr.microsoft.com/azuredocs/aci-helloworld'
@description('Port to open on the container and the public IP address.')
param port int = 80
@description('The number of CPU cores to allocate to the container.')
param cpuCores int = 1
@description('The amount of memory to allocate to the container in gigabytes.')
param memoryInGb int = 2
@description('The behavior of Azure runtime if container has stopped.')
@allowed([
'Always'
'Never'
'OnFailure'
])
param restartPolicy string = 'Always'
param subnetId string
resource containerGroup 'Microsoft.ContainerInstance/containerGroups@2021-09-01' = {
name: name
location: location
identity: {
type: 'SystemAssigned'
}
properties: {
containers: [
{
name: name
properties: {
image: image
ports: [
{
port: port
protocol: 'TCP'
}
]
resources: {
requests: {
cpu: cpuCores
memoryInGB: memoryInGb
}
}
}
}
]
osType: 'Linux'
restartPolicy: restartPolicy
ipAddress: {
type: 'Private'
ports: [
{
port: port
protocol: 'TCP'
}
]
}
subnetIds: [
{
id: subnetId
}
]
}
}
output containerManagedIdentity string = containerGroup.identity.principalId
dockerContainerRegistry.bicep
@minLength(5)
@maxLength(50)
@description('Provide a globally unique name of your Azure Container Registry')
param acrName string = 'acr${uniqueString(resourceGroup().id)}'
@description('Provide a location for the registry.')
param location string
@description('Provide a tier of your Azure Container Registry.')
param acrSku string = 'Basic'
resource acrResource 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' = {
name: acrName
location: location
sku: {
name: acrSku
}
properties: {
adminUserEnabled: false
publicNetworkAccess: 'Enabled'
}
}
@description('Output the login server property for later use')
output loginServer string = acrResource.properties.loginServer
main.bicep
param resourceGroupNetwork string
param resourceGroupContainerRegistry string
param resourceGroupContainerInstance string
param location string
param acrName string
module network 'modules/network.bicep' = {
scope: resourceGroup(resourceGroupNetwork)
name: 'deploy_network'
params: {
location: location
}
}
module dockerContainerRegistry 'modules/dockerContainerRegistry.bicep' = {
name: 'deploy_dockerContainerRegistry'
scope: resourceGroup(resourceGroupContainerRegistry)
params: {
acrName: acrName
location: location
}
}
module dockerContainerInstance 'modules/dockerContainerGroups.bicep' = {
name: 'deploy_dockerContainerInstance'
scope: resourceGroup(resourceGroupContainerInstance)
params: {
location: location
subnetId: network.outputs.subnetId
}
dependsOn: [
network
dockerContainerRegistry
]
}
resource acrResource 'Microsoft.ContainerRegistry/registries@2023-01-01-preview' existing = {
name: acrName
}
// roleDefinitionId is the ID found here for AcrPull: https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#acrpull
resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(resourceGroup().id, 'anything1', 'anything2')
scope: acrResource
properties: {
principalId: dockerContainerInstance.outputs.containerManagedIdentity
principalType: 'ServicePrincipal'
// acrPullDefinitionId has a value of 7f951dda-4ed3-4680-a7ca-43fe172d538d
roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
}
dependsOn: [
acrResource
dockerContainerInstance
dockerContainerRegistry
]
}
deploy.ps1
$resourceGroupNetwork = "wb-test-network-rg"
$resourceGroupContainerRegistry = "wb-test-acr-rg"
$resourceGroupContainerInstance = "wb-test-aci-rg"
## above resource group can be the same one.
$location = "eastus"
$deploymentName = "wbdeployment"
$param = @{
resourceGroupNetwork = $resourceGroupNetwork
resourceGroupContainerRegistry = $resourceGroupContainerRegistry
resourceGroupContainerInstance = $resourceGroupContainerInstance
acrName = "wbacr324"
location = $location
}
New-AzResourceGroup -Name $resourceGroupNetwork -Location $location -Force
New-AzResourceGroup -Name $resourceGroupContainerRegistry -Location $location -Force
New-AzResourceGroup -Name $resourceGroupContainerInstance -Location $location -Force
New-AzResourceGroupDeployment -Name $deploymentName -ResourceGroupName $resourceGroupContainerRegistry -TemplateFile ".\main.bicep" -TemplateParameterObject $param
folder structure:
deployment result: all successed.
Upvotes: 0