【问题标题】:Bicep Loop over key vault keys and encrypt storage accountBicep 循环遍历密钥库密钥并加密存储帐户
【发布时间】:2021-12-08 10:46:31
【问题描述】:

我在这里对实现逻辑有一个很大的阻碍。

我正在与二头肌合作创建这些资源。

  • 存储帐户
  • 密钥保管库
  • 将存储帐户连接字符串传递给密钥保管库机密
  • 在密钥保管库中创建一个密钥并使用该密钥加密存储帐户。

前三个步骤已经完成。如果我声明 2 个存储帐户,它将自动创建 2 个秘密连接字符串和 2 个密钥。它们匹配的所有配对(存储名称和连接字符串)。

现在我面临的问题如下,首先,这是我的代码。

param tenantCode array = [
  'dsec'
  'sdre'
]

var storageName = [for item in tenantCode :{
  name: string('sthrideveur${item}')
}]


var connectionStringSecretName = [for connection in storageName :{
  name: '${connection.name}'
  
}]

output connectionStringSecretName array= [for connection in storageName :{
  name: '${connection.name}'
  
}]






resource storage_Accounts 'Microsoft.Storage/storageAccounts@2021-06-01' = [ for name in storageName :{
  name: '${name.name}'
  location: 'westeurope'
  sku: {
    name: 'Standard_RAGRS'
  }
  kind: 'StorageV2'
  properties: {
    allowCrossTenantReplication: true
    minimumTlsVersion: 'TLS1_2'
    allowBlobPublicAccess: false
    allowSharedKeyAccess: true
    networkAcls: {
      bypass: 'AzureServices'
      virtualNetworkRules: []
      ipRules: []
      defaultAction: 'Allow'
    }
    supportsHttpsTrafficOnly: true
    encryption: {
      services: {
        file: {
          keyType: 'Account'
          enabled: true
        }
        blob: {
          keyType: 'Account'
          enabled: true
        }
      }
      keySource: 'Microsoft.Storage'
      keyvaultproperties: { 
        keyname: '${tenantKey[0]}'
        keyvaulturi: keyVault.id
      }
    }
    accessTier: 'Cool'
  }
}]

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

// Store the connection string in KV if specified
resource storageAccountConnectionString 'Microsoft.KeyVault/vaults/secrets@2019-09-01' = [for name in storageName :{
  name: '${keyVault.name}/${name.name}'
  properties: {
    value: 'DefaultEndpointsProtocol=https;AccountName=${storage_Accounts[0].name};AccountKey=${listKeys('${storage_Accounts[0].id}', '${storage_Accounts[0].apiVersion}').keys[0].value};EndpointSuffix=${environment().suffixes.storage}'
  }
}]

resource tenantKey 'Microsoft.KeyVault/vaults/keys@2021-06-01-preview' = [for tenant in tenantCode : {
  name: '${keyVault.name}/Client-Key-${tenant}'
  properties: {
    keySize: 2048
    kty: 'RSA'
  }
  
}]

我有 2 个要创建的存储帐户。和钥匙,包含存储代码。我想要做并且我有问题要实现,是如何将正确的密钥与正确的存储帐户匹配。在这种特定情况下,我必须编写如下代码:

dsec
sdre

二头肌脚本将创建 2 个相应命名的存储帐户和机密:

sthrideveurdsec
sthrideveursdre

AND 2 secrets with the same name
sthrideveurdsec
sthrideveursdre

AND 2 Keys named
Client-Key-dsec
Client-Key-sdre

我要做的是使用密钥 DSEC 加密存储帐户 DSEC,并使用密钥 SDRE 加密存储 SDRE。但由于我是二头肌新手,所以我在实现这一点时遇到了一些问题。

如果有人能帮助我了解如何实现这种正确的配对,我将不胜感激。

更新: 测试 Thomas 解决方案后,这是我得到的错误:

{"status":"Failed","error":{"code":"DeploymentFailed","message":"At least one resource deployment operation failed. Please list deployment operations for details. Please see https://aka.ms/DeployOperations for usage details.","details":[{"code":"BadRequest","message":"{\r\n  \"error\": {\r\n    \"code\": \"KeyVaultPolicyError\",\r\n    \"message\": \"Keyvault policy recoverable is not set\"\r\n  }\r\n}"},{"code":"BadRequest","message":"{\r\n  \"error\": {\r\n    \"code\": \"KeyVaultPolicyError\",\r\n    \"message\": \"Keyvault policy recoverable is not set\"\r\n  }\r\n}"}]}}

