在第一个 terraform 应用中,此配置当前成功创建了一个密钥保管库,并使用使用随机资源创建的值填充“秘密”列表中的秘密。
此后每次运行此配置都会引发此错误: │** 错误**: ID 为“https://testingkeyvault.vault.azure.net/secrets/Password1/3e4cdc60c7e12345a228fd4250b58191”的资源已存在 - 要通过 Terraform 进行管理,需要将此资源导入到状态中。请参阅“azurerm_key_vault_secret”的资源文档了解更多信息。
variable "secrets" {
type = list(string)
default = [
"Password1",
"Password2",
"Password3",
"Password4"
]
}
data "azurerm_client_config" "current" {
provider = azurerm.PlatformManagement
}
data "azurerm_key_vault" "existing" {
provider = azurerm.PlatformManagement
name = var.KeyVaultName
resource_group_name = var.KeyVault_Rg_Name
depends_on = [azurerm_key_vault.pman-vault]
}
resource "azurerm_key_vault" "pman-vault" {
provider = azurerm.PlatformManagement
name = var.KeyVaultName
location = var.Location
resource_group_name = var.KeyVault_Rg_Name
enabled_for_disk_encryption = true
tenant_id = data.azurerm_client_config.current.tenant_id
soft_delete_retention_days = 7
purge_protection_enabled = false
sku_name = "standard"
enable_rbac_authorization = true
data "azurerm_key_vault_secret" "existing-secrets" {
count = length(var.secrets)
name = var.secrets[count.index]
key_vault_id = azurerm_key_vault.pman-vault.id
depends_on = [azurerm_key_vault_secret.pman-secrets]
}
resource "random_password" "password" {
count = var.create_secrets ? length(var.secrets) : 0
length = 15
special = true
override_special = "!@#$%&*()-_=+[]{}<>:?"
}
resource "azurerm_key_vault_secret" "pman-secrets" {
count = var.create_secrets ? length(var.secrets) : 0
name = var.secrets[count.index]
value = random_password.password[count.index].result
key_vault_id = azurerm_key_vault.pman-vault.id
lifecycle {
prevent_destroy = true
}
depends_on = [azurerm_key_vault.pman-vault]
}
我正在寻找的结果是它能够检测到它已经创建并存在于 keyvault 中的密码,并且 terraform 代码能够幂等地运行。我做错了什么以及我可以做什么来实现这一目标?
我尝试配置 Terraform - Azure Key Vault Secrets 创建,但不是幂等的,我能够成功配置要求。
Terraform 配置的问题在于您在
count
资源上使用 azurerm_key_vault_secret
属性,而没有指定 for_each
参数。这意味着 Terraform 将为 secrets
变量中的每个项目创建一个新的密钥,即使该密钥已存在于 Key Vault 中。
为了使您的 Terraform 配置具有幂等性,您需要使用
for_each
参数来指定在创建机密时要迭代的数据源。在本例中,您想要迭代 azurerm_key_vault_secret.existing-secrets
数据源。
这是您的 Terraform 配置的修改版本,它是幂等的:
我的地形配置:
provider "azurerm" {
features {}
}
variable "secrets" {
type = list(string)
default = [
"Password1",
"Password2",
"Password3",
"Password4"
]
}
variable "KeyVaultName" {
description = "Name of the KeyVault"
default = "demovksbvaultvk"
}
variable "KeyVault_Rg_Name" {
description = "Resource Group of the KeyVault"
default = "v-sakavya"
}
variable "Location" {
description = "Azure region for the KeyVault"
default = "East US"
}
data "azurerm_client_config" "current" {}
data "azurerm_key_vault" "existing" {
name = var.KeyVaultName
resource_group_name = var.KeyVault_Rg_Name
}
resource "azurerm_key_vault" "pman-vault" {
count = data.azurerm_key_vault.existing.id != null ? 0 : 1
name = var.KeyVaultName
location = var.Location
resource_group_name = var.KeyVault_Rg_Name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
soft_delete_retention_days = 7
purge_protection_enabled = false
}
resource "random_password" "password" {
count = length(var.secrets)
length = 15
special = true
override_special = "!@#$%&*()-_=+[]{}<>:?"
}
resource "azurerm_key_vault_secret" "pman-secrets" {
for_each = toset(var.secrets)
name = each.value
value = random_password.password[index(var.secrets, each.value)].result
key_vault_id = length(azurerm_key_vault.pman-vault) > 0 ? azurerm_key_vault.pman-vault[0].id : data.azurerm_key_vault.existing.id
lifecycle {
ignore_changes = [value]
prevent_destroy = true
}
}
data "azurerm_key_vault_secret" "fetched_secrets" {
for_each = toset(var.secrets)
name = each.value
key_vault_id = data.azurerm_key_vault.existing.id
}
output "fetched_secrets_values" {
value = { for s in var.secrets : s => lookup(data.azurerm_key_vault_secret.fetched_secrets[s], "value", null) }
description = "The fetched secret values from Azure Key Vault."
sensitive = true
}
输出:
Terraform apply:
再次重复命令
Terraform apply: