Encrypt Azure Container Registry with CMK – Template

encrypt azure container registry with customer managed keys arm template

To encrypt Azure Container Registry using Customer Managed Keys using key vault, we would need azure managed user identity to perform the encryption on acr.

Resources needed for this project:

 

Azure Managed User Identity

We need to create user identity first using following template

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "identity_name": {
        "type": "string",
        "defaultValue": "acridentity-03",
        "metadata": {
          "description": "USER ASSIGNED IDENTITY NAME"
        }
      }
  },
    "variables": {},
  
    "resources": [
      {
        "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
        "name": "[parameters('identity_name')]",
        "apiVersion": "2018-11-30",
        "location": "[resourceGroup().location]"
      }
    ]
  }

Azure Key vault with Key

Second we need to create Key vault using this template

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "keyName": {
        "type": "string",
        "defaultValue": "klaacrkey-03"
      },
      "vault_name": {
        "type": "string",
        "defaultValue": "klaacrvault-03"
      },
      "keyVersion": {
        "type": "string",
        "defaultValue": ""
      },
      "location": {
        "type": "string",
        "defaultValue": "[resourceGroup().location]"
      },
      "attributes": {
        "type": "object",
        "defaultValue": {},
        "metadata": {
            "description": "The attributes of a key managed by the key vault service."
        }
      },
      "crv": {
        "type": "string",
        "defaultValue": "",
        "allowedValues": [
            "",
            "P-256",  
            "P-256K", 
            "P-384",  
            "P-521" 
        ],
        "metadata": {
            "description": "Elliptic curve name."
        }
      },
      "key_ops": {
        "type": "array",
        "defaultValue": [],
        "metadata": {
            "description": "JSON web key operations. Operations include: 'encrypt', 'decrypt', 'sign', 'verify', 'wrapKey', 'unwrapKey'"
        }
       },
      "key_size": {
        "type": "int",
        "defaultValue": 4096,
        "metadata": {
            "description": "The key size in bits. For example: 2048, 3072, or 4096 for RSA."
        }
       },
      "kty": {
          "type": "string",
          "defaultValue": "RSA",
          "allowedValues": [
              "EC",    
              "EC-HSM",
              "RSA",   
              "RSA-HSM"
          ],
          "metadata": {
              "description": "The type of key to create"
          }
      },
      "tags": {
          "type": "object",
          "defaultValue": {},
          "metadata": {
              "description": "Tags to be assigned to the Key."
          }
      }
  
  },
    "variables": {},
  
    "resources": [
      {
        "type": "Microsoft.KeyVault/vaults",
        "name": "[parameters('vault_name')]",
        "apiVersion": "2016-10-01",
        "location": "[parameters('location')]",
        "properties": {
          "sku": {
            "family": "A",
            "name": "standard"
          },
          "tenantId": "[subscription().tenantid]",
          "accessPolicies": [],
                "enabledForDeployment":false,
                "enabledForDiskEncryption":false,
                "enabledForTemplateDeployment":true,
                "enableSoftDelete":true,
                "enablePurgeProtection": true
        },
        "dependsOn": [
          "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name'))]"
        ]
      },
      {
        "type": "Microsoft.KeyVault/vaults/keys",
        "apiVersion": "2019-09-01",
        "name": "[concat(parameters('vault_name'), '/', parameters('keyName'))]",
        "properties": {
            "attributes": "[parameters('attributes')]",
            "crv": "[parameters('crv')]",
            "kty": "[parameters('kty')]",
            "key_ops": "[parameters('key_ops')]",
            "key_size": "[parameters('key_size')]"
        },
        "dependsOn": [
            "[resourceId('Microsoft.KeyVault/vaults/', parameters('vault_name'))]"
        ]
      }
    ]
  }

Azure KeyVault Access Policy

