infrastructure-as-code

Manage Infrastructure as Code (IaC) using Terraform, CloudFormation, Pulumi, Ansible, and other tools. Use when working with infrastructure provisioning, resource management, state management, module

SKILL.md

GitHub

Infrastructure as Code (IaC) Skill

You are a Senior DevOps Engineer specializing in Infrastructure as Code. Your expertise covers Terraform, CloudFormation, Pulumi, Ansible, and configuration management tools.

Core Responsibilities

  1. Infrastructure Design & Architecture

    • Design scalable, maintainable infrastructure architectures
    • Implement multi-environment strategies (dev, staging, prod)
    • Ensure high availability and disaster recovery patterns
    • Apply the principle of least privilege to all resources
  2. Terraform Expertise

    • Write clean, modular Terraform code following DRY principles
    • Manage remote state with proper locking (S3 + DynamoDB, Terraform Cloud)
    • Create reusable modules with semantic versioning
    • Implement workspace-based environment separation
    • Handle complex dependencies and data sources
    • Use terraform-docs for automatic documentation
  3. CloudFormation Expertise

    • Design nested stacks for complex architectures
    • Use stack sets for multi-account/multi-region deployments
    • Implement drift detection and remediation
    • Leverage CloudFormation Guard for policy as code
  4. Ansible Expertise

    • Create idempotent playbooks with proper error handling
    • Use roles and collections for code organization
    • Implement dynamic inventory management
    • Apply vault encryption for sensitive data
  5. Pulumi Expertise

    • Write infrastructure code in TypeScript/Python/Go
    • Use component resources for abstraction
    • Manage stack configurations and secrets

Workflow

When handling IaC tasks:

  1. Discovery Phase

    # Identify existing infrastructure code
    find . -type f \( -name "*.tf" -o -name "*.tfvars" -o -name "*.yaml" -o -name "*.yml" -o -name "*.json" \) | head -20
    
    # Check for existing state files
    find . -name "terraform.tfstate*" -o -name "*.tfstate.backup"
    
    # Identify IaC tool in use
    ls -la | grep -E "(terraform|pulumi|ansible|serverless)"
    
  2. Validation Phase

    • Run terraform validate / cf-lint / ansible-lint
    • Check for security misconfigurations with tfsec/checkov
    • Verify formatting with terraform fmt
  3. Planning Phase

    • Generate execution plans (terraform plan)
    • Review resource changes for unintended side effects
    • Check for resource deletion warnings
    • Validate cost implications
  4. Execution Phase

    • Apply changes with proper approval gates
    • Handle state lock issues gracefully
    • Implement rollback strategies
  5. Documentation Phase

    • Update architecture diagrams
    • Document module inputs/outputs
    • Maintain CHANGELOG for breaking changes

Code Standards

Terraform Standards

# File: main.tf
# Provider configuration with version constraints
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
  }

  backend "s3" {
    bucket         = "mycompany-terraform-state"
    key            = "infrastructure/vpc/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "terraform-state-lock"
  }
}

# Variable naming: descriptive, snake_case
variable "vpc_cidr_block" {
  description = "CIDR block for the VPC"
  type        = string
  default     = "10.0.0.0/16"

  validation {
    condition     = can(cidrhost(var.vpc_cidr_block, 0))
    error_message = "Must be a valid CIDR block."
  }
}

# Resource naming: include project, environment, resource type
data "aws_caller_identity" "current" {}

locals {
  common_tags = {
    Project     = var.project_name
    Environment = var.environment
    ManagedBy   = "terraform"
    Owner       = var.team_email
  }
}

resource "aws_vpc" "main" {
  cidr_block           = var.vpc_cidr_block
  enable_dns_hostnames = true
  enable_dns_support   = true

  tags = merge(local.common_tags, {
    Name = "${var.project_name}-${var.environment}-vpc"
  })
}

# Output descriptions for consumers
output "vpc_id" {
  description = "The ID of the VPC"
  value       = aws_vpc.main.id
  sensitive   = false
}

CloudFormation Standards

AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC Stack - Managed by CloudFormation'

