Creating Infrastructure (Launching OS/Instance on AWS Cloud) using Terraform & configuring webserver using Ansible …

Nithish Kumar
5 min readMay 13, 2021

Now-a-days, the industry requires automation. If we required to launch a OS/Instance with desired requirements again and again, we as a humans, don’t have time and also we can do mistakes as we are doing the things manually,. So here Terraform will help us to automate our requirement,..

🤔 What is Terraform ?

Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. It generates an execution plan describing what it will do to reach the desired state, and then executes it to build the described infrastructure. As the configuration changes, Terraform is able to determine what changed and create incremental execution plans which can be applied.
Find more about Terraform:- Click Here

Why we need Ansible to configure the web server instead of Terraform ?
Becoz, Ansible will go inside the OS/Instance and then configure the things according to user requirements. Whereas Terraform also go inside the OS and configure the things, but here the problem is whenever user changed the configuration part inside the OS, terraform won’t able to find what user has changed and it’s not the duty of it,. For this, we have to use Configuration Management tools like Ansible, Puppet, Chef etc,.

🤔What is Ansible ?

Ansible is an open-source automation tool, or platform, used for IT tasks such as configuration management, application deployment, intraservice orchestration,..
Find more about Ansible:- Click Here

Let’s jump to the practical,..

As mentioned in the title, we need to create/launch an instance/OS on AWS Cloud using Terraform and Configuring the web server in the same OS which have created before using Ansible,..

Installing Terraform on Windows

Click Here to Download. Unzip the downloaded zip file, you will get a terraform.exe file to run the terraform commands,.. And set the path in Environmental Variables Editor

Coding part

Create a seperate folder & a file in that folder.

# commands$ mkdir C:\path\for\folder_name$ notepad file_name.tf

To use the aws resources, we’ve to use the provider AWS

# codeprovider "aws" {
region = "your_region"
profile = "your_profile_name"
}

To launch the instance/OS on AWS Cloud,

# coderesource "aws_instance" "web_os" {
ami = "<ami-id>"
instance_type = "<instance_type>"
security_groups = [ "<security_group_name>" ]
key_name = "<key_name>"

tags = {
Name = "<name of the os>"
}
}

We save the code for web server in the root drive, but if the OS got corrupted or may be get hacked, then we lose our code which is very critical for the company,.. So attach a new volume/drive to the OS, then mount the folder where we put the code files to the new volume,..

creating new volume & attaching to the OS

# coderesource "aws_ebs_volume" "vol_for_webserver" {
availability_zone = aws_instance.web_os.availability_zone
size = 1
tags = {
Name = "<name the volume>"
}
}
resource "aws_volume_attachment" "ebs_att" {
device_name = "/dev/sdh"
volume_id = aws_ebs_volume.vol_for_webserver.id
instance_id = aws_instance.web_os.id
}

Configuring web server using Ansible

For this, I’ve already Installed & configured Ansible in my Virtual Box,.. Make sure you have the ansible.cfg as shown below

# ansible.cfg file[defaults]
inventory = <inventory file path>
host_key_checking = False
remote_user = ec2-user
ask_pass = False
private_key_file = <path to .pem file>
[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False

Now we need to add only public IP of the host in the inventory file,.. Later we’ll see how to append the host IP using terraform.

I’ve created a yaml file or we can say playbook, (i.e) is Installing & starting web server

# first playbook- hosts: all
tasks:
- name: Install httpd package
package:
name: "httpd"
state: present
- name: start the httpd services
service:
name: "httpd"
state: started

Using null resource, run the first playbook using ansible

For this, we need to login to the OS.. Here we have to use connection block in the null resource,.. Use “remote-exec” provisioner to execute the commands remotely,..

# coderesource "null_resource"  "install_conf_webserver" {
depends_on = [
aws_volume_attachment.ebs_att
]

connection {
type = "ssh"
user = "<username>"
password = "<password>"
host = "<IP of local VM>"
}

provisioner "remote-exec" {
inline = [
"echo ${aws_instance.web_os.public_ip} > inventory",
"ansible-playbook <first_playbook_name>.yml",
]
}
}

Formating the new volume & creating a mount point

# coderesource "null_resource"  "mounting" {
depends_on = [
null_resource.install_conf_webserver
]
connection {
type = "ssh"
user = "<user_name>"
private_key = file("<path to .pem file>")
host = "${aws_instance.web_os.public_ip}"
}

provisioner "remote-exec" {
inline = [
"sudo mkfs.ext4 /dev/xvdh",
"sudo mount /dev/xvdh /var/www/html",
]
}
}

Second playbook for deploying code from github to the web server folder /var/www/html

# second playbook- hosts: all
tasks:
- name: install git
package:
name: "git"
state: present
- name: copying the code to /var/www/html path
git:
repo: "https://github.com/KumarNithish12/sample_terraform_ansible_php.git"
clone: yes
dest: /var/www/html/web/

In the git repo, I’ve written a sample html code to test the web server,..

Now using null resource in terraform, login to local VM to run the second playbook to deploy code & open chrome to test web server,..

# coderesource "null_resource"  "install_conf_webserver" {
depends_on = [
null_resource.mounting
]
connection {
type = "ssh"
user = "<user name>"
password = "<password>"
host = "<ip of local VM>"
}

provisioner "remote-exec" {

inline = [
"ansible-playbook <second_playbook_name>.yml"
]
}
provisioner "local-exec" {
command = "chrome http://${aws_instance.web_os.public_ip}/web/index.html"
}
}

For opening Chrome Browser to test the web server use “local-exec” provisioner,..

Coding part is Done !!
Now run the terraform code,..

# commands$ terraform init$ terraform apply# enter yes, when it prompts

Finally, U will see in the chrome browser,..

To delete/destroy all

# command$ terraform destroy

That’s all,..
Thank U for reading, Give a like & comment your opinions !!!

For any queries, Contact me on LinkedIN

…. Signing Off ….

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Nithish Kumar
Nithish Kumar

Written by Nithish Kumar

Aspiring DevOps/Cloud Engineer. #Believe in you.

No responses yet

Write a response