Unlocking Efficiency: Harnessing the Power of Terraform and Ansible

What is Terraform ?

Terrafom is an infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. Terraform can manage low-level components like compute, storage, and networking resources, as well as high-level components like DNS entries and SaaS features.

How does Terraform work ?

Terraform creates and manages resources on cloud platforms and other services through their application programming interfaces (APIs). Providers enable Terraform to work with virtually any platform or service with an accessible API.

https://developer.hashicorp.com/terraform/intro

What is Ansible ?

Ansible is an open source IT automation engine that automates provisioning, configuration management, application deployment, orchestration, and many other IT processes. Ansible can be used to install software, automate daily tasks, provision infrastructure and network components, improve security and compliance, patch systems, and orchestrate complex workflows.

How does Ansible work ?

Ansible is agentless, which means the nodes it manages do not require any software to be installed on them. Ansible reads information about which machines you want to manage from your inventory. Ansible has a default inventory file, but you can create your own and define which servers you want to be managed.

Ansible uses SSH protocol to connect to linux servers and run tasks.Unlike Linux/Unix hosts, which use SSH, Windows hosts are configured with WinRM.
By default, Ansible uses SSH keys with ssh-agent and connects to remote machines using your current user name. Root logins are not required. You can log in as any user, and then use su or sudo commands as any user.

Currently, we’ll delve into integrating Terraform for infrastructure provisioning with Ansible for configuration management.

Let’s kick things off by provisioning an EC2 instance on AWS using Terraform. Here’s what the Terraform structure looks like.

providers.tf

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

provider "aws" {
#
}

security.tf

// securtiy group 
resource "aws_security_group" "webserver_sg" {
name = "Security group - ansible-terraform"
}

// Outbound rule
resource "aws_security_group_rule" "public_out" {
type = "egress"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]

security_group_id = aws_security_group.webserver_sg.id
}

// Inbound rule SSH
resource "aws_security_group_rule" "ssh" {
type = "ingress"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.webserver_sg.id
}

// Inbound rule http
resource "aws_security_group_rule" "public_in_http" {
type = "ingress"
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
security_group_id = aws_security_group.webserver_sg.id
}

main.tf


data "aws_ami" "ubuntu" {
most_recent = true

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
owners = ["099720109477"]
}

resource "aws_key_pair" "webserver_key_pair" {
key_name = "webserver"
public_key = file("${path.module}/id_rsa.pub")
}


resource "aws_instance" "webserver_ec2" {
count = 3
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
vpc_security_group_ids = [aws_security_group.webserver_sg.id]
key_name = aws_key_pair.webserver_key_pair.id

tags = {
Name = "webserver_ec2"
env = "dev"
vmid= "vm-id-${count.index}"
}
}

The pivotal aspect of this code lies in the tags, as we’ll leverage them later in Ansible.

Now, let’s take a look at how the Ansible code is structured.

ansible.cfg

[defaults]
host_key_checking = False

[inventory]
enable_plugins= aws_ec2
inventory=./inventories

aws_ec2.yml

It is mandatory that the inventory file looks like this aws_ec2.yml.

---
plugin: aws_ec2
boto_profile: default
regions:
- eu-west-3
keyed_groups:
- key: tags
prefix: tag
- key: tags.Name
separator: ''
filters:
tag:env: dev
instance-state-name: running

webserver_ec2.yml

ansible_user: ubuntu

Finally, let’s examine the playbook.yml, notice that the hosts value should correspond to the tag specified in Terraform. This playbook is a basic one that installs and starts the Nginx server.

---
- name: configure webserver
hosts: webserver_ec2
become: true
gather_facts: false

tasks:

- name: ensure nginx is at the latest version
apt:
name: nginx
state: latest

- name: start nginx
service:
name: nginx
state: started
enabled: true

The first step is to provision the infrastructure.

terraform plan

This is what the output should look like.

apply the plan

terraform apply --auto-approve

The resources have been successfully created. You can verify this by logging into the AWS console to check the three instances. Alternatively, you can use the ansible-playbook command to list all available hosts.

As observed, Terraform has successfully created three instances. Now, let’s proceed to run Ansible against these instances.

Once Ansible has completed its tasks, you can verify the results either by accessing the instances through a web browser or using the command line interface.

And that concludes the basic setup. From here, you can delve into more advanced topics such as setting up a load balancer, configuring RDS, or utilizing Ansible to deploy applications directly from GitHub or GitLab repositories. These advanced topics offer further flexibility and automation in managing your infrastructure and applications.

Absolutely, it’s crucial to remember to destroy the infrastructure once it’s no longer needed. Properly managing resources helps optimize costs and maintain a tidy environment. You can do this by running the appropriate Terraform commands to tear down the infrastructure provisioned earlier.

terraform destroy -auto-approve   

In conclusion, the dynamic duo of Terraform and Ansible represents a formidable force in the realm of infrastructure automation and configuration management. Together, they offer a comprehensive solution for provisioning, configuring, and managing IT resources with efficiency and consistency.

you can find the code on my github

Leave a Reply

Your email address will not be published. Required fields are marked *