diff --git a/modules/container-service/managed-cluster/README.md b/modules/container-service/managed-cluster/README.md index aaf0d56ddb..f82561d20a 100644 --- a/modules/container-service/managed-cluster/README.md +++ b/modules/container-service/managed-cluster/README.md @@ -140,6 +140,7 @@ module managedCluster 'br:bicep/modules/container-service.managed-cluster:1.0.0' ] diskEncryptionSetID: '' enableAzureDefender: true + enableAzureKeyVaultKms: true enableDefaultTelemetry: '' enableKeyvaultSecretsProvider: true enableOidcIssuerProfile: true @@ -210,6 +211,10 @@ module managedCluster 'br:bicep/modules/container-service.managed-cluster:1.0.0' resourceId: '' } } + keyVaultKms: { + keyId: '' + keyVaultNetworkAccess: 'Public' + } lock: { kind: 'CanNotDelete' name: 'myCustomLockName' @@ -361,6 +366,9 @@ module managedCluster 'br:bicep/modules/container-service.managed-cluster:1.0.0' "enableAzureDefender": { "value": true }, + "enableAzureKeyVaultKms": { + "value": true + }, "enableDefaultTelemetry": { "value": "" }, @@ -453,6 +461,12 @@ module managedCluster 'br:bicep/modules/container-service.managed-cluster:1.0.0' } } }, + "keyVaultKms": { + "value": { + "keyId": "", + "keyVaultNetworkAccess": "Public" + } + }, "lock": { "value": { "kind": "CanNotDelete", @@ -1131,6 +1145,7 @@ module managedCluster 'br:bicep/modules/container-service.managed-cluster:1.0.0' | :-- | :-- | :-- | | [`aksServicePrincipalProfile`](#parameter-aksserviceprincipalprofile) | object | Information about a service principal identity for the cluster to use for manipulating Azure APIs. Required if no managed identities are assigned to the cluster. | | [`appGatewayResourceId`](#parameter-appgatewayresourceid) | string | Specifies the resource ID of connected application gateway. Required if `ingressApplicationGatewayEnabled` is set to `true`. | +| [`keyVaultKms`](#parameter-keyvaultkms) | object | Object that contains the 'keyId', 'keyVaultNetworkAccess' and 'keyVaultResourceId' to enable Key Management Service. Required if enableAzureKeyVaultKms is set to true. | **Optional parameters** @@ -1175,6 +1190,7 @@ module managedCluster 'br:bicep/modules/container-service.managed-cluster:1.0.0' | [`dnsServiceIP`](#parameter-dnsserviceip) | string | Specifies the IP address assigned to the Kubernetes DNS service. It must be within the Kubernetes service address range specified in serviceCidr. | | [`dnsZoneResourceId`](#parameter-dnszoneresourceid) | string | Specifies the resource ID of connected DNS zone. It will be ignored if `webApplicationRoutingEnabled` is set to `false`. | | [`enableAzureDefender`](#parameter-enableazuredefender) | bool | Whether to enable Azure Defender. | +| [`enableAzureKeyVaultKms`](#parameter-enableazurekeyvaultkms) | bool | Whether to enable Key Management Service. | | [`enableDefaultTelemetry`](#parameter-enabledefaulttelemetry) | bool | Enable telemetry via a Globally Unique Identifier (GUID). | | [`enableDnsZoneContributorRoleAssignment`](#parameter-enablednszonecontributorroleassignment) | bool | Specifies whether assing the DNS zone contributor role to the cluster service principal. It will be ignored if `webApplicationRoutingEnabled` is set to `false` or `dnsZoneResourceId` not provided. | | [`enableKeyvaultSecretsProvider`](#parameter-enablekeyvaultsecretsprovider) | bool | Specifies whether the KeyvaultSecretsProvider add-on is enabled or not. | @@ -1661,6 +1677,13 @@ Whether to enable Azure Defender. - Type: bool - Default: `False` +### Parameter: `enableAzureKeyVaultKms` + +Whether to enable Key Management Service. +- Required: No +- Type: bool +- Default: `False` + ### Parameter: `enableDefaultTelemetry` Enable telemetry via a Globally Unique Identifier (GUID). @@ -1808,6 +1831,13 @@ Specifies whether the ingressApplicationGateway (AGIC) add-on is enabled or not. - Type: bool - Default: `False` +### Parameter: `keyVaultKms` + +Object that contains the 'keyId', 'keyVaultNetworkAccess' and 'keyVaultResourceId' to enable Key Management Service. Required if enableAzureKeyVaultKms is set to true. +- Required: No +- Type: object +- Default: `{}` + ### Parameter: `kubeDashboardEnabled` Specifies whether the kubeDashboard add-on is enabled or not. diff --git a/modules/container-service/managed-cluster/main.bicep b/modules/container-service/managed-cluster/main.bicep index efb5974f2d..cc9fd3c16b 100644 --- a/modules/container-service/managed-cluster/main.bicep +++ b/modules/container-service/managed-cluster/main.bicep @@ -314,6 +314,12 @@ param supportPlan string = 'KubernetesOfficial' @description('Optional. The diagnostic settings of the service.') param diagnosticSettings diagnosticSettingType +@description('Optional. Whether to enable Key Management Service.') +param enableAzureKeyVaultKms bool = false + +@description('Conditional. Object that contains the \'keyId\', \'keyVaultNetworkAccess\' and \'keyVaultResourceId\' to enable Key Management Service. Required if enableAzureKeyVaultKms is set to true.') +param keyVaultKms object = {} + @description('Optional. Specifies whether the OMS agent is enabled.') param omsAgentEnabled bool = true @@ -539,6 +545,12 @@ resource managedCluster 'Microsoft.ContainerService/managedClusters@2023-07-02-p userAssignedIdentityExceptions: podIdentityProfileUserAssignedIdentityExceptions } securityProfile: { + azureKeyVaultKms: enableAzureKeyVaultKms ? { + enabled: enableAzureKeyVaultKms + keyId: keyVaultKms.keyId + keyVaultNetworkAccess: keyVaultKms.keyVaultNetworkAccess + keyVaultResourceId: keyVaultKms.keyVaultNetworkAccess == 'Private' ? keyVaultKms.keyVaultResourceId : null + } : null defender: enableAzureDefender ? { securityMonitoring: { enabled: enableAzureDefender diff --git a/modules/container-service/managed-cluster/main.json b/modules/container-service/managed-cluster/main.json index 55eb6b6a7c..7190d6b56c 100644 --- a/modules/container-service/managed-cluster/main.json +++ b/modules/container-service/managed-cluster/main.json @@ -6,7 +6,7 @@ "_generator": { "name": "bicep", "version": "0.23.1.45101", - "templateHash": "10758692765653328788" + "templateHash": "1906456864170625087" }, "name": "Azure Kubernetes Service (AKS) Managed Clusters", "description": "This module deploys an Azure Kubernetes Service (AKS) Managed Cluster.", @@ -864,6 +864,20 @@ "description": "Optional. The diagnostic settings of the service." } }, + "enableAzureKeyVaultKms": { + "type": "bool", + "defaultValue": false, + "metadata": { + "description": "Optional. Whether to enable Key Management Service." + } + }, + "keyVaultKms": { + "type": "object", + "defaultValue": {}, + "metadata": { + "description": "Conditional. Object that contains the 'keyId', 'keyVaultNetworkAccess' and 'keyVaultResourceId' to enable Key Management Service. Required if enableAzureKeyVaultKms is set to true." + } + }, "omsAgentEnabled": { "type": "bool", "defaultValue": true, @@ -1116,6 +1130,7 @@ "userAssignedIdentityExceptions": "[parameters('podIdentityProfileUserAssignedIdentityExceptions')]" }, "securityProfile": { + "azureKeyVaultKms": "[if(parameters('enableAzureKeyVaultKms'), createObject('enabled', parameters('enableAzureKeyVaultKms'), 'keyId', parameters('keyVaultKms').keyId, 'keyVaultNetworkAccess', parameters('keyVaultKms').keyVaultNetworkAccess, 'keyVaultResourceId', if(equals(parameters('keyVaultKms').keyVaultNetworkAccess, 'Private'), parameters('keyVaultKms').keyVaultResourceId, null())), null())]", "defender": "[if(parameters('enableAzureDefender'), createObject('securityMonitoring', createObject('enabled', parameters('enableAzureDefender')), 'logAnalyticsWorkspaceResourceId', if(not(empty(parameters('monitoringWorkspaceId'))), parameters('monitoringWorkspaceId'), null())), null())]", "workloadIdentity": "[if(parameters('enableWorkloadIdentity'), createObject('enabled', parameters('enableWorkloadIdentity')), null())]" }, diff --git a/modules/container-service/managed-cluster/tests/e2e/azure/dependencies.bicep b/modules/container-service/managed-cluster/tests/e2e/azure/dependencies.bicep index 1cdf9b765a..f1ca2663b9 100644 --- a/modules/container-service/managed-cluster/tests/e2e/azure/dependencies.bicep +++ b/modules/container-service/managed-cluster/tests/e2e/azure/dependencies.bicep @@ -79,6 +79,13 @@ resource keyVault 'Microsoft.KeyVault/vaults@2022-11-01' = { kty: 'RSA' } } + + resource kmskey 'keys@2022-07-01' = { + name: 'kmsEncryptionKey' + properties: { + kty: 'RSA' + } + } } resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2022-07-02' = { @@ -98,6 +105,16 @@ resource diskEncryptionSet 'Microsoft.Compute/diskEncryptionSets@2022-07-02' = { } } +resource keyPermissionsKeyVaultCryptoUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-KeyVault-Crypto-User-RoleAssignment') + scope: keyVault + properties: { + principalId: managedIdentity.properties.principalId + roleDefinitionId: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424') // KeyVault-Crypto-User + principalType: 'ServicePrincipal' + } +} + resource keyPermissions 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid('msi-${keyVault.id}-${location}-${managedIdentity.id}-KeyVault-Key-Read-RoleAssignment') scope: keyVault @@ -160,3 +177,6 @@ output dnsZoneResourceId string = dnsZone.id @description('The resource ID of the created Log Analytics Workspace.') output logAnalyticsWorkspaceResourceId string = logAnalyticsWorkspace.id + +@description('The uri including version of the KMS Key.') +output keyUriWithVersion string = keyVault::kmskey.properties.keyUriWithVersion diff --git a/modules/container-service/managed-cluster/tests/e2e/azure/main.test.bicep b/modules/container-service/managed-cluster/tests/e2e/azure/main.test.bicep index 7776f4752f..2d835afd94 100644 --- a/modules/container-service/managed-cluster/tests/e2e/azure/main.test.bicep +++ b/modules/container-service/managed-cluster/tests/e2e/azure/main.test.bicep @@ -189,6 +189,11 @@ module testDeployment '../../../main.bicep' = { enableAzureDefender: true enableKeyvaultSecretsProvider: true enablePodSecurityPolicy: false + enableAzureKeyVaultKms: true + keyVaultKms: { + keyId: nestedDependencies.outputs.keyUriWithVersion + keyVaultNetworkAccess: 'Public' + } lock: { kind: 'CanNotDelete' name: 'myCustomLockName'