Ansible dans l'ecosysteme DevOps 28 min de lecture

Terraform et Ansible : infrastructure et configuration

Terraform + Ansible : roles complementaires

Terraform gere l'infrastructure (provisionning) tandis qu'Ansible gere la configuration des machines provisionnees.

  • Terraform : creer des VM, reseaux, load balancers, DNS
  • Ansible : configurer les OS, installer les applications, deployer le code

Generer un inventaire dynamique depuis Terraform

# Terraform output pour Ansible
# main.tf
output "web_servers" {
  value = {
    for instance in aws_instance.web :
    instance.tags.Name => instance.public_ip
  }
}

output "db_servers" {
  value = {
    for instance in aws_instance.db :
    instance.tags.Name => instance.private_ip
  }
}

Script d'inventaire dynamique

#!/usr/bin/env python3
# inventory/terraform_inventory.py
import json
import subprocess

def get_terraform_output():
    result = subprocess.run(
        ['terraform', 'output', '-json'],
        capture_output=True, text=True,
        cwd='/opt/terraform/infra'
    )
    return json.loads(result.stdout)

def main():
    tf_output = get_terraform_output()
    inventory = {
        'web_servers': {
            'hosts': list(tf_output['web_servers']['value'].values()),
        },
        'db_servers': {
            'hosts': list(tf_output['db_servers']['value'].values()),
        },
        '_meta': {'hostvars': {}},
    }

    for name, ip in tf_output['web_servers']['value'].items():
        inventory['_meta']['hostvars'][ip] = {
            'ansible_host': ip,
            'server_name': name,
        }

    print(json.dumps(inventory, indent=2))

if __name__ == '__main__':
    main()

Provisioner Terraform pour Ansible

# main.tf - executer Ansible apres la creation
resource "aws_instance" "web" {
  count         = 3
  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t3.medium"
  key_name      = "deployer"

  tags = {
    Name = "web-${count.index}"
    Role = "webserver"
  }

  provisioner "local-exec" {
    command = <<-EOT
      sleep 30
      ANSIBLE_HOST_KEY_CHECKING=False \
      ansible-playbook -i '${self.public_ip},' \
        --private-key=~/.ssh/deployer.pem \
        -u ubuntu \
        playbooks/configure-web.yml
    EOT
  }
}

Workflow complet Terraform + Ansible

# Makefile
.PHONY: deploy destroy

deploy:
	cd terraform && terraform apply -auto-approve
	cd terraform && terraform output -json > ../ansible/tf_output.json
	cd ansible && ansible-playbook -i inventory/terraform_inventory.py site.yml

destroy:
	cd ansible && ansible-playbook -i inventory/terraform_inventory.py cleanup.yml
	cd terraform && terraform destroy -auto-approve
Principe : Terraform pour le "quoi" (quelle infrastructure), Ansible pour le "comment" (quelle configuration).