Infrastructure as Code Discipline
Define infrastructure in version-controlled templates, never click-fix production by hand, and let code review and change sets catch mistakes before they ship.
Clicking around the Console is a wonderful way to learn and a terrible way to run production. The moment two people manage the same account by hand, drift and mystery follow. Infrastructure as Code (IaC) makes your environment reproducible, reviewable and reversible.
Why it is worth the discipline
- Reproducible — stand up an identical staging environment from the same template.
- Reviewable — infra changes go through a pull request like any other code.
- Auditable — Git history tells you who changed the security group and when.
- Reversible — roll back to a known-good version.
Pick a tool and commit
CloudFormation is the native, no-extra-cost option; the AWS CDK lets you write it in real languages; Terraform is the multi-cloud favourite. Any of them beats hand-crafting.
The two rules that matter most
- No manual changes to managed resources. The instant someone hot-fixes a stack in the Console, the template lies. Use drift detection to catch it, and treat drift as a bug.
- Preview before you apply. CloudFormation change sets (or
terraform plan) show exactly what will be created, changed or — crucially — replaced. That "replacement" flag on a database is how you avoid deleting production.
Example
AWSTemplateFormatVersion: '2010-09-09'
Description: Minimal, reviewable S3 bucket with sane defaults
Parameters:
BucketName:
Type: String
Description: Globally unique bucket name
Resources:
AssetsBucket:
Type: AWS::S3::Bucket
DeletionPolicy: Retain # never let an update delete our data
UpdateReplacePolicy: Retain
Properties:
BucketName: !Ref BucketName
VersioningConfiguration:
Status: Enabled
PublicAccessBlockConfiguration:
BlockPublicAcls: true
BlockPublicPolicy: true
IgnorePublicAcls: true
RestrictPublicBuckets: true
BucketEncryption:
ServerSideEncryptionConfiguration:
- ServerSideEncryptionByDefault:
SSEAlgorithm: aws:kms
Outputs:
BucketArn:
Value: !GetAtt AssetsBucket.ArnWhen to use it
- A team stores all CloudFormation templates in a Git repository so every infrastructure change has a pull request, code review, and audit trail.
- After a developer manually tweaks a security group in the Console, a CI/CD pipeline detects drift via 'aws cloudformation detect-stack-drift' and fails the pipeline.
- A platform team uses CDK to define reusable L3 constructs so all new services get VPCs, logging, and tagging by default without repeating code.
More examples
Deploy CloudFormation via CI/CD
Deploys a CloudFormation stack from a CI/CD pipeline, skipping gracefully if there are no changes, never requiring console access.
# In a CI pipeline (e.g., GitHub Actions)
aws cloudformation deploy \
--template-file infra/template.yaml \
--stack-name prod-stack \
--parameter-overrides Env=prod \
--capabilities CAPABILITY_NAMED_IAM \
--no-fail-on-empty-changesetDetect Stack Configuration Drift
Detects when someone has manually changed a resource that CloudFormation manages, exposing unauthorized out-of-band changes.
# Initiate drift detection
DETECTION_ID=$(aws cloudformation detect-stack-drift \
--stack-name prod-stack \
--query StackDriftDetectionId --output text)
# Wait and check results
aws cloudformation describe-stack-drift-detection-status \
--stack-drift-detection-id $DETECTION_ID \
--query '{Status:DetectionStatus,Drifted:StackDriftStatus}'Validate Template Before Deploying
Validates a CloudFormation template for syntax errors and runs cfn-lint for best-practice checks before any deployment.
aws cloudformation validate-template \
--template-body file://infra/template.yaml
# Also run cfn-lint for deeper checks
pip install cfn-lint -q
cfn-lint infra/template.yaml
Discussion