アルパカログ

プログラミングとエンジニアリングマネジメントがメインです。時々エモいのも書きます。

GitHub Actions(YAML)でTerraform plan/applyを自動化する

GitHub Actions のワークフロー設定ファイルは、以前はHCL形式でしたが最近YAML形式に変わったようです。なので、YAMLの例がまだあまり出てきません。

個人で使っているAWSリソースをTerraform化して、GitHub Actionsで自動化したのでその方法を紹介したいと思います。

手っ取り早くworkflowファイルのサンプルだけ欲しいという方は下記をご覧ください。

前提条件と注意点

クラウドリソースをすでにTerraformで管理している

まだだよという方は下記を参考にTerraform管理にしてください。

dev.classmethod.jp

tfstateファイルをS3などリモートで管理している

ローカルにある人は下記を参考に移行してください。GitHub Actionsからアクセスできる場所に置く必要があるためです。

qiita.com

注意点

下記にも書かれている通り、Secretsが漏洩してしまう危険性があるので、パブリックリポジトリや信用できないユーザーがいるリポジトリで実行してはいけません。ご利用は自己責任でお願いします。

www.terraform.io

サンプルとポイント

下記リポジトリにサンプルを置いたので参照してください。

github.com

ポイント1: ワークフローごとにファイルを分ける

今回は Terraform plan と apply を自動化するので、ワークフローが2つになります。

plan はPRがオープンされたり、オープンされたPRにコミットが追加されたりしたときに走ってほしいです。

一方、apply はPRがマージされるなどしてコミットが master に push されたときに走ってほしいです。

実行したいタイミングが異なるので、今回は terraform_plan.ymlterraform_apply.yml をそれぞれ定義します。

ポイント2: pull_requestイベントをフィルタする

GitHub Actions は「何が起こったか」を表すイベントによってワークフローを実行します。

当然 pull_request というイベントも用意されています。前述したように、今回は「PRがオープンされた場合」か「PRにコミットが追加された場合」にワークフローを実行したいのですが、問題は pull_request イベントを起こすためのトリガー(アクティビティタイプと言う)に関係ないものが多すぎることです。「アサインした」「アサインを外した」「ラベルを付けた」「ラベルを外した」「編集した」「レビュー準備した」...などなど。

アクティビティタイプがもっと知りたいという方は下記を参照してくださいね。

そこで、必要なアクティビティタイプだけをフィルタするため下記を導入しています。

github.com

    - name: Filter to PR Opened
      uses: actions/bin/filter@master
      with:
        args: "action 'opened|synchronize|rerequested'"

rerequestedGitHub Actions のワークフローが失敗したときに現れる再実行ボタンによる実行を表すアクティビティタイプです。

ポイント3: Secretsは環境変数で渡す

Secretsに関してはHCL形式のときと同じで、環境変数で渡してあげる必要があります。

GITHUB_TOKEN は自動でセットされるものの、使用する場合は明示的に渡してあげる必要があるので注意が必要です。

AWS関連のキー2つはSecretsに登録しておきましょう。init/plan/applyで必要です。

env:
        TF_ACTION_WORKING_DIR: "./aws_terraform"
        GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
        AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

TF_ACTION_WORKING_DIR はご自身のディレクトリ構造に合わせて変更してください。

おわりに

GitHub Actions はまだベータ期間中で、2019年11月13日に正式リリースされるまではまだ変更などあるかもしれませんが、GitHub で完結するということでとてもシンプルです。

また、料金体系も月額ではなく従量課金なので(現在はベータのため無料)、頻繁に更新しない個人所有のAWS管理リポジトリにはちょうど良いです。

とても便利なので、次は AWS Lambda を Apex 管理にしてみたいと思っています。

参考情報