如何将 Terraform 输出变量保存到 Github Action 的环境变量中

问题描述 投票:0回答:4

我的项目使用 Terraform 来设置 CI/CD 的基础设施和 Github Actions。运行后

terraform apply
我想将 Terraform 输出变量的值保存为 Github Action 环境变量,以供工作流程稍后使用。

根据 Github Action 的文档,this 是使用工作流命令创建或更新环境变量的方法。

这是我简化的 Github Action 工作流程:

name: Setup infrastructure
jobs:
  run-terraform:
    name: Apply infrastructure changes
    runs-on: ubuntu-latest
    steps:
      ...
      - run: terraform output vm_ip
      - run: echo TEST=$(terraform output vm_ip) >> $GITHUB_ENV
      - run: echo ${{ env.TEST }}

在本地运行时,命令

echo TEST_VAR=$(terraform output vm_ip)
准确输出
TEST="192.168.23.23"
但从 Github Action CLI 输出中我得到了一些非常奇怪的东西:

enter image description here

我尝试过使用单引号、双引号。在某些时候我改变了策略并尝试使用

jq
。因此,我添加了以下步骤,以便将所有 Terraform 输出导出到 json 文件并使用
jq
:

解析它
- run: terraform output -json >> /tmp/tf.out.json
- run: jq '.vm_ip.value' /tmp/tf.out.json

但是现在它抛出以下错误:

parse error: Invalid numeric literal at line 1, column 9

即使生成的 JSON 完全有效:

{
  "cc_host": {
    "sensitive": false,
    "type": "string",
    "value": "private.c.db.ondigitalocean.com"
  },
  "cc_port": {
    "sensitive": false,
    "type": "number",
    "value": 1234
  },
  "db_host": {
    "sensitive": false,
    "type": "string",
    "value": "private.b.db.ondigitalocean.com"
  },
  "db_name": {
    "sensitive": false,
    "type": "string",
    "value": "XXX"
  },
  "db_pass": {
    "sensitive": true,
    "type": "string",
    "value": "XXX"
  },
  "db_port": {
    "sensitive": false,
    "type": "number",
    "value": 1234
  },
  "db_user": {
    "sensitive": false,
    "type": "string",
    "value": "XXX"
  },
  "vm_ip": {
    "sensitive": false,
    "type": "string",
    "value": "206.189.15.70"
  }
}

命令

terraform output -json >> /tmp/tf.out.json
jq '.vm_ip.value' /tmp/tf.out.json
在本地相应地工作。

json continuous-integration environment-variables terraform github-actions
4个回答
14
投票

经过几个小时的搜索,我终于弄清楚了。

似乎 Terraform 的 Github Action 提供了一个名为

terraform_wrapper
的附加参数,如果您计划在命令中使用输出,则需要将其设置为
false
。您可以阅读更深入的文章这里

否则,它们将自动暴露给步骤的输出,并且可以像

steps.<step_id>.outputs.<variable>
一样访问它们。您可以在此处此处阅读有关它们的更多信息。


6
投票

对我来说,有效的是使用

terraform-bin output
而不是
terraform output

更多信息这里


0
投票

这真是一头野兽!在尝试了上述方法之后,我无法让任何东西发挥作用,因此将所有内容缝合在一起,我终于能够找到一种不使用任何扩展的方法。

这是我的 Terraform 应用:

- name: 'Terraform_Apply'
  id: tfapply
  if: github.ref == 'refs/heads/master'
  uses: hashicorp/terraform-github-actions@master
  with:
    tf_actions_version: 1.4.6
    tf_actions_subcommand: 'apply'
    tf_actions_working_dir: "./Admin/Infrastructure"

steps.tfapply.outputs.login_server 对我不起作用。

我正在使用 tf_actions_version 1.4.6,并使用 terraform_wrapper: true 和 false 进行了尝试。然而,最终起作用的是将 terraform_wrapper 设置为 false 并添加此中间步骤:

- name: 'Set vars'
  id: vars
  run: |
    printf "login_server=%s\n" $(terraform -chdir="./Admin/Infrastructure" output -raw login_server) >> "$GITHUB_OUTPUT"
    printf "admin_username=%s\n" $(terraform -chdir="./Admin/Infrastructure" output -raw admin_username) >> "$GITHUB_OUTPUT"
    printf "admin_password=%s\n" $(terraform -chdir="./Admin/Infrastructure" output -raw admin_password) >> "$GITHUB_OUTPUT"

我使用 -chdir 因为我的 Dockerfile 位于主解决方案的子目录中,如果您不需要格式化任何内容,也可以在此处使用 echo。

然后,变量显示时不带引号(感谢 -raw),我可以在后面的步骤中访问它们:

- name: 'Set Azure Login for ACR'
  uses: azure/docker-login@v1
  with:
    login-server: ${{steps.vars.outputs.login_server}}
    username: ${{steps.vars.outputs.admin_username}}
    password: ${{steps.vars.outputs.admin_password}}

这让我可以从 Terraform 创建 ACR,然后获取这些值,以便我可以使用它们将构建映像直接推送到 ACR。

为了完整性,这是我的 Terraform。

resource "azurerm_container_registry" "acr" {
  name                = "devportalacr"
  resource_group_name = azurerm_resource_group.rg.name
  location            = "eastus2"
  sku                 = "Basic"
  admin_enabled       = true

  tags = {
    Environment = "production"
  }
}

output login_server {
    value = azurerm_container_registry.acr.login_server
}

output admin_username {
    value = azurerm_container_registry.acr.admin_username
}

output admin_password {
    sensitive = true
    value = azurerm_container_registry.acr.admin_password
}

0
投票

在出现此错误几天后,我使用了这个并且它起作用了

- name: 'Set up Terraform'
    uses: hashicorp/setup-terraform@v1
    with:
      terraform_wrapper: false
      terraform_version: 1.0.11

 

    - name: Capture Terraform Outputs
            run: |
              EC2_PUBLIC_IP=$(terraform output -raw ec2_public_ip 2>/dev/null || echo "")
              EC2_PRIVATE_KEY=$(terraform output -raw ec2_private_ip 2>/dev/null || echo "")
    
              # Append outputs to GitHub environment
              echo "EC2_PUBLIC_IP=$EC2_PUBLIC_IP" >> $GITHUB_ENV
              echo "EC2_PRIVATE_KEY=$EC2_PRIVATE_KEY" >> $GITHUB_ENV
       
© www.soinside.com 2019 - 2024. All rights reserved.