【问题标题】:"KeyVaultAuthenticationFailure" when Storage Account attempts to Access Customer Managed Key in Key Vault with Private Endpoint (Using Terraform)当存储帐户尝试使用私有端点访问 Key Vault 中的客户管理的密钥时出现“KeyVaultAuthenticationFailure”(使用 Terraform)
【发布时间】:2022-02-16 02:32:22
【问题描述】:

我们在使用 Terraform 创建使用存储在 Key Vault 中的客户管理密钥的存储帐户时遇到问题。重要的是,Key Vault 位于存储帐户必须用来访问的私有端点之后。

得到以下错误:

│错误:更新存储帐户“t3mpnarg47sa01”(资源>组“t3-mpn-arg47”)的客户管理密钥:storage.AccountsClient#Update:未能响应请求:>StatusCode=400 -- 原始错误:autorest /azure:服务返回错误。 Status=400 >Code="KeyVaultAuthenticationFailure" Message="由于 ?>keyvault 上的身份验证问题,操作失败。" │ │ 与 >module.example_storage_account.azurerm_storage_account_customer_managed_key.cmk, │ 在 ....\terraform-azurerm-pcs-edited-storage-account\main.tf 第 104 行,在资源 >“azurerm_storage_account_customer_managed_key”“cmk”中: │> 104: 资源 "azurerm_storage_account_customer_managed_key" "cmk" {

我们如何让这个连接工作?

以下代码显示了我们如何创建密钥保管库、密钥保管库专用终结点、存储帐户和客户管理的密钥。未显示 vnet 和子网的创建:

### Key Vault Creation, Key Vault Private Endpoint Creation, and Networking

resource "azurerm_key_vault" "this" {
  name                = local.name
  resource_group_name = var.resource_group_name
  location            = var.location

  tenant_id = data.azurerm_client_config.current.tenant_id
  sku_name  = var.sku_name

  network_acls {
    default_action             = "Deny"
    bypass                     = "AzureServices"
    ip_rules                   = local.ip_rules #client ip address
    virtual_network_subnet_ids = var.virtual_network_subnet_ids
  }

  enabled_for_deployment          = var.enabled_for_deployment
  enabled_for_disk_encryption     = var.enabled_for_disk_encryption
  enabled_for_template_deployment = var.enabled_for_template_deployment
  enable_rbac_authorization       = true
  purge_protection_enabled        = var.enable_purge_protection
  soft_delete_retention_days      = var.soft_delete_retention_days

  tags = merge(var.tags, local.mandatory_tags)
}

resource "azurerm_role_assignment" "kv_role_admin_kva" {
  scope                = azurerm_key_vault.this.id
  role_definition_name = "Key Vault Administrator"
  principal_id         = data.azurerm_client_config.current.object_id
}

resource "azurerm_private_endpoint" "this" {
  name                = local.private_endpoint_name
  location            = var.location
  resource_group_name = var.resource_group_name
  subnet_id           = var.subnet_id

  private_dns_zone_group {
    name                 = "privatednszonegroup"
    private_dns_zone_ids = [azurerm_private_dns_zone.this.id]
  }

  private_service_connection {
    name                           = local.private_service_connection_name
    private_connection_resource_id = var.key_vault_id
    is_manual_connection           = false
    subresource_names              = ["vault"]
  }

  lifecycle {
    # ignore_changes = [
    #   private_dns_zone_group, # Ignore changes to private_dns_zone_group as it is applied by Azure policy
    # ]
  }

  tags = merge(var.tags, local.mandatory_tags)
}

resource "azurerm_private_dns_zone" "this" {
  name                = "privatelink.vaultcore.azure.net"
  resource_group_name = var.resource_group_name
}

resource "azurerm_private_dns_zone_virtual_network_link" "this" {
  name                  = "vnetlink"
  resource_group_name   = var.resource_group_name
  private_dns_zone_name = azurerm_private_dns_zone.this.name
  virtual_network_id    = var.virtual_network_id
}

data "azurerm_private_endpoint_connection" "this" {
  name                = local.private_endpoint_name
  resource_group_name = var.resource_group_name
  depends_on          = [ azurerm_private_endpoint.this ]
}


### Storage Account Creation & Networking

