Success: Significantly reduced deployment time and risk.
Evidence:
Recommendation: Use multi-stack for any microservices architecture.
Success: Type-safe dependencies between stacks.
Evidence:
Recommendation: Always use exports/imports over hardcoding.
Success: Simple but effective orchestration.
Evidence:
Recommendation: Start with bash, migrate to sophisticated tools only if needed.
Success: Reduced boilerplate significantly.
Evidence:
Recommendation: Use SAM for all serverless applications.
Success: Clean separation via parameters.
Evidence:
Recommendation: Always use parameters for environment-specific config.
Challenge: Initial learning curve for cross-stack references.
Impact: First deployment took 2 days to get right.
Solution:
Lesson: Invest time in documentation upfront.
Challenge: CloudFormation error messages can be cryptic.
Impact: Spent hours debugging “Resource failed to stabilize”.
Solution:
aws cloudformation describe-stack-eventsLesson: Always check CloudWatch Logs first.
Challenge: Cannot delete core stack while services are running.
Impact: Manual cleanup required in specific order.
Solution:
# Created cleanup script
./scripts/cleanup.sh staging
# Deletes in correct order:
# 1. Service stacks
# 2. Core stack
# 3. Deployment bucket
Lesson: Plan deletion strategy from the start.
Challenge: Changed export name, broke all importing stacks.
Impact: Had to update all service stacks simultaneously.
Solution:
Lesson: Plan export names carefully - they’re hard to change.
Challenge: Sequential deployment slow for many services.
Impact: Full deployment took 15+ minutes.
Solution:
Lesson: Parallelize independent operations.
# ✅ Good: Include stack name
Export:
Name: !Sub '${AWS::StackName}-ResourceName'
# ❌ Bad: Generic name
Export:
Name: ResourceName
✅ Core Stack:
- DynamoDB Tables
- S3 Buckets
- Cognito User Pools
- VPC/Networking
✅ Service Stacks:
- Lambda Functions
- API Gateway
- SQS Queues
- SNS Topics
# Always validate before deploy
aws cloudformation validate-template \
--template-body file://template.yaml
# Use linting tools
cfn-lint template.yaml
# Use set -e in all scripts
set -e
set -o pipefail
# Add cleanup trap
trap cleanup ERR EXIT
## Stack Exports
- `{StackName}-ArticlesTableName`: DynamoDB table name
- `{StackName}-ArticlesTableArn`: DynamoDB table ARN
## Deployment
```bash
./deploy.sh staging us-east-1
./rollback.sh staging
#### 6. Testing Strategy
```bash
# Test in staging first
./deploy.sh staging
# Verify functionality
./test.sh staging
# Deploy to production
./deploy.sh prod
# Always have rollback ready
git tag v1.2.3
git push --tags
# If issues:
git checkout v1.2.2
./deploy.sh prod
Current: Manual deployment via scripts.
Improvement: Automate with GitHub Actions/GitLab CI.
Example:
# .github/workflows/deploy.yml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Deploy to staging
run: ./deploy.sh staging
Benefit: Automatic deployment on merge.
Current: Sequential service deployment.
Improvement: Deploy services in parallel.
Example:
for service in "${SERVICES[@]}"; do
./deploy-service.sh $service $ENV &
done
wait
Benefit: 3x faster deployment.
Current: Secrets in parameter files (not committed).
Improvement: Use AWS Systems Manager Parameter Store.
Example:
Parameters:
DatabasePassword:
Type: AWS::SSM::Parameter::Value<String>
Default: /travelguide/staging/db-password
Benefit: Centralized secret management.
Current: Manual monitoring via console.
Improvement: Automated dashboards for stack health.
Example:
Dashboard:
Type: AWS::CloudWatch::Dashboard
Properties:
DashboardBody: !Sub |
{
"widgets": [
{
"type": "metric",
"properties": {
"metrics": [
["AWS/Lambda", "Errors", {"stat": "Sum"}]
]
}
}
]
}
Benefit: Proactive monitoring.
Current: Manual policy validation.
Improvement: Automated policy enforcement.
Example:
# rules/security.guard
AWS::S3::Bucket {
Properties.PublicAccessBlockConfiguration exists
Properties.BucketEncryption exists
}
Benefit: Prevent security misconfigurations.
Current: Manual documentation.
Improvement: Generate docs from templates.
Example:
# Use cfn-diagram
cfn-diagram template.yaml > architecture.png
Benefit: Always up-to-date documentation.
| Aspect | CloudFormation/SAM | Terraform | AWS CDK | Pulumi |
|---|---|---|---|---|
| Our Experience | ✅ Positive | N/A | N/A | N/A |
| Learning Curve | Medium | Medium | High | High |
| AWS Integration | Excellent | Good | Excellent | Good |
| State Management | Automatic | Manual | Automatic | Cloud |
| Multi-Cloud | No | Yes | No | Yes |
| Cost | Free | Free | Free | Free |
| Recommendation | ✅ For AWS-only | For multi-cloud | For complex logic | For full language power |
The multi-stack pattern with CloudFormation/SAM proved to be the right choice for our Travel Guide Application. While there were challenges, the benefits far outweighed the costs:
Wins:
Areas for Improvement:
Would we do it again? Absolutely yes! ✅