Ansible has to know its target nodes where it has to configure all the things and the information about the target nodes is written in the inventory file of ansible. But what if we don’t know the IP of the target node, which happens most of the time in real scenario. If we use ansible to provision an ec2 instance, we get the IP only after provisioning. So, we want that after instance is created ansible retrieve the instance IP for further configuration. In this situation dynamic inventory can help to dynamically get the current IP of the target node.
We are going to configure apache web server on an ec2 instance provisioned by ansible using the dynamic inventory concept.
My ansible configuration file looks like this, here I have given the path of inventory directory (which can contain multiple inventories). Also given roles path where I file create roles and the private key file location for AWS authentication. We log in to amazon instance as ec2-user but for configuration we need more powers which is called privilege escalation and we use sudo for becoming root user.
For retrieving the information of running instances at my AWS account we are using a python script which has ability to connect with the aws and get the information of running instance,
This script is already created by community and we can get it from here
So, I downloaded this script ec2.py inside the directory for inventories.
I have python3 installed in my system so I did a little change in the script and changed it to python3 from python
Make this file executable so that ansible can run it,
chmod +x ec2.py
It also requires boto library of python to connect with AWS cloud.
pip3 install boto
For authentication we can give the aws IAM user credentials as shell variable like shown below,
We are also installing boto3 library of python which will be required by ansible ec2 module for connecting AWS and launching instance,
🔳 Now, let’s create a ansible role for launching ec2 instance. For creating a role we have the ansible command, I named it ‘aws-webserver’
ansible-galaxy init role_name
Let’s see the tasks to be done in this role. I created tasks for creating and saving a private key, then for launching aws instance. After the instance is launched we have to wait for ssh to enabled and also we have to refresh the inventory otherwise it will fail to find the dynamic host name.
These are variables to be by default used if not passed in playbook
🔳 Now we have to create another role for configuring apache web server. I named it ‘config-server’,
Following are the tasks written in it. First installed httpd package, created a directory and copied a file to it, changed the Listening port number and document root of apache httpd server (if this task is changed then we notify a handler to restart the httpd service).
This is the handler to restart the httpd service when required,
Finally, we write a playbook and have to use these two roles created to perform the task,
First we launch one aws instance with name tag ‘webserver’ using the ‘aws-webserver’ role. Then we have to configure apache web server in the launched instance so we used ‘config-server’ role for it. But for host name we can use the name tag given to the instance written as tag_Name_webserver (as that ec2.py script is run by ansible and it retrieves the information of the running instances which ansible uses as inventory, we can also run that script as ./ec2.py - -list and it will show us running instances with tags)
Finally, running the playbook
The playbook has successfully run and an instance named ‘webserver’ is launched as we can see the ec2 dashboard,
Also, we can access the page deployed in the changed document root of the web server.
So, we have successfully created this ansible automation setup with aws cloud
The complete code is here at my GitHub repo,
Contribute to VikasVerma25/ansiblet2 development by creating an account on GitHub.