By Fatskills Exam Guides Team — the exam nerds behind 28,500+ quizzes and 2.1M practice questions across 500+ global exams.
Deploy infrastructure with Terraform, then configure it with Ansible or Chef—without breaking production.
You’re a cloud engineer at a fintech startup. Your team uses Terraform to spin up AWS EC2 instances, RDS databases, and VPCs. But Terraform only gets you halfway—it provisions the infrastructure, but doesn’t install software, apply security patches, or configure services (e.g., Nginx, PostgreSQL, Docker).
That’s where configuration management (CM) tools like Ansible or Chef come in. They take over after Terraform deploys the infrastructure and handle: - Software installation (e.g., apt install nginx) - Configuration files (e.g., /etc/nginx/nginx.conf) - Security hardening (e.g., disabling root SSH, setting firewall rules) - Service management (e.g., systemctl enable postgresql)
apt install nginx
/etc/nginx/nginx.conf
systemctl enable postgresql
remote-exec
You inherit a legacy Terraform codebase that uses null_resource + remote-exec to install software on EC2 instances. Every deploy takes 20+ minutes, fails randomly, and is impossible to debug. Your mission:1. Replace remote-exec with Ansible (or Chef) for configuration management.2. Make deployments faster, more reliable, and auditable.3. Ensure rollbacks work cleanly.
null_resource
terraform apply
-target
output "instance_ips" { value = aws_instance.web.*.public_ip }
aws_ec2
knife ec2
aws_instance
azurerm_linux_virtual_machine
Name
Environment
Role
local_file
templatefile()
local-exec
terraform_data
Goal: Deploy an AWS EC2 instance with Terraform, then configure Nginx using Ansible.
✅ AWS account with IAM permissions for EC2 ✅ Terraform installed (terraform --version) ✅ Ansible installed (ansible --version) ✅ SSH key pair (~/.ssh/id_rsa.pub)
terraform --version
ansible --version
~/.ssh/id_rsa.pub
Create main.tf:
main.tf
terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } } } provider "aws" { region = "us-east-1" } resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" # Ubuntu 22.04 LTS instance_type = "t3.micro" key_name = "your-key-pair" # Replace with your SSH key name tags = { Name = "web-server" Role = "nginx" } } # Output the public IP for Ansible output "instance_ip" { value = aws_instance.web.public_ip }
Apply Terraform:
terraform init terraform apply -auto-approve
Add this to main.tf:
resource "local_file" "ansible_inventory" { filename = "inventory.ini" content = <<-EOT [webservers] ${aws_instance.web.public_ip} ansible_user=ubuntu EOT }
Re-apply Terraform:
terraform apply -auto-approve
This creates inventory.ini with the EC2 IP.
inventory.ini
Create nginx.yml:
nginx.yml
--- - name: Install and configure Nginx hosts: webservers become: yes tasks: - name: Update apt cache apt: update_cache: yes - name: Install Nginx apt: name: nginx state: present - name: Start and enable Nginx service: name: nginx state: started enabled: yes
ansible-playbook -i inventory.ini nginx.yml
Verify Nginx is running:
curl http://<EC2_PUBLIC_IP>
You should see the Nginx welcome page.
Use null_resource (or terraform_data in v1.4+) to trigger Ansible after Terraform:
resource "null_resource" "run_ansible" { triggers = { instance_ip = aws_instance.web.public_ip } provisioner "local-exec" { command = "ansible-playbook -i inventory.ini nginx.yml" } depends_on = [local_file.ansible_inventory] }
Now Terraform automatically runs Ansible after deploying the EC2 instance.
ansible-vault
aws_security_group
aws_spot_instance_request
t3.micro
m5.large
Environment=prod
Role=web
Owner=team-x
vpc.tf
ec2.tf
ansible.tf
cloud-init
--check
apply
terraform plan
depends_on
depends_on = [aws_instance.web]
taint
❌ Wrong: Hardcode IPs in Ansible or use remote-exec.
“What’s the best way to trigger Ansible after Terraform?”
❌ Wrong: Manually run Ansible after Terraform.
“Why avoid remote-exec for configuration?”
❌ Wrong: “It’s fine for small deployments.”
“How do you handle secrets in Ansible?”
terraform.tfstate
Challenge:Deploy a PostgreSQL database on AWS RDS with Terraform, then use Ansible to: 1. Install psql on an EC2 instance.2. Create a database and user.3. Load a sample schema.
psql
Solution:1. Terraform (rds.tf): hcl resource "aws_db_instance" "postgres" { allocated_storage = 20 engine = "postgres" instance_class = "db.t3.micro" db_name = "mydb" username = "admin" password = "securepassword123" # Use AWS Secrets Manager in prod! skip_final_snapshot = true } 2. Ansible Playbook (postgres.yml): ```yaml - name: Configure PostgreSQL client hosts: webservers become: yes tasks: - name: Install PostgreSQL client apt: name: postgresql-client state: present
rds.tf
hcl resource "aws_db_instance" "postgres" { allocated_storage = 20 engine = "postgres" instance_class = "db.t3.micro" db_name = "mydb" username = "admin" password = "securepassword123" # Use AWS Secrets Manager in prod! skip_final_snapshot = true }
postgres.yml
- name: Create database postgresql_db: name: mydb login_host: "{{ rds_endpoint }}" login_user: admin login_password: securepassword123
3. Run it:bash terraform apply -auto-approve ansible-playbook -i inventory.ini postgres.yml ```
3. Run it:
Why It Works:- Terraform provisions the RDS instance.- Ansible installs psql and configures the database without manual steps.
terraform output -json > outputs.json
ansible-inventory --list -i inventory.ini
ansible-playbook --check -i inventory.ini playbook.yml
knife ec2 server list
terraform taint aws_instance.web
root
ec2-user
ansible_user=ubuntu
Join 4M+ learners. Unlock unlimited quizzes, wrong-answer tracking, flashcards + reminders, study guides, and 1-on-1 challenges.