07. ブランチ保護 / CODEOWNERS / Environments
「main へ直接 push できる」「誰でも apply できる」状態は、いつか必ず事故ります。GitHub の機能で 人間の手によるレビューと承認 をワークフローに組み込みます。
Branch Rulesets(ブランチ保護)
GitHub の Repository → Settings → Rules → Rulesets から設定します。「Branch protection rules」より新しい仕組みで、複数のルールを重ねがけできます。
main にかける標準ルール
- Restrict deletions: main の削除禁止
- Require linear history: マージコミットの乱発を防ぐ(rebase / squash 必須)
- Require a pull request before merging:
- Required approvals: 1〜2(チームサイズに応じて)
- Dismiss stale pull request approvals when new commits are pushed: ✓
- Require review from Code Owners: ✓(後述)
- Require status checks to pass: 必須の CI チェックを指定(
Terraform / terraformジョブ等) - Require signed commits: 任意(Git の
user.signingkey設定が必要) - Block force pushes: 履歴破壊を禁止
設定のコツ
Required status checks は最初は緩く(
terraform-fmt のみ)始め、CI が安定してきたら terraform-validate → terraform-plan と段階的に必須化する。最初から全部必須にすると、CI 不調時に誰もマージできなくなる。
CODEOWNERS で自動レビュアー指定
.github/CODEOWNERS(または root / docs/)に置くと、変更されたパスごとに レビュー依頼が自動で飛びます。Branch Rulesets の「Require review from Code Owners」と組み合わせて使います。
# .github/CODEOWNERS
# 構文: パスパターン @user または @org/team
# 全体のデフォルトレビュアー
* @your-org/platform-team
# Terraform の本番環境は SRE のみ
/envs/prd/ @your-org/sre-team
/envs/prd/**.tf @your-org/sre-team
# AWS IAM の変更はセキュリティチーム必須
/modules/iam/ @your-org/security-team @your-org/platform-team
# CI 設定はインフラチーム
/.github/workflows/ @your-org/platform-team
注意
指定するユーザー/チームは、そのリポジトリに write 権限を持っている必要 があります。読み取りだけのチームを書いても無視されます。
Environments で apply に承認ゲート
GitHub Environments(Settings → Environments)は「デプロイ先の名前付き設定」です。必須レビュアー・待機時間・許可ブランチ・環境固有 Secrets を設定でき、ジョブが environment: production を宣言すると これらの保護ルールを通過するまで実行されません。
本番環境の典型設定
- Required reviewers: 2 名(自分以外の承認が必須)
- Wait timer: 5 分(承認後すぐに走らせず、最終確認の余地を残す)
- Deployment branches:
mainのみ - Environment secrets: 本番用ロール ARN や DB 接続情報
ワークフローでの宣言
jobs:
apply:
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
environment: production # ← ここ。承認待ちが入る
permissions:
id-token: write
contents: read
steps:
- uses: actions/checkout@v4
- uses: hashicorp/setup-terraform@v3
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ secrets.PROD_TF_ROLE_ARN }}
aws-region: ap-northeast-1
- run: terraform init -input=false
working-directory: envs/prd
- run: terraform apply -auto-approve -input=false
working-directory: envs/prd
3 つを組み合わせた標準構成
本番運用での「最低これだけは入れる」セットです。
- Rulesets で main を保護:
- PR 必須、approvals = 1+、CODEOWNERS 必須、status checks 必須
- Force push / 削除禁止、linear history 必須
- CODEOWNERS で重要パスにレビュアーを固定:
- 本番環境(
/envs/prd/)→ SRE - IAM(
/modules/iam/)→ セキュリティ
- 本番環境(
- Environments で apply にゲート:
production: required reviewers 2 + wait 5 min + main のみstaging: 自動デプロイ可、main のみ
- OIDC ロールを Environment ごとに分ける(前章):
productionロールはsubをenvironment:production縛り → 開発時に絶対に発火しない
これで完成
この 4 つを組むと、「PR を出す → CI で plan → CODEOWNERS にレビュー依頼 → 承認 → main マージ → environment の reviewer が再度承認 → wait timer → apply」 という、本番に対する人間ゲートが二重三重にかかった IaC ワークフローになります。次は実際の HCL の書き方へ。