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

8mmmxcuj  于 2023-06-25  发布在  Git
关注(0)|答案(3)|浏览(132)

我的项目使用Terraform来设置基础设施,并使用Github Actions来设置CI/CD。在运行terraform apply之后,我想将Terraform输出变量的值保存为Github Action环境变量,以便稍后由工作流使用。
根据Github Action的文档,这是使用工作流命令创建或更新环境变量的方法。
以下是我简化的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输出中我得到了一些非常奇怪的东西:

我试过用单引号和双引号。在某个时候,我改变了策略,尝试使用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.jsonjq '.vm_ip.value' /tmp/tf.out.json相应地在local上工作。

vom3gejh

vom3gejh1#

经过几个小时的搜寻,我终于弄明白了。
似乎Terraform's Github Action提供了一个名为terraform_wrapper的额外参数,如果您计划在命令中使用输出,则需要将其设置为false。你可以阅读更深入的文章here
否则,它们将自动暴露给步骤的输出,并且可以像steps.<step_id>.outputs.<variable>一样访问它们。你可以在这里和这里阅读更多关于他们的信息。

kt06eoxx

kt06eoxx2#

对我来说,有效的是使用terraform-bin output而不是terraform output
更多信息在这里。

qojgxg4l

qojgxg4l3#

这是一头野兽!在尝试了上面的方法之后,我无法让任何东西工作,所以将所有东西拼接在一起,我终于能够找到一种不使用任何扩展的方法。
以下是我的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:真与假然而,最终成功的是将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。
这是我的地形完整性。

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
}

相关问题