Ansible: Webserver on Amazon EC2
Today In this article we'll see how to launch the instance in aws cloud and configure the Webserver in it using Ansible. we also use the concept of Ansible Roles and Dynamic Inventory. After launching the instance in the AWS Cloud, our inventory is updated dynamically with the IP of newly launched instances and then Webserver is configured in it.
Ansible is an open-source software provisioning, configuration management, and application-deployment tool enabling infrastructure as code.
Ansible 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.
Here is my GitHub Repository link for this complete Ansible Playbook -
Here we have created two different roles, One role named as “aws” is to create security group, key-pairs and Launch ec2 instance and another role named as “webserver” is to configure the web server in the instance which is just launched by aws role.
Ansible Configuration file - This file is an ansible configuration file which contains different configurations like the path of inventory, the path of the private key for ec2 instances and the privilage_escalation configurations. As in ec2 instance by default we always log in with ec2-user but to install something we need root privileges, so we have used privilege_escalation block here to become root.
Inventory - This is an inventory file before ansible-playbook runs, there is no. IP here and they will be updated here dynamically when playbook runs.
Let’s Move to our Ansible Playbook YML Code :-
aws-web.yml - This is my main Ansible Playbook file. we have to run this file and to do all the configurations. It includes role and applies them to different host groups according to the requirements. Here “aws” role will run on localhost and “webserver” role will run on ‘webserver’ group of hosts which are our ec2 instances and their IPs are dynamically updated in inventory.
In the AWS Role :-
Variables file - This file contains all the variables used in the aws role like region, instance type, ami_id and subnet_id.
Tasks file - This file contains all the tasks for AWS Role. There are many tasks written here for different purposes.
- The first task will create a Key-Pair for our ec2 instances, and on changed it will also notify the handler “Save Key PEM File” which will save the PEM key.
- The second task will create a Security Group for our web server instances. It will also add an ingress rule for SSH and HTTP so that clients can connect to our webserver.
- The third task will launch the instance in which we are going to configure the webserver.
- Next task is to update the inventory for us. Dynamically this task will fetch the IP address of our instance launched and then updated it in the inventory file. This will update that IP in the webserver hosts group.
- Now after updating the inventory we need to refresh it otherwise the changes will not reflect in same running Ansible Playbook. So our next task is to refresh the inventory.
- Finally, our last task is just a pause for sometime before going ahead so that instances become ready in AWS Cloud.
Handlers file - This files contain all the handlers used in aws role. Here we have used one handler to save the private key PEM in a file. This handler is notified by the “Creating key-pair” task that is If this task will change that means new key-pair is created, so this handler will be notified and private key PEM will be saved to /etc/ansible/webkey.pem
In the Webserver Role :-
Tasks file - This is the tasks file for webserver role which contains the tasks to Install the httpd web server in the instance launched, after that start the httpd service and copy our webpage into its document root i.e. /var/www/html/ directory
Files - It contains all the files which are used in webserver role. Here we need to copy our HTML code i.e. webpage in the instance. So this is our HTML code file which will be copied in the instance.
Now we are ready to run our Ansible code. Before running playbook this is my status of EC2 dashboard, i.e. no instance is running, no key-pair is there and only one security group is there i.e. default.
Here in the ansible to use our aws we need to provide the access_id and access_key so that Ansible can log in to our aws and do something for us. So if we provide our aws credentials in a normal file (i.e. in plain text) then anybody can read it. so here we used ansible vault.
Ansible vault encrypts our file, only those can read it who have the vault password. So I created ansible vault named “aws-key.yml”, in which I have provided aws_access_id and aws_secure_access_key, and this will be encrypted.
Now if someone tries to open it with the wrong pass then it shows an error, it will only show real decrypted data to whom who have the right password. Also if anyone try to open it directly then it will show some encrypted data.
Here, we run the Playbook using “ansible-playbook --ask-vault-pass playbook_name.yml” command. we have used --ask-vault-pass option because we are using vault here and we need to pass the password so that ansible-playbook is able to decrypt it. Here in between the running playbook, we can see that role webserver is applied to an IP but there is no IP in the inventory before so here this IP is updated dynamically in the inventory by the aws role after launching the instance.
Now after the playbook completes running this is the status of my ec2 dashboard, now we can see that one key pair and one more security group is created, and one instance is running.
As one instance is running in ec2, so here in inventory also the IP of that instance is updated dynamically in webserver hosts group. After updating and refreshing the inventory that same playbook also configure the webserver in the IPs under webserver host group.
We can also see that the private key PEM is stored in webkey.pem file in /etc/ansible/ directory
Finally, everything is configured and we are connected to our website that is hosted on aws ec2 instance.
Here I conclude my article in hope that this is helpful to you. Thanks!!