# Create environmentsterraform workspace new development
terraform workspace new staging
terraform workspace new production
# Deploy to stagingterraform workspace select staging
terraform apply -var="environment=staging"
#!/bin/bash
# promote.sh - Promote build from one env to anotherFROM_ENV=$1TO_ENV=$2if[[ -z "$FROM_ENV"|| -z "$TO_ENV"]];thenecho"Usage: ./promote.sh staging production"exit1fi# Get current version in source envVERSION=$(aws ssm get-parameter \
--name "/${FROM_ENV}/app/version"\
--query 'Parameter.Value'\
--output text)echo"Promoting version $VERSION from $FROM_ENV to $TO_ENV"# Tag image for new environmentdocker pull myapp:${FROM_ENV}-${VERSION}docker tag myapp:${FROM_ENV}-${VERSION} myapp:${TO_ENV}-${VERSION}docker push myapp:${TO_ENV}-${VERSION}# Update version in target envaws ssm put-parameter \
--name "/${TO_ENV}/app/version"\
--value "$VERSION"\
--overwrite
# Trigger deploymentaws ecs update-service \
--cluster ${TO_ENV}-cluster \
--service app \
--force-new-deployment
# migrations/env.py (Alembic)fromalembicimportcontextimportosdefrun_migrations():env=os.environ.get("ENV","development")ifenv=="production":# Extra safety for prodprint("Running production migration - are you sure? (yes/no)")confirm=input()ifconfirm!="yes":print("Aborted")return# Run migrationscontext.run_migrations()
Migration workflow:
1
2
3
4
5
6
7
8
9
10
11
# 1. Create migrationalembic revision --autogenerate -m "add users table"# 2. Test in devENV=development alembic upgrade head
# 3. Test in stagingENV=staging alembic upgrade head
# 4. Run in production (during maintenance window)ENV=production alembic upgrade head
fromconfigimportsettingsFEATURE_FLAGS={"new_checkout":{"development":True,"staging":True,"production":False,# Enable after testing},"dark_mode":{"development":True,"staging":True,"production":True,}}defis_enabled(feature:str)->bool:env=settings.environmentreturnFEATURE_FLAGS.get(feature,{}).get(env,False)# Usageifis_enabled("new_checkout"):returnnew_checkout_flow()else:returnlegacy_checkout()