Deploy a load balancer and multiple webservers on AWS instances through Ansible
By: Sachin Kumar
Tags: Web Server, Load Balancer, AWS, Ansible, Haproxy

Deploy a load balancer and multiple webservers on AWS instances through Ansible

Let’s see how to provision AWS instances and deploy Webservers and HAProxy Server with the help of Ansible dynamically.

Welcome back to my another article, Here you will get the solution to many problems like how to provision AWS instance and retrieve its IP dynamically as well as you will learn about HAProxy server and at the end of the article, you will see the deployment of Webservers on the AWS instances through Ansible. These webservers are accessible for the client through the Load balancer and how we can scale up & down the Webserver dynamically. So let’s get started.

Load Balancer

load balancer acts as the “traffic cop” sitting in front of your servers and routing client requests across all servers capable of fulfilling those requests in a manner that maximizes speed and capacity utilization and ensures that no one server is overworked, which could degrade performance. If a single server goes down, the load balancer redirects traffic to the remaining online servers. When a new server is added to the server group, the load balancer automatically starts to send requests to it.

In this manner, a load balancer performs the following functions:

Distributes client requests or network load efficiently across multiple servers

Ensures high availability and reliability by sending requests only to servers that are online

Provides the flexibility to add or subtract servers as demand dictates

The architecture of Load Balancer

HAProxy

HAProxy, which stands for High Availability Proxy, is a popular open-source software TCP/HTTP Load Balancer and proxying solution which can be run on Linux, Solaris, and FreeBSD. Its most common use is to improve the performance and reliability of a server environment by distributing the workload across multiple servers (e.g. web, application, database). It is used in many high-profile environments, including GitHub, Imgur, Instagram, and Twitter.

Ansible

Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code. It runs on many Unix-like systems and can configure both Unix-like systems as well as Microsoft Windows. It includes its own declarative language to describe system configuration. Ansible was written by Michael DeHaan and acquired by Red Hat in 2015. Ansible is agentless, temporarily connecting remotely via SSH or Windows Remote Management (allowing remote PowerShell execution) to do its tasks.

Hopefully, now you have a little bit of idea about above mentioned So let’s see what are the pre-requisites and how you can design the below-mentioned architecture using ansible.

Architecture of HAProxy

So you are going to design this architecture using the Automation tool Ansible.

Pre-requisite

To configure the above architecture you have some pre-requisite which are mentioned here.

Configured Ansible Controller node 4 or more than 4 AWS instances. IAM Account

Create an IAM Account

Create an IAM Account with programmatic access to get the access and secret key so that we can access the AWS services.

So you have to click on the next and next with proper access, your IAM account will be ready after a minute but if you are no comfortable with this process then simply visit the below-mentioned article.

Configuration of the Controller node

After creating IAM Account, now you have to install ansible on your system that’s known as a controller node. So if your controller node isn’t configured then you can visit the below-mentioned article where you will find lots of information about the installation of Ansible.

Create a Vault

Ansible Vault is a feature of ansible that allows you to keep sensitive data such as passwords or keys in encrypted files, rather than as plaintext in playbooks or roles. Alternately, you may specify the location of a password file or command Ansible to always prompt for the password in your ansible. cfg file. So simply run the below command and put your access and secret key inside it which you downloaded from your IAM Account and then save it with your suitable password.

ansible-vault create vault_file_name.yml

Install boto library

Here we can use our localhost IP address to behave as a managed node and we will use the SDK to launch the ec2 instance on AWS as Ansible is built on python language so we will be using boto. Boto as it an API so it has the capability to contact AWS. So install boto in your controller node.

sudo pip3 install boto3

Write a playbook for launching the Instances

After installing the boto library, you can provision the EC2 instances through the Ansible playbook. So just create the playbook and write the below code.

After creating the playbook, run it with your vault using the below command, and give your password which you gave during the vault creation.

ansible-playbook --ask-vault-password playbook_name.yml

