📁 完全なコードはGitHubで公開:GitHub: pipeiac02
シリーズ一覧(全12回)
Phase 1: 基盤構築
Phase 2: ワークフロー
Phase 3: セキュリティ・運用
Phase 4: 開発効率化
1. はじめに
1-1. 今回のゴール
GitHub Actionsを使って、Terraformの自動デプロイ(CI/CD)を設定します。
| ゴール | 内容 |
|---|---|
| 理解 | CI/CD・PR(Pull Request)・OIDCの仕組みを理解する |
| 実装 | GitHub Actionsワークフローを作成 |
| 確認 | PRでplan、マージでapplyを確認 |
PR(Pull Request)とは?
コードの変更を他の開発者にレビューしてもらい、承認後にメインブランチへ統合する仕組みです。詳細は 3-1. PR(Pull Request)とは で説明します。
1-2. なぜCI/CDが必要か
現状は 手動で terraform apply を実行しています。
これを 自動化 します。
1-3. この記事で作るもの
2. 比喩で理解する
2-1. CI/CDを「自動発注システム」で考える
レストランの在庫管理を自動化するイメージです。
2-2. 比喩の図解(レストラン)
2-3. 対応関係
| レストラン | CI/CD | 役割(意味) |
|---|---|---|
| 発注書の作成 | PRの作成 | 変更の提案 |
| 発注内容の確認 | terraform plan | 変更内容のプレビュー |
| 店長の承認 | レビュー&マージ | 変更の承認 |
| 発注の実行 | terraform apply | 変更の適用 |
| 納品確認 | 動作確認 | 正常動作の確認 |
2-4. なぜ自動化するのか?
| 手動 | 自動(CI/CD) |
|---|---|
| 忘れる | 必ず実行される |
| ミスする | 一貫性がある |
| 時間がかかる | 高速 |
| 属人化 | 誰でも同じ結果 |
3. 前提知識
このセクションでは、CI/CDを理解するための前提知識を説明します。
3-1. PR(Pull Request)とは
「変更を提案して、レビューしてもらう仕組み」 です。
3-1-1. 比喩:レストランの新メニュー提案
| 手順 | レストラン | GitHub |
|---|---|---|
| 1 | 新メニューを考える | コードを修正 |
| 2 | 試作品を店長に見せる | PRを作成 |
| 3 | 店長が味見・確認 | レビュー |
| 4 | OKなら正式メニューに | mainにマージ |
3-1-2. 図解
3-1-3. なぜPRを使うのか
| 方式 | 問題点 |
|---|---|
| 直接main修正 | ミスがすぐ本番に影響 ❌ |
| PR経由 | レビューでミスを防げる ✅ |
3-2. GitHub Actionsとは
「GitHubが提供する自動実行サービス」 です。
3-2-1. 比喩:レストランの自動調理器
3-2-2. GitHub Actionsの場合
3-2-3. 用語整理
| 用語 | 説明 | 例え |
|---|---|---|
| ワークフロー | 自動実行の設定ファイル | レシピ |
| トリガー | 実行のきっかけ | 注文 |
| ジョブ | 実行する作業のまとまり | 調理工程 |
| ステップ | ジョブ内の個々の処理 | 切る、焼く、盛る |
3-3. なぜ認証が必要か
GitHub ActionsからAWSを操作するには、「AWSへの入場許可」 が必要です。
3-3-1. 比喩:業者が倉庫に入る場合
3-3-2. AWSの場合
3-4. OIDCとは?(OpenID Connect)
「毎回身分証明書を見せる方式」 です。
3-4-1. 2つの認証方式の比較
3-4-2. 比喩:ホテルの入館方法
| 方式 | 例え | リスク |
|---|---|---|
| アクセスキー | マスターキーを渡す | 紛失すると誰でも入れる ❌ |
| OIDC | フロントで毎回本人確認 | 本人以外は入れない ✅ |
3-4-3. OIDCの仕組み
3-4-4. なぜOIDCを使うのか
| 項目 | アクセスキー | OIDC |
|---|---|---|
| 認証情報 | 長期(漏洩リスク) | 一時的(安全) |
| 管理 | キーのローテーション必要 | 不要 |
| 推奨度 | ⚠️ 非推奨 | ✅ 推奨 |
4. 全体像の確認
4-0. CI/CDの全体像
4-1. 作るもの一覧
今回作成するもの:
| # | 場所 | 作るもの | 役割 |
|---|---|---|---|
| 1 | AWS | S3バケット | tfstate保存場所 |
| 2 | AWS | OIDCプロバイダ | GitHubを信頼する設定 |
| 3 | AWS | IAMロール | GitHub Actionsの権限 |
| 4 | GitHub | Secrets | AWSアカウントID保存 |
| 5 | リポジトリ | backend.tf | S3バックエンド設定 |
| 6 | リポジトリ | terraform-plan.yml | PR時の自動plan |
| 7 | リポジトリ | terraform-apply.yml | マージ時の自動apply |
4-2. 作業の流れ
5章以降の章番号と内容を記載し、流れを確認します。
5. 実装(AWS事前準備)
5-1. ファイル構成
ローカル(PC/リポジトリ):
pipeiac02/
├── .github/
│ └── workflows/
│ ├── terraform-plan.yml # ★今回作成
│ └── terraform-apply.yml # ★今回作成
├── tf/
│ ├── backend.tf # ★今回作成
│ └── (既存ファイル)
└── oidc/ # ★今回作成(別管理推奨)
├── main.tf # OIDCプロバイダ・IAMロール
├── variables.tf # 変数定義
└── outputs.tf # 出力値
S3バケット(tfstate保存先):
dp-tfstate-bucket/ # バケット名(要変更)
└── pipeline/ # backend.tf の key で指定
└── terraform.tfstate # 状態ファイル(自動作成)
⚠️注意:
S3バケット名はグローバルでユニークである必要があります。
dp-tfstate-bucket は例です。
yourname-tfstate-20260125 のように、自分専用のユニークな名前で使用します。
5-2. S3バックエンド(tfstate保存場所)
5-2-1. なぜ必要か
| 管理方式 | メリット | デメリット |
|---|---|---|
| ローカル | 設定不要 | PC依存、チーム共有不可 |
| S3 | 共有可能、バックアップ | 事前準備が必要 |
5-2-2. Step 1: S3バケット作成(AWS CLI)
S3バケット作成:
# tfstate保存用バケットを作成
# (バケット名は例)
aws s3 mb s3://dp-tfstate-bucket --region ap-northeast-1
バージョニング有効化:
# バージョニング有効化(誤削除対策)
aws s3api put-bucket-versioning \
--bucket dp-tfstate-bucket \
--versioning-configuration Status=Enabled
⚠️注意:
バージョニングを有効にすると、ファイルの変更履歴が保存されます。
tfstateを誤って削除・上書きしても、過去のバージョンから復元できます。
5-2-3. Step 2: backend.tf を作成
コードの骨格:
# tf/backend.tf(骨格)
terraform {
backend "s3" {
# 保存先バケット
# 保存ファイルのパス
# リージョン
# 暗号化設定
}
}
フルコード:
# tf/backend.tf
# Terraformの状態管理をS3で行う設定
# これにより、チームでの共有やCI/CDが可能になる
terraform {
backend "s3" {
bucket = "dp-tfstate-bucket" # 保存先バケット
key = "pipeline/terraform.tfstate" # 保存ファイルのパス
region = "ap-northeast-1" # リージョン
encrypt = true # 暗号化を有効化
}
}
5-2-4. コード解説
| 設定 | 値 | 説明 |
|---|---|---|
| bucket | dp-tfstate-bucket | 保存先のS3バケット |
| key | pipeline/terraform.tfstate | バケット内のパス |
| region | ap-northeast-1 | 東京リージョン |
| encrypt | true | サーバーサイド暗号化 |
5-3. OIDC設定(GitHub認証)
5-3-1. なぜ必要か
GitHub ActionsがAWSを操作するために、「GitHubを信頼する」設定 が必要です。
5-3-2. 作成方法の選択
| 方法 | メリット | デメリット |
|---|---|---|
| A: AWSコンソール | 視覚的で分かりやすい | 手順が多い、再現性なし |
| B: Terraform | コード管理、再現性あり | 事前知識が必要 |
推奨: 初めての方は 方法A(AWSコンソール) で仕組みを理解してから、Terraformに移行するのがおすすめです。
【方法A】AWSコンソールで作成
5-3-3. Step 1: OIDCプロバイダ作成
- IAM → IDプロバイダ → プロバイダを追加
- 以下を入力:
| 項目 | 値 |
|---|---|
| プロバイダのタイプ | OpenID Connect |
| プロバイダのURL | https://token.actions.githubusercontent.com |
| 対象者 | sts.amazonaws.com |
- プロバイダを追加 をクリック
5-3-4. Step 2: IAMロール作成
- IAM → ロール → ロールを作成
- 信頼されたエンティティタイプ: ウェブアイデンティティ
- アイデンティティプロバイダー: token.actions.githubusercontent.com
- Audience: sts.amazonaws.com
- GitHub 組織/リポジトリを入力(後で編集)
5-3-5. Step 3: 信頼ポリシーの編集
ロール作成後、信頼関係タブ で以下に編集:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::123456789012:oidc-provider/token.actions.githubusercontent.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
},
"StringLike": {
"token.actions.githubusercontent.com:sub": "repo:YOUR_USERNAME/pipeiac02:*"
}
}
}
]
}
⚠️
123456789012を自分のAWSアカウントIDに、YOUR_USERNAMEを自分のGitHubユーザー名に置き換える。
5-3-6. Step 4: 権限ポリシーをアタッチ
学習用として AdministratorAccess をアタッチします。
⚠️ 本番環境では最小権限にすべき。
【方法B】Terraformで作成
5-3-7. ファイル構成
(再掲)
pipeiac02/
├── .github/
│ └── workflows/
│ ├── terraform-plan.yml # ★今回作成
│ └── terraform-apply.yml # ★今回作成
├── tf/
│ ├── backend.tf # ★今回作成
│ └── (既存ファイル)
└── oidc/ # ★今回作成(別管理)
├── main.tf # OIDCプロバイダ・IAMロール
├── variables.tf # 変数定義
└── outputs.tf # 出力値
コードの骨格:
# oidc/main.tf(骨格)
# プロバイダ設定
terraform {
# バージョン制約
}
# OIDCプロバイダ
resource "aws_iam_openid_connect_provider" "github" {
# GitHubのOIDCエンドポイント
}
# IAMロール
resource "aws_iam_role" "github_actions" {
# 信頼ポリシー(どのGitHubリポジトリを許可するか)
}
# 権限
resource "aws_iam_role_policy_attachment" "admin" {
# 必要な権限をアタッチ
}
フルコード(3ファイル構成):
oidc/main.tf
# oidc/main.tf
# ================================
# プロバイダ設定
# ================================
terraform {
required_version = ">= 1.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = var.aws_region
}
# ================================
# OIDCプロバイダ
# ================================
# GitHubをAWSが信頼するための設定
# これにより、GitHub ActionsがAWSリソースを操作できる
resource "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
# ↑ GitHubのサーバー証明書の「指紋」(フィンガープリント)
tags = {
Name = "github-actions-oidc"
Project = var.project_name
Environment = var.environment
ManagedBy = "Terraform"
}
}
# ================================
# IAMロール
# ================================
# GitHub Actionsが引き受けるロール
resource "aws_iam_role" "github_actions" {
name = "github-actions-terraform"
# 信頼ポリシー:どのGitHubリポジトリからのアクセスを許可するか?
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Federated = aws_iam_openid_connect_provider.github.arn
}
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringEquals = {
"token.actions.githubusercontent.com:aud" = "sts.amazonaws.com"
}
StringLike = {
# このリポジトリからのみ許可
"token.actions.githubusercontent.com:sub" = "repo:${var.github_username}/${var.github_repo}:*"
}
}
}
]
})
tags = {
Name = "github-actions-terraform"
Project = var.project_name
Environment = var.environment
ManagedBy = "Terraform"
}
}
# ================================
# 権限ポリシー
# ================================
# 学習用:AdministratorAccess(本番では最小権限に)
resource "aws_iam_role_policy_attachment" "admin" {
role = aws_iam_role.github_actions.name
policy_arn = "arn:aws:iam::aws:policy/AdministratorAccess"
}
💡補足:
oidc/main.tf コード内の thumbprint_list は秘密情報ではない
thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
thumbprint_list は公開情報
| 項目 | 説明 |
|---|---|
| これは何? | GitHubのサーバー証明書の「指紋」(フィンガープリント) |
| 役割 | 「接続先が本物のGitHubか」を確認するために使用 |
| 公開情報? | AWS公式ドキュメントで公開 |
| 悪用リスク | この値を知られても、他人のAWSにはアクセス不可 |
比喩で理解:
thumbprint = 「GitHubの顔写真」
- 顔写真を公開しても、本人になりすますことはできない
- 「この顔の人だけ入れて」という確認に使うだけ
秘密にすべきものは別:
| 公開OK ✅ | 秘密にすべき 🔐 |
|---|---|
| thumbprint_list | AWS_ACCOUNT_ID |
| OIDCプロバイダのURL | terraform.tfvars の内容 |
| 信頼ポリシーの構造 | tfstateファイル |
oidc/variables.tf
# oidc/variables.tf
# ================================
# 必須変数
# ================================
variable "github_username" {
description = "GitHubユーザー名またはOrganization名"
type = string
}
variable "github_repo" {
description = "GitHubリポジトリ名"
type = string
}
# ================================
# オプション変数(デフォルト値あり)
# ================================
variable "aws_region" {
description = "AWSリージョン"
type = string
default = "ap-northeast-1"
}
variable "project_name" {
description = "プロジェクト名(タグ用)"
type = string
default = "dp"
}
variable "environment" {
description = "環境名(タグ用)"
type = string
default = "dev"
}
oidc/outputs.tf
# oidc/outputs.tf
# ================================
# 出力
# ================================
output "oidc_provider_arn" {
description = "OIDCプロバイダのARN"
value = aws_iam_openid_connect_provider.github.arn
}
output "github_actions_role_arn" {
description = "GitHub Actions用IAMロールのARN"
value = aws_iam_role.github_actions.arn
}
output "github_actions_role_name" {
description = "GitHub Actions用IAMロール名"
value = aws_iam_role.github_actions.name
}
oidc/terraform.tfvars(要作成)
# /pipeiac02/oidc/terraform.tfvars を編集
# ================================
# 必須:自分の値に置き換える
# ================================
github_username = "YOUR_USERNAME" # ← 自分のGitHubユーザー名に変更
github_repo = "pipeiac02"
# ================================
# オプション(デフォルト値を使う場合は省略可)
# ================================
# aws_region = "ap-northeast-1"
# project_name = "dp"
# environment = "dev"
実行方法:
# /pipeiac02/oidc/
terraform init
terraform plan
terraform apply
5-4. GitHub Secrets設定
5-4-1. なぜ必要か?
AWSアカウントIDは 機密情報 なので、コードに直接書かずにSecretsで管理します。
5-4-2. 設定手順
- GitHubリポジトリを開く
- Settings タブをクリック
- 左メニューの Secrets and variables → Actions
- New repository secret をクリック
- 以下を入力:
| Name | Secret |
|---|---|
| AWS_ACCOUNT_ID | あなたのAWSアカウントID(12桁の数字) |
| ALERT_EMAIL | アラート通知用のメールアドレス |
- Add secret をクリック
5-4-3. AWSアカウントIDの確認方法(AWS CLI)
aws sts get-caller-identity --query Account --output text
6. 実装(ワークフロー作成)
6-1. terraform-plan.yml(PR時の自動チェック)
(再掲)
pipeiac02/
├── .github/
│ └── workflows/
│ ├── terraform-plan.yml # ★今回作成
│ └── terraform-apply.yml # ★今回作成
(省略)
6-1-1. なぜ必要か
PRを作成したとき、変更内容を自動でプレビュー します。
6-1-2. コードの骨格
# .github/workflows/terraform-plan.yml(骨格)
name: Terraform Plan
# いつ実行するか
on:
pull_request:
# mainブランチへのPR時
# 権限
permissions:
# OIDC認証用
# PRコメント用
# 実行内容
jobs:
plan:
steps:
# 1. コードを取得
# 2. AWS認証(OIDC)
# 3. Terraformセットアップ
# 4. terraform init
# 5. terraform fmt(フォーマットチェック)
# 6. terraform validate(構文チェック)
# 7. terraform plan
# 8. 結果をPRにコメント
# 9. 失敗時はワークフローを失敗させる
図解① YAML構造:
| ブロック | 設定内容 |
|---|---|
| name |
Terraform Plan(ワークフロー名) |
| on |
pull_request → branches: main, paths: tf/**
|
| permissions |
id-token: write, contents: read, pull-requests: write
|
| jobs | steps: Checkout → AWS認証 → Setup → init → fmt → validate → plan → コメント → 失敗チェック |
図解② シーケンス(処理の流れ):
steps:のステップ一覧:
| Step | 名前 | 目的 | 使用するAction名/コマンド |
|---|---|---|---|
| 1 | Checkout | コード取得 | actions/checkout@v4 |
| 2 | AWS認証 | OIDC認証 | aws-actions/configure-aws-credentials@v4 |
| 3 | Setup | Terraform準備 | hashicorp/setup-terraform@v3 |
| 4 | Init | 初期化 | terraform init |
| 5 | Fmt | フォーマット確認 | terraform fmt -check |
| 6 | Validate | 構文確認 | terraform validate |
| 7 | Plan | 差分確認 | terraform plan -no-color |
| 8 | Comment | 結果通知 | actions/github-script@v7 |
| 9 | Check Status | 失敗時に終了 |
exit 1(plan失敗時) |
@v4 @v3 とは?
GitHub Actions のバージョン指定です。
uses: actions/checkout@v4
~~~~~~~~~~~~~~~~ ~~~
Action名 バージョン
バージョンの種類:
| 指定方法 | 例 | 意味 |
|---|---|---|
| メジャー | @v4 |
v4.x.x の最新を自動取得。バグ修正は自動反映、破壊的変更は入らない(推奨) |
| 完全指定 | @v4.1.0 |
厳密にそのバージョンのみ使用。予期しない変更を防ぎたい場合に使用 |
| コミットSHA | @a1b2c3d... |
特定のコミットを指定。セキュリティ最重視の本番環境向け |
| ブランチ | @main |
常に最新を取得。開発中のため不安定な可能性あり(非推奨) |
補足: 各Actionの最新バージョンは公式リポジトリで確認できます。
例: actions/checkout
6-1-3. フルコード
# .github/workflows/terraform-plan.yml
name: Terraform Plan
# ================================
# トリガー:いつ実行するか
# ================================
on:
pull_request:
branches:
- main # mainブランチへのPR時
paths:
- 'tf/**' # tf/配下の変更時のみ
# ================================
# 権限
# ================================
permissions:
id-token: write # OIDC認証に必要
contents: read # コード読み取り
pull-requests: write # PRコメントに必要
# ================================
# 環境変数
# ================================
env:
AWS_REGION: ap-northeast-1
TF_VERSION: 1.6.0
WORKING_DIR: tf
# ================================
# ジョブ
# ================================
jobs:
plan:
name: Terraform Plan
runs-on: ubuntu-latest
steps:
# ----------------------------------------
# Step 1: コードを取得
# ----------------------------------------
- name: Checkout
uses: actions/checkout@v4
# ----------------------------------------
# Step 2: AWS認証(OIDC)
# ----------------------------------------
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-terraform
aws-region: ${{ env.AWS_REGION }}
# ----------------------------------------
# Step 3: Terraformセットアップ
# ----------------------------------------
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
# ----------------------------------------
# Step 4: terraform init
# ----------------------------------------
- name: Terraform Init
working-directory: ${{ env.WORKING_DIR }}
run: terraform init
# ----------------------------------------
# Step 5: terraform fmt(フォーマットチェック)
# ----------------------------------------
- name: Terraform Format Check
id: fmt
working-directory: ${{ env.WORKING_DIR }}
run: terraform fmt -check
continue-on-error: true
# ----------------------------------------
# Step 6: terraform validate(構文チェック)
# ----------------------------------------
- name: Terraform Validate
id: validate
working-directory: ${{ env.WORKING_DIR }}
run: terraform validate
continue-on-error: true
# ----------------------------------------
# Step 7: terraform plan
# ----------------------------------------
- name: Terraform Plan
id: plan
working-directory: ${{ env.WORKING_DIR }}
run: terraform plan -no-color -out=tfplan -var="alert_email=${{ secrets.ALERT_EMAIL }}"
continue-on-error: true
# ----------------------------------------
# Step 8: 結果をPRにコメント
# ----------------------------------------
- name: Comment on PR
uses: actions/github-script@v7
with:
script: |
const output = `### 🏗️ Terraform Plan Result
| Check | Status |
|-------|--------|
| 🖌️ Format | \`${{ steps.fmt.outcome }}\` |
| ✅ Validate | \`${{ steps.validate.outcome }}\` |
| 📋 Plan | \`${{ steps.plan.outcome }}\` |
<details><summary>📖 Plan Details</summary>
\`\`\`terraform
${{ steps.plan.outputs.stdout }}
\`\`\`
</details>
> Pushed by: @${{ github.actor }}`;
github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body: output
})
# ----------------------------------------
# Step 9: Planが失敗したらワークフローを失敗させる
# ----------------------------------------
- name: Check Plan Status
if: steps.plan.outcome == 'failure'
run: exit 1
6-1-4. コード解説
| セクション | 説明 |
|---|---|
on.pull_request |
PRが作成/更新されたときに実行 |
permissions |
OIDC認証とPRコメントに必要な権限 |
role-to-assume |
OIDCで引き受けるIAMロール |
terraform plan -no-color |
色コードなしで出力(コメント用) |
-var="alert_email=..." |
GitHub Secretsからalert_email変数を渡す |
continue-on-error: true |
エラーでも次のステップに進む |
6-2. terraform-apply.yml(マージ時の自動デプロイ)
(再掲)
pipeiac02/
├── .github/
│ └── workflows/
│ ├── terraform-plan.yml # ★今回作成
│ └── terraform-apply.yml # ★今回作成
(省略)
6-2-1. なぜ必要か?
mainブランチにマージされたとき、自動でインフラをデプロイ します。
6-2-2. コードの骨格
# .github/workflows/terraform-apply.yml(骨格)
name: Terraform Apply
# いつ実行するか
on:
push:
branches:
- main # mainブランチへのプッシュ時
# 権限
permissions:
# OIDC認証用
# 実行内容
jobs:
apply:
steps:
# 1. コードを取得
# 2. AWS認証(OIDC)
# 3. Terraformセットアップ
# 4. terraform init
# 5. terraform apply(自動承認)
図解① YAML構造:
| ブロック | 設定内容 |
|---|---|
| name |
Terraform Apply(ワークフロー名) |
| on |
push → branches: main, paths: tf/**
|
| permissions |
id-token: write, contents: read
|
| jobs | steps: Checkout → AWS認証 → Setup → init → apply |
図解② シーケンス(処理の流れ):
steps:ステップ一覧:
| Step | 名前 | 目的 | 使用Action/コマンド |
|---|---|---|---|
| 1 | Checkout | コード取得 | actions/checkout@v4 |
| 2 | AWS認証 | OIDC認証 | aws-actions/configure-aws-credentials@v4 |
| 3 | Setup | Terraform準備 | hashicorp/setup-terraform@v3 |
| 4 | Init | 初期化 | terraform init |
| 5 | Apply | インフラ適用 | terraform apply -auto-approve |
plan.yml との違い:
fmt/validate/コメント機能がなく、-auto-approveで自動適用します。PRで既にレビュー済みのため、マージ後は即座に適用します。
6-2-3. フルコード
# .github/workflows/terraform-apply.yml
name: Terraform Apply
# ================================
# トリガー:いつ実行するか
# ================================
on:
push:
branches:
- main # mainブランチへのプッシュ時
paths:
- 'tf/**' # tf/配下の変更時のみ
# ================================
# 権限
# ================================
permissions:
id-token: write # OIDC認証に必要
contents: read # コード読み取り
# ================================
# 環境変数
# ================================
env:
AWS_REGION: ap-northeast-1
TF_VERSION: 1.6.0
WORKING_DIR: tf
# ================================
# ジョブ
# ================================
jobs:
apply:
name: Terraform Apply
runs-on: ubuntu-latest
steps:
# ----------------------------------------
# Step 1: コードを取得
# ----------------------------------------
- name: Checkout
uses: actions/checkout@v4
# ----------------------------------------
# Step 2: AWS認証(OIDC)
# ----------------------------------------
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::${{ secrets.AWS_ACCOUNT_ID }}:role/github-actions-terraform
aws-region: ${{ env.AWS_REGION }}
# ----------------------------------------
# Step 3: Terraformセットアップ
# ----------------------------------------
- name: Setup Terraform
uses: hashicorp/setup-terraform@v3
with:
terraform_version: ${{ env.TF_VERSION }}
# ----------------------------------------
# Step 4: terraform init
# ----------------------------------------
- name: Terraform Init
working-directory: ${{ env.WORKING_DIR }}
run: terraform init
# ----------------------------------------
# Step 5: terraform apply(自動承認)
# ----------------------------------------
- name: Terraform Apply
working-directory: ${{ env.WORKING_DIR }}
run: terraform apply -auto-approve -var="alert_email=${{ secrets.ALERT_EMAIL }}"
6-2-4. コード解説
| セクション | 説明 |
|---|---|
on.push.branches: main |
mainブランチへのプッシュ時に実行 |
terraform apply -auto-approve |
確認なしで自動実行 |
-var="alert_email=..." |
GitHub Secretsからalert_email変数を渡す |
7. 動作確認
7-1. 事前準備チェックリスト
| # | 項目 | 確認 |
|---|---|---|
| 1 | S3バックエンド用バケット作成 | ☐ |
| 2 | OIDCプロバイダ作成 | ☐ |
| 3 | GitHub Actions用IAMロール作成 | ☐ |
| 4 | GitHub Secrets設定(AWS_ACCOUNT_ID, ALERT_EMAIL) | ☐ |
| 5 | backend.tf 作成 | ☐ |
| 6 | terraform-plan.yml 作成 | ☐ |
| 7 | terraform-apply.yml 作成 | ☐ |
7-2. バックエンド移行
ローカルのtfstateをS3に移行:
cd pipeiac02/tf
# backend.tf を追加後
terraform init -migrate-state
確認メッセージが表示されたら yes と入力
期待される出力:
Successfully configured the backend "s3"!
7-3. PRでPlan確認
7-3-1. フロー図(8ステップ)
7-3-2. Step 1: 新しいブランチを作成
git checkout -b feature/test-cicd
7-3-3. Step 2: 軽微な変更を追加
例:main.tf にコメントを追加
echo "# CI/CD test" >> tf/main.tf
7-3-4. Step 3: コミット
git add .
git commit -m "test: CI/CD動作確認"
7-3-5. Step 4: プッシュ
git push origin feature/test-cicd
7-3-6. Step 5: PRを作成
GitHubでPRを作成します。
手順:
| Step | GitHub画面での操作 | 確認内容 |
|---|---|---|
| 1 | リポジトリページを開く |
https://github.com/YOUR_USERNAME/pipeiac02 にアクセス |
| 2 | Compare & pull request ボタンをクリック | 黄色いバナー「feature/test-cicd had recent pushes...」が表示される |
| 3 | PRの内容を入力 | base: main ← compare: feature/test-cicd、Able to merge と表示 |
| 4 | Create pull request ボタンをクリック | PRが作成され、自動的にGitHub Actionsが起動 |
PRの入力項目:
| 項目 | 入力内容 |
|---|---|
| Title |
test: CI/CD動作確認(コミットメッセージが自動入力される) |
| Description | 変更内容の説明(任意) |
💡バナーが消えた場合:
Pull requests タブ → New pull request → ブランチを選択
7-3-7. Step 6: 自動Plan実行を確認
GitHub ActionsでPlanが実行され、PRにコメントが付きます。
確認手順:
-
Actionsの実行状況を確認
PRページの下部 Checks セクションに、チェック状況が表示されます:
状態 表示 実行中 🟡 Terraform Plan — In progress 成功 ✅ All checks have passed 成功 ✅ Terraform Plan — Successful in 45s -
詳細を見る場合:Actionsタブをクリック
リポジトリページ上部のタブから Actions をクリックします。
タブ 説明 Code ソースコード Pull requests PR一覧 Actions ワークフロー実行履歴 ← ここをクリック All workflows に実行履歴が表示されます:
ステータス ワークフロー コミット ブランチ 時間 ✅ Terraform Plan test: CI/CD動作確認 #1 feature/test-cicd 45s -
PRにコメントが自動追加される
ワークフロー完了後、PRのコメント欄に github-actions bot から結果が投稿されます:
項目 内容 タイトル Terraform Plan Result Format success Validate success Plan success Plan Details No changes / 変更内容 Pushed by @your-username 💡このコメントを見て、変更内容を確認してからマージするかどうか判断します
7-4. マージでApply確認
7-4-1. Step 7: PRをマージ
GitHubでPRをマージします。
手順:
| Step | GitHub画面での操作 | 確認内容 |
|---|---|---|
| 1 | チェック完了を確認 | ✅ All checks have passed |
| 2 | Merge pull request ボタンをクリック | This branch has no conflicts with the base branch |
| 3 | Confirm merge ボタンをクリック | コミットメッセージを確認 |
| 4 | マージ完了 | 🟣 Pull request successfully merged and closed |
マージ完了後の表示:
| 項目 | 内容 |
|---|---|
| ステータス | Pull request successfully merged and closed |
| 次のアクション | Delete branch ボタンでブランチを削除(推奨) |
💡 「Delete branch」をクリックして、不要になったブランチを削除しておきましょう
7-4-2. Step 8: 自動デプロイを確認
GitHub → Actions タブで実行状況を確認します。
手順:
-
Actionsタブをクリック
リポジトリページ上部のタブから Actions をクリックします。
-
Terraform Applyワークフローを確認
All workflows に実行履歴が表示されます:
ステータス ワークフロー コミット ブランチ 状態 🟡 Terraform Apply Merge pull request #1 main Running... ✅ Terraform Plan test: CI/CD動作確認 #1 feature/test-cicd 45s 成功すると:
ステータス ワークフロー コミット ブランチ 時間 ✅ Terraform Apply Merge pull request #1 main 1m 23s -
実行詳細を確認(クリックで展開)
ワークフロー名をクリックすると、各ステップの詳細が見れます:
ステータス ステップ 時間 ✅ Set up job 3s ✅ Checkout 2s ✅ Configure AWS Credentials 5s ✅ Setup Terraform 8s ✅ Terraform Init 15s ✅ Terraform Apply 45s ✅ Post actions 2s 💡 各ステップをクリックすると、コマンドの出力ログが確認できます
-
失敗した場合
ステータス ワークフロー ブランチ 状態 ❌ Terraform Apply main Failed 失敗したステップをクリックしてログを確認し、エラー内容を修正してください
7-4-3. AWSで変更を確認
AWSコンソールで変更が反映されていることを確認します。
確認方法:
- AWSマネジメントコンソール にログイン
- 変更したリソースのサービス画面を開く
- 変更が反映されていることを確認
CLIでの確認例:
# S3バケット一覧を確認
aws s3 ls | grep dp-
# Lambda関数を確認
aws lambda list-functions --query 'Functions[?starts_with(FunctionName, `dp-`)].FunctionName'
# Step Functionsを確認
aws stepfunctions list-state-machines --query 'stateMachines[?starts_with(name, `dp-`)].name'
💡今回はコメントを追加しただけなので、AWSリソースに変更はありません。
実際にリソースを変更した場合は、ここで反映を確認します。
7-5. 確認チェックリスト
| 確認項目 | 期待値 |
|---|---|
| PR作成時 | Planワークフローが実行 ✅ |
| PRコメント | Plan結果が表示 ✅ |
| マージ時 | Applyワークフローが実行 ✅ |
| AWS | 変更が反映 ✅ |
8. まとめ
8-1. この記事でやったこと
| 項目 | 内容 |
|---|---|
| 理解 | CI/CD・PR・OIDCの仕組みを学んだ |
| 実装 | Plan/Apply ワークフローを作成 |
| 確認 | PRでplan、マージでapplyを確認 |
8-2. 比喩の振り返り
| レストラン | CI/CD | 今回やったこと |
|---|---|---|
| 自動発注システム | GitHub Actions | ワークフロー作成 |
| 身分証明書確認 | OIDC認証 | 安全な認証設定 |
| 発注書作成 | PR作成 | ワークフロートリガー |
| 発注確認 | Plan | 自動実行&コメント |
| 店長承認 | レビュー | PRレビュー |
| 発注実行 | Apply | 自動実行 |
8-3. CI/CDの全体像(再掲)
8-4. 作成したもの一覧
| # | 場所 | ファイル | 役割 |
|---|---|---|---|
| 1 | AWS | S3バケット | tfstate保存 |
| 2 | AWS | OIDCプロバイダ | GitHub認証 |
| 3 | AWS | IAMロール | Actions権限 |
| 4 | GitHub | Secrets | アカウントID |
| 5 | リポジトリ | backend.tf | S3バックエンド |
| 6 | リポジトリ | terraform-plan.yml | PR時plan |
| 7 | リポジトリ | terraform-apply.yml | マージ時apply |
8-5. セキュリティのポイント
| ポイント | 説明 |
|---|---|
| OIDC認証 | 長期認証情報を使わない ✅ |
| 最小権限 | 本番では権限を絞る |
| Secrets | 機密情報はコードに書かない ✅ |
| ブランチ保護 | mainへの直接プッシュを禁止(推奨) |
| レビュー必須 | 1人以上のレビューを必須に(推奨) |
8-6. 次回予告
第12回: 総まとめ では、シリーズ全体を振り返ります。
- 全12回の振り返り
- 作成したリソース一覧
- 学んだことのまとめ
- 次のステップ
レストランで言うと「開店準備完了の確認」です。