Infrastructure as Code (IaC) is the practice of managing and provisioning computing infrastructure through configuration files instead of manual processes.

What is IaC?

IaC is the process of managing and provisioning computing infrastructure through configuration files that can be versioned, reused, and shared.

IaC Benefits

Automation

  • **Automated deployment": Infrastructure deployed automatically
  • **Consistency": Consistent configuration across environments
  • **Reproducibility": Same infrastructure in different environments
  • **Efficiency": Reduced deployment time

Version Control

  • **Versioning": Infrastructure version control
  • **Rollback": Ability to revert changes
  • **History": Change traceability
  • **Collaboration": Multiple developers working together

Security

  • **Secure configuration": Secure configuration by default
  • **Audit": Change traceability
  • **Compliance": Regulatory compliance
  • **Validation": Configuration validation

IaC Tools

Terraform

  • **Multi-cloud": Support for multiple providers
  • **State": Infrastructure state management
  • **Plan": Change planning
  • **Apply": Change application

Ansible

  • **Agentless": No agents required
  • **YAML": YAML configuration
  • **Idempotency": Idempotent execution
  • **Orchestration": Task orchestration

CloudFormation

  • **AWS native": Native AWS service
  • **JSON/YAML": JSON or YAML configuration
  • **Stacks": Stack management
  • **Drift detection": Drift detection

Pulumi

  • **Multi-language": Multiple programming languages
  • **Real-time": Real-time updates
  • **Testing": Testing capabilities
  • **CI/CD": CI/CD integration

Example with Terraform

Basic Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# main.tf
provider "aws" {
  region = "us-west-2"
}

resource "aws_instance" "web_server" {
  ami           = "ami-0c55b159cbfafe1d0"
  instance_type = "t3.micro"
  
  tags = {
    Name = "Web Server"
    Environment = "production"
  }
}

resource "aws_security_group" "web_sg" {
  name_prefix = "web-"
  
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }
  
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }
}

Modules

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# modules/web-server/main.tf
variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t3.micro"
}

variable "environment" {
  description = "Environment name"
  type        = string
}

resource "aws_instance" "web" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = var.instance_type
  
  tags = {
    Name        = "Web Server"
    Environment = var.environment
  }
}

# modules/web-server/outputs.tf
output "instance_id" {
  description = "ID of the EC2 instance"
  value       = aws_instance.web.id
}

Using Modules

1
2
3
4
5
6
7
# main.tf
module "web_server" {
  source = "./modules/web-server"
  
  instance_type = "t3.small"
  environment   = "production"
}

Example with Ansible

Basic Playbook

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# playbook.yml
---
- name: Configure web server
  hosts: web_servers
  become: yes
  vars:
    nginx_port: 80
    
  tasks:
    - name: Install nginx
      package:
        name: nginx
        state: present
        
    - name: Start nginx
      service:
        name: nginx
        state: started
        enabled: yes
        
    - name: Configure nginx
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: restart nginx
      
  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted

Inventory

1
2
3
4
5
6
7
# inventory.ini
[web_servers]
web1 ansible_host=10.0.1.10
web2 ansible_host=10.0.1.11

[db_servers]
db1 ansible_host=10.0.2.10

Security in IaC

Secure Configuration

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Secure S3 configuration
resource "aws_s3_bucket" "secure_bucket" {
  bucket = "my-secure-bucket"
  
  versioning {
    enabled = true
  }
  
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
  
  public_access_block {
    block_public_acls       = true
    block_public_policy     = true
    ignore_public_acls      = true
    restrict_public_buckets = true
  }
}

Secret Management

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Using secrets
resource "aws_db_instance" "database" {
  identifier = "my-database"
  engine     = "mysql"
  
  username = var.db_username
  password = var.db_password
  
  vpc_security_group_ids = [aws_security_group.db.id]
}

Validation

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Input validation
variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  
  validation {
    condition     = contains(["t3.micro", "t3.small", "t3.medium"], var.instance_type)
    error_message = "Instance type must be t3.micro, t3.small, or t3.medium."
  }
}

Best Practices

Project Structure

project/
├── main.tf
├── variables.tf
├── outputs.tf
├── terraform.tfvars
├── modules/
│   └── web-server/
│       ├── main.tf
│       ├── variables.tf
│       └── outputs.tf
└── environments/
    ├── dev/
    ├── staging/
    └── production/

Versioning

  • **Git": Use Git for version control
  • **Tags": Tag versions
  • **Branches": Use branches for different environments
  • **Commits": Descriptive commit messages

Testing

  • **Unit tests": Unit tests
  • **Integration tests": Integration tests
  • **Security tests": Security tests
  • **Compliance tests": Compliance tests

CI/CD

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# .github/workflows/terraform.yml
name: Terraform
on:
  push:
    branches: [main]
    
jobs:
  terraform:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v2
      
      - name: Setup Terraform
        uses: hashicorp/setup-terraform@v1
        
      - name: Terraform Init
        run: terraform init
        
      - name: Terraform Plan
        run: terraform plan
        
      - name: Terraform Apply
        run: terraform apply -auto-approve

Monitoring and Auditing

Logs

  • **Terraform logs": Execution logs
  • **Cloud logs": Cloud provider logs
  • **Application logs": Application logs
  • **Security logs": Security logs

Metrics

  • **Deployment time": Deployment time
  • **Success rate": Success rate
  • **Error rate": Error rate
  • **Resource usage": Resource usage

Alerts

  • **Deployment failures": Deployment failures
  • **Configuration drift": Configuration drift
  • **Security issues": Security issues
  • **Performance issues": Performance issues

References