豆苗を初めて買いました。一度刈り取った後、水につけて再度育てているのですが、トトロのワンシーンを彷彿とさせる成長を見ることができ、とても楽しいです。豆苗にハマりそうです。いえ、既にハマっています。
今回は、Terraformによるインフラ構成変更の本番反映までの開発フローを紹介します。
YOUTRUSTのインフラの概要やTerraformにおけるディレクトリ構成の詳細に関しては、過去の記事をご覧ください。
- ブランチ戦略
- まとめ
ブランチ戦略
ブランチにはmain
、sandbox
、feature/xxx
があります。
main
- Production環境に対応するブランチ。Production環境の状態と
main
ブランチの状態は一致します。
- Production環境に対応するブランチ。Production環境の状態と
sandbox
- Sandbox環境に対応するブランチ。Sandbox環境の状態と
sandbox
ブランチの状態は一致します。
- Sandbox環境に対応するブランチ。Sandbox環境の状態と
feature/xxx
- 作業用のブランチ。このブランチに対応する環境はありません。
なお、Production環境とSandbox環境は以下の用途で利用している環境になります。
- Production環境
- サービス提供に利用しています。いわゆる本番環境です。
- Sandbox環境
- インフラの動作確認や脆弱性診断に利用する本番と同じ構成の環境です。ステージング環境と呼ばれることもあります。
本番に構成を反映するまでのフローは、以下の通りです。
- 変更作業を
feature/xxx
ブランチにて実施しGitHubにプッシュ feature/xxx
ブランチからsandbox
ブランチに向けてプルリクエストを作成- レビューに通過したら
sandbox
ブランチにマージしてSandbox環境に構成を反映(GitHub Actionsにて反映) - Sandbox環境にて挙動の確認
sandbox
ブランチからmain
ブランチに向けてプルリクエストを作成(GitHub Actionsにて作成)- 差分を確認した後、マージしてTerraformの構成をProduction環境に反映(GitHub Actionsにて反映)
GitFlowを簡略化したようなイメージです。
このフローでは、sandbox
ブランチにマージしないと挙動確認ができない、という悩みポイントがあります。ですが、現在のYOUTRUSTでTerraformを触るのがほぼ1人という状況のため、問題は起きていません。feature/xxx
ブランチをSandbox環境に反映して挙動確認できるようにすることで、もしかしたらよりよいフローを作れるかもしれません。
上記のフローでは、GitHub Actionsを用いて自動化している部分や変更のチェックをしている部分がありますので、以下で説明していきます。
feature/xxx
ブランチからsandbox
ブランチへのプルリクエスト作成時
このタイミングでは、以下の4つを行なっています。
- Terraformファイルのフォーマットのチェック
- Linterによるエラーの発見や非推奨の書式の警告
- 静的解析によるセキュリティスキャン
- Sandbox環境およびProduction環境に対する
terraform plan
の実行
Terraformファイルのフォーマットのチェック
terraform fmt -check -recursive
を用いて、Terraformファイルのフォーマットのチェックを行っています。
それにより、terraform fmt
が実行されていない場合に気づけるようにしています。
対応するworkflowの設定は以下になります。
name: tffmt on: push: jobs: tffmt: name: tffmt runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - uses: hashicorp/setup-terraform@v2 with: terraform_version: 1.2.7 - name: Terraform fmt run: terraform fmt -check -recursive
Linterによるエラーの発見や非推奨の書式の警告
TerraformのLinterであるTFLintを用いて、実行時にエラーとなる可能性がある箇所の検出や非推奨の書式に対する警告などを出力するようにしています。
workflowにおいては、Setup TFLint Actionを用いてTFLintを利用できるようにしています。 設定方法の詳細は、Setup TFLint ActionのREADMEをご覧ください。
対応するworkflowの設定は以下になります。 なお、一つのyamlファイル内でjobをSandbox環境用とProduction環境用に分けているのですが、ファイルを別にしなかった理由は覚えていません...
name: tflint on: pull_request: permissions: id-token: write contents: read jobs: tflint-for-sandbox: name: tflint-for-sandbox runs-on: ubuntu-latest defaults: run: shell: bash working-directory: environments/sandbox steps: - name: Checkout uses: actions/checkout@v3 - name: Configure aws credentials uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: arn:aws:iam::xxxxxxxxxxxx:role/sample aws-region: ap-northeast-1 - name: Setup terraform uses: hashicorp/setup-terraform@v2 with: terraform_version: 1.2.7 - name: Init terraform run: terraform init -upgrade - uses: terraform-linters/setup-tflint@v2 name: Setup tflint with: tflint_version: v0.39.2 github_token: ${{ secrets.GITHUB_TOKEN }} - name: Init tflint run: tflint --init env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Run tflint run: tflint
静的解析によるセキュリティスキャン
Terraformコードの静的解析によるセキュリティスキャナーであるtfsecを用いてセキュリティのチェックを行っています。
workflowにおいては、tfsec-pr-commenter-actionを用いてtfsecを実行しています。
オプションのsoft_fail_commenter
をtrue
にしているため、結果がFailになることはありません。
そのため、扱いとしては参考情報、ということになります。
対応するworkflowの設定は以下になります。
name: tfsec on: pull_request: paths: - '**.tf' jobs: tfsec: name: tfsec-pr-commenter runs-on: ubuntu-latest strategy: matrix: working_directory: [ environments/sandbox, environments/prod ] steps: - name: Checkout uses: actions/checkout@v3 - name: tfsec uses: aquasecurity/tfsec-pr-commenter-action@v1.2.0 with: github_token: ${{ github.token }} working_directory: ${{ matrix.working_directory }} soft_fail_commenter: true
Sandbox環境およびProduction環境に対するterraform plan
の実行
sandbox
ブランチにプルリクエストを作成したタイミングで、Sandbox環境へのplan
の結果とProduction環境へのplan
の結果を確認します。
tfcmtおよびactions-setup-tfcmtを用いて、plan
の結果がプルリクエストにコメントされるようにしています。
また、最新の結果だけをコメント上に表示するために、github-commentおよびactions-setup-github-commentを用いて、最新ではない結果のコメントを非表示にするようにしています。
Sandbox環境へのplan
に対応するworkflowの設定は以下になります。
name: Plan Sandbox on: pull_request: branches: - sandbox jobs: plan: name: Plan runs-on: ubuntu-latest strategy: matrix: dir: [environments/sandbox] permissions: contents: read id-token: write pull-requests: write steps: - name: Checkout uses: actions/checkout@v3 - name: Configure aws credentials uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: arn:aws:iam::xxxxxxxxxxxx:role/sample aws-region: ap-northeast-1 - name: Setup terraform uses: hashicorp/setup-terraform@v2 with: terraform_version: 1.2.7 - name: Setup tfcmt uses: shmokmt/actions-setup-tfcmt@v2 - name: Setup github-comment uses: shmokmt/actions-setup-github-comment@v2 - name: Check format id: fmt run: terraform fmt -check -recursive continue-on-error: true - name: Initialize id: init run: terraform init -upgrade working-directory: ${{ matrix.dir }} - name: Validate id: validate run: terraform validate -no-color working-directory: ${{ matrix.dir }} - name: Print PR number id: pr-number run: | PR_NUMBER=$(echo $GITHUB_REF | sed -e 's/[^0-9]//g') echo "number=${PR_NUMBER}" >> $GITHUB_ENV - name: Plan id: plan run: | tfcmt -owner team-youtrust -repo infra-aws -pr ${PR_NUMBER} -var target:sandbox plan -- terraform plan -no-color continue-on-error: true working-directory: ${{ matrix.dir }} env: PR_NUMBER: ${{ env.number }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Hide old plan comments run: | github-comment hide -org team-youtrust -repo infra-aws -pr ${PR_NUMBER} -token ${GITHUB_TOKEN} \ -condition 'Comment.HasMeta && (Comment.Meta.SHA1 != Commit.SHA1)' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} PR_NUMBER: ${{ env.number }}
上記で出力されるコメントは、以下のようになります。
sandbox
ブランチへのプルリクエストのマージ時
このタイミングでは、以下の2つを行なっています。
- Sandbox環境への
terraform apply
sandbox
ブランチからmain
ブランチへのプルリクエストの作成
Sandbox環境へのterraform apply
sandbox
ブランチにマージされたタイミングで、Sandbox環境に適用しています。
対応するworkflowの設定は以下になります。
name: Apply Sandbox on: push: branches: - sandbox jobs: plan: name: Apply runs-on: ubuntu-latest strategy: matrix: dir: [environments/sandbox] permissions: id-token: write contents: read steps: - name: Checkout uses: actions/checkout@v3 - name: Configure aws credentials uses: aws-actions/configure-aws-credentials@v2 with: role-to-assume: arn:aws:iam::xxxxxxxxxxxx:role/sample aws-region: ap-northeast-1 - name: Setup terraform uses: hashicorp/setup-terraform@v2 with: terraform_version: 1.2.7 - name: Apply run: | terraform init -upgrade terraform apply -auto-approve working-directory: ${{ matrix.dir }}
sandbox
ブランチからmain
ブランチへのプルリクエストの作成
毎回手動でプルリクエストを作るのが面倒なため、workflowでプルリクエストを作成しています。
作成されるプルリクエストの内容は必要最低限になっています。
どのfeature/xxx
ブランチが含まれるのか分かるようにするなど、より良くできる余地はありますが、関わっているメンバーが限られているため、現時点では必要十分と考えています。
対応するworkflowの設定は以下になります。
name: Create Pull Requests to Apply to Production Environments on: pull_request: types: - closed branches: - sandbox jobs: create_pull_requests: if: github.event.pull_request.merged == true name: Create pull requests to apply to production environments runs-on: ubuntu-latest env: GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN_OF_GITHUB }} steps: - name: Checkout uses: actions/checkout@v3 - name: Set current date id: set_current_date env: TZ: 'Asia/Tokyo' run: | echo "current_date=$(date +'%Y-%m-%d')" >> $GITHUB_ENV - name: Check if pull request to main exists or not id: check_pull_request_to_main run: | echo "count=$(gh pr list --base 'main' | wc -l)" >> $GITHUB_ENV - name: Create pull request to main from sandbox if: ${{ env.count == 0 }} run: | gh pr create --base "main" --title "apply to production on ${{ env.current_date }}" --body ""
sandbox
ブランチからmain
ブランチへのプルリクエスト作成時
このプルリクエストは自動で作成され、このタイミングでは、以下の4つを行なっています。
- Terraformファイルのフォーマットのチェック
- Linterによるエラーの発見や非推奨の書式の警告
- 静的解析によるセキュリティスキャン
- Production環境に対する
terraform plan
の実行
terraform plan
以外は、sandbox
ブランチへのプルリクエスト作成時にも実行しているので、実行しなくても良いですが、多大なコストがかかるわけではないので、このタイミングでも実行しています。
具体的なworkflowの設定は、sandbox
ブランチへのプルリクエストと同様のため、そちらを参考にしてください。
main
ブランチへのプルリクエストのマージ時
このタイミングでは、以下を行なっています。
- Production環境への
terraform apply
具体的なworkflowの設定は、sandbox
ブランチへのプルリクエストと同様のため、そちらを参考にしてください。
まとめ
今回は、Terraformによるインフラ構成変更の本番反映までの開発フローを紹介しました。
現在、インフラの構成変更に携わるメンバーは流動的で、同タイミングで作業をするメンバーは多くて2人です。 この状況において、困ることは発生しておらず、また問題も発生しておりません。 同タイミングで作業するメンバーが少し増えても、おそらく問題は発生しないだろうと考えています。
ぜひ参考にしていただければと思います。
YOUTRUSTでは、積極的にエンジニアを採用しています。 カジュアル面談も大歓迎ですので、興味がある方はぜひお声がけください!