Search code examples
azuregithub-actionsazure-resource-managerazure-keyvaultazure-bicep

Azure ARM templates in Github Actions Keyvault Policies


I have a .bicep file which creates my cloud resources one of which is a new keyvault into which I am able to store connection strings from the different resources e.g ACR username/password, redis connection string, etc. The .bicep file is referenced in a github actions workflow with the action azure/arm-deploy@v1 I need to be able to access the secrets downstream but for that I would need to run something that updates the keyvault policy to allow the service principal I am using to call the github action workflow get/list permissions. I tried using this:

      - name: set policies
    continue-on-error: true
    env:
      clientId: ${{ secrets.AZURE_CREDENTIALS }}
    run: |
      az keyvault set-policy -n kv-dev-lightningocr --secret-permissions get list set --spn $clientId

but the $clientId is not inserted as expected as shown in the snapshot below: enter image description here

It is possible to set policies directly in the .bicep template but I am having issues with that because I'm not sure how I can substitute the value for the objectId in the template.

    resource keyVaultPolicies 'Microsoft.KeyVault/vaults/accessPolicies@2021-06-01-preview' = {
  name: '${keyVault.name}/add'
  properties: {
    accessPolicies: [
      {
        tenantId: subscription().tenantId
        objectId: // how to get the objectId of the service principal that calls the azure deploy action? 
        permissions: {
          keys: []
          secrets: [
            'get'
            'list'
          ]
          certificates: []
        }
      }
    ]
  }
}

I have crawled through the microsoft documentation but it feels like looking for a needle in a haystack, so any specific answers to this very specific question are much aprpeciated.


Solution

  • It is not possible to reference the Azure AD objects from a ARM template except for the ones which are associated to the Azure resources as a System-Assigned Identity or User-Assigned Identity.

    Example to reference System-Assigned Identity or User-Assigned Identity of a virtual machine :

    "[reference(resourceId('Microsoft.Compute/virtualMachines', variables('vmName')),'2019-12-01', 'Full').identity.principalId]",
    

    The only way for now is to get the Service principal object id from Portal or using Azure AD Powershell module or az CLI or copy the clientID from the environment variable that you have stored for the Github Actions.

    Then you can directly paste it in the below bicep template:

      resource keyVaultPolicies 'Microsoft.KeyVault/vaults/accessPolicies@2021-06-01-preview' = {
      name: '${keyVault.name}/add'
      properties: {
        accessPolicies: [
          {
            tenantId: subscription().tenantId
            objectId:// copied from portal, az cli,powershell or environment variable
            permissions: {
              keys: []
              secrets: [
                'get'
                'list'
              ]
              certificates: []
            }
          }
        ]
      }
    }
    

    The below way you are using the environment variable is also wrong.

    name: set policies
        continue-on-error: true
        env:
          clientId: ${{ secrets.AZURE_CREDENTIALS }}
        run: |
          az keyvault set-policy -n kv-dev-lightningocr --secret-permissions get list set --spn $clientId
    

    ${{ secrets.AZURE_CREDENTIALS }} will contain something like below and you are referencing the clientid using the whole Azure_credential Environment Variable which is not possible.

      {
        "clientId": "<GUID>",
        "clientSecret": "<GUID>",
        "subscriptionId": "<GUID>",
        "tenantId": "<GUID>",
        (...)
      }
    

    AZURE_CREDENTIALS is used as a credential variable for logging into the Azure like below :

    steps:
        # checkout the repo
        - uses: actions/checkout@v2
        - uses: Azure/login@v1
          with:
            creds: ${{ secrets.AZURE_CREDENTIALS }}
    

    So, in the Github actions also you will have to hard code it like below :

    name: set policies
        continue-on-error: true
        run: |
          az keyvault set-policy -n kv-dev-lightningocr --secret-permissions get list set --spn <ClientID>
    

    Reference:

    Quickstart - Use Azure Key Vault secrets in GitHub Actions workflows | Microsoft Docs

    Setting Key Vault Access Policy from Azure Pipelines