resource "azurerm_storage_account" "sa" {
  name                = local.name
  resource_group_name = var.resourceGroupName
  location            = data.azurerm_resource_group.arg.location

  account_kind              = "StorageV2"
  account_tier              = "Standard"
  account_replication_type  = "LRS"
  access_tier               = "Hot"
  enable_https_traffic_only = true
  is_hns_enabled            = true
  min_tls_version           = "TLS1_2"
  shared_access_key_enabled = false
  allow_blob_public_access  = false

  identity {
    type = "SystemAssigned"
  }

  network_rules {
    default_action             = "Deny"
    bypass                     = ["AzureServices"]
    ip_rules                   = local.ipRules #client ip address
    virtualNetworkSubnetIds =   [module.example_subnet.id]
  }
}

resource "azurerm_key_vault_key" "kvkey" {
  name            = format("cmk-%s", local.name)
  key_vault_id    = var.keyVaultId
  key_type        = "RSA-HSM"
  key_size        = 2048
  key_opts        = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"]
  expiration_date = var.expirationDate
}

resource "azurerm_role_assignment" "sa_role_admin_sbdo" {
  scope                = azurerm_storage_account.sa.id
  role_definition_name = "Storage Blob Data Owner"
  principal_id         = data.azurerm_client_config.current.object_id
}

resource "azurerm_role_assignment" "sa_role_admin_sqdc" {
  scope                = azurerm_storage_account.sa.id
  role_definition_name = "Storage Queue Data Contributor"
  principal_id         = data.azurerm_client_config.current.object_id
}

resource "azurerm_role_assignment" "kv_role_client_kvc" {
  scope                = var.keyVaultId
  role_definition_name = "Key Vault Contributor"
  principal_id         = data.azurerm_client_config.current.object_id
}

resource "azurerm_role_assignment" "kv_role_sa_kvcseu" {
  scope                = var.keyVaultId
  role_definition_name = "Key Vault Crypto Service Encryption User"
  principal_id         = azurerm_storage_account.sa.identity.0.principal_id
}

# Customer Managed Key Creation (fails)
resource "azurerm_storage_account_customer_managed_key" "cmk" {
  storage_account_id = azurerm_storage_account.sa.id
  key_vault_id       = var.keyVaultId
  key_name           = azurerm_key_vault_key.kvkey.name

  depends_on = [
    azurerm_role_assignment.kv_role_client_kvc,
    azurerm_role_assignment.kv_role_sa_kvcseu,
  ]
}

【问题讨论】:

标签: azure networking terraform azure-storage


【解决方案1】:

我尝试使用以下代码创建具有私有端点和存储帐户加密的密钥库

您必须设置 shared_access_key_enabled = true 而不是 falsekey_type = "RSA" 而不是 RSA-HSM 并添加必要的依赖于其他资源块。

您可以尝试如下进行必要的更改:

### Key Vault Creation, Key Vault Private Endpoint Creation, and Networking
provider "azurerm"{
    features{}
}

data "azurerm_virtual_network" "vnet" {
  name = "ansuman-vnet"
  resource_group_name="ansumantest"
}

data "azurerm_client_config" "current" {}
resource "azurerm_key_vault" "this" {
  name                = "terraformtestkv12"
  resource_group_name = "ansumantest"
  location            = "East US"

  tenant_id = data.azurerm_client_config.current.tenant_id
  sku_name  = "standard"

  network_acls {
    default_action             = "Deny"
    bypass                     = "AzureServices"
    ip_rules                   = ["49.xx.xx.234"] #client ip address
    virtual_network_subnet_ids = ["${data.azurerm_virtual_network.vnet.id}/subnets/default"]
  }

  enabled_for_deployment          = true
  enabled_for_disk_encryption     = true
  enabled_for_template_deployment = true
  enable_rbac_authorization       = true
  purge_protection_enabled        = true
  soft_delete_retention_days      = 7
}

resource "azurerm_role_assignment" "kv_role_admin_kva" {
  scope                = azurerm_key_vault.this.id
  role_definition_name = "Key Vault Administrator"
  principal_id         = data.azurerm_client_config.current.object_id
}
resource "azurerm_private_dns_zone" "this" {
  name                = "privatelink.vaultcore.azure.net"
  resource_group_name = "ansumantest"
}

