使用 Github Actions 執行 Terraform,以部署至 GCP

简而言之

我用Github Actions来执行了Terraform。

前提是指一个基本的条件或假设

后台

在使用Terraform进行后端配置时,应了解以下两点。(※由于我选择了GCS作为提供者,所以如果提供者不同,可能还需要注意其他事项。)

    1. 需要预先创建存储空间。

 

    1. 无法在 apply 中同时创建指定给后端的存储空间。必须先预先创建。

 

    1. 授权顺序

 

    根据以下文章,Terraform 在加载模块之前加载,因此需要在后端指定凭据。如果在提供方 (provider) 中指定凭据,则不需要在后端指定。如果没有在提供方指定并且没有在后端指定,则将使用默认服务帐户。因此,除非特殊情况,否则我们不太经常这样做。但正如后面所述,我们将凭据作为环境变量传递,因此无需设置任何路径。

请参考以下链接获取帮助:

Error configuring the backend “gcs”: storage.NewClient() failed: dialing: google: could not find default credentials


https://www.terraform.io/docs/github-actions/actions/plan.html

HCL语法的更改转换为yaml

截至2019年9月21日,Github Actions工作流语法已更改为yaml格式(尽管仍可用但已被弃用)。因此,根据以下文章的指示,需要执行迁移工具将HCL转换为yaml格式。

开始

首先,将Terraform官方提供的工作流示例复制并粘贴。

workflow "Terraform Cloud" {
  resolves = "terraform-plan"
  on = "pull_request"
}

action "filter-to-pr-open-synced" {
  uses = "actions/bin/filter@master"
  args = "action 'opened|synchronize'"
}

action "terraform-fmt" {
  uses = "hashicorp/terraform-github-actions/fmt@<latest tag>"
  needs = "filter-to-pr-open-synced"
  secrets = ["GITHUB_TOKEN"]
}

action "terraform-init" {
  uses = "hashicorp/terraform-github-actions/init@<latest tag>"
  needs = "terraform-fmt"
  secrets = ["GITHUB_TOKEN", "TF_ACTION_TFE_TOKEN"]
  env = {
    TF_ACTION_TFE_HOSTNAME = "app.terraform.io"
  }
}

action "terraform-validate" {
  uses = "hashicorp/terraform-github-actions/validate@<latest tag>"
  needs = "terraform-init"
  secrets = ["GITHUB_TOKEN"]
}

action "terraform-plan" {
  uses = "hashicorp/terraform-github-actions/plan@<latest tag>"
  needs = "terraform-validate"
  secrets = ["GITHUB_TOKEN", "TF_ACTION_TFE_TOKEN"]
  env = {
    TF_ACTION_TFE_HOSTNAME = "app.terraform.io"
  }
}

我对Pull Request执行简单的操作,包括fmt、init、validate和plan。每个操作都在uses中指定了相应的脚本。

将其改写为YAML文件

首先,将其转换为YAML格式。
然后,从这里下载最新的二进制文件,并设置路径。

将要转换的HCL工作流文件放置在存储库根目录下的.github/main.workflow。
在存储库根目录下执行migrate-actions。

然后将创建一个转换后的文件到存储库根目录下的.github/workflows/pull_request.yml。就是这样。

on: pull_request
name: Terraform Cloud
jobs:
  filter-to-pr-open-synced:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
    - name: filter-to-pr-open-synced
      uses: actions/bin/filter@master
      with:
        args: action 'opened|synchronize'
    - name: terraform-fmt
      uses: hashicorp/terraform-github-actions/fmt@<latest tag>
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    - name: terraform-init
      uses: hashicorp/terraform-github-actions/init@<latest tag>
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        TF_ACTION_TFE_HOSTNAME: app.terraform.io
        TF_ACTION_TFE_TOKEN: ${{ secrets.TF_ACTION_TFE_TOKEN }}
    - name: terraform-validate
      uses: hashicorp/terraform-github-actions/validate@<latest tag>
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    - name: terraform-plan
      uses: hashicorp/terraform-github-actions/plan@<latest tag>
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        TF_ACTION_TFE_HOSTNAME: app.terraform.io
        TF_ACTION_TFE_TOKEN: ${{ secrets.TF_ACTION_TFE_TOKEN }}

填写必要的事项

只需要跟着《入门指南》逐渐阅读,并填写必要的部分即可。

设置凭据

由于本次使用的Provider是Google,我们需要将Service Account的秘钥设置为凭据。创建Service Account,并为其分配Terraform所需的角色(具体操作取决于具体需求)。将下载的Service Account秘钥的JSON文件添加到GitHub仓库设置 -> Secrets中,并命名为GOOGLE_CREDENTIALS。然后只需将其作为环境变量传递给工作流程即可。

最终文件

最终文件是这个。
我认为可能存在一些目录和命令标志方面的小差异。

on: pull_request
name: Terraform
jobs:
  filter-to-pr-open-synced:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@master
    - name: filter-to-pr-open-synced
      uses: actions/bin/filter@master
      with:
        args: action 'opened|synchronize'
    - name: terraform-fmt
      uses: hashicorp/terraform-github-actions/fmt@v0.4.0
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        TF_ACTION_WORKING_DIR: ./main
    - name: terraform-init
      uses: hashicorp/terraform-github-actions/init@v0.4.0
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}
        TF_ACTION_WORKING_DIR: ./main
    - name: terraform-validate
      uses: hashicorp/terraform-github-actions/validate@v0.4.0
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        TF_ACTION_WORKING_DIR: ./main
    - name: terraform-plan
      uses: hashicorp/terraform-github-actions/plan@v0.4.0
      with:
        args: '-var-file=./config.tfvars'
      env:
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        TF_ACTION_WORKING_DIR: ./main
        TF_ACTION_WORKSPACE: default
        GOOGLE_CREDENTIALS: ${{ secrets.GOOGLE_CREDENTIALS }}

只需将此文件放置在存储库根目录的.github/workflows/pull_request.yml位置,然后创建拉取请求即可完成。工作流将被执行,并将结果作为评论贴出来。

总结和未来计划

尝试一下,意外地很简单。其他就是希望将 apply 作为 issue 评论(例如 /apply)触发成为一个事件。

广告
将在 10 秒后关闭
bannerAds