我们正在使用 terraform 在 DevOps 管道中部署包含机密的 Azure Key Vault。在密钥保管库模块中,我们还添加私有端点。服务连接对订阅具有 Key Vault 管理员 IAM 访问权限。该管道在自托管代理上运行。该代理可以访问专用端点使用的新部署的虚拟网络。
当管道尝试部署机密时,我们在第一次运行时收到 403 错误,无需任何更改,第二次运行将成功。就像第一次运行不包含 IAM 一样,但一旦在第二次运行中包含 IAM,它就会成功创建秘密。
有没有办法让管道在第一次部署时“识别”IAM角色?
使用私有端点进行 Key Vault 秘密部署
IAM(身份和访问管理)角色和权限遇到的挑战是由于它们在系统中传播所需的时间而产生的。如果在应用 IAM 角色或策略后立即执行,此延迟可能会导致依赖于新分配的权限的操作失败。在 Azure 中,角色分配激活之前会有短暂的延迟,这可能会导致初始尝试失败,而后续尝试成功。
一种策略是在管道中实现延迟或重试机制,特别是在分配 IAM 角色之后和启动需要这些权限的操作之前。遗憾的是,Terraform 本身并不支持等待 IAM 角色传播。尽管如此,您可以通过利用 Terraforms
null_resource
与 local-exec
配置程序或外部数据源来规避此限制,以引入延迟或执行检查以确保权限已传播。
我尝试了 terraform 配置的演示版本,它是如何工作的。
我的地形配置:
provider "azurerm" {
features {}
}
data "azurerm_client_config" "current" {}
data "azurerm_resource_group" "example" {
name = "v-bolliv-Mindtree"
}
resource "azurerm_virtual_network" "example" {
name = "testvk-vnet"
address_space = ["10.0.0.0/16"]
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
}
resource "azurerm_subnet" "example" {
name = "testvk-subnet"
resource_group_name = data.azurerm_resource_group.example.name
virtual_network_name = azurerm_virtual_network.example.name
address_prefixes = ["10.0.2.0/24"]
service_endpoints = ["Microsoft.KeyVault"]
}
resource "azurerm_key_vault" "example" {
name = "testvksskv"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
tenant_id = data.azurerm_client_config.current.tenant_id
sku_name = "standard"
network_acls {
default_action = "Deny"
bypass = "AzureServices"
ip_rules = ["yourIP"]
virtual_network_subnet_ids = [azurerm_subnet.example.id]
}
}
resource "azurerm_private_endpoint" "example" {
name = "testvk-endpoint"
location = data.azurerm_resource_group.example.location
resource_group_name = data.azurerm_resource_group.example.name
subnet_id = azurerm_subnet.example.id
private_service_connection {
name = "example-connection"
private_connection_resource_id = azurerm_key_vault.example.id
is_manual_connection = false
subresource_names = ["vault"]
}
}
resource "azurerm_key_vault_access_policy" "example" {
key_vault_id = azurerm_key_vault.example.id
tenant_id = data.azurerm_client_config.current.tenant_id
object_id = data.azurerm_client_config.current.object_id
key_permissions = ["Get", "List", "Update", "Create", "Import", "Delete", "Recover", "Backup", "Restore", "Decrypt", "Encrypt", "UnwrapKey", "WrapKey", "Verify", "Sign", "Purge", "Release", "Rotate", "GetRotationPolicy", "SetRotationPolicy"]
secret_permissions = ["Get", "List", "Set", "Delete", "Recover", "Backup", "Restore", "Purge"]
certificate_permissions = ["Get", "List", "Delete", "Recover", "Backup", "Restore", "Purge"]
}
resource "null_resource" "delay" {
depends_on = [azurerm_key_vault.example]
provisioner "local-exec" {
interpreter = ["pwsh", "-Command"]
command = "Start-Sleep -Seconds 60"
}
}
resource "azurerm_key_vault_secret" "example" {
name = "testvk-secret"
value = "s3cr3t"
key_vault_id = azurerm_key_vault.example.id
depends_on = [null_resource.delay]
}
部署成功: