Phase 4: Infrastructure as Code & Cloud

Static & Dynamic Inventory

Intermediate ~2 min read
Think of it this way A friendly analogy. Read this if the technical version feels dense. Show Hide

Imagine you’re a super chef preparing a huge feast for lots of hungry guests. Before you even think about chopping vegetables or mixing batter, you need a list! You need to know exactly which dishes to prepare – like a yummy pizza, a fluffy cake, or a warm soup – and who each dish is for. This master list, which tells your cooking tools what to do and where to send the food, is super important so nothing gets forgotten. In the world of computers, this kind of list is called an "inventory," and it tells your computer programs which other computers (like different dishes) need specific tasks done.

Now, let’s think about that list. For your very first party, you might just grab a pen and paper and write down every single dish you need: "Pizza for table 1, Cake for table 2, Soup for table 3." This is like a "static inventory." It’s a simple, clear, handwritten list that you create yourself. It works perfectly if you have only a few dishes to make, or if your guest list and their food requests never ever change. You can easily look at your paper and know exactly what you need to cook.

But what happens when your party gets enormous? Suddenly, you have hundreds of guests, and new ones keep arriving, some leave early, and others change their minds about what they want to eat! It would be a nightmare trying to cross out old dishes and write in new ones on your paper list all by yourself. You'd spend all your time just updating the list, making mistakes, and getting confused, instead of actually cooking those delicious meals. Your simple handwritten list would quickly become a huge, messy problem!

This is where a "dynamic inventory" comes to the rescue, like having a super-smart chef’s assistant. Instead of you scribbling on paper, you tell your assistant: "Hey, go check our special online guest system and tell me right now what everyone wants." Your assistant instantly goes to the online system, sees all the latest guest updates, and automatically creates a brand new, perfectly accurate cooking list for you: "Okay, chef, today it’s Pizza for table 1, Cake for table 2, Soup for table 3, AND now Tacos for table 4 because three new guests just RSVP'd!" This means you always have the most up-to-date cooking instructions without lifting a finger. You can focus on preparing amazing meals, knowing your assistant keeps track of all the changing demands for dishes.

Ansible's inventory is fundamentally the list of hosts – your servers, VMs, or containers – that it will manage. It acts as the "source of truth" for where Ansible needs to run its tasks. A static inventory is the simplest form, where you manually define your hosts, their IP addresses or hostnames, and group them directly within a file. This approach is straightforward and effective for smaller, stable environments, such as a development server, a few on-premise machines with fixed IPs, or a proof-of-concept setup. You typically write these in an INI or YAML format, providing clear, human-readable definitions of your infrastructure's targets.

While simple, static inventories quickly become unwieldy and error-prone as your infrastructure grows or becomes more dynamic, especially in cloud environments where instances are frequently provisioned, de-provisioned, or scaled automatically. This is where dynamic inventory shines. Instead of a fixed file, dynamic inventory relies on a script or a plugin that queries an external source – like AWS EC2, Azure VMs, Google Cloud, VMware vSphere, or even a Configuration Management Database (CMDB) – to generate the list of hosts on-the-fly. This ensures that Ansible always has the most up-to-date view of your infrastructure, automatically including new instances and excluding terminated ones.

Embracing dynamic inventory is critical for a DevOps Engineer working with modern cloud-native architectures. It eliminates manual intervention, reduces human error, and allows Ansible playbooks to adapt seamlessly to changes in your environment, such as auto-scaling events or blue/green deployments. You'd typically use static inventory for very contained, unchanging environments, perhaps for a local Vagrant setup or specific immutable infrastructure components. For anything scalable, ephemeral, or cloud-based, dynamic inventory is the go-to solution, providing the necessary automation backbone to manage complex, distributed systems efficiently.

Key Takeaways

  • Static inventory manually defines hosts in a file, suitable for small, stable environments.
  • Dynamic inventory automatically discovers hosts via scripts/plugins, essential for scalable cloud infrastructure.
  • Dynamic inventory integrates with cloud providers (AWS, Azure, GCP), virtualization, and CMDBs.
  • Use static for simplicity in fixed setups; use dynamic for automation, scalability, and cloud environments.

Code Example

ini
[webservers]
web1.example.com
web2.example.com ansible_host=192.168.1.10

[databases]
db1.example.com

[all:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file=~/.ssh/id_rsa

How this code works

This Ansible inventory file acts as a central directory, telling Ansible which servers it can manage and how to communicate with them. It organizes hosts into logical groups, enabling targeted operations. The [webservers] and [databases] sections define these groups, listing individual servers like web1.example.com and db1.example.com. For web2.example.com, the ansible_host variable explicitly tells Ansible to connect to a specific IP address (192.168.1.10) instead of relying on the hostname's default DNS resolution. This flexibility is key when hostnames aren't directly routable or need specific IP mapping.

The [all:vars] section establishes global connection parameters that apply to every host listed in this inventory. ansible_user=ubuntu specifies the username for SSH connections, while ansible_ssh_private_key_file points to the authentication key. A subtle but crucial point is Ansible's connection behavior: if ansible_host is present for a host, Ansible prioritizes that specified IP address for the connection, effectively overriding any attempt to resolve the declared hostname. If ansible_host is absent, Ansible will connect directly to the hostname, expecting it to be resolvable via DNS or /etc/hosts.