IaC(Terraformなど)で構成をコード化するなら、その土台はGitです。本記事は未経験〜駆け出しの方向けに、AWS運用の現場で必要になるGitのユースケース(最小ワークフロー→ブランチ/PR→tfstateの扱い→事故防止→CI/CD)を、コピペで動く断片つきで整理します。
01なぜGit — IaC は「構成をコードで管理」する
AWS の構成をマネジメントコンソールの手作業(ポチポチ)で作ると、「誰がいつ何を、なぜ変えたか」が残りません。同じ環境をもう一度作るのも一苦労です。IaC(Infrastructure as Code)は、構成を Terraform / CloudFormation / CDK などのコードで書き、そのコードを Git で管理する考え方です。
Git を挟むだけで、手作業では得られなかった安全網が手に入ります。
- 履歴が残る:いつ・誰が・何を変えたかが log に残る
- レビューできる:プルリク(PR)で第三者が確認してから反映
- 巻き戻せる:問題があれば前の状態に戻せる
- 再現できる:同じコードから同じ構成を何度でも作れる
IaC の設計思想や、複数アカウントをコードで束ねる話は クラウドエンジニアの基礎(教科書) と AWS Organizations 設計(IaC・委任) も合わせて読むと視野が広がります。
02最小ワークフロー — まずこれだけ
日々使うのは、ごく少数のコマンドです。「取得 → 変更 → 確認 → 記録 → 共有」の流れを体に入れましょう。
git clone https://github.com/my-org/my-iac-repo.git # 最初の1回だけ
cd my-iac-repo
git status # 今どのファイルが変わっているか
git diff # 変更の中身を差分で確認
git add main.tf # 記録したい変更をステージ(git add -p で部分選択も可)
git commit -m "vpc: サブネットを3AZに拡張" # 1つの意味ある単位で記録
git pull # リモートの最新を取り込む(push 前に)
git push # 自分の変更を共有
git log --oneline --graph # 履歴を1行ずつ・流れで確認 status/diffは commit 前に必ず。「何を記録しようとしているか」を毎回自分の目で確認するcommitは小さく。メッセージは「何を・なぜ」を一行で- push の前に
pull。いきなり push してコンフリクトで慌てないため
git status。今の状態と「次にやるべきこと」をGit自身が教えてくれます。03ブランチとPR — main を直接触らない
チーム開発では、本番相当の main を直接触らず、作業ごとにブランチを切ります。作業が終わったらプルリク(PR)を出し、レビューを受けてからマージします。
git switch -c feature/add-nat-gateway # ブランチを作って移動(旧: git checkout -b)
# ... main.tf を編集 ...
git add main.tf
git commit -m "network: プライベートサブネット用にNAT GWを追加"
git push -u origin feature/add-nat-gateway # 初回は -u でひも付け
# → GitHub/GitLab 側でプルリクを作成し、terraform plan の結果を貼ってレビュー依頼
# → 承認されたらマージ。ローカルは main を最新化
git switch main
git pull switch / restore は比較的新しいコマンドです。古い環境や資料では checkout が使われますが、同じことができます。git checkout -b = git switch -c と読み替えて構いません。- ブランチ名は用途がわかる形に(例:
feature/add-nat-gateway、fix/sg-egress) - 1つの PR は1つの目的に絞る。レビューしやすく、巻き戻しやすい
- IaC では
terraform planの結果を PR に貼る。「適用すると何が変わるか」を人が読める形で残す
ブランチ運用の型(GitHub Flow など)そのものを深掘りしたい場合は GitHub Flow / GitLab Flow / トランクベースの比較 もどうぞ。
04ユースケース:IaCリポジトリの運用 — 入れないものを決める
IaC リポジトリで最初にやるのは、「Git に入れてはいけないもの」を .gitignore で除外することです。とくに Terraform の tfstate は Git 管理しません。
- state には接続文字列やパスワードなど機密が平文で入りうる
- 複数人が同時に apply すると state が壊れる(=ロックが必要)
- そのため state は S3 バックエンド+DynamoDB ロックに置き、共有はバックエンド経由で行う
# ---- .gitignore(IaCリポジトリの例)----
# Terraform
*.tfstate
*.tfstate.*
.terraform/
crash.log
# 環境ごとの値。機密を含みやすいので原則コミットしない
*.tfvars
!example.tfvars # サンプルだけは共有したい場合は除外解除
# 認証情報・鍵
.env
*.pem
*.key
credentials
.aws/ state の置き場所(バックエンド)は、暗号化を有効にした S3 とロック用の DynamoDB テーブルで構成するのが定番です。
terraform {
backend "s3" {
bucket = "my-tfstate-bucket"
key = "prod/network/terraform.tfstate"
region = "ap-northeast-1"
dynamodb_table = "terraform-locks" # 同時 apply を防ぐロック
encrypt = true # 保存時暗号化
}
} 05ユースケース:事故防止 — secrets はコミットしない
もっとも避けたい事故は、アクセスキーやパスワードをコミットして push してしまうことです。とくに公開リポジトリでは、上がった瞬間に自動収集される前提で動くべきです。
重要なのは順番です。履歴に一度入った秘密は、後から消すのが非常に困難です(履歴を書き換えても、clone された分は取り戻せません)。だから「消す」より先に、そのキーを無効化(ローテーション)するのが正解です。
コミット前に機械的に止める仕組みとして、AWS Labs 製の git-secrets(github.com/awslabs/git-secrets)が定番です。Git のフックとして働き、AWS キーらしき文字列を含むコミットをブロックします。
# macOS: brew install git-secrets(他OSはリポジトリの手順を参照)
cd /path/to/my-iac-repo
git secrets --install # このリポジトリにフックを入れる
git secrets --register-aws # AWSキー検出パターンを登録
git secrets --scan # 追跡中ファイルを走査
git secrets --scan-history # 過去の履歴も走査 - pre-commit / commit-msg / prepare-commit-msg のフックが入り、疑わしいコミットを止める
- ただしすべてを捕まえる保証はない。あくまで最後の砦
- 大前提は「そもそも書かない設計」:ダミー値(
YOUR_ACCESS_KEY等)・環境変数・Secrets Manager 参照
YOUR_ACCESS_KEY のようなダミーに。「後で消す」は間に合いません。06ユースケース:AWSと繋ぐCI/CD — キーレスが基本
push をトリガに terraform plan / apply を回すと、レビュー済みのコードだけが AWS に反映されます。実行基盤は GitHub Actions や AWS CodePipeline が代表的です。
ここで重要なのが認証方法です。GitHub Actions から AWS を操作するとき、長期アクセスキーを Secrets に置くのは避け、OIDC で IAM ロールを引き受ける「キーレス」構成にするのが推奨です。
ワークフロー側は、id-token: write 権限を与え、aws-actions/configure-aws-credentials でロールを引き受けます。
permissions:
id-token: write # OIDCトークン発行に必須
contents: read
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789012:role/gha-terraform
aws-region: ap-northeast-1
- run: terraform init
- run: terraform plan
# apply は main へのマージ時だけ、人の承認を挟んで実行する AWS 側は token.actions.githubusercontent.com を信頼する OIDC プロバイダを作り、IAM ロールの信頼ポリシーで sts:AssumeRoleWithWebIdentity を許可します。sub 条件で「対象リポジトリ・ブランチだけ」に絞るのが肝心です。
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:my-org/my-iac-repo:ref:refs/heads/main"
}
} 07つまづきポイント — 事故りやすい所
コンフリクト(衝突):pull や merge で同じ行を別々に変えていると、Git がファイルに衝突マーカーを書き込みます。両方を見て正しい形に手で直し、マーカーを消してから add → commit します。
<<<<<<< HEAD
instance_type = "t3.small"
=======
instance_type = "t3.medium"
>>>>>>> feature/scale-up 上の3種類のマーカー行(<<< / === / >>>)を削除し、残す方を決めて保存 → git add → git commit で解消完了です。
push --forceは危険:他人のコミットを上書きで消しかねない。どうしても要るときは--force-with-lease(相手の更新に気づいたら失敗してくれる)を使う- 巨大ファイル / state をコミットしない:一度入ると履歴が重くなる。
.gitignoreを最初に整える - detached HEAD:
git checkout <コミットID>で「どのブランチにも乗っていない」状態のこと。作業を残すならgit switch -c 新ブランチ、戻るならgit switch main
git status と git log で現状を確認しましょう。08早見表 — Gitコマンド逆引き(1画面チートシート)
| やりたいこと | コマンド | ひとことメモ |
|---|---|---|
| リポジトリを取得する | git clone リポジトリURL | 最初の1回だけ |
| 今の状態を見る | git status | commit前に必ず |
| 変更の中身を見る | git diff | 差分で確認 |
| 記録する(部分選択も) | git add -p → git commit -m "…" | 意味ある単位で |
| 共有する/取り込む | git push / git pull | push前にpull |
| 履歴を短く見る | git log --oneline --graph | 流れを把握 |
| ブランチを作って移る | git switch -c feature/x | 旧: checkout -b |
| ブランチを切り替える | git switch main | 旧: checkout |
| 取り込む(マージ) | git merge feature/x | PR経由が基本 |
| 直前のcommitを戻す(未push) | git reset --soft HEAD~1 | 変更は手元に残る |
| 作業を一時退避する | git stash / git stash pop | 割り込み対応 |
| 安全に強制pushする | git push --force-with-lease | --force は避ける |
| secretsを走査する | git secrets --scan-history | awslabs製フック |
| 特定コミットの中身を見る | git show コミットID | 中身確認 |
09よくある質問(FAQ)
tfstate は Git に入れてはいけないのですか?
入れないのが基本です。state には接続情報やパスワードが平文で含まれることがあり、複数人が同時に apply すると壊れる恐れもあります。暗号化を有効にした S3 バックエンド+DynamoDB ロックに置き、共有はバックエンド経由で行います。
間違ってアクセスキーをコミットしてしまいました。どうすれば?
まず対象のキーを無効化(ローテーション)してください。履歴からの削除より無効化が先です。一度 push すると取り戻せない前提で動き、git-secrets の導入と、以後はダミー値・環境変数・Secrets Manager 参照で再発を防ぎます。
CodeCommit と GitHub、どちらを使えばよいですか?
CodeCommit は2024年7月に新規受付を一旦停止し、2025年11月に一般提供へ復帰しました。ただし実運用では GitHub/GitLab が主流で、GitHub Actions の OIDC キーレス連携など周辺エコシステムも厚めです。最新の公式情報を確認しつつ、チームの標準に合わせて選ぶのが無難です。
git switch と git checkout の違いは?
できることは重なりますが、switch/restore は「ブランチ操作」と「ファイル復元」に役割を分けた新しめのコマンドで、誤操作が減ります。古い資料の checkout -b は switch -c に読み替えて構いません。
EMWは「基礎を積む姿勢」を大切にする札幌のAWSコンサルです。IaCやCI/CDの型づくり、Gitの運用ルール整備もご相談ください。未経験からの成長を後押しします。
相談する