Ansible Dynamic Inventory and Refresh Inventory at Run time

Ansible Dynamic Inventory and Refresh Inventory at Run time

Hello Connection,

Here is my article about

  • Provisioning EC2 instance in AWS with Ansible
  • Dynamically update inventory as we launch more Instances
  • Configure the WebServer to deploy Website with Role

Pre-Configuration :

  • Install Ansible

Follow this Article to Install and Learn How Ansible Works.

Dynamic Inventory

There are two types of Inventories in Ansible

  1. Static: The User has to configure the inventory Manually
  2. Dynamic: The Inventory is configured with Scripts. The Script will automatically pick the IP's and configure the inventor

We have to update the inventory in Ansible to Configure Managed Node. We have to add some lines in this configuration file /etc/ansible/ansible.cfg

  • We are Launching Managed node in AWS so, There is a famous python script to retrieve the IP's - ec2.py and we are also using ec2.ini for Making Groups

Download the Scripts

  • ec2.py
  • ec2.ini
  • Copy these two scripts in /etc/ansible/ and make them executable
chmod  +x  ec2.py 

chmod  +x  ec2.ini
  • Copy the Private Key of the AWS instance to /etc/ansible
No alt text provided for this image

Configure Ansible :

  • We have to configure the /etc/ansible/ansible.cfg

Add the path to ec2.py in ansible.cfg file with inventory keyword. Ansible does configuration with SSH protocol so the Ansible has to log in and we have to provide the remote_user

No alt text provided for this image
  • when we do SSH we have to accept the Host Keys but when the SSH is done by Ansible there's no one to accept the host keys so we have to disable that
No alt text provided for this image
  • When installing any packages we have to be root but If we do SSH with root AWS doesn't accept the SSH request.
  • The ec2-user gets root power with sudo and we have to add the configuration rule in ansible Inventory to use sudo with user ec2-user. The concept of giving the root power to normal user with sudo is called privilege escalation
No alt text provided for this image
  • We need the Private Key of Instance running in AWS to do SSH and have to add the path of Private Key in Inventory
No alt text provided for this image
Ansible Role

Ansible Role is to Mange the Playbook. 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.

Create Role :

ansible-galaxy  role  init  RoleName
No alt text provided for this image
  • The command creates a structure to manage multiple things in a playbook
No alt text provided for this image
  • We have to write the tasks in a playbook to file /tasks/main.yml in the webserver role
---
# tasks file for webserve
- name: Install Httpd
  package:
    name: httpd
    state: present
- name:  Copy Website to Webserver
  copy:
    src: ./files/index.html
    dest: /var/www/html/
- name: Start Service
  service:
    name: httpd
    state: started

No alt text provided for this image
  • The Static file in the playbook will be stored in /files/ in the role and we have the index.html file stored in that directory

To know more about Ansible Role Follow Link :

Run the Ansible Role :

We can write a playbook to run the role and I call it main.yml. This file actually have hosts where we have to run the role.

- hosts: all
  roles:
  - role: webserver

This snippet of code run the role and configure the webserver in all Managed node but we don't have any AWS instances running.

Provision EC2 Instances with Ansible

Configure AWS command or Export the AWS_ACCESS_KEY or AWS_SECRET_KEY

No alt text provided for this image

or

export AWS_ACCESS_KEY_ID='YOUR_AWS_API_KEY'

export AWS_SECRET_ACCESS_KEY='YOUR_AWS_API_SECRET_KEY'

Let's Provision Instance in AWS with Ansible and we have to do that before we configure the role we can add the step of provisioning in the same main.yml file.

  • We are going to use the module ec2 and that module works internally with he AWS EC2 API so we have to launch instances in localhost so the request is forwarded to AWS to launch the instances in AWS
  • Collect the required information from the AWS Management Console [AWS WebPortal] to launch an instance. Create a security group to allow port 80 and get ID
- name: Provision OS in AWS
    ec2:
      instance_tags:
        Name: Webserver
      key_name: "keypair_docker_webserver"
      instance_type: "t2.micro"
      image: "ami-09a7bbd08886aafdf"
      wait: yes
      count: 1
      vpc_subnet_id: "subnet-9e9fa5f6"
      assign_public_ip: yes
      state: present
      region: "ap-south-1"
      group_id: "sg-02548637202b85d22"
      aws_access_key: "{{ access_key }}"
      aws_secret_key: "{{ secret_key }}"

This snippet will take care to launch the instance in AWS. This has to run before we configure the webserver role so this is a pre_task of ansible role

Create a Vault for AWS Keys :

The AWS Access Key and Secret Key is store in Ansible-vault.

ansible-vault  create VaultFile.yml
No alt text provided for this image

The command will open a file and we have given the variable of aws_access_key and aws_secrete_key and their values so we can include this file secure.yml in main.yml and use the variable in place of these keywords where we need to provide keys

Everything Looks Cool but we missed one thing !!

In Ansible when we run a playbook Inventory only update once in the beginning but we need our inventory to refresh after we launch the Instance in AWS and we have to wait for the Instance to Provision completely

  • Let's Make our Playbook wait for Instances provisioning in AWS. Ansible has the pause module to do that for us
- name: Wait to Completely Provision Instances
    pause:
      minutes: 2

This code snippet makes the playbook to wait for 2 minutes

Let's do a step which I stuck a lot when doing this task.. Refresh Inventory

  • Refresh Inventory at Run Time. We have to refresh after we wait for Instances to Launch
- name: Refresh Inventory
    meta: refresh_inventory

Finally, Our Playbook main.yml

- hosts: localhost
  vars_files:
  - secure.yml
  pre_tasks:
  - name: Provision OS in AWS
    ec2:
      instance_tags:
        Name: Webserver
      key_name: "keypair_docker_webserver"
      instance_type: "t2.micro"
      image: "ami-09a7bbd08886aafdf"
      wait: yes
      count: 1
      vpc_subnet_id: "subnet-9e9fa5f6"
      assign_public_ip: yes
      state: present
      region: "ap-south-1"
      group_id: "sg-02548637202b85d22"
      aws_access_key: "{{ access_key }}"
      aws_secret_key: "{{ secret_key }}"
  - name: Wait to Completely Provision Instances
    pause:
      minutes: 2
  - name: Refresh Inventory
    meta: refresh_inventory


- hosts: all
  roles:
  - role: webserver

Run Playbook :

ansible-playbook  main.yml  --ask-vault-pass
No alt text provided for this image
No alt text provided for this image

Website :

No alt text provided for this image
No alt text provided for this image

GitHub URL :

Done this task under the guidance of Mr.Vimal Daga Sir

Thank you Vimal Daga sir.


Thank you for Reading, Please Drop a message If you have any questions about this article. Happy to Help!



Tharak Ram

Site Reliability Engineer II @ JP Morgan Chase. @IUDX, @IISC

3 年

Nice article ??

回复
Kalla Kruparaju

DevOps Engineer at DataGrokr | ?? 1X AWS, 2X Google Cloud, and 3X Azure Certified | Cloud Architect | Infrastructure Automation Enthusiast | Docker | Kubernetes | Terraform | Ansible | Jenkins | Gitlab

3 年

Great work ??????

要查看或添加评论,请登录

社区洞察

其他会员也浏览了