使用[Terraform]GithubActions执行Terraform存储库的CI

简而言之

我会通过GitHub操作来记录使用Terraform仓库的连续集成的设置步骤,以便能够手把手地进行操作。这不适用于那些不想将机密信息存放在GitHub上的人。

前提 tí) – premise / assumption / prerequisite

    • Githubでtfファイルを管理している

 

    AWSアカウントを保持している

用中文对以下内容进行修改:
检查内容通过CI.

请参阅这篇文章。

Github Actions的设置

请查看此链接以获取完成形。

特点

以下是与CodeBuild配置相比的特点。

○ 設定的方式很容易
○ 可以并行执行
△ 需要将AWS或Terraform Cloud的凭据记录到Github中

如果您对在Github上管理Credentials有疑虑,我们建议您使用CodeBuild进行CI。由于它在AWS上运行,不需要AWS的Credentials,而其他Credentials可以使用SSM Parameter-Store和KMS来存储机密数据。

目录结构

仓库的目录结构如下所示。

├── .github/
│  └── workflows/
│     └── terraform_ci.yml # Actionsの設定ファイル
├── environments/          # CIの対象ファイル群
│  └── aws/
│     ├── development/
│     └── practice/
└── scripts/
   └── ci/                 # スクリプト群

设定文件的描述设定文件的描述

スクリーンショット 2020-07-06 0.11.51.png

模板设置概述

在这里创建的模板是根据以下假设进行设计的。

masterブランチへのpushおよびPR作成・更新時にワークフローが実行される
リポジトリのルートディレクトリに対象のtfファイルが存在する
ステートファイルをTerraform Cloudで管理している、またplan等のコマンドをTerraform Cloud上で実行する

fmtとplanを実行する

masterブランチへのpushを契機に、applyを実行する

我打算对与本次前提不同的部分进行定制。也就是说,我会进行定制。

    • AWSのcredentialsを読み込む

 

    • コマンドはGithub上で実行する

applyは実行しない

validate tflintも実行する

environmentsディレクトリ以下の各環境別にCIを実行する

我会逐步进行更改。

加载AWS凭证

首先,在存储库中注册AWS和TerraformCloud(如果在状态管理中使用)的凭据。

在存储库的 Settings → Secrets 页面中,使用以下环境变量名进行注册。

シークレット名称概要AWS_ACCESS_KEY_IDAWSのアクセスキーIDAWS_SECRET_ACCESS_KEYAWSのシークレットアクセスキーTF_API_TOKENTerraform Cloudの認証トークン

由于当前情况下,AWS认证信息无法加载,因此我们需要在checkoutstep之后添加一个设置credentials的步骤。

- name: Configure AWS Credentials
  uses: aws-actions/configure-aws-credentials@v1
  with:
    aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
    aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
    aws-region: ap-northeast-1

执行命令在Github上进行

如果您在Terraform Cloud中进行状态管理,则只适用于此。(如果您在S3或GCS中进行状态管理,则命令会在Github Actions上必然执行,因此不需要担心。)
在设置→常规中,将执行模式设置为本地(默认为远程)。

スクリーンショット 2020-07-06 0.27.38.png

不执行申请。

这意味着将重点放在CI上。 只需删除或注释掉以下apply行即可。

- name: Terraform Apply
  if: github.ref == 'refs/heads/master' && github.event_name == 'push'
  run: terraform apply -auto-approve

验证并执行tflint

由于validate可以在terraform validate命令中执行,因此只需要将其作为步骤添加(在init之后),即可完成。

- name: Terraform Validate
  id: validate
  run: terraform validate -no-color
スクリーンショット 2020-07-06 0.38.26.png

由于该命令是基于init的前提条件,因此我们会在init之后添加step。

- name: TFLint
  uses: reviewdog/action-tflint@master
  with:
    github_token: ${{ secrets.github_token }}
    reporter: github-pr-review                 # PRにコメントする
    fail_on_error: true

在environments文件夹中,按照每个环境执行CI操作。

使用Github Actions中提供的strategy.matrix来实现多个目录的CI。
请注意,在这种情况下,工作流将按照设置的矩阵数量(并行地)执行。
由于矩阵部分是直接编辑的,如果增加了目标环境,则需要添加相应的设置。我想不出一个有效解决这个问题的方法。
如果只想执行特定目录,则不需要使用strategy.matrix,只需将working-directory设置为目标目录即可。