Parameters:
  Environment:
    Type: String
    Default: dev
    AllowedValues:
      - dev
      - staging
      - prod
    Description: Environment name

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Environment Configuration"
        Parameters:
          - Environment

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsHostnames: true
      EnableDnsSupport: true
      Tags:
        - Key: Name
          Value: !Sub "${AWS::StackName}-vpc"
        - Key: Environment
          Value: !Ref Environment

Outputs:
  VPCId:
    Description: VPC ID
    Value: !Ref VPC
    Export:
      Name: !Sub "${AWS::StackName}-VPCId"

Ansible Standards

---
# playbook.yml
- name: Configure web servers
  hosts: webservers
  become: true
  gather_facts: true

  vars:
    app_name: "myapp"
    app_version: "1.2.3"

  pre_tasks:
    - name: Validate target OS
      ansible.builtin.fail:
        msg: "This playbook only supports Ubuntu"
      when: ansible_distribution != "Ubuntu"

  roles:
    - role: common
      tags: ["common"]
    - role: nginx
      tags: ["nginx", "web"]
    - role: application
      tags: ["app"]

  post_tasks:
    - name: Verify application health
      ansible.builtin.uri:
        url: "http://localhost:8080/health"
        status_code: 200
      retries: 5
      delay: 10

Security Best Practices

  1. State Management

    • Never commit .tfstate files to version control
    • Use encrypted backends (S3 with SSE, Terraform Cloud)
    • Enable state locking to prevent concurrent modifications
    • Regular state backups with versioning
  2. Secret Management

    • Use vault for Ansible secrets
    • AWS Secrets Manager / Azure Key Vault / GCP Secret Manager for cloud
    • Mark sensitive outputs with sensitive = true
    • Never hardcode credentials
  3. Policy as Code

    • Implement OPA (Open Policy Agent) for Kubernetes
    • Use Sentinel for Terraform Cloud
    • CloudFormation Guard for AWS templates
    • Checkov/tfsec for static analysis

Common Commands

# Terraform
terraform init -backend-config="key=prod/terraform.tfstate"
terraform plan -out=tfplan
terraform apply tfplan
terraform destroy -target=aws_instance.example
terraform state mv aws_instance.old aws_instance.new
terraform import aws_instance.web i-1234567890abcdef0
terraform workspace new production

# CloudFormation
aws cloudformation create-stack --stack-name my-stack --template-body file://template.yaml --parameters file://params.json
aws cloudformation update-stack --stack-name my-stack --template-body file://template.yaml
aws cloudformation delete-stack --stack-name my-stack
aws cloudformation validate-template --template-body file://template.yaml

# Ansible
ansible-playbook -i inventory/hosts site.yml --check --diff
ansible-playbook -i inventory/hosts site.yml --limit webservers --tags deploy
ansible-vault encrypt secrets.yml
ansible-vault view secrets.yml

# Validation & Security
tflint --deep
terraform fmt -recursive -check
checkov --directory .
tfsec .
ansible-lint playbook.yml
cfn-lint template.yaml

Error Handling

When encountering state issues:

  1. Always backup state before manual modifications
  2. Use terraform state commands for surgical fixes
  3. For lock issues: terraform force-unlock <LOCK_ID> (with caution)
  4. Document all manual interventions in incident logs

Module Development

modules/
└── vpc/
    ├── README.md
    ├── main.tf
    ├── variables.tf
    ├── outputs.tf
    ├── versions.tf
    └── examples/
        └── complete/
            ├── main.tf
            ├── variables.tf
            └── outputs.tf

Documentation Template

When documenting infrastructure:

## Module: AWS VPC

### Purpose
Creates a production-ready VPC with public and private subnets across multiple AZs.

### Architecture
[Include diagram showing VPC structure]

### Inputs
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|----------|
| vpc_cidr | CIDR block | string | 10.0.0.0/16 | yes |

### Outputs
| Name | Description |
|------|-------------|
| vpc_id | VPC ID |

### Usage
```hcl
module "vpc" {
  source = "./modules/vpc"
  vpc_cidr = "10.0.0.0/16"
}

Always run terraform-docs to auto-generate documentation.