はじめに
TerraformとGitHub Actionsを使って、Dockerで作ったWordPressアプリケーションをECS(Fargate)に完全自動デプロイする構成を構築しました。
VPCやALB、CloudFront、Route53までTerraformでコード化し、GitHub ActionsのpushイベントをトリガーにDockerビルド&ECRプッシュ→Terraform applyまでCI/CD化しています。
構成
ディレクトリ
├── .github/
│ └── workflows/
│ └── main.yml
│
├── terraform/
│ ├── main.tf
│ └── variables.tf
│
├── modules/
│ ├── vpc/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── ecs/
│ │ ├── main.tf
│ │ ├── variables.tf
│ ├── rds/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── alb/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── cloudfront/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│ ├── route53/
│ │ ├── main.tf
│ │ ├── variables.tf
│ │ └── outputs.tf
│
├── Dockerfile
├── .gitignore
└── README.md
前提
- AWS CLIのインストール、クレデンシャル設定済み(ワークフローでECR URIを取得するため)
- Terraform.tfstateのためのS3バケット(バージョニング有効)を作成
- ECRリポジトリの作成
- GitHub secretsに下の認証情報を保存
①AWS_ACCESS_KEY_ID
②AWS_SECRET_ACCESS_KEY
③AWS_REGION
④DOCKERHUB_USERNAME
⑤DOCKERHUB_PASSWORD
各テンプレート
- terraform/main.tfのプロバイダは明示しておらず、Github ActionsワークフローではGitHubのsecretsから環境変数を渡しています
- ローカル実行する場合はAWS CLIで設定している認証情報が自動で使用されます
- 各テンプレートは以下を参照ください
ワークフロー
要約
- GitHub上の変更検知 or 手動実行
- ソースコード取得
- AWS/ECR/DockerHub認証
- Dockerイメージビルド&ECRプッシュ
- Terraform plan && apply
name: Deploy Terraform Configuration
on:
push:
workflow_dispatch: # 手動トリガーを追加
jobs:
deploy-terraform:
name: Apply Terraform Configuration to AWS
runs-on: ubuntu-latest
env:
AWS_REGION: ap-northeast-1
ECR_REPO: wordpress # ECRリポジトリ名
IMAGE_TAG: ${{ github.sha }} # DockerイメージタグにlatestではなくコミットSHAを使う
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Terraform
uses: hashicorp/setup-terraform@v2
with:
terraform_version: 1.4.0 # 使用するTerraformのバージョンを明示指定
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} # GitHub Secrets に設定されたAWS認証情報
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} # GitHub Secrets に設定されたAWS認証情報
aws-region: ${{ env.AWS_REGION }} # 上で定義したリージョン
# DockerHubにログイン
- name: Login to DockerHub
run: echo "${{ secrets.DOCKERHUB_PASSWORD }}" | docker login -u ${{ secrets.DOCKERHUB_USERNAME }} --password-stdin
- name: Login to ECR
uses: aws-actions/amazon-ecr-login@v2
# カレントディレクトリにあるDockerfileからイメージをビルド
- name: Build Docker image
run: |
docker build -t $ECR_REPO:$IMAGE_TAG .
- name: Tag & Push to ECR
run: |
ECR_URI=$(aws ecr describe-repositories --repository-names $ECR_REPO --query 'repositories[0].repositoryUri' --output text)
docker tag $ECR_REPO:$IMAGE_TAG $ECR_URI:$IMAGE_TAG
docker push $ECR_URI:$IMAGE_TAG
- name: Initialize Terraform
run: cd terraform && terraform init
- name: Terraform Plan
run: cd terraform && terraform plan -var="image_tag=${{ github.sha }}"
- name: Terraform Apply
run: cd terraform && terraform apply -auto-approve -var="image_tag=${{ github.sha }}"
ワークフローの結果
テスト
ECS タスクの起動確認
LBターゲット確認
レスポンス確認
ヘッダ | 解説 |
---|---|
HTTP/1.1 302 Found | リダイレクト |
Location:ttps://hogehoge.click/wp-admin/install.php | リダイレクト先 |
Server: Apache/2.4.62 (Debian) | Webサーバ情報 |
X-Powered-By: PHP/8.1.32 | PHPバージョン |
Cache-Control: no-cache, must-revalidate, max-age=0 | CloudFrontはCathing Disabledのため正常 |
X-Redirect-By: WordPress | リダイレクトの実行元 |
X-Cache: Miss from cloudfront | キャッシュされておらず、オリジンサーバー(ALB→ECS)から取り出している |
Via: 1.1 ...cloudfront.net (CloudFront) | CloudFront経由である |