terraform-ci:
  name: Terraform
  strategy:
    matrix:
      env: [practice, development]  # ここに対象環境名を羅列

  runs-on: ubuntu-latest

  defaults:
    run:
      shell: bash
      working-directory: ./environments/aws/${{ matrix.env }}  # このディレクトリでこれ以下のコマンドを実行していく

推送更改

到目前为止,定制工作已经完成。让我们提交配置文件的更改吧。
在“操作”选项卡中,确认工作流正在执行,说明它正常运行!

1. 将CI的结果作为PR的评论

通过上述设置,CI现在已经开始执行,但是结果需要查看Actions选项卡的执行结果→目标步骤。然而,在PR上可能会有一些情况,我们希望能够完成这个确认。因此,我们将尝试添加一个设置来将CI执行结果作为PR的评论进行记录。此外,一次工作流可以完成所有的检查也是很有吸引力的。
但是,请注意,即使在fmt等方面失败,CI的执行状态仍然是Complete(如果能够采取适当的执行结果检查机制,这可能是可能的)请在权衡中选择是否引入。

即使在每个命令中都失败了,也不会中断工作流程。

为了一次性查看所有结果,需要运行工作流程直到结束。因此,我们在fmtvalidateplan中追加了在错误情况下继续进行的设置。同时,我们也应该给每个步骤分配一个id。

- name: Terraform Validate
  id: validate                      # ここを追記
  run: terraform validate -no-color
  continue-on-error: true           # ここを追記

实现评论通知

你可以使用公式Readme中的输出在后续步骤中对拉取请求进行评论。steps..outcome表示该步骤的执行结果(成功、失败、取消、跳过),steps..outputs.stdout表示该命令的执行结果标准输出。

# 一番最後のstepとして定義
- uses: actions/github-script@0.9.0
  if: github.event_name == 'pull_request'  # PR作成・更新時だけ実行する
  env:
    PLAN: "terraform\n${{ steps.plan.outputs.stdout }}"
  with:
    github-token: ${{ secrets.GITHUB_TOKEN }}
    script: |
      const output = `## \`${{ matrix.env }}\`
      #### Terraform Format and Style ?\`${{ steps.fmt.outcome }}\`
      #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\`
      #### Terraform Validation ?${{ steps.validate.outputs.stdout }}
      #### Terraform Plan ?\`${{ steps.plan.outcome }}\`

      <details><summary>Show Plan</summary>

      \`\`\`${process.env.PLAN}\`\`\`

      </details>

      *Pusher: @${{ github.actor }}, Action: \`${{ github.event_name }}\`, Workflow: \`${{ github.workflow }}\`*`;

      github.issues.createComment({
        issue_number: context.issue.number,
        owner: context.repo.owner,
        repo: context.repo.repo,
        body: output
      })
スクリーンショット 2020-07-06 1.16.55.png

用下述的选项在中文中重新表述:

选项2. 不使用strategy.matrix,对多个目录进行CI。

这与CodeBuild运行时使用的方法相同,需创建包装脚本,在其中列举目标目录并执行命令。它具有以下特点。

    • ワークフローは単一のものとなる

 

    • 対象ディレクトリが増えた場合も、CI設定の変更は不要

 

    • ラッパースクリプトを作成する必要がある

tfnotifyを利用する場合、pull_requestイベントではうまく発火されない(これは設定が悪いのかもしれません)

另外,请参考本文中的链接,此处的包装器脚本几乎与那篇文章中创建的脚本相同。本文中仅记录差异部分。

创建GithubActions的配置文件

基本的流程不会改变,只会有以下方面的变化。

strategy.matrixは使用しない
各stepではラッパースクリプトを実行する

runs-on: ubuntu-latest
defaults:
  run:
    shell: bash
    working-directory: .
############## 中略 ##############
- name: Install Dependent Packages
    run: ./scripts/ci/install_packages.sh

- name: Terraform Format Check
    run: ./scripts/ci/format.sh
############## 以下同様 ##############

将tfnotify适配Github Actions。

只需要修改第一行中的ci描述。其他部分可以保持不变并进行重用。

ci: github-actions

另外,目前尚不清楚是tfnotify的问题还是我们的设置有问题,但在执行pull_request时无法成功在PR上添加评论。同时,标签设置也无法正常运行。若有相关信息,请提供给我们。

on:
  push:
  # どうもGithub-Actions上でtfnotifyはpushでないと動かない様子
  #   branches:
  #     - master
  #     - development
  # pull_request:
スクリーンショット 2020-07-06 1.41.07.png

参考文献

    • GitHub Actionsのワークフロー構文

 

    setup-terraform
广告
将在 10 秒后关闭
bannerAds