Terraform 资源未正确读取另一个资源的更新值

Terraform resource isn't reading updated value of another resource correctly

我不知道这是 Terraform 问题还是提供商有错误。

我正在使用 kubernetes_deployment 和 kubernetes_config_map。

在 kubernetes_deployment 我有这个:

template {
  metadata {
    labels = {
      config_version = kubernetes_config_map.myconfig.metadata[0].resource_version

事情是这样的:

  1. 我修改了 kubernetes_config_map 资源正在使用的配置文件 运行 申请
  2. Terraform 看到配置映射资源发生变化,但 kubernetes_deployment 资源没有显示任何变化
  3. 申请后我运行申请第二次
  4. 现在 kubernetes_deployment 看到更改的值并将其注册为更改

不管有没有显式 depends_on,都会发生这种情况。

为什么会这样? kubernetes_deployment 应该看到值已更改并将其也注册为更改。

我没有注意正在发生的事情。

认为这是kubernetes_config_map资源中的错误。

修改配置映射数据后,kubernetes_config_map 资源只会显示“数据”属性的变化,这是导致我出现问题的错误行为。

如果数据被修改,则 resource_version 必须并且将始终更改,但资源不会注册此更改。由于此依赖资源查看该属性看不到任何更改。

太糟糕了,因为这将是一个非常明确的方法。

幸运的是,在修复该错误之前,我可以使用数据属性的哈希值:

template {
  metadata {
    labels = {
      config_hash = md5(kubernetes_config_map.myconfig.data)

这实际上是在修改 ConfigMap 或 Secret 时有意 design decision in the provider, since Deployments in Kubernetes do not currently 重启。在 Terraform 和 Kubernetes 中,有几种方法可以获得所需的行为:

  1. 将 Secret 或 ConfigMap 挂载为卷并在应用程序代码中使用热重载机制(例如 viper) or a sidecar container like weaveworks/watch.
  2. 运行 确保部署使用最新配置的控制器,例如 stakater/reloader or pusher/wave.
  3. 向 Deployment 或 Daemonset 添加注释,它是 config_map 和秘密中数据的散列。这是一个例子:
    annotations = {
        config_change = sha1(jsonencode(merge(
            kubernetes_config_map.test_config.data,
            kubernetes_secret.test_secret.data
        )))
    }

#3 的缺点是您必须为每个使用特定 configmap/secret 的部署复制此代码。它还会在差异中产生一些噪音,对于进行配置更改但未进行设置的人来说,这些噪音可能不会立即直观。