Infrastructure as Code: Fundamentals
Table of Contents
- What is Infrastructure as Code
- Why IaC Matters
- Core IaC Concepts
- IaC Approaches
- Security Considerations for IaC
- Getting Started
What is Infrastructure as Code
Infrastructure as Code (IaC) is the practice of managing and provisioning infrastructure through machine-readable definition files rather than manual processes or interactive configuration tools.
Core Definition
IaC treats infrastructure configuration as software code that can be:
- Version controlled
- Reviewed and tested
- Automatically deployed
- Repeatedly applied with consistent results
- Shared and reused across teams
What IaC Manages
Compute Resources:
- Virtual machines
- Containers
- Serverless functions
- Auto-scaling groups
Networking:
- Virtual networks and subnets
- Load balancers
- DNS records
- Firewalls and security groups
- VPNs and network gateways
Storage:
- Block storage volumes
- Object storage buckets
- File systems
- Databases
Identity and Access:
- IAM roles and policies
- Service accounts
- API keys
- Security credentials
Application Services:
- Message queues
- Caching layers
- CDN configurations
- Monitoring and logging
Traditional vs. IaC Approach
| Aspect | Traditional (Manual) | Infrastructure as Code |
|---|---|---|
| Provisioning | Point-and-click in console | Code execution |
| Documentation | Separate documents (often outdated) | Code is documentation |
| Consistency | Manual steps = human error | Automated = consistent |
| Speed | Hours to days | Minutes |
| Scalability | Manual replication | Automated replication |
| Version Control | Limited or none | Full git history |
| Disaster Recovery | Manual rebuild from docs | Automated rebuild from code |
| Testing | Manual verification | Automated testing |
Why IaC Matters
Speed and Efficiency
Faster Provisioning:
- Deploy complete environments in minutes, not hours
- Automate repetitive infrastructure tasks
- Reduce time from request to deployment
Parallel Execution:
- Provision multiple resources simultaneously
- Scale infrastructure quickly
- Handle traffic spikes automatically
Consistency and Reliability
Eliminate Configuration Drift:
- Infrastructure matches code definition
- Detect and correct drift automatically
- Prevent “snowflake” servers with unique configurations
Repeatable Deployments:
- Same code produces identical infrastructure
- Reduce environment-specific bugs
- Predictable outcomes
Risk Reduction
Testing Before Production:
- Test infrastructure changes in staging
- Validate configurations before applying
- Preview changes before execution
Quick Recovery:
- Rebuild infrastructure from code
- Disaster recovery becomes deployment
- Reduce MTTR (Mean Time To Recovery)
Rollback Capability:
- Version control enables rollback
- Revert to known-good configurations
- Minimize downtime from bad changes
Cost Optimization
Resource Lifecycle Management:
- Automatically tear down unused environments
- Schedule resources (dev environments off at night)
- Right-size infrastructure based on metrics
Visibility:
- Track infrastructure costs in code
- Review infrastructure changes like code reviews
- Identify cost optimization opportunities
Collaboration and Knowledge Sharing
Code Review Process:
- Infrastructure changes reviewed like code
- Knowledge sharing through pull requests
- Documented decisions in commit history
Standardization:
- Reusable modules and templates
- Organization-wide best practices
- Reduced learning curve
Transparency:
- Clear visibility into infrastructure
- Self-service for developers
- Reduced dependency on ops team
Core IaC Concepts
Declarative vs. Imperative
Declarative (What): Describe the desired end state; the tool figures out how to achieve it.
# Terraform example - Declarative
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
count = 3
}
Characteristics:
- Define desired state
- Tool determines steps to reach that state
- Idempotent by nature
- Easier to reason about
Tools: Terraform, CloudFormation, Pulumi (declarative mode)
Imperative (How): Specify the exact steps to execute to achieve the desired state.
# Imperative approach
for i in range(3):
create_ec2_instance(
ami="ami-0c55b159cbfafe1f0",
instance_type="t2.micro"
)
Characteristics:
- Define specific actions
- Explicit control over execution
- Must handle state checking manually
- More flexible but more complex
Tools: Ansible (can be declarative), scripts, SDKs
Idempotency
Definition: Running the same IaC code multiple times produces the same result without unintended side effects.
Why it matters:
- Safe to re-run deployments
- Automatic drift correction
- Simplified automation
- Predictable outcomes
Example:
# First run: Creates 3 instances
# Second run: No changes (3 instances already exist)
# Third run: Still no changes
resource "aws_instance" "web" {
count = 3
# ...
}
Achieving idempotency:
- Check current state before acting
- Use unique identifiers
- Avoid hardcoded values that change
- Design for re-execution
Immutability
Immutable Infrastructure: Rather than updating existing resources, replace them with new versions.
Benefits:
- Prevents configuration drift
- Easier rollback (keep old version)
- Simplified testing (test exact deployment artifact)
- Reduced debugging complexity
Mutable vs. Immutable:
| Approach | Update Process | Pros | Cons |
|---|---|---|---|
| Mutable | Modify existing resources | Faster updates | Configuration drift, harder to reproduce |
| Immutable | Replace with new resources | Consistent, reproducible | Longer deployment, more complex |
Implementation:
- Blue-green deployments
- Canary deployments
- Container-based deployments
- AMI/image-based deployments
IaC Approaches
Declarative Approach
Philosophy: Describe what you want, not how to get there.
How it works:
- Define desired state in configuration files
- Tool compares desired state to current state
- Tool calculates and executes necessary changes
Advantages:
- Simpler to understand (what, not how)
- Automatically idempotent
- Easier to maintain
- Tool handles complexity
Disadvantages:
- Less control over execution order (sometimes)
- Abstraction can hide underlying operations
- Learning curve for tool-specific syntax
Best for:
- Cloud infrastructure provisioning
- Consistent, repeatable deployments
- Teams preferring simplicity
- Complex state management
Imperative Approach
Philosophy: Define exact steps to execute.
How it works:
- Write scripts/code with specific actions
- Execute actions in defined order
- Handle state checking and updates manually
Advantages:
- Full control over execution
- Use familiar programming languages
- Fine-grained error handling
- Flexibility for complex scenarios
Disadvantages:
- Must implement idempotency manually
- More code to write and maintain
- Higher risk of errors
- State management complexity
Best for:
- Complex orchestration workflows
- Migration tasks
- Custom automation
- When declarative tools don’t fit
Hybrid Approach
Philosophy: Combine declarative and imperative as needed.
How it works:
- Use declarative tools for infrastructure provisioning
- Use imperative scripts for configuration management
- Orchestrate with higher-level tools
Example:
# Terraform for infrastructure (declarative)
# Ansible for configuration (imperative playbooks)
# CI/CD pipeline orchestrates both
Advantages:
- Best of both worlds
- Right tool for each job
- Flexibility where needed
Disadvantages:
- Multiple tools to learn
- Integration complexity
- Potential consistency issues
Security Considerations for IaC
Never Commit Secrets to Code
The problem: IaC templates often need credentials, API keys, and passwords. Hardcoding these in files that go into version control is a critical security risk.
Terraform example:
# ❌ NEVER do this
resource "aws_db_instance" "db" {
password = "MyPassword123!" # Committed to git = exposed
}
# ✅ Use variables marked as sensitive
variable "db_password" {
type = string
sensitive = true
}
resource "aws_db_instance" "db" {
password = var.db_password
}
CloudFormation example:
# ✅ Reference secrets from AWS Secrets Manager
Resources:
Database:
Type: AWS::RDS::DBInstance
Properties:
MasterUserPassword: !Sub '{{resolve:secretsmanager:${DBSecret}:SecretString:password}}'
Use Secret Management Services
Don’t pass secrets as plain text - retrieve them from secure stores:
- AWS Secrets Manager / Parameter Store: Native AWS secret storage
- HashiCorp Vault: Multi-cloud secret management
- Azure Key Vault: Native Azure secret storage
- GCP Secret Manager: Native GCP secret storage
State Files Contain Secrets
Critical: IaC state files (like Terraform’s terraform.tfstate) contain the actual values of all resources, including secrets.
Protect state files:
- Always use remote state with encryption (covered in IaC State Management)
- Restrict access to state storage (S3 bucket policies, IAM roles)
- Never commit state files to version control
Scan IaC Before Applying
Static analysis tools catch security issues before deployment:
- Checkov: Multi-framework scanner (Terraform, CloudFormation, Kubernetes)
- tfsec: Terraform-focused security scanner
- cfn-lint: CloudFormation linter with security checks
- Terrascan: Policy-as-code scanner
Run security scans before deployment and integrate them into your CI/CD pipeline to automatically fail builds with security issues.
Getting Started
Choosing Your First IaC Tool
For AWS-only projects:
- Start with AWS CloudFormation (native, free, deep integration)
For multi-cloud or flexibility:
- Start with Terraform (most popular, broad ecosystem, declarative)
For developers who prefer code:
- AWS CDK (AWS-focused, TypeScript/Python/Java/C#/.NET, generates CloudFormation)
- Pulumi (multi-cloud, TypeScript/Python/Go/C#/Java, own state management)
For configuration management:
- Start with Ansible (agentless, easy to learn, YAML-based)
Learning Path
1. Start Small
- Deploy a single resource (S3 bucket, EC2 instance)
- Understand the workflow: write configuration, preview changes, apply
- Practice with non-production resources
2. Add Complexity Gradually
- Multiple resources with dependencies
- Variables and outputs
- Modules and reusable components
3. Implement Best Practices
- Remote state management (covered in IaC State Management)
- Version control and code review process
- Automated testing (covered in IaC Testing)
4. Production Readiness
- Security scanning integration
- Multi-environment management
- CI/CD pipeline integration
- Disaster recovery procedures
Found this guide helpful? Share it with your team:
Share on LinkedIn