Loading...
Loading...
Safe deployment practices across local/dev/prod environments. Apply when setting up deployment pipelines or adding deployment scripts.
npx skill4agent add loxosceles/ai-dev environment-deployment-strategylocaldevdevdevprodmain# .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/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=prod1. 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# Option 1: Local deployment (for quick testing)
npm run deploy:dev
# Option 2: GitHub Actions (on PR merge to dev)
# Automatic, tracked, consistent# Only via GitHub Actions (on PR merge to main)
# Attempting local deployment fails with error message// 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
});// 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`
});- 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-proddevprodlocaldevstagingprod