Now we need to add Azure managed user identity to key vault access policy and grant permission to have read/write access to key vault key. for this we would need to use nested arm template.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "identity_name": {
        "type": "string",
        "defaultValue": "acridentity-03",
        "metadata": {
          "description": "USER ASSIGNED IDENTITY NAME"
        }
      },
      "keyName": {
        "type": "string",
        "defaultValue": "klaacrkey-03"
      },
      "vault_name": {
        "type": "string",
        "defaultValue": "klaacrvault-03"
      },
      "keyVersion": {
        "type": "string",
        "defaultValue": ""
      },
      "location": {
        "type": "string",
        "defaultValue": "[resourceGroup().location]"
      },
      "attributes": {
        "type": "object",
        "defaultValue": {},
        "metadata": {
            "description": "The attributes of a key managed by the key vault service."
        }
      },
      "crv": {
        "type": "string",
        "defaultValue": "",
        "allowedValues": [
            "",
            "P-256",  
            "P-256K", 
            "P-384",  
            "P-521" 
        ],
        "metadata": {
            "description": "Elliptic curve name."
        }
      },
      "key_ops": {
        "type": "array",
        "defaultValue": [],
        "metadata": {
            "description": "JSON web key operations. Operations include: 'encrypt', 'decrypt', 'sign', 'verify', 'wrapKey', 'unwrapKey'"
        }
       },
      "key_size": {
        "type": "int",
        "defaultValue": 4096,
        "metadata": {
            "description": "The key size in bits. For example: 2048, 3072, or 4096 for RSA."
        }
       },
      "kty": {
          "type": "string",
          "defaultValue": "RSA",
          "allowedValues": [
              "EC",    
              "EC-HSM",
              "RSA",   
              "RSA-HSM"
          ],
          "metadata": {
              "description": "The type of key to create"
          }
      },
      "tags": {
          "type": "object",
          "defaultValue": {},
          "metadata": {
              "description": "Tags to be assigned to the Key."
          }
      }
  
  },
    "variables": {},
  
    "resources": [
      {
        "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
        "name": "[parameters('identity_name')]",
        "apiVersion": "2018-11-30",
        "location": "[resourceGroup().location]"
      },
      {
        "type": "Microsoft.KeyVault/vaults",
        "name": "[parameters('vault_name')]",
        "apiVersion": "2016-10-01",
        "location": "[parameters('location')]",
        "properties": {
          "sku": {
            "family": "A",
            "name": "standard"
          },
          "tenantId": "[subscription().tenantid]",
          "accessPolicies": [],
                "enabledForDeployment":false,
                "enabledForDiskEncryption":false,
                "enabledForTemplateDeployment":true,
                "enableSoftDelete":true,
                "enablePurgeProtection": true
        },
        "dependsOn": [
          "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name'))]"
        ]
      },
      {
        "type": "Microsoft.KeyVault/vaults/keys",
        "apiVersion": "2019-09-01",
        "name": "[concat(parameters('vault_name'), '/', parameters('keyName'))]",
        "properties": {
            "attributes": "[parameters('attributes')]",
            "crv": "[parameters('crv')]",
            "kty": "[parameters('kty')]",
            "key_ops": "[parameters('key_ops')]",
            "key_size": "[parameters('key_size')]"
        },
        "dependsOn": [
            "[resourceId('Microsoft.KeyVault/vaults/', parameters('vault_name'))]"
        ]
      },
      {
        "type": "Microsoft.Resources/deployments",
        "apiVersion": "2019-07-01",
        "name": "CreateRegistry",
        "dependsOn": [
          "[resourceId('Microsoft.KeyVault/vaults', parameters('vault_name'))]"
        ],
        "properties": {
          "mode": "Incremental",
          "template": {
            "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
            "contentVersion": "0.1.0.0",
            "resources": [
              {
                "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
                "name": "[parameters('identity_name')]",
                "apiVersion": "2018-11-30",
                "location": "[resourceGroup().location]"
              },
              {
                "type": "Microsoft.KeyVault/vaults",
                "name": "[parameters('vault_name')]",
                "apiVersion": "2016-10-01",
                "location": "[parameters('location')]",
                "properties": {
                  "sku": {
                    "family": "A",
                    "name": "standard"
                  },
                  "tenantId": "[subscription().tenantid]",
                  "accessPolicies": [],
                        "enabledForDeployment":false,
                        "enabledForDiskEncryption":false,
                        "enabledForTemplateDeployment":true,
                        "enableSoftDelete":true,
                        "enablePurgeProtection": true
                },
                "dependsOn": [
                  "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name'))]"
                ]
              },
              {
                "type": "Microsoft.KeyVault/vaults/accessPolicies",
                "name": "[concat(parameters('vault_name'), '/add')]",
                "apiVersion": "2019-09-01",
                "dependsOn": [
                  "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name'))]", 
                  "[resourceId('Microsoft.KeyVault/vaults/', parameters('vault_name'))]"
                ],
                "properties": {
                  "accessPolicies": [
                    {
                      "tenantId": "[subscription().tenantid]",
                      "objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name')), '2018-11-30').principalId]",
                      "permissions": {
                        "keys": [
                          "get",
                          "list",
                          "update",
                          "create",
                          "import",
                          "delete",
                          "recover",
                          "backup",
                          "restore",
                          "decrypt",
                          "encrypt",
                          "unwrapKey",
                          "wrapKey",
                          "verify",
                          "sign",
                          "purge"
                        ],
                        "secrets": [],
                        "certificates": []
                      }
                    }
                  ]
                }
              }
            ]
          }
        }
      }
    ]
  }

 

