Terraform:仅在 Vault 机密数据更改时更新资源

Terraform: update resources only when Vault secret data has changed

这应该是相当容易的,否则我可能会做错什么,但是在深入研究了一段时间后我找不到解决方案。

我有一个 Terraform 配置,其中包含数据来自 Vault 的 Kubernetes Secret 资源。资源配置如下所示:

resource "kubernetes_secret" "external-api-token" {
  metadata {
    name      = "external-api-token"
    namespace = local.platform_namespace
    annotations = { 
      "vault.security.banzaicloud.io/vault-addr" = var.vault_addr
      "vault.security.banzaicloud.io/vault-path" = "kubernetes/${var.name}"
      "vault.security.banzaicloud.io/vault-role" = "reader"
    }   
  }

  data = { 
    "EXTERNAL_API_TOKEN" = "vault:secret/gcp/${var.env}/micro-service#EXTERNAL_API_TOKEN"
  }
}

到目前为止一切正常,但每次我做 terraform planterraform apply,它都会将该资源标记为“已更改”并更新它,即使我没有接触该资源或与之相关的其他资源。例如:

... (other actions to be applied, unrelated to the offending resource) ...


  # kubernetes_secret.external-api-token will be updated in-place
  ~ resource "kubernetes_secret" "external-api-token" {
      ~ data = (sensitive value)
        id   = "platform/external-api-token"
        type = "Opaque"

        metadata {
            annotations      = {
                "vault.security.banzaicloud.io/vault-addr" = "https://vault.infra.megacorp.io:8200"
                "vault.security.banzaicloud.io/vault-path" = "kubernetes/gke-pipe-stg-2"
                "vault.security.banzaicloud.io/vault-role" = "reader"
            }
            generation       = 0
            labels           = {}
            name             = "external-api-token"
            namespace        = "platform"
            resource_version = "160541784"
            self_link        = "/api/v1/namespaces/platform/secrets/external-api-token"
            uid              = "40e93d16-e8ef-47f5-92ac-6d859dfee123"
        }
    }

Plan: 3 to add, 1 to change, 0 to destroy.

表示此资源的数据已更改。但是 Vault 中的数据保持不变,那里没有任何修改。此更新现在每一次都会发生。

我正在考虑使用 ignore_changes 生命周期功能,但我认为这将使 Terraform 忽略在 Vault 秘密中所做的任何更改,我也不希望这样做。 我希望资源仅在 Vault 中的秘密更改时更新。

有办法吗?我错过了什么或做错了什么?

您需要在 Terraform 生命周期忽略更改元参数中添加您的代码。对于具有 API 标记值以及出于某种原因的注释的数据,Terraform 似乎假设每次计划或应用甚至销毁时数据都会更改 运行。我在使用 Azure KeyVault 时遇到了类似的问题。

这是包含生命周期忽略更改元参数的代码:

resource "kubernetes_secret" "external-api-token" {
  metadata {
    name      = "external-api-token"
    namespace = local.platform_namespace
    annotations = { 
      "vault.security.banzaicloud.io/vault-addr" = var.vault_addr
      "vault.security.banzaicloud.io/vault-path" = "kubernetes/${var.name}"
      "vault.security.banzaicloud.io/vault-role" = "reader"
    }   
  }

  data = { 
    "EXTERNAL_API_TOKEN" = "vault:secret/gcp/${var.env}/micro-service#EXTERNAL_API_TOKEN"
  }

lifecycle {
    ignore_changes = [
      # Ignore changes to data, and annotations e.g. because a management agent
      # updates these based on some ruleset managed elsewhere.
      data,annotations,
    ]
  }
}

link 到具有生命周期的元参数:

https://www.terraform.io/language/meta-arguments/lifecycle