CDKTF × GitHub Actions × GCP × Cloudflare で Next.js を爆速デプロイ
はじめに
CDKTF(CDK for Terraform)を使って、
- GCP(Cloud Run)にNext.jsをデプロイ
- CloudflareでDNSの設定
- GitHub ActionsでCI/CDを構築
という構成をすぐに立ち上げられるテンプレートを作成しました。
この記事では、そのテンプレートを使ってインフラからアプリのデプロイまでを自動化する手順を解説します。
構成概要(アーキテクチャ)
- フロントエンド:Next.js
- インフラ:CDK for Terraform(TypeScript)
- 実行環境:Cloud Run
- ドメイン:Cloudflare
- CI/CD:GitHub Actions
事前準備
- GCP
- プロジェクトID
- Cloudflare
- ドメイン
- ゾーンID
- APIトークン
- GitHub
- リポジトリ
ツール名 | バージョン | URL |
---|---|---|
Node.js | v22.16.0 | https://nodejs.org/ |
pnpm | 10.12.1 | https://pnpm.io/ja/installation |
Terraform | v1.9.4 | https://www.terraform.io/ |
GitHub CLI (gh) | 2.48.0 | https://cli.github.com/ |
Google Cloud SDK | 524.0.0 | https://cloud.google.com/sdk/docs/install |
デプロイ手順
1. 認証(GCP & GitHub)
gcloud auth login
gcloud auth application-default login
gh auth login
2. クローン&リモートURLの設定
git clone git@github.com:yoppyDev/cdktf-nextjs-gcp-template.git --depth 1 <your-repo-name>
cd <your-repo-name>
自分のGitHubリポジトリに変更
git remote set-url origin git@github.com:<your-github-username>/<your-repo-name>.git
git remote -v
3. 環境変数の設定
cp .env.example .env
cp infra/.env.example infra/.env
.env
に記入する内容
GCP_PROJECT_ID=your-gcp-project-id
GCP_PROJECT_NUMBER=your-gcp-project-number
CLOUDFLARE_API_TOKEN=your-cloudflare-api-token
DOMAIN_NAME=your-domain-name
ZONE_ID=your-cloudflare-zone-id
4. CDKTF環境のセットアップ
make all-setup
all-setupで実行している内容を確認してください。
5. インフラ & Next.jsのデプロイ
git push origin main
dev環境のデプロイが実行されます。
ドメインのステータスが「ACTIVE」になると、https://dev.<your-domain-name>
にアクセスできます!
この画面が表示されれば、デプロイ成功です!🎉
all-setupで実行している内容
make all-setup
コマンドは、プロジェクトの初期セットアップを自動化するコマンドです。
1. Terraform状態ファイル用バケット作成
作成されるリソース:
- GCSバケット:
gs://tfstate-{PROJECT_ID}
- 用途: Terraform状態ファイルの保存
2. Workload Identityのデプロイ
実行内容:
- CDKTFを使用してWorkload Identity PoolとProviderを作成
- GitHub Actions用のService Accountを作成
- 必要なIAM権限を付与
作成されるリソース:
- Workload Identity Pool:
projects/{PROJECT_ID}
- Workload Identity Provider:
github-actions
- Service Account:
github-actions-sa@{PROJECT_ID}.iam.gserviceaccount.com
3. GitHub Secrets設定(各環境:dev / stg / prod)
設定されるSecrets:
-
GCP_PROJECT_ID
: GCPプロジェクトID -
GCP_PROJECT_NUMBER
: GCPプロジェクト番号 -
WORKLOAD_IDENTITY_PROVIDER
: Workload Identity ProviderのARN -
SERVICE_ACCOUNT
: Service Accountのメールアドレス -
CLOUDFLARE_API_TOKEN
: Cloudflare APIトークン -
DOMAIN_NAME
: ドメイン名 -
ZONE_ID
: CloudflareゾーンID -
GIT_REPO
: GitHubリポジトリ名
4. 必要なAPIの有効化
有効化されるAPI:
-
iamcredentials.googleapis.com
- Workload Identity用 -
artifactregistry.googleapis.com
- Artifact Registry用 -
compute.googleapis.com
- Compute Engine用 -
iam.googleapis.com
- IAM用 -
run.googleapis.com
- Cloud Run用 -
cloudbuild.googleapis.com
- Cloud Build用
Github Actionsのワークフロー
ワークフロー構成
.github/workflows/
├── deploy-dev.yml # dev環境自動デプロイ
├── deploy-stg.yml # stg環境自動デプロイ
├── deploy-prod.yml # prod環境自動デプロイ
├── infra-deploy.yml # インフラ手動デプロイ
├── infra-plan.yml # インフラプラン実行
└── app-deploy.yml # アプリケーション手動デプロイ
deploy-dev.yml
)
dev環境自動デプロイ (
トリガー: mainブランチへのpush
実行内容:
- インフラデプロイ: CDKTFでインフラリソースをデプロイ
- アプリケーションデプロイ: Cloud BuildでNext.jsアプリをデプロイ
deploy-stg.yml
)
stg環境自動デプロイ (
トリガー: GitHub Release(prerelease)
実行内容: dev環境と同様のデプロイ処理
deploy-prod.yml
)
prod環境自動デプロイ (
トリガー: GitHub Release(release)
実行内容: dev環境と同様のデプロイ処理
infra-deploy.yml
)
インフラ手動デプロイ (
トリガー: 手動実行
実行内容: 選択した環境のインフラのみをデプロイ
app-deploy.yml
)
アプリケーション手動デプロイ (
トリガー: 手動実行
実行内容: 選択した環境のアプリケーションのみをデプロイ
infra-plan.yml
)
インフラプラン実行 (
トリガー:
- 手動実行
- Pull Request(infraディレクトリの変更時)
実行内容:
- 選択した環境のTerraformプランを実行
- 変更内容をPull Requestにコメント
感想
CDKTFを使って、Next.jsをGCPとCloudflareでデプロイする方法を紹介しました。
TERASSの私の所属しているチームでは GCP を使っており、CDKTF で構成を管理しています。
開発しているプロダクトは現状社内の人間しか使わないため、Cloud Run + IAP を使って、社内ユーザーのみにアクセスを制限しています。
プロダクトごとにインフラは各チームで管理していますが、DNS設定や Workload Identity など、複数プロジェクトにまたがる共通リソースについては、専用のリポジトリで CDKTF によりコード管理しています。
変更は PR ベースで行い、GitHub Actions によって差分確認(cdktf plan
)からデプロイ(cdktf deploy
)までを自動化しています。
また、GitHub Actions から GCP にアクセスする際は Workload Identity を利用しており、サービスアカウントの鍵を発行せずに安全に認証できて非常に便利です。
今回紹介したテンプレートでは、Cloud Run が全アクセスを受け入れる設定(--ingress=all)になっているので、ロードバランサーを通さなくても直接アクセスできちゃう状態です。
今後はサービスアカウント経由の制限を入れて、LB経由のアクセスだけを許可するように変更する予定です。
そのほかにも、もう少し実用的な構成に近づけるために、以下のようなリソースや設定も追加していきたいと思ってます:
- Cloud SQL:DB付き構成に対応したい
- Cloud Tasks:非同期ジョブを扱えるようにしたい
- 請求アラートの設定:無料枠を超える前に通知が欲しい
…などなど、引き続きアップデートしていく予定です!
Discussion