【问题标题】:Re-run the "program" of an external data source on every plan (refresh state) terraform在每个计划(刷新状态)terraform 上重新运行外部数据源的“程序”
【发布时间】:2021-04-26 09:44:07
【问题描述】:

我正在使用外部数据源,以便使用程序参数执行 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 数据源来创建zips 文件,所以我的GCP应用引擎资源可以读取它们,并且在terraform apply之后正在执行local-exec,这不起作用,因为在计划期间正在刷新或创建数据源。

【问题讨论】:

  • 已经是这样了。任何时候刷新状态,程序都会被执行。你能更清楚地解释你所看到的让你认为情况并非如此的事情吗?如果可以的话,您能否提供一个 minimal reproducible example 来展示这种行为?
  • 因为我收到一条错误消息,提示我应该使用 curl 获取的文件丢失(存档文件数据源需要)+ 我没有看到 curl 输出。明天我会尝试提供一个最小的可重现示例。

标签: google-cloud-platform terraform terraform-provider-gcp


【解决方案1】:

在我看来,你把事情复杂化了。你到底想达到什么目的?对于 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 以防万一。

【讨论】:

    【解决方案2】:

    更新

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

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

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

    这是我的资源:

    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()
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2019-12-09
      • 2019-11-28
      • 2020-01-11
      • 2019-01-22
      • 2017-01-02
      • 1970-01-01
      • 2016-01-11
      • 1970-01-01
      • 2018-01-14
      相关资源
      最近更新 更多