Adding support for ETCD encryption with KMS (#351)

* various improvements

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* kms

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* contrib

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* KMS working on public kv

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* adding support for private kms

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* Updating branch to main

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* tested and working

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* added UI

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* Added byoKeyId to the UI

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* kms byo key validation

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* better error message

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* better regex

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* regext dot bracket

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* better regex still....!  (amazing :D )

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* slash dots

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* useless-regexp-character

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* regex

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* byo kms bicep

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* UI private link behaviour

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* key var conditionality

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* metadata

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* Add Byo KV RG

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* meta

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* added ui for rg name

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* kms working!

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

* typos

Signed-off-by: Gordonby <gordon.byers@microsoft.com>

Signed-off-by: Gordonby <gordon.byers@microsoft.com>
This commit is contained in:
Gordon Byers 2022-09-21 20:32:50 +01:00 коммит произвёл GitHub
Родитель c103a28ff1
Коммит 3a5bbcd0f1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
15 изменённых файлов: 392 добавлений и 17 удалений

5
.github/workflows/regressionparams.yml поставляемый
Просмотреть файл

@ -99,7 +99,7 @@ jobs:
}
}
- name: Replace subnet and dnszone param values from secret
- name: Replace subnet, dnszone and kv param values from secret
shell: pwsh
run: |
$paramFilePath="${{ env.ParamDir }}${{ matrix.files }}"
@ -114,6 +114,9 @@ jobs:
if($params.parameters.byoAGWSubnetId.value -ne $null) {
$params.parameters.byoAGWSubnetId.value = "${{ secrets.ByoAgwSubnetId }}"
}
if($params.parameters.keyVaultKmsByoKeyId.value -ne $null) {
$params.parameters.keyVaultKmsByoKeyId.value = "${{ secrets.ByoKmsKeyId }}"
}
$params | ConvertTo-Json -Depth 4 | Out-File "${{ env.ParamDir }}${{ matrix.files }}"

24
.github/workflows_dep/regressionparams/byoKms.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,24 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"resourceName": {
"value": "az-k8s-kmsbyopub"
},
"agentVMSize": {
"value": "Standard_DS3_v2"
},
"JustUseSystemPool": {
"value": true
},
"keyVaultKmsCreate": {
"value": false
},
"keyVaultKmsByoRG": {
"value": "Automation-Actions-AksDeployCI"
},
"keyVaultKmsByoKeyId": {
"value": "https://YOURVAULTNAME.vault.azure.net/keys/YOURKEYNAME/KEYVERSIONSTRING"
}
}
}

36
.github/workflows_dep/regressionparams/byoKmsPrivateLink.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,36 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"resourceName": {
"value": "az-k8s-kmsbyopl"
},
"agentVMSize": {
"value": "Standard_DS3_v2"
},
"JustUseSystemPool": {
"value": true
},
"custom_vnet": {
"value": true
},
"privateLinks": {
"value": true
},
"bastion": {
"value": true
},
"registries_sku": {
"value": "Premium"
},
"keyVaultKmsCreate": {
"value": false
},
"keyVaultKmsByoRG": {
"value": "Automation-Actions-AksDeployCI"
},
"keyVaultKmsByoKeyId": {
"value": "https://YOURVAULTNAME.vault.azure.net/keys/YOURKEYNAME/KEYVERSIONSTRING"
}
}
}

21
.github/workflows_dep/regressionparams/publicKms.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,21 @@
{
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"resourceName": {
"value": "az-k8s-kmspp1"
},
"agentVMSize": {
"value": "Standard_DS3_v2"
},
"JustUseSystemPool": {
"value": true
},
"keyVaultKmsCreate": {
"value": true
},
"keyVaultKmsOfficerRolePrincipalId": {
"value": "Make sure to override this value"
}
}
}

Просмотреть файл

