As a full-stack developer, managing servers and infrastructure is an important part of the job. Ansible is a powerful infrastructure automation tool that allows you to configure and manage servers declaratively using playbooks.

A key component of Ansible is the inventory – a list of servers that Ansible knows about. By default, Ansible uses an INI-style inventory file. However, the inventory can also be specified in JSON format, which offers some key advantages.

In this comprehensive guide, we will look at how to build an Ansible inventory file in JSON format, including:

  • Benefits of the JSON inventory format
  • JSON inventory structure and syntax
  • Organizing complex inventories
  • Integrating with dynamic sources
  • Managing changes with version control
  • Variables precedence and override behavior
  • Key takeaways and adopting recommendations

So let‘s get started on building robust JSON-based inventories for Ansible automation.

Why Choose the JSON Inventory Format?

Before diving into syntax and structure, it‘s worth highlighting some of the key benefits of using a JSON inventory file:

  • Human readable: JSON is easy for both humans and machines to read and parse
  • Structural flexibility: Supports more complex data structures to accurately model your infrastructure
  • Dynamic integration: Integrates seamlessly with dynamic inventory sources and external JSON APIs
  • Version control: JSON plays nicer with source control vs INI format
  • Infrastructure as code: Fits modern infrastructure as code workflows and tooling

Additionally, some benchmarks have found the JSON parser in Ansible to be upto 5x faster than the INI parser, allowing faster execution.

So in summary, the JSON inventory format brings improved performance, accuracy, portability and flexibility compared to the older INI format. It is the recommended approach for modeling infrastructure as you scale your Ansible usage.

JSON Inventory Structure and Syntax

Now that we know the benefits, let‘s jump into the syntax and structure for building JSON Ansible inventories:

{

  "all": {
    "hosts": {
      "host1": null
    },
    "vars": {

    },
    "children": {
      "group1": {
        "hosts": {
          "host2": null
        }  
      }
    }
  } 

} 

The inventory follows basic JSON syntax, with the root node being the "all" group. Within "all", common keys are:

  • hosts: Where you list individual hosts
  • children: Logical groups of hosts
  • vars: Global variables

Hosts and groups have a consistent structure like:

"webservers": {
  "hosts": {

  },
  "vars": {

  } 
}

Defining "vars" per group allows setting group-specific variables.

Now that we‘ve covered the basic structure, let‘s walk through more real-world examples…

Organizing Complex Inventories

For simple inventories, directly listing hosts and children under "all" works fine.

But as you scale, best practice is to logically organize more complex inventories.

For example, hosts and groups can be segmented by different environments or regions:

{
  "production": {
    "usa": {
      "children": {

      }
    }
  },
  "staging": {

  } 
}

Here the top level separates production vs staging environments. Within production, groups are broken down by USA and Europe regions.

Benefits include:

  • Easier to understand structure
  • Changes limited to environment or region
  • Matches actual infrastructure topology

Additional levels can be added for datacenters, availability zones, roles, etc. Make your inventory model the real-world infrastructure as much as possible.

Integrating with Dynamic Sources

The JSON inventory also supports integrating dynamic inventory sources:

{
  "_meta": {
    "hostvars": {
      "host1": {
        "ansible_host": "1.2.3.4"  
      }
    }
  },

  "all": {
    "children": [
      "production"
    ]
  }
}

The _meta node comes from the dynamic source, providing a map of hosts and attributes like ansible_host per host.

This allows incorporating infrastructure details from:

  • Cloud providers (AWS, GCP, Azure, etc)
  • CMDB systems
  • External JSON files

So JSON inventory provides flexibility to integrate Ansible with broader infrastructure tooling and sources.

Managing Changes with Version Control

Since JSON inventory is code, standard version control and change management techniques apply:

  • Store inventory in source control (Git, SVN etc)
  • Maintain branches for production vs staging
  • Use pull requests and peer reviews for changes
  • Audit history and roll back if needed

This brings discipline around inventory changes. Only approved, reviewed changes get applied.

Compare this to INI format, where changes canhappen ad hoc without rigor or history.

So JSON enables infrastructure as code best practices for your inventory.

Understanding Variable Precedence

A key concept in Ansible is variable precedence across different scopes.

For example, say we define variables at different levels:

{

  "all": {
    "vars": {
      "example_var": "global"  
    },

    "children": {
      "webservers": { 
        "vars": {
          "example_var": "group"
        },
        "hosts": {
          "host1": {
            "example_var": "host"  
          }
        }  
      }
    }
  }

}

Here example_var is defined globally, for a group, and for a host. Which value will apply for host1?

Ansible variable precedence rules specify:

1. Host vars
2. Group vars
3. Global vars

So for host1, it will use its own host value for example_var.

To illustrate:

host1 # example_var = "host" 
host2 # example_var = "group"
host3 # example_var = "global"

Understanding this precedence logic is key for defining and overriding variables across hosts.

Key Takeaways and Recommendations

We‘ve covered a lot of ground around modeling infrastructure using Ansible JSON inventory files. Here are some key takeaways:

  • JSON syntax provides flexibility to capture infrastructure complexity
  • Logically organize using regions, environments, roles etc
  • Integrate external data sources for latest infrastructure state
  • Put inventory under source control for reviewed changes & auditing
  • Override variables from global -> group -> host levels

Here are some recommendations as you adopt JSON inventory:

  • Start simple, directly listing hosts/groups under "all"
  • Build up gradually as complexity increases
  • Document structure using comments for longer inventories
  • Use external data to avoid manual changes

The time invested in a well-structured inventory pays dividends through more accurate, automated Ansible workflows.

Conclusion

JSON inventory brings order and consistency to managing infrastructure state for Ansible automation. With its flexibility, portability across environments, and support for infrastructure as code practices, the JSON inventory format is recommended over INI as a best practice.

This guide provided a comprehensive overview of JSON syntax, organization approaches, integrating external data, version control practices and variable precedence specifics to be aware of.

Putting these recommendations into practice will ensure your Ansible inventory remains accurate and manageable as your infrastructure grows. So leverage JSON format to build robust foundations for automation using Ansible playbooks.

Similar Posts