Infrastructure as Code (IaC) allows us to:
For the Travel Guide Application, we chose AWS CloudFormation with SAM (Serverless Application Model) for the following reasons:
1. Native AWS Integration
2. SAM Simplification
sam local)3. No Additional Cost
4. AWS Ecosystem
| Feature | CloudFormation/SAM | Terraform | AWS CDK | Pulumi |
|---|---|---|---|---|
| Learning Curve | Medium | Medium | High | High |
| Syntax | YAML/JSON | HCL | TypeScript/Python | TypeScript/Python/Go |
| State Management | AWS-managed | Manual/Cloud | AWS-managed | Cloud |
| Multi-Cloud | ❌ No | ✅ Yes | ❌ No | ✅ Yes |
| Cost | Free | Free (Cloud paid) | Free | Free (Cloud paid) |
| AWS Integration | Native | Good | Native | Good |
| Serverless Support | Excellent (SAM) | Good | Excellent | Good |
Our templates are organized as follows:
infrastructure/
├── core/
│ └── template.yaml # Core stack (DynamoDB, S3, Cognito)
├── services/
│ ├── auth/
│ │ └── template.yaml # Auth service Lambda functions
│ ├── articles/
│ │ └── template.yaml # Article service Lambda functions
│ ├── media/
│ │ └── template.yaml # Media processing Lambda functions
│ └── ...
├── parameters/
│ ├── staging.json # Staging environment parameters
│ └── prod.json # Production environment parameters
└── scripts/
├── deploy.sh # Main deployment orchestration
├── deploy-core.sh # Core stack deployment
└── deploy-service.sh # Service stack deployment
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: Travel Guide - Core Infrastructure
Parameters:
Environment:
Type: String
Default: staging
AllowedValues: [staging, prod]
Resources:
# DynamoDB Tables
ArticlesTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: !Sub '${AWS::StackName}-articles'
BillingMode: PAY_PER_REQUEST
AttributeDefinitions:
- AttributeName: articleId
AttributeType: S
KeySchema:
- AttributeName: articleId
KeyType: HASH
Outputs:
ArticlesTableName:
Description: Articles DynamoDB Table Name
Value: !Ref ArticlesTable
Export:
Name: !Sub '${AWS::StackName}-ArticlesTableName'
SAM simplifies Lambda and API Gateway definitions:
# Without SAM (CloudFormation only)
CreateArticleFunction:
Type: AWS::Lambda::Function
Properties:
FunctionName: create-article
Runtime: python3.11
Handler: index.handler
Code:
S3Bucket: my-bucket
S3Key: function.zip
Role: !GetAtt LambdaRole.Arn
# With SAM
CreateArticleFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: ./src
Handler: create_article.handler
Runtime: python3.11
Events:
CreateArticle:
Type: Api
Properties:
Path: /articles
Method: post