@ -78,7 +78,7 @@ If you're interested in contributing, we have two contribution guides in the rep
Guide | Description
----- | -----------
[Generic Contribution Guide](CONTRIBUTING.md) | Talks about the branching strategy, using CodeSpaces and general guidance
[Helper Contribtion Guide](https://github.com/Azure/AKS-Construction/blob/main/docs/ContributingHelper.md) | Talks about the structure of the app and walks through a sample change of adding a new feature to the UI and Bicep
[Helper Contribution Guide](https://github.com/Azure/AKS-Construction/blob/main/docs/ContributingHelper.md) | Talks about the structure of the app and walks through a sample change of adding a new feature to the UI and Bicep
This project welcomes contributions and suggestions. Most contributions require you to agree to a
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us

Просмотреть файл

@ -45,6 +45,9 @@
},
"use-stable-vm-image": {
"level": "warning"
},
"secure-secrets-in-params" : {
"level": "error"
}
}
}

24
bicep/keyvaultkey.bicep Normal file
Просмотреть файл

@ -0,0 +1,24 @@
param keyVaultName string
resource kv 'Microsoft.KeyVault/vaults@2021-11-01-preview' existing = {
name: keyVaultName
}
resource kvKmsKey 'Microsoft.KeyVault/vaults/keys@2021-11-01-preview' = {
name: 'kmskey'
parent: kv
properties: {
kty: 'RSA'
keySize: 2048
keyOps: [
'wrapKey'
'unwrapKey'
'decrypt'
'encrypt'
'verify'
'sign'
]
}
}
output keyVaultKmsKeyUri string = kvKmsKey.properties.keyUriWithVersion

Просмотреть файл

@ -11,6 +11,24 @@ param rbacSecretOfficerSps array = []
@description('An array of Service Principal IDs')
param rbacCertOfficerSps array = []
@description('An array of Service Principal IDs')
param rbacCryptoUserSps array = []
@description('An array of Service Principal IDs')
param rbacCryptoOfficerSps array = []
@description('An array of Service Principal IDs')
param rbacCryptoServiceEncryptSps array = []
@description('An array of Service Principal IDs')
param rbacKvContributorSps array = []
@description('An array of Service Principal IDs')
param rbacAdminSps array = []
@description('An array of User IDs')
param rbacCryptoOfficerUsers array = []
@description('An array of User IDs')
#disable-next-line secure-secrets-in-params //Disabling validation of this linter rule as param does not contain a secret.
param rbacSecretOfficerUsers array = []
@ -18,9 +36,17 @@ param rbacSecretOfficerUsers array = []
@description('An array of User IDs')
param rbacCertOfficerUsers array = []
@description('An array of User IDs')
param rbacAdminUsers array = []
var keyVaultAdministratorRole = resourceId('Microsoft.Authorization/roleDefinitions', '00482a5a-887f-4fb3-b363-3b7fe8e74483')
var keyVaultContributorRole = resourceId('Microsoft.Authorization/roleDefinitions', 'f25e0fa2-a7c8-4377-a976-54943a77a395')
var keyVaultSecretsUserRole = resourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')
var keyVaultSecretsOfficerRole = resourceId('Microsoft.Authorization/roleDefinitions', 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7')
var keyVaultCertsOfficerRole = resourceId('Microsoft.Authorization/roleDefinitions', 'a4417e6f-fecd-4de8-b567-7b0420556985')
var keyVaultCryptoUserRole = resourceId('Microsoft.Authorization/roleDefinitions', '12338af0-0e69-4776-bea7-57ae8d297424')
var keyVaultCryptoOfficerRole = resourceId('Microsoft.Authorization/roleDefinitions', '14b46e9e-c2b7-41b4-b07b-48a6ebf60603')
var keyVaultCryptoServiceEncrpytionRole = resourceId('Microsoft.Authorization/roleDefinitions','e147488a-f6f5-4113-8e2d-b22465e65bf6')
resource kv 'Microsoft.KeyVault/vaults@2021-11-01-preview' existing = {
name: keyVaultName
@ -56,6 +82,66 @@ resource rbacCertsOfficerSp 'Microsoft.Authorization/roleAssignments@2022-04-01'
}
}]
resource rbacCryptoUserSp 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for rbacSp in rbacCryptoUserSps : if(!empty(rbacSp)) {
scope: kv
name: guid(kv.id, rbacSp, keyVaultCryptoUserRole)
properties: {
roleDefinitionId: keyVaultCryptoUserRole
principalType: 'ServicePrincipal'
principalId: rbacSp
}
}]
resource rbacCryptoServiceEncryptionSp 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for rbacSp in rbacCryptoServiceEncryptSps : if(!empty(rbacSp)) {
scope: kv
name: guid(kv.id, rbacSp, keyVaultCryptoServiceEncrpytionRole)
properties: {
roleDefinitionId: keyVaultCryptoServiceEncrpytionRole
principalType: 'ServicePrincipal'
principalId: rbacSp
}
}]
resource rbacKvContributorSp 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for rbacSp in rbacKvContributorSps : if(!empty(rbacSp)) {
scope: kv
name: guid(kv.id, rbacSp, keyVaultContributorRole)
properties: {
roleDefinitionId: keyVaultContributorRole
principalType: 'ServicePrincipal'
principalId: rbacSp
}
}]
resource rbacCryptoOfficerSp 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for rbacSp in rbacCryptoOfficerSps : if(!empty(rbacSp)) {
scope: kv
name: guid(kv.id, rbacSp, keyVaultCryptoUserRole)
properties: {
roleDefinitionId: keyVaultCryptoOfficerRole
principalType: 'ServicePrincipal'
principalId: rbacSp
}
}]
resource rbacAdminSp 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for rbacSp in rbacAdminSps : if(!empty(rbacSp)) {
scope: kv
name: guid(kv.id, rbacSp, keyVaultAdministratorRole)
properties: {
roleDefinitionId: keyVaultAdministratorRole
principalType: 'ServicePrincipal'
principalId: rbacSp
}
}]
resource rbacCryptoOfficerUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for rbacSp in rbacCryptoOfficerUsers : if(!empty(rbacSp)) {
scope: kv
name: guid(kv.id, rbacSp, keyVaultCryptoOfficerRole)
properties: {
roleDefinitionId: keyVaultCryptoOfficerRole
principalType: 'User'
principalId: rbacSp
}
}]
resource rbacSecretOfficerUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for rbacSp in rbacSecretOfficerUsers : if(!empty(rbacSp)) {
scope: kv
name: guid(kv.id, rbacSp, keyVaultSecretsOfficerRole)
@ -75,3 +161,13 @@ resource rbacCertsOfficerUser 'Microsoft.Authorization/roleAssignments@2022-04-0
principalId: rbacSp
}
}]
resource rbacAdminUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = [for rbacSp in rbacAdminUsers : if(!empty(rbacSp)) {
scope: kv
name: guid(kv.id, rbacSp, keyVaultAdministratorRole)
properties: {
roleDefinitionId: keyVaultAdministratorRole
principalType: 'User'
principalId: rbacSp
}
}]

