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

GitHub Actions中Terraform输出文件冗余行问题的原因及解决方法

GitHub Action中Terraform输出JSON包含冗余内容的原因及解决方法

问题场景

我在GitHub Action工作流中编写了以下代码:

- name: Save Terraform Output to JSON File
  run: |
    terraform output -json > output.json
- name: Upload Terraform Output JSON File as Artifact
  uses: actions/upload-artifact@v3
  with:
    name: terraformOutput
    path: output.json

但下载产物文件后,发现其中包含大量冗余行:

[command]/home/runner/work/_temp/59756a93-8dd6-479b-ac36-25cce5af6f4d/terraform-bin output -json
{
  "hello": {
    "sensitive": false,
    "type": "string",
    "value": "world"
  }
}
::debug::Terraform exited with code 0.
::debug::stdout: {%0A  "hello": {%0A    "sensitive": false,%0A    "type": "string",%0A    "value": "world"%0A  }%0A}%0A

::set-output name=stderr::

::set-output name=exitcode::0

期望产物文件仅包含以下内容:

{
  "hello": {
    "sensitive": false,
    "type": "string",
    "value": "world"
  }
}

原因分析

这些冗余内容来自GitHub Actions的命令包装器:

  • GitHub Actions会自动包装run步骤中的命令,打印执行的命令路径(以[command]/xxx开头的行)
  • 同时,Terraform的Action包装器会输出调试日志(以::debug::开头的行)和工作流输出变量(::set-output::行),这些内容会被错误地重定向到output.json中——因为默认情况下run步骤会合并标准输出(stdout)和标准错误(stderr)的内容。

解决方法

要只保留Terraform的纯JSON输出,需要明确捕获Terraform命令的标准输出,排除包装器产生的额外内容,以下是几种可靠方案:

方案1:直接调用原始Terraform二进制文件

GitHub Actions中,Terraform的二进制文件路径可通过TERRAFORM_CLI_PATH环境变量获取,直接调用它能避免命令包装器的额外输出:

- name: Save Terraform Output to JSON File
  run: |
    "$TERRAFORM_CLI_PATH" output -json > output.json
- name: Upload Terraform Output JSON File as Artifact
  uses: actions/upload-artifact@v3
  with:
    name: terraformOutput
    path: output.json

方案2:用jq过滤有效JSON内容

如果无法直接调用原始二进制文件,可通过jq工具提取有效的JSON内容(前提是工作流环境已安装jq):

- name: Save Terraform Output to JSON File
  run: |
    terraform output -json | jq . > output.json
- name: Upload Terraform Output JSON File as Artifact
  uses: actions/upload-artifact@v3
  with:
    name: terraformOutput
    path: output.json

jq .会自动过滤非JSON内容,仅保留格式化后的有效JSON对象。

方案3:区分stdout和stderr重定向(不推荐生产环境)

若包装器的额外内容通过stderr输出,可只重定向stdout并丢弃stderr,但这种方式会丢失Terraform的真实错误信息:

- name: Save Terraform Output to JSON File
  run: |
    terraform output -json 1> output.json 2>/dev/null
- name: Upload Terraform Output JSON File as Artifact
  uses: actions/upload-artifact@v3
  with:
    name: terraformOutput
    path: output.json

内容的提问来源于stack exchange,提问作者Charlie Fish

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 22:45:39