12. CI/CD Pipeline Guide

GitHub Actions CI/CD Pipeline guide for MILU2 Infrastructure.

Overview

┌─────────────────────────────────────────────────────────────────┐
│                        GitHub Actions                            │
│                                                                  │
│  ┌─────────────────────┐      ┌─────────────────────┐           │
│  │   Infra Pipeline    │      │    App Pipeline     │           │
│  │                     │      │                     │           │
│  │  milu2-github-      │      │  milu2-github-      │           │
│  │  actions-infra      │      │  actions-app-deploy │           │
│  │                     │      │                     │           │
│  │  AdministratorAccess│      │  ECR/ECS/CodeDeploy │           │
│  └──────────┬──────────┘      └──────────┬──────────┘           │
└─────────────┼─────────────────────────────┼─────────────────────┘
              │                             │
              ▼                             ▼
┌─────────────────────────┐    ┌─────────────────────────────────┐
│  Terraform Apply        │    │  1. Build & Push ECR            │
│  - VPC, RDS, ECS, etc.  │    │  2. Register Task Definition    │
└─────────────────────────┘    │  3. CodeDeploy Blue/Green       │
                               └─────────────────────────────────┘

GitHub OIDC Trust Model

┌──────────────┐    1. Request token     ┌──────────────┐
│   GitHub     │ ──────────────────────► │   GitHub     │
│   Actions    │                         │    OIDC      │
│   Workflow   │ ◄────────────────────── │   Provider   │
└──────────────┘    2. JWT token         └──────────────┘
       │
       │ 3. AssumeRoleWithWebIdentity
       │    (sts:AssumeRoleWithWebIdentity)
       ▼
┌──────────────┐    4. Temporary creds   ┌──────────────┐
│     AWS      │ ◄─────────────────────  │  IAM Role    │
│     STS      │                         │ (trust OIDC) │
└──────────────┘                         └──────────────┘

Infrastructure Pipeline

Role: milu2-github-actions-infra

Permissions: AdministratorAccess

# .github/workflows/infra-deploy.yml
name: Infrastructure Deploy

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

permissions:
  id-token: write
  contents: read

jobs:
  deploy:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/milu2-github-actions-infra
          aws-region: ap-northeast-1
          role-session-name: GitHubActionsInfra
      
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v3
        with:
          terraform_version: 1.11.5
      
      - name: Download Env Vars
        run: |
          aws s3 cp s3://milu2-iac-env/tofu/common_vars.hcl tofu/envs/
          aws s3 cp s3://milu2-iac-env/tofu/test/env_vars.hcl tofu/envs/test/
      
      - name: Terraform Plan
        if: github.event_name == 'pull_request'
        run: |
          cd tofu/envs/test/core
          terragrunt plan
      
      - name: Terraform Apply
        if: github.ref == 'refs/heads/main'
        run: |
          cd tofu/envs/test/core
          terragrunt apply -auto-approve

Application Pipeline

Role: milu2-github-actions-app-deploy

Permissions: ECR push/pull, ECS task definitions, CodeDeploy, Lambda

# .github/workflows/app-deploy.yml
name: Application Deploy

on:
  push:
    branches: [main]

permissions:
  id-token: write
  contents: read

env:
  AWS_REGION: ap-northeast-1
  ECR_REGISTRY: 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com
  SERVICE_NAME: api

jobs:
  build-and-deploy:
    runs-on: ubuntu-latest
    
    steps:
      - uses: actions/checkout@v4
      
      - name: Configure AWS Credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          role-to-assume: arn:aws:iam::123456789012:role/milu2-github-actions-app-deploy
          aws-region: ${{ env.AWS_REGION }}
      
      - name: Login to ECR
        run: |
          aws ecr get-login-password --region ${{ env.AWS_REGION }} | \
          docker login --username AWS --password-stdin ${{ env.ECR_REGISTRY }}
      
      - name: Build and Push
        run: |
          docker build -t ${{ env.ECR_REGISTRY }}/milu2-test-${{ env.SERVICE_NAME }}:${{ github.sha }} .
          docker push ${{ env.ECR_REGISTRY }}/milu2-test-${{ env.SERVICE_NAME }}:${{ github.sha }}
      
      - name: Create CodeDeploy Deployment
        run: |
          aws deploy create-deployment \
            --application-name milu2-test \
            --deployment-group-name ${{ env.SERVICE_NAME }} \
            --revision '...'

CodeDeploy Blue/Green Deployment

Blue/Green Deployment:
                                  
┌──────────────┐     ┌──────────────┐
│   Blue TG    │     │   Green TG   │
│  (current)   │     │   (new)      │
└──────┬───────┘     └──────┬───────┘
       │                    │
       ▼                    ▼
┌──────────────┐     ┌──────────────┐
│  Blue Tasks  │     │  Green Tasks │
│  (running)   │     │  (deploying) │
└──────────────┘     └──────────────┘

Deployment Lifecycle:
1. CreateDeployment
        │
        ▼
2. Start new tasks (Green)
        │
        ▼
3. Health checks pass
        │
        ▼
4. Shift traffic (Blue → Green)
        │
        ▼
5. Wait for approval (STOP_DEPLOYMENT action)
        │
        ▼
6. ContinueDeployment (manual)
        │
        ▼
7. Terminate Blue tasks (after 60 min)

Deployment Commands

# Approve pending deployment
aws deploy continue-deployment \
  --deployment-id d-XXXXXXXXX \
  --deployment-wait-type READY_WAIT

# Or stop and rollback
aws deploy stop-deployment \
  --deployment-id d-XXXXXXXXX \
  --auto-rollback-enabled

Troubleshooting CI/CD

OIDC Issues

# Check role trust policy
aws iam get-role --role-name milu2-github-actions-infra \
  --query 'Role.AssumeRolePolicyDocument'

# Verify OIDC provider
aws iam list-open-id-connect-providers

# Re-apply github_provider if thumbprint changed
cd tofu/envs/shared/github_provider
terragrunt apply

CodeDeploy Issues

# Check deployment status
aws deploy get-deployment --deployment-id d-XXXXXXXXX

# List deployment events
aws deploy list-deployment-targets \
  --deployment-id d-XXXXXXXXX

# View deployment logs
aws logs tail /aws/codedeploy/milu2-test-api