Просмотреть файл

@ -38,7 +38,7 @@ param byoAKSSubnetId string = ''
param byoAGWSubnetId string = ''
//--- Custom, BYO networking and PrivateApiZones requires BYO AKS User Identity
var createAksUai = custom_vnet || !empty(byoAKSSubnetId) || !empty(dnsApiPrivateZoneId)
var createAksUai = custom_vnet || !empty(byoAKSSubnetId) || !empty(dnsApiPrivateZoneId) || keyVaultKmsCreateAndPrereqs || !empty(keyVaultKmsByoKeyId)
resource aksUai 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = if (createAksUai) {
name: 'id-aks-${resourceName}'
location: location
@ -95,7 +95,7 @@ param privateLinkSubnetAddressPrefix string = '10.240.4.192/26'
@description('The address range for Azure Firewall in your custom vnet')
param vnetFirewallSubnetAddressPrefix string = '10.240.50.0/24'
@description('Enable support for private links')
@description('Enable support for private links (required custom_vnet)')
param privateLinks bool = false
@description('Enable support for ACR private pool')
@ -194,8 +194,9 @@ param keyVaultAksCSI bool = false
@description('Rotation poll interval for the AKS KV CSI provider')
param keyVaultAksCSIPollInterval string = '2m'
@description('Creates a KeyVault for application secrets (eg. CSI)')
module kv 'keyvault.bicep' = if(keyVaultCreate) {
name: 'keyvault'
name: 'keyvaultApps'
params: {
resourceName: resourceName
keyVaultPurgeProtection: keyVaultPurgeProtection
@ -217,7 +218,7 @@ var rbacSecretUserSps = union([deployAppGw && appgwKVIntegration ? appGwIdentity
@description('A seperate module is used for RBAC to avoid delaying the KeyVault creation and causing a circular reference.')
module kvRbac 'keyvaultrbac.bicep' = if (keyVaultCreate) {
name: 'KeyVaultRbac'
name: 'KeyVaultAppsRbac'
params: {
keyVaultName: keyVaultCreate ? kv.outputs.keyVaultName : ''
@ -236,6 +237,125 @@ output keyVaultName string = keyVaultCreate ? kv.outputs.keyVaultName : ''
output keyVaultId string = keyVaultCreate ? kv.outputs.keyVaultId : ''
/* KeyVault for KMS Etcd*/
@description('Enable encryption at rest for Kubernetes etcd data')
param keyVaultKmsCreate bool = false
@description('Bring an existing Key from an existing Key Vault')
param keyVaultKmsByoKeyId string = ''
@description('The resource group for the existing KMS Key Vault')
param keyVaultKmsByoRG string = resourceGroup().name
@description('The PrincipalId of the deploying user, which is necessary when creating a Kms Key')
param keyVaultKmsOfficerRolePrincipalId string = ''
@description('The extracted name of the existing Key Vault')
var keyVaultKmsByoName = !empty(keyVaultKmsByoKeyId) ? split(split(keyVaultKmsByoKeyId,'/')[2],'.')[0] : ''
@description('The deployment delay to introduce when creating a new keyvault for kms key')
var kmsRbacWaitSeconds=30
@description('This indicates if the deploying user has provided their PrincipalId in order for the key to be created')
var keyVaultKmsCreateAndPrereqs = keyVaultKmsCreate && !empty(keyVaultKmsOfficerRolePrincipalId) && privateLinks == false
resource kvKmsByo 'Microsoft.KeyVault/vaults@2021-11-01-preview' existing = if(!empty(keyVaultKmsByoName)) {
name: keyVaultKmsByoName
scope: resourceGroup(keyVaultKmsByoRG)
}
@description('Creates a new Key vault for a new KMS Key')
module kvKms 'keyvault.bicep' = if(keyVaultKmsCreateAndPrereqs) {
name: 'keyvaultKms-${resourceName}'
params: {
resourceName: 'kms${resourceName}'
keyVaultPurgeProtection: keyVaultPurgeProtection
keyVaultSoftDelete: keyVaultSoftDelete
location: location
privateLinks: privateLinks
//aksUaiObjectId: aksUai.properties.principalId
}
}
module kvKmsCreatedRbac 'keyvaultrbac.bicep' = if(keyVaultKmsCreateAndPrereqs) {
name: 'keyvaultKmsRbacs-${resourceName}'
params: {
keyVaultName: keyVaultKmsCreate ? kvKms.outputs.keyVaultName : ''
//We can't create a kms kv and key and do privatelink. Private Link is a BYO scenario
// rbacKvContributorSps : [
// createAksUai && privateLinks ? aksUai.properties.principalId : ''
// ]
//This allows the Aks Cluster to access the key vault key
rbacCryptoUserSps: [
createAksUai ? aksUai.properties.principalId : ''
]
//This allows the Deploying user to create the key vault key
rbacCryptoOfficerUsers: [
!empty(keyVaultKmsOfficerRolePrincipalId) && !automatedDeployment ? keyVaultKmsOfficerRolePrincipalId : ''
]
//This allows the Deploying sp to create the key vault key
rbacCryptoOfficerSps: [
!empty(keyVaultKmsOfficerRolePrincipalId) && automatedDeployment ? keyVaultKmsOfficerRolePrincipalId : ''
]
}
}
module kvKmsByoRbac 'keyvaultrbac.bicep' = if(!empty(keyVaultKmsByoKeyId)) {
name: 'keyvaultKmsByoRbacs-${resourceName}'
scope: resourceGroup(keyVaultKmsByoRG)
params: {
keyVaultName: kvKmsByo.name
//Contribuor allows AKS to create the private link
rbacKvContributorSps : [
createAksUai && privateLinks ? aksUai.properties.principalId : ''
]
//This allows the Aks Cluster to access the key vault key
rbacCryptoUserSps: [
createAksUai ? aksUai.properties.principalId : ''
]
}
}
@description('It can take time for the RBAC to propagate, this delays the deployment to avoid this problem')
module waitForKmsRbac 'br/public:deployment-scripts/wait:1.0.1' = if(keyVaultKmsCreateAndPrereqs && kmsRbacWaitSeconds>0) {
name: 'keyvaultKmsRbac-waits-${resourceName}'
params: {
waitSeconds: kmsRbacWaitSeconds
location: location
}
dependsOn: [
kvKmsCreatedRbac
]
}
@description('Adding a key to the keyvault... We can only do this for public key vaults')
module kvKmsKey 'keyvaultkey.bicep' = if(keyVaultKmsCreateAndPrereqs) {
name: 'keyvaultKmsKeys-${resourceName}'
params: {
keyVaultName: keyVaultKmsCreateAndPrereqs ? kvKms.outputs.keyVaultName : ''
}
dependsOn: [waitForKmsRbac]
}
var azureKeyVaultKms = {
securityProfile : {
azureKeyVaultKms : {
enabled: keyVaultKmsCreateAndPrereqs || !empty(keyVaultKmsByoKeyId)
keyId: keyVaultKmsCreateAndPrereqs ? kvKmsKey.outputs.keyVaultKmsKeyUri : !empty(keyVaultKmsByoKeyId) ? keyVaultKmsByoKeyId : ''
keyVaultNetworkAccess: privateLinks ? 'private' : 'public'
keyVaultResourceId: privateLinks && !empty(keyVaultKmsByoKeyId) ? kvKmsByo.id : ''
}
}
}
@description('The name of the Kms Key Vault')
output keyVaultKmsName string = keyVaultKmsCreateAndPrereqs ? kvKms.outputs.keyVaultName : !empty(keyVaultKmsByoKeyId) ? keyVaultKmsByoName : ''
@description('Indicates if the user has supplied all the correct parameter to use a AKSC Created KMS')
output kmsCreatePrerequisitesMet bool = keyVaultKmsCreateAndPrereqs
/* ___ ______ .______
/ \ / | | _ \
/ ^ \ | ,----' | |_) |
@ -973,7 +1093,6 @@ var agentPoolProfiles = JustUseSystemPool ? array(union(systemPoolBase, userPool
var akssku = AksPaidSkuForSLA ? 'Paid' : 'Free'
var aks_addons = union({
azurepolicy: {
config: {
@ -1110,7 +1229,8 @@ var aksProperties = union({
}
},
aksOutboundTrafficType == 'managedNATGateway' ? managedNATGatewayProfile : {},
defenderForContainers && createLaw ? azureDefenderSecurityProfile : {}
defenderForContainers && createLaw ? azureDefenderSecurityProfile : {},
keyVaultKmsCreateAndPrereqs || !empty(keyVaultKmsByoKeyId) ? azureKeyVaultKms : {}
)
resource aks 'Microsoft.ContainerService/managedClusters@2022-05-02-preview' = {
@ -1126,6 +1246,7 @@ resource aks 'Microsoft.ContainerService/managedClusters@2022-05-02-preview' = {
}
dependsOn: [
privateDnsZoneRbac
waitForKmsRbac
]
}
output aksClusterName string = aks.name

Просмотреть файл

@ -29,6 +29,7 @@
"azurerm",
"bitnami",
"Burstable",
"byoprivate",
"BYOVNET",
"carvals",
"Cleanup",
@ -41,12 +42,13 @@
"currenttab",
"currt",
"currv",
"Daemonset",
"dapr",
"Dapr",
"Daemonset",
"demoapp",
"denydefault",
"deploycmd",
"deploystr",
"DNAT",
"dnsname",
"dnszones",
@ -56,19 +58,18 @@
"externaldns",
"fluentui",
"ghpages",
"gitops",
"githubrepo",
"deploystr",
"updatevals",
"githubrepobranch",
"gitops",
"Grafana",
"hashicorp",
"ilbsub",
"initializr",
"Inconsolata",
"initializr",
"jsondecode",
"jsonencode",
"Jumpboxes",
"keda",
"keyvault",
"khowling",
"kube",
@ -98,6 +99,7 @@
"NSG's",
"omsagent",
"pagename",
"petclinic",
"pivotkey",
"playwrighttests",
"podid",
@ -118,6 +120,7 @@
"testid",
"Tfcmd",
"tfplan",
"updatevals",
"urlname",
"userauth",
"valres",
@ -127,8 +130,7 @@
"vnetprivateend",
"Walkthrough",
"Wautoscale",
"Wsku",
"keda"
"Wsku"
],
"ignoreWords": [
"sconfiguration",

Просмотреть файл

@ -40,4 +40,4 @@ Sample Repo | Description
1. In your repo, create a new file in your `.github/workflows` folder, pasting in the yaml from the GitHub Actions script box
1. Commit the file to your main branch
1. In your repo, navigate to the actions tab and initiate the new workflow
1. Inspect the created resources in your Azure Subscription
1. Inspect the created resources in your Azure Subscription

Просмотреть файл

@ -23,7 +23,7 @@ export const VMs = [
]
export default function ({ tabValues, updateFn, featureFlag, invalidArray }) {
const { cluster } = tabValues
const { net, addons, cluster, deploy } = tabValues
const defenderFeatureFlag = featureFlag.includes('defender')
@ -339,6 +339,42 @@ export default function ({ tabValues, updateFn, featureFlag, invalidArray }) {
/>
</Stack.Item>
<Separator className="notopmargin" />
<Stack.Item align="start">
<Label required={true}>
Key Management Service (KMS) etcd Encryption
</Label>
<MessageBar messageBarType={MessageBarType.info}>
Using the CSI Secrets Add-On, with volume mounted secrets is the recommended approach for secrets management. <Link target='_' href='https://docs.microsoft.com/azure/aks/csi-secrets-store-driver'>docs</Link>
</MessageBar>
<MessageBar messageBarType={MessageBarType.info} styles={{ root: { display: (net.vnetprivateend ? "block" : "none") } }}>
Using an existing Key Vault for KMS is the only supported scenario when using Private Link Networking
</MessageBar>
<MessageBar messageBarType={MessageBarType.warning} styles={{ root: { display: (cluster.keyVaultKms !== "none" ? "block" : "none") } }}>
KMS requires the customer to be responsible for key management (to include rotation).
<br />
Mismanagement can cause the secrets to be unrecoverable in the cluster. <Link target='_' href='https://docs.microsoft.com/azure/aks/use-kms-etcd-encryption'>docs</Link>
</MessageBar>
<ChoiceGroup
selectedKey={cluster.keyVaultKms}
styles={{ root: { marginLeft: '50px' } }}
options={[
{ key: 'none', text: 'No encryption of etcd required' },
{ key: 'public', text: 'Create a new Key Vault with least privileged access and generate the key', disabled: net.vnetprivateend },
{ key: 'byoprivate', text: 'Use an existing Key Vault Key.' }
]}
onChange={(ev, { key }) => updateFn("keyVaultKms", key)}
/>
<Stack.Item align="center" styles={{ root: { marginLeft:'100px', maxWidth: '700px', display: (cluster.keyVaultKms === "byoprivate" ? "block" : "none") } }} >
<TextField label="Existing Key Identifier" onChange={(ev, val) => updateFn("keyVaultKmsByoKeyId", val)} value={cluster.keyVaultKmsByoKeyId} errorMessage={getError(invalidArray, 'keyVaultKmsByoKeyId')} />
<TextField label="Key Vault Resource Group Name" onChange={(ev, val) => updateFn("keyVaultKmsByoRG", val)} value={cluster.keyVaultKmsByoRG} required errorMessage={getError(invalidArray, 'keyVaultKmsByoRG')} />
<MessageBar messageBarType={MessageBarType.warning}>The deploying user must have RBAC permission (Owner) on the existing vault to create new RBAC permissions for the AKS cluster to access the key and (if configured) create the network private link</MessageBar>
</Stack.Item>
</Stack.Item>
<Stack.Item align="center" styles={{ root: { maxWidth: '700px', display: (cluster.apisecurity === "private" ? "block" : "none") } }} >
<Label style={{ marginBottom: "0px" }}>Private dns zone mode for private cluster.</Label>
<Stack tokens={{ childrenGap: 15 }}>

Просмотреть файл

@ -88,6 +88,10 @@ export default function DeployTab({ defaults, updateFn, tabValues, invalidArray,
...(net.vnet_opt === "byo" && {
...(net.aksOutboundTrafficType !== defaults.net.aksOutboundTrafficType && {aksOutboundTrafficType: net.aksOutboundTrafficType})
}),
...(cluster.keyVaultKms !== defaults.cluster.keyVaultKms && {
...(cluster.keyVaultKms === "public" && {keyVaultKmsCreate: true, keyVaultKmsOfficerRolePrincipalId: "$(az ad signed-in-user show --query id --out tsv)"}),
...(cluster.keyVaultKms === "byoprivate" && cluster.keyVaultKmsByoKeyId !== '' && cluster.keyVaultKmsByoRG !== '' && {keyVaultKmsByoKeyId: cluster.keyVaultKmsByoKeyId, keyVaultKmsByoRG: cluster.keyVaultKmsByoRG}),
}),
...(addons.csisecret !== "none" && { keyVaultAksCSI: true }),
...(addons.csisecret === 'akvNew' && { keyVaultCreate: true, ...(deploy.kvCertSecretRole && { keyVaultOfficerRolePrincipalId: "$(az ad signed-in-user show --query id --out tsv)"}) }),
...(addons.csisecret !== "none" && addons.keyVaultAksCSIPollInterval !== defaults.addons.keyVaultAksCSIPollInterval && { keyVaultAksCSIPollInterval: addons.keyVaultAksCSIPollInterval }),

Просмотреть файл

@ -330,6 +330,8 @@ export default function PortalNav({ config }) {
invalidFn('cluster', 'osDiskType', cluster.osDiskType === 'Ephemeral' && !VMs.find(i => i.key === cluster.vmSize).eph, 'The selected VM cache is not large enough to support Ephemeral. Select \'Managed\' or a VM with a larger cache')
invalidFn('cluster', 'aad_tenant_id', cluster.enable_aad && cluster.use_alt_aad && cluster.aad_tenant_id.length !== 36, 'Enter Valid Directory ID')
invalidFn('addons', 'registry', net.vnetprivateend && (addons.registry !== 'Premium' && addons.registry !== 'none'), 'Premium tier is required for Private Link, either select Premium, or disable Private Link')
invalidFn('cluster', 'keyVaultKmsByoKeyId', cluster.keyVaultKms === "byoprivate" && !cluster.keyVaultKmsByoKeyId.match('https:\/\/[^]+.vault.azure.net/keys/[^ ]+/[^ ]+$'), 'Enter valid KeyVault Versioned Key ID (https://YOURVAULTNAME.vault.azure.net/keys/YOURKEYNAME/KEYVERSIONSTRING)')
invalidFn('cluster', 'keyVaultKmsByoRG', cluster.keyVaultKms === "byoprivate" && !cluster.keyVaultKmsByoRG, 'Enter existing KeyVault Resource Group Name')
invalidFn('addons', 'dnsZoneId', addons.dns && !addons.dnsZoneId.match('^/subscriptions/[^/ ]+/resourceGroups/[^/ ]+/providers/Microsoft.Network/(dnszones|privateDnsZones)/[^/ ]+$'), 'Enter valid Azure Public or Private DNS Zone resourceId')
invalidFn('cluster', 'dnsApiPrivateZoneId', cluster.apisecurity === 'private' && cluster.privateClusterDnsMethod==='privateDnsZone' && !cluster.dnsApiPrivateZoneId.match('^/subscriptions/[^/ ]+/resourceGroups/[^/ ]+/providers/Microsoft.Network/privateDnsZones/[^/ ]+.azmk8s.io$'), 'Enter valid Azure Private DNS Zone resourceId')
invalidFn('addons', 'certEmail', addons.certMan && !addons.certEmail.match('^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+$'), 'Enter valid email for certificate generation')

Просмотреть файл

@ -28,6 +28,9 @@
"deployItemKey": "deployArmCli"
},
"cluster": {
"keyVaultKmsByoRG": "",
"keyVaultKmsByoKeyId": "",
"keyVaultKms": "none",
"AksPaidSkuForSLA": false,
"apisecurity": "none",
"privateClusterDnsMethod": "system",