resource "azurerm_private_dns_zone_virtual_network_link" "this" {
  name                  = "vnetlink"
  resource_group_name   = "ansumantest"
  private_dns_zone_name = azurerm_private_dns_zone.this.name
  virtual_network_id    = data.azurerm_virtual_network.vnet.id
}
resource "azurerm_private_endpoint" "this" {
  name                = "keyvault-endpoint"
  location            = "eastus"
  resource_group_name = "ansumantest"
  subnet_id           = "${data.azurerm_virtual_network.vnet.id}/subnets/default"

  private_dns_zone_group {
    name                 = "privatednszonegroup"
    private_dns_zone_ids = [azurerm_private_dns_zone.this.id]
  }

  private_service_connection {
    name                           = "keyvault-privatednsconnection"
    private_connection_resource_id = azurerm_key_vault.this.id
    is_manual_connection           = false
    subresource_names              = ["vault"]
  }
  depends_on = [
    azurerm_private_dns_zone_virtual_network_link.this
  ]
}

### Storage Account Creation & Networking

resource "azurerm_storage_account" "sa" {
  name                = "ansumantestsa12"
  resource_group_name = "ansumantest"
  location            = "eastus"

  account_kind              = "StorageV2"
  account_tier              = "Standard"
  account_replication_type  = "LRS"
  access_tier               = "Hot"
  enable_https_traffic_only = true
  is_hns_enabled            = true
  min_tls_version           = "TLS1_2"
  shared_access_key_enabled = true ##enable to access the storage account with key
  allow_blob_public_access  = false

  identity {
    type = "SystemAssigned"
  }

  network_rules {
    default_action             = "Deny"
    bypass                     = ["AzureServices"]
    ip_rules                   = ["49.xx.xx.234"] #client ip address
    virtual_network_subnet_ids =   ["${data.azurerm_virtual_network.vnet.id}/subnets/default"]
  }
  depends_on = [
    azurerm_key_vault.this,
    azurerm_private_endpoint.this
  ]
}

resource "azurerm_key_vault_key" "kvkey" {
  name            = "storageencryptionkey"
  key_vault_id    = azurerm_key_vault.this.id
  key_type        = "RSA"#as its normal keyvault you can't use RSA-HSM instead use RSA
  key_size        = 2048
  key_opts        = ["decrypt", "encrypt", "sign", "unwrapKey", "verify", "wrapKey"]
    depends_on = [
    azurerm_key_vault.this,
    azurerm_private_endpoint.this
  ]
}

resource "azurerm_role_assignment" "sa_role_admin_sbdo" {
  scope                = azurerm_storage_account.sa.id
  role_definition_name = "Storage Blob Data Owner"
  principal_id         = data.azurerm_client_config.current.object_id
}

resource "azurerm_role_assignment" "sa_role_admin_sqdc" {
  scope                = azurerm_storage_account.sa.id
  role_definition_name = "Storage Queue Data Contributor"
  principal_id         = data.azurerm_client_config.current.object_id
}

resource "azurerm_role_assignment" "kv_role_client_kvc" {
  scope                = azurerm_key_vault.this.id
  role_definition_name = "Key Vault Contributor"
  principal_id         = data.azurerm_client_config.current.object_id
}

resource "azurerm_role_assignment" "kv_role_sa_kvcseu" {
  scope                = azurerm_key_vault.this.id
  role_definition_name = "Key Vault Crypto Service Encryption User"
  principal_id         = azurerm_storage_account.sa.identity.0.principal_id
}

# Customer Managed Key Creation (fails)
resource "azurerm_storage_account_customer_managed_key" "cmk" {
  storage_account_id = azurerm_storage_account.sa.id
  key_vault_id       = azurerm_key_vault.this.id
  key_name           = azurerm_key_vault_key.kvkey.name

  depends_on = [
    azurerm_role_assignment.kv_role_admin_kva,
    azurerm_role_assignment.kv_role_client_kvc,
    azurerm_role_assignment.kv_role_sa_kvcseu,
    azurerm_storage_account.sa
  ]
}

输出:

【讨论】:

    【解决方案2】:

    我最近在使用 terraform 在 azure keyvault 上创建私有端点时遇到了问题,然后在我创建机密的同一个 terraform 中时无法访问该资源。

    问题是由私有端点状态“待定”引起的,并且需要几秒钟才能被“批准”(使用自动 rbac)...所以只需在其中添加等待或依赖于秘密创建在您知道是最后创建的资源上,并且需要一段时间才能创建。

    【讨论】:

      猜你喜欢
      • 2019-12-24
      • 2019-07-28
      • 2021-01-26
      • 1970-01-01
      • 2020-08-22
      • 2022-01-26
      • 1970-01-01
      • 2021-04-18
      • 2020-01-17
      相关资源
      最近更新 更多