Deploy a Load Balancer and multiple Web Servers on AWS instances through ANSIBLE!
🔅Provision EC2 instances through ansible.
🔅 Retrieve the IP Address of instances using the dynamic inventory concept.
🔅Configure the web servers through the ansible role.
🔅Configure the load balancer through the ansible role.
🔅The target nodes of the load balancer should auto-update as per the status of web servers.
For performing the above task we need to first launch the instances on AWS, we can either go manually and launch these or we can simply do this part using the ansible. I have divided this part into two parts.
In the first part, I will explain the launching of aws instances using the ansible in your local system and in the second part i will configure the loadbalancer and webservers in these instances with the help of ansible. So, lets now begin this task.
First in your local virtual machine(RHEL8) install the ansible program, using
pip3 install ansible
As this tool is created using the python language we have to install it using this command. Next check if the installation is completed or not using
ansible — — version
Now we need to create a configuration file for ansible. Create a folder using
In this folder create a file ansible.cfg with any editor.
Write the cfg file as shown in the below image
The value of inventory keyword is used to define the location of file which contains the hosts and group hosts details upon which the commands, modules etc. will operate. You have to put the cfg file in this folder also.
Ansible enables host key checking by default. Checking host keys guards against server spoofing and man-in-the-middle attacks, but it does require some maintenance. To disable this behavior, you can do so by setting the host_keyword_checking=false.
The remote_user keyword is used to set the value of the user through which we are logging into the target hosts. In AWS cloud we always use ec2-user to login into the instance.
If we have to login to the vm or instance using a password base authentication than we can use the ask_pass variable as true. But in the aws instance the authentication is done using key-based method so here we set this variable as false.
Here the private_key_file variable will store the path where the key is located.
And the roles_path will indicate the location of the ansible roles.
The privilige escalation block is used to change the user powers in the instances. You can check the details of these contents here.
After setting the configuration files we can now move on to instance launching part.
For this first thing you need to do is to create an encrypted file using ansible-vault to store the access key and secret key of your aws account.
Use the following commands:-
ansible-vault create — — vault-id values@prompt creds.yml
Where you can change the prompt name(values) and filename(creds.yml) as you want.
After running this command enter the password and confirm it.
Now this file will open up and you can write the accesskey and secretkey variables and their values as shown
After creating the credential file, create an ansible playbook and in this playbook you can write all the details of your ec2 instance. For Ex the keyname, security group, ami-id etc.
In my case you can see I have first written the host details as i will use my local vm(controller node) to run the playbook and it will configure the instances on the cloud. And also in the var_files block I have given the credentials files name as i dont want to share the access key and secret key with anyone else.
After creating this file you can simply run the playbook using:
ansible-playbook — — vault-id values@prompt instances.yml
where the instances.yml file is my playbook, in your case you can change the name of this file.
After running these instances we need to retrieve the ip addresses of these instances. For this we need to download some scripts which the ansible provides us. You can learn more about it here.
Download the scripts using wget command. Links for your reference:
After downloading these scripts put them into the inventory folder and make them executable using:
chmod +x ec2.py
chmod +x ec2.ini
In the ec2.py file in first line change the python version as shown:
#!/usr/bin/env python → #!/usr/bin/env python3
After this, export the enviornmental variables for the AWS region, access key and secret key.
Now you can run the commands “ ./ec2.py ” to check the ip addresses of the instances.
Also you can use
ansible all — — list hosts
Now after retrieving the ip addresses of the instances. We can now move onto the Second part of the Task where we will configure the load balancer and webserver on these instances using the ansible.
For this first create a hosts file in the inventory folder(vi /etc/ansible/hosts) and write the ip addresses and the other keywords as shown.
You can change the value of ansible_ssh_private_key_file and give the path where you have stored the private key.
You can use ping module to check whether our local system have the connectivity to the cloud instances or not using:
ansible all -m ping
Now we will create the ansible roles to perform or tasks.
Roles provide a framework for fully independent, or interdependent collections of variables, tasks, files, templates, and modules.
In Ansible, the role is the primary mechanism for breaking a playbook into multiple files. This simplifies writing complex playbooks, and it makes them easier to reuse. The breaking of playbook allows you to logically break the playbook into reusable components.
You can check more about the ansible roles here.
In my case i will create two different roles, One role is used to configure the loadbalancer and the second role will be used to configure the webapps/webservers. Use
ansible-galaxy init rolename
To initialize the roles.
After this to check whether the roles have been created or not, use:
Now go to the folder and change the yaml files accordingly. In my case i have created a folder /etc/roles and declared it in the ansible.cfg as the role path. So the location of my roles will be /etc/roles/loadbalancer and /etc/roles/webapp.
FOR LOADBALANCER ROLE:
a. Go into the tasks folder and change the main.yaml file as shown.
This yaml file will first install the package haproxy in the target host and then it will copy the haproxy file from our local system to the target host dest. and it will notify the handler also to restart the services if their is any change in the haproxy.cfg file.
b. After this go to the handlers folder and change the main.yaml file as shown.
This will restart the haproxy services whenever the tasks/main.yaml file notifies.
c. After this you need to first get the haproxy.cfg file, For this you can install the haproxy program in your local system manually or you can use any other vm and cp the haproxy file into the etc/roles/loadbalancer/templates/ folder. In the cfg file according to your choice you can change the bind address and write the for loop to change the no of instances dynamically in the configuration file as shown.
FOR WEBAPP ROLE:
Make changes in the tasks/main.yaml file as shown.
This yaml file will first install the httpd package in the target host and then it will write the given content in the index.html file and after this it will start the httpd services.
To run both these roles you need to create a playbook and give the roles details in it. I have created this file in /task3/ folder.
Before running this playbook you need to give permissions to the .pem key othervice it wont be able to connect to the aws instance, use:
chmod 600 /path/keyname.pem
where keyname is the name of your aws instance key and the path refers to the location in which you have stored the key. in my case i have put the key in the /etc/ansible file so the command will be
chmod 600 /etc/ansible/nkey.pem
Now after setting the permissions we can simply run the playbook using
As you can see the webapp instances are configured.
But the haproxy services shows some error and hence the services cant be started.
I have manually logged into the loadbalancer instance and checked the port no. and configuration files as if there is any problem with the configuration.
Here, the configuration files is correct and it have successfully copied the public ip of the other 3 instances and the port no is also the same as we have written in the file of our local system vm.
But as you can see this port no is not shown when i check the netstat -tnlp command.
This problem occurs because of the selinux security, we can’t change the port no of any program config file and if we do so the selinux won’t allow to start the services of that particular program.
To avoid this problem you can either use the by default port no 5000 in this configuration file or we can set the SElinux security off so that these services can be started. Use setenforce 0 to temporarily stop the security.
Now again run the ansible playbook and this time it will not give any error in starting the services.
You can also check it from the loadbalancer instance.
After this we can simply check our webserver with the help of loadbalancer ip and the given port no.
With this, we have successfully completed the given TASK.
Github URL: https://github.com/akshat-crypto/RH294_task3.git