You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Terraform在Azure AKS中启用Azure Key Vault Secrets Provider插件

通过Terraform配置AKS的Azure Key Vault Secrets Provider插件

1. 启用密钥提供程序驱动

Terraform中启用该插件的核心是在azurerm_kubernetes_cluster资源的addon_profile块下配置azure_key_vault_secrets_provider并设置enabled = true,这和你用CLI执行的az aks enable-addons命令效果完全一致。你看到的key_vault_secrets_provider嵌套块是用来配置密钥轮换的可选设置,并非启用插件本身的操作。

示例代码:

resource "azurerm_kubernetes_cluster" "aks_cluster" {
  name                = "myAKSCluster"
  location            = azurerm_resource_group.rg.location
  resource_group_name = azurerm_resource_group.rg.name
  node_resource_group = "myAKSNodeRG"
  dns_prefix          = "myAKSDNS"

  default_node_pool {
    name       = "default"
    node_count = 3
    vm_size    = "Standard_D2s_v3"
  }

  identity {
    type = "SystemAssigned"
  }

  # 启用Azure Key Vault Secrets Provider插件
  addon_profile {
    azure_key_vault_secrets_provider {
      enabled = true

      # 可选:配置密钥轮换(仅当需要自动轮换时设置)
      key_vault_secrets_provider {
        rotation_poll_interval = "5m" # 每5分钟轮询一次密钥更新
      }
    }
  }
}

2. 创建Kubernetes Secret同步Azure密钥

要实现Key Vault密钥到K8s Secret的同步,需要先给AKS集群的系统身份分配Key Vault访问权限,再创建SecretProviderClass自定义资源(CSI驱动用来关联Key Vault和K8s Secret的配置)。

步骤2.1:配置Key Vault及权限

# 创建Key Vault
resource "azurerm_key_vault" "kv" {
  name                       = "myKeyVault"
  location                   = azurerm_resource_group.rg.location
  resource_group_name        = azurerm_resource_group.rg.name
  tenant_id                  = data.azurerm_client_config.current.tenant_id
  soft_delete_retention_days = 7
  purge_protection_enabled   = true
  sku_name                   = "standard"
}

# 给AKS系统身份分配Key Vault密钥读取权限
resource "azurerm_key_vault_access_policy" "aks_kv_policy" {
  key_vault_id = azurerm_key_vault.kv.id
  tenant_id    = data.azurerm_client_config.current.tenant_id
  object_id    = azurerm_kubernetes_cluster.aks_cluster.identity[0].object_id

  secret_permissions = [
    "Get",
    "List",
  ]
}

步骤2.2:创建SecretProviderClass同步密钥到K8s Secret

resource "kubernetes_manifest" "secret_provider_class" {
  manifest = {
    apiVersion = "secrets-store.csi.x-k8s.io/v1"
    kind       = "SecretProviderClass"
    metadata = {
      name      = "azure-kv-secrets"
      namespace = "default"
    }
    spec = {
      provider = "azure"
      parameters = {
        usePodIdentity = "false"
        useVMIdentity  = "true" # 使用AKS节点的系统身份
        keyvaultName   = azurerm_key_vault.kv.name
        objects = jsonencode([
          {
            objectName = "mySecret" # Key Vault中存储的密钥名称
            objectType = "secret"
            objectVersion = "" # 留空使用最新版本密钥
          }
        ])
        tenantId = data.azurerm_client_config.current.tenant_id
      }
      secretObjects = [
        {
          secretName = "kv-synced-secret" # 要在K8s中创建的Secret名称
          type       = "Opaque"
          data = [
            {
              objectName = "mySecret"
              key        = "secret-value" # K8s Secret中存储该密钥的键名
            }
          ]
        }
      ]
    }
  }
}

执行后,CSI驱动会自动将Key Vault的mySecret同步到K8s的kv-synced-secret Secret中。

3. 将密钥注入Kubernetes Deployment

可以通过两种方式将密钥注入Deployment:直接挂载CSI卷,或者引用同步后的K8s Secret注入环境变量/卷。

示例代码:

resource "kubernetes_deployment" "app_deployment" {
  metadata {
    name      = "my-app"
    namespace = "default"
    labels = {
      app = "my-app"
    }
  }

  spec {
    replicas = 1
    selector {
      match_labels = {
        app = "my-app"
      }
    }

    template {
      metadata {
        labels = {
          app = "my-app"
        }
      }

      spec {
        volumes = [
          # 方式1:挂载CSI卷直接访问Key Vault密钥
          {
            name = "secrets-store-inline"
            csi = {
              driver = "secrets-store.csi.k8s.io"
              readOnly = true
              volumeAttributes = {
                secretProviderClass = "azure-kv-secrets" # 对应上面的SecretProviderClass名称
              }
            }
          },
          # 方式2:引用同步后的K8s Secret
          {
            name = "synced-secret"
            secret = {
              secretName = "kv-synced-secret"
            }
          }
        ]

        container {
          name  = "my-app-container"
          image = "nginx:latest"

          # 挂载CSI卷到容器目录
          volume_mounts = [
            {
              name       = "secrets-store-inline"
              mount_path = "/mnt/secrets-store"
              read_only  = true
            },
            {
              name       = "synced-secret"
              mount_path = "/mnt/synced-secret"
              read_only  = true
            }
          ]

          # 通过环境变量注入Secret值
          env = [
            {
              name = "APP_SECRET"
              value_from = {
                secret_key_ref = {
                  name = "kv-synced-secret"
                  key  = "secret-value"
                }
              }
            }
          ]
        }
      }
    }
  }
}

内容的提问来源于stack exchange,提问作者Jananath Banuka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 04:40:19