【问题讨论】:

    标签: azure azure-resource-manager azure-storage-account azure-bicep


    【解决方案1】:

    我假设已创建密钥保管库并使用访问策略。

    如果您想使用客户管理的密钥创建存储,则存储需要在创建之前访问密钥保管库,因此我在示例中使用用户分配的身份。

    步骤如下:

    • 创建托管标识并授予对密钥保管库的密钥权限
    • 在密钥保管库中创建两个密钥
    • 创建存储、分配托管标识并使用密钥进行加密
    // Default values I'm using to test 
    param keyVaultName string = 'kvthomastest'
    param managedIdentityName string = 'mi-storage-encryption-thomas-test'
    
    param tenantCodes array = [
      'dsec'
      'sdre'
    ]
    
    // I'm using prefix so I dont need to create additional arrays
    var keyVaultKeyPrefix = 'Client-Key-'
    var storagePrefix = 'stthomastest'
    
    // Get a reference to key vault
    resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = {
      name: keyVaultName
    }
    
    // Create a managed identity
    resource managedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
      name: managedIdentityName
      location: resourceGroup().location
    }
    
    // Grant permissions to key vault
    resource accessPolicy 'Microsoft.KeyVault/vaults/accessPolicies@2019-09-01' = {
      name: '${keyVault.name}/add'
      properties: {
        accessPolicies: [
          {
            tenantId: subscription().tenantId
            objectId: managedIdentity.properties.principalId
            permissions: {
              // minimum required permissions
              keys: [
                'get'
                'unwrapKey'
                'wrapKey'
              ]
            }
          }
        ]
      }
    }
    
    // Create key vault keys
    resource keyVaultKeys 'Microsoft.KeyVault/vaults/keys@2021-06-01-preview' = [for tenantCode in tenantCodes: {
      name: '${keyVault.name}/${keyVaultKeyPrefix}${tenantCode}'
      properties: {
        keySize: 2048
        kty: 'RSA'
        // storage key should only needs these operations
        keyOps: [
          'unwrapKey'
          'wrapKey'
        ]
      }
    }]
    
    // Create storage accounts
    resource storageAccount 'Microsoft.Storage/storageAccounts@2021-04-01' = [for tenantCode in tenantCodes: {
      name: '${storagePrefix}${tenantCode}'
      location: resourceGroup().location
      kind: 'StorageV2'
      sku: {
        name: 'Standard_RAGRS'
      }
      // Assign the identity
      identity: {
        type: 'UserAssigned'
        userAssignedIdentities: {
          '${managedIdentity.id}': {}
        }
      }
      properties: {
        allowCrossTenantReplication: true
        minimumTlsVersion: 'TLS1_2'
        allowBlobPublicAccess: false
        allowSharedKeyAccess: true
        networkAcls: {
          bypass: 'AzureServices'
          virtualNetworkRules: []
          ipRules: []
          defaultAction: 'Allow'
        }
        supportsHttpsTrafficOnly: true
        encryption: {
          identity: {
            // specify which identity to use
            userAssignedIdentity: managedIdentity.id
          }
          keySource: 'Microsoft.Keyvault'
          keyvaultproperties: {
            keyname: '${keyVaultKeyPrefix}${tenantCode}'
            keyvaulturi: keyVault.properties.vaultUri
          }
          services: {
            file: {
              keyType: 'Account'
              enabled: true
            }
            blob: {
              keyType: 'Account'
              enabled: true
            }
          }
        }
        accessTier: 'Cool'
      }
    }]
    

    【讨论】:

    • 非常感谢您的时间和帮助。我尝试了您的代码,但出现错误,我将使用错误更新我的帖子。
    • 您是否使用与我相同的密钥保管库名称?我刚刚删除了它,你将无法重新创建它
    • 您需要设置 keyVaultName 和 managedIdentityName 参数以匹配您想要的任何名称
    • 不,我确实更改了 managedIdentity 和 KeyvaultName
    • 我发现了问题。密钥保管库应该已启用清除保护。在投票之前,我可以问你一个问题吗?我看到您创建了一个托管标识。脚本是否需要这样才能访问密钥保管库?创建 azure 托管标识与仅将“systemAssigned”提供给需要访问密钥保管库的资源之间有什么区别?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-17
    • 1970-01-01
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多