Skip to main content
Back to Blog

Automating Infrastructure with Terraform and Ansible

terraformansibleautomationiac

Automating Infrastructure with Terraform and Ansible

Infrastructure as Code (IaC) has become essential in modern DevOps practices. In this post, I'll share my approach to combining Terraform and Ansible for end-to-end infrastructure automation.

The Two-Phase Approach

I use a two-phase approach for infrastructure automation:

  1. Terraform: Provision infrastructure (servers, networks, storage)
  2. Ansible: Configure and manage the provisioned resources

This separation of concerns makes the code more maintainable and follows the principle of using the right tool for the job.

Why This Combination?

Terraform Strengths

  • Declarative syntax for infrastructure
  • Excellent state management
  • Multi-cloud support
  • Large provider ecosystem

Ansible Strengths

  • Agentless architecture
  • Great for configuration management
  • Powerful templating with Jinja2
  • Extensive module library

Example Workflow

Here's a typical workflow I use:

1. Terraform Provisions Infrastructure

resource "aws_instance" "web_servers" {
  count         = 3
  ami           = var.ami_id
  instance_type = "t3.medium"
  
  tags = {
    Name = "web-server-${count.index + 1}"
    Role = "web"
  }
}

# Generate Ansible inventory
resource "local_file" "ansible_inventory" {
  content = templatefile("${path.module}/inventory.tpl", {
    web_servers = aws_instance.web_servers[*].public_ip
  })
  filename = "../ansible/inventory/hosts"
}

2. Ansible Configures the Servers

---
- name: Configure web servers
  hosts: web
  become: yes
  
  tasks:
    - name: Install Nginx
      apt:
        name: nginx
        state: present
        update_cache: yes
    
    - name: Copy configuration
      template:
        src: nginx.conf.j2
        dest: /etc/nginx/nginx.conf
      notify: restart nginx
  
  handlers:
    - name: restart nginx
      service:
        name: nginx
        state: restarted

Best Practices

  1. Use Terraform workspaces for different environments
  2. Store Terraform state remotely (S3, Azure Blob, etc.)
  3. Encrypt sensitive data in Ansible with Vault
  4. Use dynamic inventories generated by Terraform
  5. Keep modules/roles reusable and well-documented

Integration Tips

Automatic Inventory Generation

Use Terraform's local_file resource to automatically generate Ansible inventories:

locals {
  ansible_groups = {
    web = aws_instance.web_servers[*].public_ip
    db  = aws_instance.db_servers[*].private_ip
  }
}

Passing Variables

Use Terraform outputs to create Ansible variable files:

output "database_endpoint" {
  value = aws_db_instance.main.endpoint
}

Conclusion

Combining Terraform and Ansible provides a powerful, flexible approach to infrastructure automation. Terraform handles the "what" (infrastructure resources), while Ansible manages the "how" (configuration and state).

This separation makes your automation more maintainable and allows each tool to focus on what it does best.