So after running the playbook, let’s see your EC2 Dashboard and check the instances are provisioned or not. and write your private IP somewhere which you will get after running a playbook.

Copy a key pair to a Remote System with the scp Command

To copy a key from a local to a remote system run the following command:

scp -i key_name.pem remote_username@10.10.0.2:/remote/directory

Where key.pem is the name of the private key we want to copy, remote_username is the user on the remote server, 10.10.0.2 is the server IP address. The /remote/directory is the path to the directory you want to copy the key to. If you don’t specify a remote directory, the file will be copied to the remote user home directory.

Give user login permission for a managed node through Ansible. cfg to the controller node

Now if you want to login to your EC2 instances dynamically, So write the below code in your ansible.cfg file. Because by default, login of the root has disabled. So you can’t log in with the root account in AWS. So go inside the below-mentioned location of the controller node and write the below syntax.

sudo vi /etc/ansible/ansible.cfg

Make an inventory and write the info of Instances

Now your config file has been configured in the controller node so you can do anything on your instances (managed nodes) whatever you want to do so write the private IP and username which you got when you run the playbook for provisioning the Instances.

And check that your managed nodes are available or not using the below command.

ansible all --list-hosts

Check your EC2 Instances (Managed nodes) are pingable or not.

ansible all -m ping

After checking all these things, create the roles to deploy the web server and load balancer in the Managed nodes (EC2 Instances).

Create Roles for deploying the Webserver and load balancer.

Roles let you automatically load related vars_files, tasks, handlers, and other Ansible artifacts based on a known file structure. Once you group your content in roles, you can easily reuse them and share them with other users. Role directory structure. Storing and finding roles. So use the below command for creating the role.

ansible-galaxy init role_name

So after creating roles for load balancer and webserver, Install HAProxy software in your controller node using the below command.

yum install haproxy -y

After installing HAProxy, go inside /etc/haproxy/haproxy.cfg and copy haproxy.cfg into the ib_role/templates/ directory which is inside your load balancer role. Here you can use the cp command to copy the haproxy.cfg file.

Then open the haproxy.cfg file which is inside lb_role/templates/ and binds the port 8080.

Also, write the below-mentioned jinja code to update the haproxy.cfg file to load balancer dynamically.

After completing the template, open your lb_role/tasks/directory and write the below code inside main.yml to configure the load balancer.

So your load Balancer role is done, now open your web_role/files/ and make a webpage but I have mentioned here a PHP webpage with the name of index.php.

Now open your web_role/tasks/directory and write the below code inside main.yml to configure the load balancer.

So there are two tasks are created. one is for WebServer and another one is for Load Balancer.

Create a playbook for roles

Now create a playbook to run your roles which contains only the information of your load balancer and web server instances and the location of roles path.

Now run the playbook using the below command.

ansible-playbook playbookname.yml

After running the playbook, let’s both webservers and load balancer are working properly. So take the IP of a load balancer and browse with lb_pubic_ip:8080

It’s working well with two web servers so now if you want to add one or more than one web server so let’s check how to add a new webserver with the load balancer. So provision one more instance with ec2.yml playbook which is mentioned above.

Open your inventory file and write the information about the newly launched instance which you want to make a web server.

After adding the information of a new instance, run again your playbook.

Running the playbook again

Now you can see in the above clip one new web server has been configured successfully. So let’s check the final output.

Final Output

Load Balancer is also working great with all three web servers as you can see in the above clip.

Conclusion

Here you have learned how we can launch the AWS instances as well as you saw the about roles and at the end of the article, your all setup is ready to update and configure the load balancer and webservers dynamically. Here you can add how many web servers you want, only write the information about the operating system in an inventory file, and run the playbook.

I tried to explain as much as possible. Hope You learned Something from here. Feel free to check out my LinkedIn profile mentioned below and obviously feel free to comment. I write Cloud Computing, Machine Learning, Bigdata, DevOps and Web, etc. blogs so feel free to follow me on Medium.

Thanks, Everyone for reading. That’s all… Signing Off… 😊