Azure Container Registry

In order to create azure container registry and start encrypt it using user identity and key vault and key, we would need to use nested arm template deployment inside arm template. as we already used one nested template previously for key vault key access policy to add user managed identity, we will just another resource under nested template to create Container registry and encrypt it using key vault and user identity.

so the Full arm template will look like this including azure container registry.

{
    "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
    "contentVersion": "1.0.0.0",
    "parameters": {
      "identity_name": {
        "type": "string",
        "defaultValue": "acridentity-03",
        "metadata": {
          "description": "USER ASSIGNED IDENTITY NAME"
        }
      },
      "registry_name": {
        "type": "string",
        "defaultValue": "klaregistry03",
        "metadata": {
          "description": "Globally unique name of your Azure Container Registry"
        }
      },
      "acrAdminUserEnabled": {
          "type": "bool",
          "defaultValue": false,
          "metadata": {
            "description": "Enable admin user that has push / pull permission to the registry."
          }
      },
      "acrSku": {
        "type": "string",
        "defaultValue": "Premium",
        "allowedValues": [
          "Premium"
        ],
        "metadata": {
          "description": "Tier of your Azure Container Registry. Geo-replication requires Premium SKU."
        }
      },
      "keyName": {
        "type": "string",
        "defaultValue": "klaacrkey-03"
      },
      "vault_name": {
        "type": "string",
        "defaultValue": "klaacrvault-03"
      },
      "keyVersion": {
        "type": "string",
        "defaultValue": ""
      },
      "location": {
        "type": "string",
        "defaultValue": "[resourceGroup().location]"
      },
      "attributes": {
        "type": "object",
        "defaultValue": {},
        "metadata": {
            "description": "The attributes of a key managed by the key vault service."
        }
      },
      "crv": {
        "type": "string",
        "defaultValue": "",
        "allowedValues": [
            "",
            "P-256",  
            "P-256K", 
            "P-384",  
            "P-521" 
        ],
        "metadata": {
            "description": "Elliptic curve name."
        }
      },
      "key_ops": {
        "type": "array",
        "defaultValue": [],
        "metadata": {
            "description": "JSON web key operations. Operations include: 'encrypt', 'decrypt', 'sign', 'verify', 'wrapKey', 'unwrapKey'"
        }
       },
      "key_size": {
        "type": "int",
        "defaultValue": 4096,
        "metadata": {
            "description": "The key size in bits. For example: 2048, 3072, or 4096 for RSA."
        }
       },
      "kty": {
          "type": "string",
          "defaultValue": "RSA",
          "allowedValues": [
              "EC",    
              "EC-HSM",
              "RSA",   
              "RSA-HSM"
          ],
          "metadata": {
              "description": "The type of key to create"
          }
      },
      "tags": {
          "type": "object",
          "defaultValue": {},
          "metadata": {
              "description": "Tags to be assigned to the Key."
          }
      }
  
  },
    "variables": {},
  
    "resources": [
      {
        "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
        "name": "[parameters('identity_name')]",
        "apiVersion": "2018-11-30",
        "location": "[resourceGroup().location]"
      },
      {
        "type": "Microsoft.KeyVault/vaults",
        "name": "[parameters('vault_name')]",
        "apiVersion": "2016-10-01",
        "location": "[parameters('location')]",
        "properties": {
          "sku": {
            "family": "A",
            "name": "standard"
          },
          "tenantId": "[subscription().tenantid]",
          "accessPolicies": [],
                "enabledForDeployment":false,
                "enabledForDiskEncryption":false,
                "enabledForTemplateDeployment":true,
                "enableSoftDelete":true,
                "enablePurgeProtection": true
        },
        "dependsOn": [
          "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name'))]"
        ]
      },
      {
        "type": "Microsoft.KeyVault/vaults/keys",
        "apiVersion": "2019-09-01",
        "name": "[concat(parameters('vault_name'), '/', parameters('keyName'))]",
        "properties": {
            "attributes": "[parameters('attributes')]",
            "crv": "[parameters('crv')]",
            "kty": "[parameters('kty')]",
            "key_ops": "[parameters('key_ops')]",
            "key_size": "[parameters('key_size')]"
        },
        "dependsOn": [
            "[resourceId('Microsoft.KeyVault/vaults/', parameters('vault_name'))]"
        ]
      },
      {
        "type": "Microsoft.Resources/deployments",
        "apiVersion": "2019-07-01",
        "name": "CreateRegistry",
        "dependsOn": [
          "[resourceId('Microsoft.KeyVault/vaults', parameters('vault_name'))]"
        ],
        "properties": {
          "mode": "Incremental",
          "template": {
            "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
            "contentVersion": "0.1.0.0",
            "resources": [
              {
                "type": "Microsoft.ManagedIdentity/userAssignedIdentities",
                "name": "[parameters('identity_name')]",
                "apiVersion": "2018-11-30",
                "location": "[resourceGroup().location]"
              },
              {
                "type": "Microsoft.KeyVault/vaults",
                "name": "[parameters('vault_name')]",
                "apiVersion": "2016-10-01",
                "location": "[parameters('location')]",
                "properties": {
                  "sku": {
                    "family": "A",
                    "name": "standard"
                  },
                  "tenantId": "[subscription().tenantid]",
                  "accessPolicies": [],
                        "enabledForDeployment":false,
                        "enabledForDiskEncryption":false,
                        "enabledForTemplateDeployment":true,
                        "enableSoftDelete":true,
                        "enablePurgeProtection": true
                },
                "dependsOn": [
                  "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name'))]"
                ]
              },
              {
                "type": "Microsoft.KeyVault/vaults/accessPolicies",
                "name": "[concat(parameters('vault_name'), '/add')]",
                "apiVersion": "2019-09-01",
                "dependsOn": [
                  "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name'))]", 
                  "[resourceId('Microsoft.KeyVault/vaults/', parameters('vault_name'))]"
                ],
                "properties": {
                  "accessPolicies": [
                    {
                      "tenantId": "[subscription().tenantid]",
                      "objectId": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name')), '2018-11-30').principalId]",
                      "permissions": {
                        "keys": [
                          "get",
                          "list",
                          "update",
                          "create",
                          "import",
                          "delete",
                          "recover",
                          "backup",
                          "restore",
                          "decrypt",
                          "encrypt",
                          "unwrapKey",
                          "wrapKey",
                          "verify",
                          "sign",
                          "purge"
                        ],
                        "secrets": [],
                        "certificates": []
                      }
                    }
                  ]
                }
              },
              {
                "type": "Microsoft.ContainerRegistry/registries",
                "apiVersion": "2019-12-01-preview",
                "name": "[parameters('registry_name')]",
                "location": "[resourceGroup().location]",
                "sku": {
                  "name": "Premium",
                  "tier": "Premium"
                },
                "identity": {
                  "type": "UserAssigned",
                  "userAssignedIdentities": {
                    "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name'))]": {}
                  }
                },
                "properties": {
                  "adminUserEnabled": false,
                  "networkRuleSet": {
                    "defaultAction": "Allow",
                    "virtualNetworkRules": [],
                    "ipRules": []
                  },
                  "policies": {
                    "quarantinePolicy": {
                      "status": "disabled"
                    },
                    "trustPolicy": {
                      "type": "Notary",
                      "status": "disabled"
                    },
                    "retentionPolicy": {
                      "days": 7,
                      "status": "disabled"
                    }
                  },
                  "encryption": {
                    "status": "enabled",
                    "keyVaultProperties": {
                      "identity": "[reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name')), '2018-11-30').clientId]",
                      "keyIdentifier": "[concat('https://', parameters('vault_name'),'.vault.azure.net/keys/', parameters('keyname'))]"
                    }
                  }
                },
                "dependsOn": [
                  "[resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', parameters('identity_name'))]"
                ]
              }
            ]
          }
        }
      }
    ]
  }

 

 

Exit mobile version