How to Use Static and Dynamic Inventories in Ansible?


Ansible is a powerful automation tool that allows you to manage and configure systems, deploy software, and orchestrate more advanced IT tasks such as continuous deployments or zero downtime rolling updates. One of the key components of Ansible is the inventory file, which describes the hosts and groups of hosts upon which commands, modules, and tasks in a playbook operate.

In this article, we'll explore how to use both static and dynamic inventories in Ansible, complete with examples and their outputs.

Static Inventories

Static inventories are the simplest way to manage and organize your servers. They are defined in INI or YAML format. Here's an example of a static inventory in INI format −

[webservers]
webserver1.example.com
webserver2.example.com

[dbservers]
dbserver1.example.com

In this example, we have two groups − webservers and dbservers. Each group contains the hostnames of the servers in that group.

You can use these groups in your playbooks to target specific servers for different tasks. For example −

- hosts: webservers
  tasks:
    - name: ensure apache is at the latest version
      ansible.builtin.yum:
        name: httpd
        state: latest

In this playbook, the task of ensuring Apache is at the latest version will only run on the servers in the webservers group.

More Static Inventory Examples

Using Variables in Static Inventory

You can define variables in your static inventory file. These variables can be used in your playbooks. Here's an example −

[webservers]
webserver1.example.com http_port=80 max_clients=200

[dbservers]
dbserver1.example.com mysql_port=3306

In this example, the http_port and max_clients variables are defined for webserver1.example.com, and the mysql_port variable is defined for dbserver1.example.com. You can use these variables in your playbooks like this −

- hosts: webservers
  tasks:
    - name: ensure apache is running on the right port
      ansible.builtin.template:
        src: /srv/httpd.j2
        dest: /etc/httpd.conf

In the httpd.j2 template file, you can use the http_port variable like this −

Listen {{ http_port }}

Using Child Groups in Static Inventory

You can also define child groups in your static inventory file. Here's an example −

[atlanta]
host1
host2

[raleigh]
host3
host4

[southeast:children]
atlanta
raleigh

In this example, atlanta and raleigh are child groups of the southeast group. You can use the southeast group in your playbooks to target all hosts in the atlanta and raleigh groups.

Using Aliases in Static Inventory

In your static inventory, you can assign aliases to your hosts. This can be useful for making your playbooks more readable. Here's an example −

[webservers]
web1 ansible_host=webserver1.example.com
web2 ansible_host=webserver2.example.com

[dbservers]
db1 ansible_host=dbserver1.example.com

In this example, web1 and web2 are aliases for webserver1.example.com and webserver2.example.com, respectively. Similarly, db1 is an alias for dbserver1.example.com. You can use these aliases in your playbooks like this −

- hosts: web1
  tasks:
    - name: ensure apache is at the latest version
      ansible.builtin.yum:
        name: httpd
        state: latest

Defining Variables in a Separate File

If you have a lot of variables, it might be cleaner to define them in a separate file. Here's how you can do it −

[webservers]
webserver1.example.com
webserver2.example.com

[dbservers]
dbserver1.example.com

Create a separate file named group_vars/webservers −

http_port: 80
max_clients: 200

In this example, the http_port and max_clients variables are defined for all hosts in the webservers group. You can use these variables in your playbooks just like before.

Dynamic Inventories

While static inventories are easy to understand and use, they can become difficult to manage as the number of servers you're managing increases. This is where dynamic inventories come in.

Dynamic inventories are scripts that dynamically generate inventory data. They are especially useful when you're working with cloud providers, where the number of servers can change frequently.

Here's an example of how you might use a dynamic inventory with AWS −

First, you'll need to install the boto library, which allows Python to interface with AWS −

pip install boto

Next, you'll need to create a script that retrieves your AWS instances. Ansible provides a script for this purpose.

You'll also need to create a configuration file for the script, which might look something like this −

[ec2]
regions = us-west-2
destination_variable = public_dns_name
vpc_destination_variable = ip_address

This configuration file tells the script to retrieve instances from the us-west-2 region and to use the public_dns_name and ip_address as the destination variables.

You can then use the script as your inventory in your playbooks −

ansible-playbook -i ec2.py playbook.yml

In this command, -i ec2.py tells Ansible to use the ec2.py script as the inventory.

More Dynamic Inventory Examples

Using Tags in AWS Dynamic Inventory

You can use tags to further filter your AWS instances in your dynamic inventory. Here's how you might do it −

First, add a tag to your AWS instances. You might add a tag named Type with a value of WebServer.

Next, modify your ec2.ini configuration file to include a tags option −

[ec2]
regions = us-west-2
destination_variable = public_dns_name
vpc_destination_variable = ip_address
tags = Type:WebServer

This configuration file will now only retrieve instances that have a Type tag with a value of WebServer.

Using Dynamic Inventory with Azure

You can also use dynamic inventory with Azure. Here's how you might do it −

First, you'll need to install the azure library −

pip install azure

Next, you'll need to create a script that retrieves your Azure VMs. Ansible provides a script for this purpose.

You'll also need to create a configuration file for the script, which might look something like this −

[azure]
subscription_id = your_subscription_id
client_id = your_client_id
secret = your_secret
tenant = your_tenant_id

You can then use the script as your inventory in your playbooks −

ansible-playbook -i azure_rm.py playbook.yml

In this command, -i azure_rm.py tells Ansible to use the azure_rm.py script as the inventory.

Using Dynamic Inventory with Google Cloud Platform (GCP)

You can also use dynamic inventory with GCP. Here's how you might do it −

First, you'll need to install the google-auth library −

pip install google-auth

Next, you'll need to create a script that retrieves your GCP instances. Ansible provides a script for this purpose.

You'll also need to create a configuration file for the script, which might look something like this −

[gce]
project = your_project_id
auth_kind = serviceaccount
service_account_file = /path/to/your/service/account/file.json

You can then use the script as your inventory in your playbooks −

ansible-playbook -i gce.py playbook.yml

In this command, -i gce.py tells Ansible to use the gce.py script as the inventory.

Using Dynamic Inventory with Docker

You can use dynamic inventory with Docker as well. Here's how you might do it −

First, you'll need to install the docker library −

pip install docker

Next, you'll need to create a script that retrieves your Docker containers. Ansible provides a script for this purpose.

You can then use the script as your inventory in your playbooks −

ansible-playbook -i docker.py playbook.yml

In this command, -i docker.py tells Ansible to use the docker.py script as the inventory.

Conclusion

Whether you choose to use static or dynamic inventories in Ansible will depend on your specific use case. Static inventories are simple and straightforward, but can become difficult to manage as the number of servers increases. Dynamic inventories, on the other hand, are more complex but can handle a large number of servers more easily, especially when those servers are hosted on a cloud provider.

Updated on: 13-Jul-2023

278 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements