Day57 ----> 90DaysOfDevOps Challenge @TWS

Day57 ----> 90DaysOfDevOps Challenge @TWS

Ansible Inventory Files: Default Inventory, Custom Inventories and Essential Tips πŸ“

Ansible, the popular automation tool, relies heavily on inventory files to manage and organize hosts. Inventory files define the target systems on which Ansible executes tasks, making them a crucial component of any Ansible playbook.

In this blog, we will explore Ansible inventory files, dive into custom inventories, and discuss important tips and tricks to enhance your Ansible workflows.

Understanding Ansible Inventory Files:

Ansible inventory files are plain text files that contain a list of hostnames or IP addresses, grouped into categories called "inventory groups." These files define the infrastructure and allow Ansible to locate and interact with the target hosts.

By default, Ansible uses the /etc/ansible/hosts file as its inventory. However, custom inventory files can be created to meet specific requirements.

Custom Inventories and How They Work:

  1. Creating a Custom Inventory File:

To create a custom inventory file, you can start from scratch or modify an existing inventory file. Here's an example of creating a custom inventory file named my_inventory.inv from scratch:

my_inventory.inv

[web_servers]
webserver1 ansible_host=192.168.1.10
webserver2 ansible_host=192.168.1.11

[db_servers]
dbserver1 ansible_host=192.168.1.20
dbserver2 ansible_host=192.168.1.21

In this example, we have defined two groups, [web_servers] and [db_servers], and assigned hosts to each group using the ansible_host parameter. You can add more groups and hosts as per your infrastructure requirements.

  1. Specifying Hosts and Groups:

In a custom inventory file, hosts are assigned to specific groups using the [group_name] notation.

my_inventory.inv

[web_servers]
webserver1 ansible_host=192.168.1.10
webserver2 ansible_host=192.168.1.11

[db_servers]
dbserver1 ansible_host=192.168.1.20
dbserver2 ansible_host=192.168.1.21

[staging_servers]
webserver2
dbserver1

[production_servers]
webserver1
dbserver2

Here, we have added two more groups, [staging_servers] and [production_servers], and assigned hosts to each group based on their respective roles.

  1. Variables and Metadata:

Inventory files allow you to define variables and metadata for hosts and groups. Let's enhance our custom inventory file to include variables:

my_inventory.inv

[web_servers]
webserver1 ansible_host=192.168.1.10 ansible_user=ubuntu
webserver2 ansible_host=192.168.1.11 ansible_user=centos

[db_servers]
dbserver1 ansible_host=192.168.1.20 ansible_user=ubuntu
dbserver2 ansible_host=192.168.1.21 ansible_user=centos

[staging_servers]
webserver2 ansible_ssh_private_key_file=/path/to/staging_key.pem
dbserver1 ansible_ssh_private_key_file=/path/to/staging_key.pem

[production_servers]
webserver1 ansible_ssh_private_key_file=/path/to/production_key.pem
dbserver2 ansible_ssh_private_key_file=/path/to/production_key.pem

In this example, we have added the ansible_user variable to specify the SSH user for each host. Additionally, we have included the ansible_ssh_private_key_file variable to define different SSH private keys for hosts in the [staging_servers] and [production_servers] groups.

You can also add metadata to hosts or groups using comments. For instance:

my_inventory.inv

[web_servers]
webserver1 ansible_host=192.168.1.10
webserver2 ansible_host=192.168.1.11

[db_servers]
dbserver1 ansible_host=192.168.1.20
dbserver2 ansible_host=192.168.1.21

# Metadata for web servers group
[web_servers:vars]
environment=production
tags=web
ansible_python_interpreter=/usr/bin/python3

# Metadata for db servers group
[db_servers:vars]
environment=staging
tags=db
ansible_python_interpreter=/usr/bin/python3

In this example, we have added metadata in the form of variables for the [web_servers] and [db_servers] groups. The environment variable indicates the environment the servers belong to (production or staging), while the tags variable provides additional descriptive tags for each group.

By utilizing variables and metadata in your custom inventory file, you can customize the behavior of your Ansible playbooks and make them more adaptable to different environments or specific host requirements.

Remember to save the custom inventory file my_inventory.inv in a location accessible by Ansible.

How to use custom inventory files:

The below command will ping hosts from the default inventory host's list of [web_servers] and [db_servers] groups

ansible web_servers -m ping

ansible db_servers -m ping

You can reference it using the -i flag.

Now using our custom inventory

ansible web_servers -m ping -i my_inventory.inv

ansible db_servers -m ping -i my_inventory.inv

This ensures that Ansible targets the hosts defined in your custom inventory file.

Creating a custom inventory file allows you to organize your hosts into groups, assign variables and metadata, and customize your Ansible playbook execution. With the ability to define specific attributes for hosts and groups, you gain fine-grained control over your automation workflows.

Tips and Tricks for Ansible Inventory Files:

  1. Dynamic Inventories:

    Ansible supports various plugins for dynamic inventories. One popular option is the "aws_ec2" plugin, which allows you to fetch inventory information from Amazon Web Services (AWS) EC2 instances. Here's an example of how to configure it:

