実践LESSON 04
この教材で学ぶこと テストからデプロイまでのCI/CDを構築します。GitHub Actions — CI/CD パイプライン構築
対象読者: GitHub Actionsでインフラ・バックエンド向けのCI/CDを構築したい人。
1. 基本構造
.github/
└── workflows/
├── ci.yml # テスト・ビルド(PR時)
├── deploy.yml # デプロイ(main マージ時)
└── terraform.yml # インフラ変更
# 基本的な構造
name: CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest # GitHub ホステッドランナー
steps:
- uses: actions/checkout@v4 # リポジトリをチェックアウト
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
cache: 'pip'
- name: Install dependencies
run: pip install -r requirements.txt
- name: Run tests
run: pytest --cov=src --cov-report=xml
- name: Upload coverage
uses: codecov/codecov-action@v4
2. 実践的な Python アプリのCI
name: Python CI
on:
pull_request:
push:
branches: [main]
jobs:
lint-and-test:
runs-on: ubuntu-latest
strategy:
matrix:
python-version: ['3.11', '3.12'] # 複数バージョンでテスト
steps:
- uses: actions/checkout@v4
- name: Setup Python ${{ matrix.python-version }}
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: 'pip'
- name: Install dependencies
run: |
pip install --upgrade pip
pip install -r requirements.txt
pip install ruff pytest pytest-cov
- name: Lint(ruff)
run: ruff check src/
- name: Type check(mypy)
run: mypy src/ --ignore-missing-imports
- name: Test
env:
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
run: |
pytest tests/ -v --cov=src --cov-report=term-missing
- name: セキュリティスキャン(bandit)
run: |
pip install bandit
bandit -r src/ -ll # 中程度以上の問題を検出
docker-build:
needs: lint-and-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
permissions:
id-token: write # OIDC認証に必要
contents: read
steps:
- uses: actions/checkout@v4
# AWS OIDC認証(キーレス!)
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: arn:aws:iam::123456789:role/github-actions
aws-region: ap-northeast-1
- name: Login to ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v2
- name: Build and push
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/myapp:$IMAGE_TAG .
docker build -t $ECR_REGISTRY/myapp:latest .
docker push $ECR_REGISTRY/myapp:$IMAGE_TAG
docker push $ECR_REGISTRY/myapp:latest
3. AWS OIDC 認証(キーレスで最も安全)
# Terraform で GitHub Actions 用の IAM Role を作成
resource "aws_iam_openid_connect_provider" "github" {
url = "https://token.actions.githubusercontent.com"
client_id_list = ["sts.amazonaws.com"]
thumbprint_list = ["6938fd4d98bab03faadb97b34396831e3780aea1"]
}
resource "aws_iam_role" "github_actions" {
name = "github-actions-deploy"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Principal = { Federated = aws_iam_openid_connect_provider.github.arn }
Action = "sts:AssumeRoleWithWebIdentity"
Condition = {
StringLike = {
"token.actions.githubusercontent.com:sub" =
"repo:myorg/myrepo:ref:refs/heads/main" # 特定ブランチのみ
}
}
}]
})
}
4. ECS デプロイパイプライン
deploy-ecs:
runs-on: ubuntu-latest
needs: docker-build
environment: production # GitHub Environments で承認フロー
steps:
- uses: actions/checkout@v4
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: ${{ vars.DEPLOY_ROLE_ARN }}
aws-region: ap-northeast-1
- name: タスク定義を更新
id: render-task
uses: aws-actions/amazon-ecs-render-task-definition@v1
with:
task-definition: ecs/task-definition.json
container-name: myapp
image: ${{ needs.docker-build.outputs.image }}
- name: ECS デプロイ
uses: aws-actions/amazon-ecs-deploy-task-definition@v1
with:
task-definition: ${{ steps.render-task.outputs.task-definition }}
service: myapp-service
cluster: production
wait-for-service-stability: true # 安定するまで待機
- name: デプロイ通知(Slack)
if: always()
uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "${{ job.status == 'success' && '✅' || '❌' }} Deploy to production: ${{ job.status }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
5. 便利なパターン
キャッシュで高速化
# Docker レイヤーキャッシュ
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build with cache
uses: docker/build-push-action@v5
with:
cache-from: type=gha
cache-to: type=gha,mode=max
条件付き実行
# 特定ファイルが変更された時のみ実行
on:
push:
paths:
- 'src/**'
- 'Dockerfile'
- '!**.md' # Markdown変更は除外
# ジョブレベルの条件
deploy:
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
並列実行でビルドを高速化
jobs:
test-unit:
runs-on: ubuntu-latest
steps: [...] # ユニットテスト
test-integration:
runs-on: ubuntu-latest
steps: [...] # 統合テスト(並列実行)
build:
needs: [test-unit, test-integration] # 両方成功後にビルド
steps: [...]
6. Secrets 管理
# GitHub CLI でシークレット設定
gh secret set AWS_ACCESS_KEY_ID
gh secret set SLACK_WEBHOOK_URL
# 環境別シークレット(Environments 機能)
# Settings → Environments → production → Secrets
⚠️ 推奨: AWS の永続的なキーより OIDC(キーレス)認証を優先
🔗 次のステップ
- ../IaC/01_Terraform.md — Terraform の CI/CD
- ../../03_Cloud/AWS/02_コンテナサービス.md — ECS/ECR の設定