🦎

CDKTF × GitHub Actions × GCP × Cloudflare で Next.js を爆速デプロイ

に公開

はじめに

CDKTF(CDK for Terraform)を使って、

  • GCP(Cloud Run)にNext.jsをデプロイ
  • CloudflareでDNSの設定
  • GitHub ActionsでCI/CDを構築

という構成をすぐに立ち上げられるテンプレートを作成しました。

https://github.com/yoppyDev/cdktf-nextjs-gcp-template

この記事では、そのテンプレートを使ってインフラからアプリのデプロイまでを自動化する手順を解説します。


構成概要(アーキテクチャ)

アーキテクチャ

  • フロントエンド: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コマンドは、プロジェクトの初期セットアップを自動化するコマンドです。

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/Makefile#L14-L20

1. Terraform状態ファイル用バケット作成

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/Makefile#L66-L69

作成されるリソース:

  • GCSバケット: gs://tfstate-{PROJECT_ID}
  • 用途: Terraform状態ファイルの保存

2. Workload Identityのデプロイ

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/Makefile#L85-L95

実行内容:

  • 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)

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/Makefile#L23-L49

設定される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の有効化

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/Makefile#L52-L62

有効化される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      # アプリケーション手動デプロイ

dev環境自動デプロイ (deploy-dev.yml)

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/.github/workflows/deploy-dev.yml#L1-L6

トリガー: mainブランチへのpush
実行内容:

  1. インフラデプロイ: CDKTFでインフラリソースをデプロイ
  2. アプリケーションデプロイ: Cloud BuildでNext.jsアプリをデプロイ

stg環境自動デプロイ (deploy-stg.yml)

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/.github/workflows/deploy-stg.yml#L1-L6

トリガー: GitHub Release(prerelease)
実行内容: dev環境と同様のデプロイ処理

prod環境自動デプロイ (deploy-prod.yml)

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/.github/workflows/deploy-prod.yml#L1-L6

トリガー: GitHub Release(release)
実行内容: dev環境と同様のデプロイ処理

インフラ手動デプロイ (infra-deploy.yml)

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/.github/workflows/infra-deploy.yml#L1-L10

トリガー: 手動実行
実行内容: 選択した環境のインフラのみをデプロイ

アプリケーション手動デプロイ (app-deploy.yml)

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/.github/workflows/app-deploy.yml#L1-L10

トリガー: 手動実行
実行内容: 選択した環境のアプリケーションのみをデプロイ

インフラプラン実行 (infra-plan.yml)

https://github.com/yoppyDev/cdktf-nextjs-gcp-template/blob/ba6ea2fd1b08bf80b03aa035b20b9f3d18f54c5b/.github/workflows/infra-plan.yml#L1-L15

トリガー:

  • 手動実行
  • 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:非同期ジョブを扱えるようにしたい
  • 請求アラートの設定:無料枠を超える前に通知が欲しい

…などなど、引き続きアップデートしていく予定です!

Terass Tech Blog

Discussion