# ansible.cfg
[defaults]
inventory_plugins = aws_ec2

# inventory.aws_ec2.yml
plugin: aws_ec2
regions:
  - us-west-1
  - us-east-1
keyed_groups:
  - key: tags.Name

This configuration fetches inventory information from EC2 instances in the specified regions and groups them based on the value of the Name tag.

  1. Aliases and Patterns:

    Aliases provide a convenient way to reference hosts with alternative names. Consider the following example:

# inventory.yml
webserver01 ansible_host=192.168.1.10
webserver02 ansible_host=192.168.1.11
webserver03 ansible_host=192.168.1.12

[webservers]
webserver01
webserver02
webserver03

[alias_hosts]
webserver01 ansible_host=web01.example.com
webserver02 ansible_host=web02.example.com
webserver03 ansible_host=web03.example.com

In this inventory, we define hosts using their IP addresses and assign them to the webservers group. Additionally, we provide aliases for the same hosts in the alias_hosts group, using their fully qualified domain names (FQDNs).

Patterns allow you to select hosts based on specific criteria. Here's an example that uses patterns to select hosts based on a variable value:

# inventory.yml
webserver01 ansible_host=192.168.1.10 ansible_os_family=debian
webserver02 ansible_host=192.168.1.11 ansible_os_family=redhat
webserver03 ansible_host=192.168.1.12 ansible_os_family=debian

[webservers]
webserver*

[debian_hosts]
* ansible_os_family=debian

[redhat_hosts]
* ansible_os_family=redhat

In this case, the pattern webserver* selects all hosts starting with "webserver" and assigns them to the webservers group. Similarly, the debian_hosts and redhat_hosts groups use patterns to select hosts based on their ansible_os_family variable value.

  1. Inventory Plugins:

    Inventory plugins can fetch inventory information from various sources. Let's look at an example using the "gcp_compute" plugin, which retrieves inventory data from the Google Cloud Platform (GCP):

# ansible.cfg
[defaults]
inventory_plugins = gcp_compute

# inventory.gcp_compute.yml
plugin: gcp_compute
projects:
  - my-project
auth_kind: serviceaccount
service_account_file: /path/to/service_account.json
groups:
  - key: labels.environment

In this example, the configuration fetches inventory information from GCP instances in the specified project. It groups the instances based on the value of the environment label.

  1. Encrypted Inventory:

    Ansible Vault allows you to encrypt sensitive data in your inventory files. Here's an example:

# vault.yml (encrypted)
database_password: !vault |
          $ANSIBLE_VAULT;1.1;AES256
          66306432313664306334303066663634383066623162313764393833363531316262383661326665
          663939343665663437383630316330333663373

Your Playbook File playbook.yml references both the inventory file and the vault file.

- name: Example Playbook
  hosts: db_servers
  gather_facts: false
  vars_files:
    - vault.yml

  tasks:
    - name: Display database password
      debug:
        var: database_password

ansible-playbook -i inventory.yml playbook.yml --ask-vault-pass

During playbook execution, you will be prompted to provide the vault password to decrypt the vault file vault.yml containing the sensitive variables.

What is Ansible Vault?

Ansible Vault is a feature that allows you to encrypt sensitive data, such as passwords, API keys, or other confidential information, within your inventory files or any other YAML file used by Ansible. Here's how you can use Ansible Vault:

  1. Create an Encrypted File:

    To create an encrypted file using Ansible Vault, use the ansible-vault create command followed by the name of the file you want to encrypt. For example:

ansible-vault create vault.yml

This command will open an editor where you can enter your sensitive data. After saving and closing the file, Ansible Vault will encrypt its contents.

  1. Edit an Encrypted File:

    To edit an existing encrypted file, use the ansible-vault edit command followed by the file name. For example:

ansible-vault edit vault.yml

This command will prompt you to enter the password you used to encrypt the file. Once authenticated, you can modify the file contents.

  1. View the Encrypted File:

    To view the contents of an encrypted file without editing it, use the ansible-vault view command followed by the file name. For example:

ansible-vault view vault.yml

This command will prompt you to enter the password, and once authenticated, it will display the decrypted contents of the file.

  1. Encrypt a File:

    If you have an existing YAML file that you want to encrypt, you can use the ansible-vault encrypt command followed by the file name. For example:

ansible-vault encrypt vault.yml

This command will encrypt the file and overwrite its contents with the encrypted version.

  1. Decrypt a File:

    To decrypt an encrypted file and revert it back to its original form, use the ansible-vault decrypt command followed by the file name. For example:

ansible-vault decrypt vault.yml

This command will decrypt the file and overwrite its contents with the decrypted version.

Note: When running playbooks or executing commands that involve encrypted files, you will be prompted to enter the vault password to access the encrypted data.

Ansible Vault provides a secure way to handle sensitive information within your Ansible inventory files, ensuring that confidential data remains protected. It's essential to keep your vault password secure and share it only with authorized individuals.

I hope you have learned something valuable today with me!

Day 57 task is complete!

90DaysOfDevOps TasksπŸ‘‡

github.com/Chaitannyaa/90DaysOfDevOps.git

Chaitannyaa Gaikwad | LinkedIn

Β