Over the flows

personal space about software engineering


Inspect dynamic Ansible AWS inventory

The inventory in ansible helps identify machines that need to be updated. The inventory can be dynamic. This is the case that will interest us. In this case, it’s hard to figure out what inventory ansible actually made. ansible-inventory allows us to inspect the inventory that ansible loaded and saves us from wasting time guessing which group and which machines ansible has referenced.

The aws_ec2 plugin builds the inventory from the metadata it finds on an AWS account.

To use it, we have to configure aws_ec2 plugin as an inventory file.

ansible -i aws_ec2.yml --list-hosts all
  hosts (2):
    ec2-52-XX-XX-25.eu-west-1.compute.amazonaws.com
    ec2-52-XX-XX-48.eu-west-1.compute.amazonaws.com

Then the error happens

It all starts with this warning … This error message is generated when ansible cannot find a match between groups and hosts referenced in the inventory.

[WARNING]: Could not match supplied host pattern

Usually, this error message happens when we are running this command.

ansible-playbook -i aws_ec2.yml deploy.yml
[WARNING]: Could not match supplied host pattern, ignoring: farcellier.com

PLAY [farcellier.com] *******************************************************************************************
skipping: no hosts matched

Yesterday, I wasted an hour trying to figure out why ansible couldn’t find the farcellier.com group in the inventory when it should have been there. It would have saved time if I had a technical how-to to inspect the inventory. I would have seen that the farcellier.com group was renamed to farcellier_com.

Inspect inventory

The ansible-inventory command allows you to inspect the inventory as ansible sees it. It’s a release to be able to see what ansible is interpreting instead of trying to guess.

ansible-inventory -i aws_ec2.yml --graph
@all:
  |--@aws_ec2:
  |  |--ec2-52-XX-XX-25.eu-west-1.compute.amazonaws.com
  |  |--ec2-52-XX-XX-48.eu-west-1.compute.amazonaws.com
  |--@other_website:
  |  |--ec2-52-XX-XX-25.eu-west-1.compute.amazonaws.com
  |--@farcellier_com:
  |  |--ec2-52-XX-XX-48.eu-west-1.compute.amazonaws.com
  |--@ungrouped:

The solution is before our eyes. Ansible renames the farcellier.com tag to farcellier_com.

Inspect inventory deeply

The ansible-inventory command allows you to see even more. It is able to trace all the variables captured at the host level. This is handy for improving the AWS inventory definition file.

ansible-inventory -i aws_ec2.yml --list

I’ve posted a snippet of all the variables that are fetched.

{
  "_meta": {
    "hostvars": {
      "ec2-52-XX-XX-25.eu-west-1.compute.amazonaws.com": {
        "ami_launch_index": 0,
        "ansible_host": "ec2-52-XX-XX-25.eu-west-1.compute.amazonaws.com",
        "architecture": "x86_64"
      },
      "ec2-52-XX-XX-48.eu-west-1.compute.amazonaws.com": {
        "ami_launch_index": 0,
        "ansible_host": "ec2-52-XX-XX-48.eu-west-1.compute.amazonaws.com",
        "architecture": "x86_64"
      }
    }
  },
  "all": {
    "children": [
      "aws_ec2",
      "other_website",
      "farcellier_com",
      "ungrouped"
    ]
  },
  "aws_ec2": {
    "hosts": [
      "ec2-52-XX-XX-25.eu-west-1.compute.amazonaws.com",
      "ec2-52-XX-XX-48.eu-west-1.compute.amazonaws.com"
    ]
  },
  "other_website": {
    "hosts": [
      "ec2-52-XX-XX-48.eu-west-1.compute.amazonaws.com"
    ]
  },
  "farcellier_com": {
    "hosts": [
      "ec2-52-XX-XX-25.eu-west-1.compute.amazonaws.com"
    ]
  }
}

References

Ansible AWS inventory used in this blog post

For reference, I share the inventory I used. It selects machines in the eu-west-1 region, groups them from the Name tag.

aws_ec2.yml

---
plugin: aws_ec2

regions:
  - eu-west-1

filters:
  # All instances with their state as `running`
  instance-state-name: running

keyed_groups:
 - key: tags.Name
   separator: ''
   prefix: ''

compose:
    ansible_host: public_dns_name