Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot apply roleAssignment to type Microsoft.Keyvault/vaults/xxx/certificates #5630

Closed
ianjirka opened this issue Jan 13, 2022 · 2 comments · Fixed by #5887
Closed

Cannot apply roleAssignment to type Microsoft.Keyvault/vaults/xxx/certificates #5630

ianjirka opened this issue Jan 13, 2022 · 2 comments · Fixed by #5887
Assignees

Comments

@ianjirka
Copy link

ianjirka commented Jan 13, 2022

Bicep version
Bicep CLI version 0.4.1124 (66c84c8)

Describe the bug

  • Cannot convert an arm template with scope 'Microsoft.KeyVault/vaults/{0}/certificates/{1}' to bicep:

Error BCP036: The property "scope" expected a value of type "resource | tenant" but the provided value is of type "'Microsoft.KeyVault/vaults/xxx/certificates/yyy'".

  • Cannot create a bicep template referencing 'Microsoft.KeyVault/vaults/xxx/certificates/yyy' because there is no certificates type and bicep cannot generate a scope from a resourceId (AFAICT)

To Reproduce
Steps to reproduce the behavior (conversion failure)

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "variables": {
        "keyvaultCertificatesOfficer": "[tenantResourceId('Microsoft.Authorization/roleDefinitions', 'a4417e6f-fecd-4de8-b567-7b0420556985')]",
    },
    "resources": [
        {
            "type": "Microsoft.Authorization/roleAssignments",
            "apiVersion": "2020-08-01-preview",
            "name": "[format('{0}', guid(subscription().id, 'xxxx', variables('keyvaultCertificatesOfficer')))]",
            "properties": {
                "description": "Assign permissions to read certificate secret value",
                "principalId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', 'zzzz'), '2018-11-30').principalId]",
                "principalType": "ServicePrincipal",
                "roleDefinitionId": "[variables('keyvaultCertificatesOfficer')]"
            },
            "scope": "[format('Microsoft.KeyVault/vaults/{0}/certificates/{1}', 'xxxx', 'yyyy')]"
        }
    ]
}
az bicep decompile --file .\repro.json
WARNING: Decompilation is a best-effort process, as there is no guaranteed mapping from ARM JSON to Bicep.
You may need to fix warnings and errors in the generated bicep file(s), or decompilation may fail entirely if an accurate conversion is not possible.
If you would like to report any issues or inaccurate conversions, please see https://github.com/Azure/bicep/issues.
G:\rep\uhe\product\quark\bicep\private\compute\uhe-prod\it-quark-dmz-prd-eus2-rg\foo.bicep(4,10) : Error BCP036: The property "scope" expected a value of type "resource | tenant" but the provided value is of type "'Microsoft.KeyVault/vaults/it-quark-dmz-prd-eus2-kv/certificates/traefik-ingress-www'".
  • Repro setup to find 'certificates' resource in bicep
targetScope = 'resourceGroup'
var keyvaultCertificatesOfficer = tenantResourceId('Microsoft.Authorization/roleDefinitions', 'a4417e6f-fecd-4de8-b567-7b0420556985')

resource reprokvACFX 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = {
  name: 'reprokvACFX'

  resource cert 'certificates' existing = {
    name: 'reprocert'
  }
}

resource id_it_quark_dmz_traefik_eus2_aks_id_keyvaultCertificatesOfficer 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = {
  scope: reprokvACFX::cert
  name: '${subscription().id}foo${keyvaultCertificatesOfficer}'
  properties: {
    description: 'Assign managed identity permissions to read certificate secret value'
    principalId: reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', 'foo'), '2018-11-30').principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: keyvaultCertificatesOfficer
  }
}
az group create --resource-group repro --location westus2
az identity create --resource-group repro --location westus2 --name foo
az keyvault create --resource-group repro --location westus2 --name 'reprokvACFX'
az keyvault certificate create --vault-name 'reprokvACFX' --name 'reprocert' --policy "$(az keyvault certificate get-default-policy
)"
az deployment group create --resource-group repro --template-file .\repro.bicep
G:\rep\uhe\product\quark\bicep\private\compute\uhe-prod\it-quark-dmz-prd-eus2-rg\foo.bicep(7,17) : Warning BCP081: Resource type "Microsoft.KeyVault/vaults/certificates@2021-06-01-preview" does not have types available.

{'code': 'InvalidTemplate', 'message': "Deployment template validation failed: 'The template resource '/subscriptions/94096a90-f4e9-48dc-bdb3-96afc3259359it-quark-dmz-traefik-eus2-aks-id/providers/Microsoft.Authorization/roleDefinitions/a4417e6f-fecd-4de8-b567-7b0420556985' for type 'Microsoft.Authorization/roleAssignments' at line '16' and column '55' has incorrect segment lengths. A nested resource type must have identical number of segments as its resource name. A root resource type must have segment length one greater than its resource name. Please see https://aka.ms/arm-template/#resources for usage details.'.", 'additionalInfo': [{'type': 'TemplateViolation', 'info': {'lineNumber': 16, 'linePosition': 55, 'path': 'properties.template.resources[0].type'}}]}

Additional context
Seems primarily an issue with the KeyVault provider - though since this is doable with ARM, an escape valve allowing explicit scope definition in bicep may be worthwhile.

I've been wrestling with this for a while - I think at this point I'll fall back to an ARM template for this roleAssignment but if anyone has any ideas how to work around with bicep I'm all ears.

Edit: Forgot one part of the repro output.

@anthony-c-martin
Copy link
Member

Looking at the original template, here's what I think is the most idiomatic way to do this in Bicep:

resource keyvaultCertificatesOfficer 'Microsoft.Authorization/roleDefinitions@2015-07-01' existing = {
  scope: tenant()
  name: 'a4417e6f-fecd-4de8-b567-7b0420556985'
}

resource userAssignedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' existing = {
  name: 'zzz'
}

resource keyVault 'Microsoft.KeyVault/vaults@2019-09-01' existing = {
  name: 'xxxx'
}

resource certificate 'Microsoft.KeyVault/vaults/certificates@2019-09-01' existing = {
  parent: keyVault
  name: 'yyyy'
}

resource certificateRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = {
  scope: certificate
  name: guid(certificate.id, keyvaultCertificatesOfficer.id, userAssignedIdentity.id)
  properties: {
    description: 'Assign permissions to read certificate secret value'
    principalId: userAssignedIdentity.properties.principalId
    principalType: 'ServicePrincipal'
    roleDefinitionId: keyvaultCertificatesOfficer.id
  }
}

@anthony-c-martin
Copy link
Member

It looks like the root cause of this is a problem in the decompiler - I've raised #5881 with a simplified repro.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants