TerraformCloud + GithubActionsを使ってPRのコメントにplan結果を出してみる
TerraformCloud
個人で検証がてらtryしてみた話
- TerraformCloudは簡単にいうと以下です
今回やってみたこと
- Github Actionsを使用してPlan結果をPRのコメントに表示させるということをします。
- またコメントは必ず最新のcommitに対してのplan結果のみを表示するようにします。
完成形
準備すること
Terraform Cloud
- Workspaceというものを作成します。
- こちらの作成方法ですがTerraformを使用して作成します。
- 他にやり方を見つけられなかったので知っている方いたら教えて欲しいです
terraform { cloud { organization = "hironeko" workspaces { name = "tf-cloud-sample" } } }
こちらをmain.tf
などに書いてもらい、 以下のコマンドを実行します
terraform login
ブラウザを開くのでAPIのtokenを作成し作成されたらコピーしておきます。
再び、ターミナルを開きコピーしたAPI tokenを貼ります。ターミナル上は表示されませんがエンターを押してもらい完了です。
最後に下記コマンドを実行してください
terraform init
これで下準備は完了です。
実装
- main.tfを下記のようにひとまず書いておきます
terraform { cloud { organization = "hironeko" workspaces { name = "tf-cloud-sample" } } } provider "aws" { region = "ap-northeast-1" } variable "sample_instance_type" { default = "t2.micro" } resource "aws_instance" "sample" { ami = "ami-05ffd9ad4ddd0d6e2" instance_type = var.sample_instance_type tags = { Name = "sample" } }
Terraform Cloudでplanを実行可能にする
- Terraform Cloudでplanを可能にするには、IAMユーザーのクレデンシャル情報が必要になります。なので発行しましょう
今回はAPI経由でplanを行うのでこの設定を行なっています
Github Actionsを書く
name: "Terraform" on: push: branches: - main pull_request: jobs: terraform: name: "Terraform" runs-on: ubuntu-latest env: tf_version: "1.5.3" steps: - name: Checkout uses: actions/checkout@v3 - name: Setup Terraform uses: hashicorp/setup-terraform@v2 with: terraform_version: ${{ env.tf_version }} cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }} - name: Terraform Format id: fmt run: terraform fmt -check -recursive - name: Terraform Init id: init run: terraform init - name: Terraform Validate id: validate run: terraform validate -no-color - name: Terraform Plan id: plan if: github.event_name == 'pull_request' run: terraform plan -no-color -input=false continue-on-error: true - name: Remove old comment id: remove_old_comment uses: actions/github-script@0.9.0 if: github.event_name == 'pull_request' with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | opts = github.issues.listComments.endpoint.merge({ owner: context.repo.owner, repo: context.repo.repo, issue_number: context.issue.number, per_page: 100, }) const comments = await github.paginate(opts) for(const comment of comments) { if (comment.user.login === "github-actions[bot]") { github.issues.deleteComment({ owner: context.repo.owner, repo: context.repo.repo, comment_id: comment.id, }) } } - name: Update Pull Request uses: actions/github-script@v6 if: github.event_name == 'pull_request' env: PLAN: "terraform\n${{ steps.plan.outputs.stdout }}" with: github-token: ${{ secrets.GITHUB_TOKEN }} script: | const output = `#### Terraform Format and Style 🖌\`${{ steps.fmt.outcome }}\` #### Terraform Initialization ⚙️\`${{ steps.init.outcome }}\` #### Terraform Plan 📖\`${{ steps.plan.outcome }}\` #### Terraform Validation 🤖\`${{ steps.validate.outcome }}\` <details><summary>Show Plan</summary> \`\`\`\n ${process.env.PLAN} \`\`\` </details> *Pushed by: @${{ github.actor }}, Action: \`${{ github.event_name }}\`*`; github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: output }) - name: Terraform Plan Status if: steps.plan.outcome == 'failure' run: exit 1
PushしてPR作成すれば終わりです
参考にした記事
とても助かりました。ありがとうございます。
また記載しているコードのほとんどを上記記事の内容を流用しています。