environment-deployment-strategy について
Environment Deployment Strategy は、開発チーム向けのデプロイ参考パターンで、ローカル、開発、本番を 3 層に分けます。本番デプロイを GitHub Actions に限定し、リソース分離とデプロイ手順の例を示します。
主な機能
- 01local、dev、prod 環境の分離
- 02本番デプロイ経路の制限
- 03ローカル開発で dev リソースを利用
- 04環境ごとのクラウドリソース分離
- 05GitHub Actions によるデプロイ例
- 06代替手段として AWS CodePipeline を提示
活用シーン
- 01開発者マシンからの本番誤デプロイ防止
- 02ローカルから dev バックエンドにつないで反復開発
- 03dev で検証してから本番へデプロイ
- 04環境ごとに別のクラウドリソースを設定
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ loxosceles-dev/ dev-skills --skill environment-deployment-strategyインストール後、Claude Code で/environment-deployment-strategyを入力して読み込まれたか確認します。
詳細
環境デプロイ戦略
これは参考パターンです。 アプローチを学び、状況に合わせて適用してください。そのままコピーしないでください。
問題:開発を迅速に反復できるようにしながら、本番環境への誤ったデプロイを防ぐ安全なデプロイ手法が必要です。
解決策:デプロイを制限する、3 層の環境戦略です。
パターン
3 つの環境:
-
ローカル(
local)- 開発者のマシン上で動作します
dev環境のクラウドリソースを使用します- デプロイできません(クラウドリソースがありません)
- デプロイの待ち時間がなく、迅速に反復できます
-
開発(
dev)- クラウドにデプロイします
- 本番環境のアーキテクチャを再現します
- 次の方法でデプロイできます:ローカルスクリプト、または GitHub Actions(
devブランチへのマージ時) - テストと検証に使用します
-
本番(
prod)- クラウドにデプロイします
- 顧客に公開される稼働環境です
- 次の方法でのみデプロイできます:GitHub Actions(
mainブランチへのマージ時) - ローカルマシンからデプロイすることはありません
このパターンを採用する理由
メリット:
- 安全性:本番環境をローカルからの誤ったデプロイから保護します
- 速度:ローカル開発ではクラウド上の開発リソースを使用し、ローカル環境を構築する必要がありません
- 一貫性:開発環境が本番環境を再現するため、本番環境に反映する前に問題を発見できます
- 監査証跡:本番環境へのデプロイはすべて、GitHub Actions のログに記録されます
- ロールバック:Git の履歴を使って簡単にロールバックできます
防止できること:
- 開発者のマシンから本番環境への誤ったデプロイ
- テストされていないコードの本番環境への反映
- 環境間の設定ドリフト
- 「自分のマシンでは動く」という問題
実装
環境設定:
# .env (local - not committed)
ENVIRONMENT=local
AWS_REGION=eu-central-1
# Uses dev resources
API_ENDPOINT=https://api-dev.example.com
# .env.dev (committed template)
ENVIRONMENT=dev
AWS_REGION=eu-central-1
API_ENDPOINT=https://api-dev.example.com
# .env.prod (committed template, secrets from SSM)
ENVIRONMENT=prod
AWS_REGION=eu-central-1
API_ENDPOINT=https://api.example.com
デプロイスクリプト:
// package.json
{
"scripts": {
"deploy:dev": "cdk deploy --all --context environment=dev",
"deploy:prod": "echo 'ERROR: Production can only be deployed via GitHub Actions' && exit 1"
}
}
GitHub Actions ワークフロー:
# .github/workflows/deploy.yml
name: Deploy
on:
pull_request:
types: [closed]
branches: [dev, main]
jobs:
deploy-dev:
if: github.base_ref == 'dev' && github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Dev
run: npm run deploy:dev
deploy-prod:
if: github.base_ref == 'main' && github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Production
run: cdk deploy --all --context environment=prod
デプロイの流れ
開発サイクル:
1. Developer works locally (uses dev resources)
2. Commits to feature branch
3. Opens PR to dev branch
4. PR merged → GitHub Actions deploys to dev
5. Test in dev environment
6. Open PR from dev to main
7. PR merged → GitHub Actions deploys to prod
ローカル開発:
# Developer runs frontend locally
npm run dev
# Frontend connects to dev API
# No infrastructure deployment needed
# Fast iteration
開発環境へのデプロイ(2 つの選択肢):
# Option 1: Local deployment (for quick testing)
npm run deploy:dev
# Option 2: GitHub Actions (on PR merge to dev)
# Automatic, tracked, consistent
本番環境へのデプロイ(選択肢は 1 つのみ):
# Only via GitHub Actions (on PR merge to main)
# Attempting local deployment fails with error message
CORS:ローカル環境から開発バックエンドを共有
ローカル開発ではデプロイ済みの開発 API にアクセスするため、開発環境では CORS で両方のオリジンを許可する必要があります。
# .env.dev (used by dev Lambda)
CORS_ALLOWED_ORIGINS=http://localhost:3010,https://dev.project.example.com
# .env.prod (only the production domain)
CORS_ALLOWED_ORIGINS=https://project.example.com
ルール:開発バックエンド(API Gateway、Lambda など)の CORS を設定する際は、デプロイ済みの開発フロントエンドのドメインとともに、必ず http://localhost:<port> を含めてください。これがないと、デプロイ済みの開発フロントエンドは正常に動作する一方で、ローカル開発は CORS によってブロックされます。
リソースの分離
環境ごとにリソースを分ける:
// All resources include environment identifier
const bucket = new s3.Bucket(this, 'Bucket', {
bucketName: `${PROJECT_ID}-data-${environment}` // dev or prod
});
const table = new dynamodb.Table(this, 'Table', {
tableName: `${PROJECT_ID}-users-${environment}` // dev or prod
});
理由:開発環境と本番環境でリソースを共有しないようにして、データの破損や競合を防ぎます。
AWS CodePipeline との連携
代替手段:GitHub Actions の代わりに AWS CodePipeline を使用します
// Separate pipelines per environment
const devPipeline = new codepipeline.Pipeline(this, 'DevPipeline', {
pipelineName: `${PROJECT_ID}-pipeline-dev`
});
const prodPipeline = new codepipeline.Pipeline(this, 'ProdPipeline', {
pipelineName: `${PROJECT_ID}-pipeline-prod`
});
GitHub Actions のトリガー:
- name: Trigger Dev Pipeline
run: aws codepipeline start-pipeline-execution --name ${PROJECT_ID}-pipeline-dev
- name: Trigger Prod Pipeline
run: aws codepipeline start-pipeline-execution --name ${PROJECT_ID}-pipeline-prod
メリット:
- AWS CloudWatch にビルドログが記録されます
- IAM ベースの権限を使用できます(GitHub シークレットは不要です)
- AWS サービスと連携できます
バリエーション
2 環境(シンプルなプロジェクト向け):
dev- 開発とテストprod- 本番環境のみ
4 環境(エンタープライズ向け):
local- 開発者のマシンdev- 開発staging- 本番前のテストprod- 本番環境
関連パターン
- リソースの命名 - 環境ごとのリソースの命名方法
- 環境の検証 - 環境設定を早い段階で検証する方法
- 静的フロントエンドのホスティング - デプロイパイプラインの例
段階的な改善
開発者が、このスキルによって防げるはずの動作を修正した場合は、今後同じ修正が必要にならないよう、このスキルに加える具体的な変更案を提案してください。