在每个计划(刷新状态)terraform 上重新 运行 外部数据源的 "program"

Re-run the "program" of an external data source on every plan (refresh state) terraform

我正在使用外部数据源,以便使用程序参数执行 cURL 命令:

data "external" "curl_zip" {
    program = ["bash", "-c", "curl", ...]
}

我运行在管道中设置 Terraform,因此我需要检索每个 Terraform 计划的数据。

在我创建一个需要执行 curl 的新资源之前,它似乎运行良好。但看起来 Terraform 只是刷新,所以在第一个计划之后不执行程序命令:

data.external.curl_zip["something.json"]: Refreshing state... [id=-]

我的问题是:有没有办法在刷新期间重新运行每个计划的程序参数?

PS :我已经尝试使用 null_resource 代替 local-exec,结果证明这不是解决方案,因为(出于某种原因)我还需要使用一个 archive_file 数据源来创建 zip 文件,这样我的 GCP 应用引擎资源就可以读取它们,并且 local-exec 在 terraform apply 之后执行,这不起作用,因为数据源正在刷新或在计划期间创建。

我觉得你把事情复杂化了。你到底想达到什么目的?对于 Terraform 的所有东西,通常询问 how can I achieve so and so?how can I get my Terraform code to work?.

更好

以下是您想要的吗?

data "external" "hello" {
    program = ["bash", "-c", "echo 'Hello World!' > helloworld.txt; echo -n '{\"hello\":\"world!\"}'"]
}

resource "null_resource" "world" {
  provisioner "local-exec" {
    command = "echo '${data.external.hello.result["hello"]}'"
  }
}

从以下输出中的时间戳可以看出,helloworld.txt 生成了五次,每次调用 Terraform 计划一次:

jdsalaro$ for i in {1..5} ;do terraform plan; ls -lah --full-time helloworld.txt ;done \
| grep helloworld.txt | cut -d ' ' -f 7,9

00:04:18.610304219 helloworld.txt
00:04:19.902246088 helloworld.txt
00:04:21.226186506 helloworld.txt
00:04:22.574125835 helloworld.txt
00:04:23.886066774 helloworld.txt

为了以防万一,我上传了整个示例here

更新

非常感谢您的回复,很抱歉没有早点回复您。所以出于某种原因我很难使用数据源,而且似乎在 apply 之后数据源被保存到状态:terraform state list。所以下面的 plan 没有重新创建我用来执行 curl 的数据源。

所以我回到了 null_resource 解决方案。它有点复杂,但之前我遇到了 curl 请求的问题,导致 zip 无法用于我的 GAE 资源。所以我不得不在卷曲的顶部使用 archive_file 。但这行不通,因为在 计划 期间正在处理数据源,并且在 期间正在执行 null_resourcelocal-exec申请.

无论如何,我修复了我的卷曲,所以我不需要 archive_file 数据源。我还需要将解释器更改为 ["/bin/bash", "-c"] 才能完成这项工作。此外,我使用触发器在每次应用期间始终 运行 卷曲。

这是我的资源:

resource "null_resource" "curl_zip" {
    for_each = local.json_data
    provisioner "local-exec" {
        command = "curl -H 'API_KEY' -sLo ./path/to/zip"
        interpreter = ["/bin/bash", "-c"]
    }

    triggers = {
        always_run = timestamp()
    }
}