Skip to the content.

Terraform Ansible Inventory

About

A high-performance, zero-dependency Go command-line tool for building complete Ansible inventories from Terraform state generated by the ansible/ansible provider.

terraform-ansible-inventory is a small Go CLI for converting Terraform state into complete Ansible inventories. The tool was created to work with the ansible/ansible Terraform provider which stores hosts, groups and variables in the state file. RedHat also provides a dynamic inventory plugin that reads Terraform state, but it cannot handle child modules and therefore misses large parts of real-world configurations. This CLI parses the state directly and fully supports nested modules so you can build inventories reliably.

To generate usable state data you must manage your inventory with the ansible/ansible provider. Once the provider has written hosts and groups into your state file, this tool can consume it and output Ansible formatted data.

Features

Installation

Clone and build from source or grab a prebuilt binary from the releases page:

# Build from source
git clone https://github.com/HilkopterBob/terraform-ansible-inventory.git
cd terraform-ansible-inventory

go build -o terraform-ansible-inventory ./main.go

# (Optional) install globally
go install github.com/HilkopterBob/terraform-ansible-inventory@latest

Download the latest release if you prefer not to build the binary yourself.

Docker image

Two container images are published on GitHub Container Registry. terraform-ansible-inventory contains only the inventory binary while the -tf tag additionally installs the latest Terraform release. Use the -tf variant when accessing remote state.

# minimal image
docker run --rm ghcr.io/HilkopterBob/terraform-ansible-inventory:latest --help

# with Terraform installed
docker run --rm ghcr.io/HilkopterBob/terraform-ansible-inventory:latest-tf terraform version

In GitLab CI you must override the image entrypoint so the pipeline script can run:

image:
  name: ghcr.io/HilkopterBob/terraform-ansible-inventory:latest
  entrypoint: [""]

generate-inventory:
  script:
    - terraform-ansible-inventory --input tf.json --format yaml > inventory.yaml

Usage

Run the executable with --help to see all options:

terraform-ansible-inventory --help

Common examples assuming your state file is state.json:

# YAML inventory
terraform-ansible-inventory -i state.json -f yaml > inventory.yml

# INI inventory
terraform-ansible-inventory -i state.json -f ini > inventory.ini

# JSON machine readable form
terraform-ansible-inventory -i state.json -f json > inventory.json

# Native Ansible inventory
terraform-ansible-inventory -i state.json -f ansible

Example HCL and Generated Inventory

Below is a small Terraform snippet demonstrating how hosts and groups are defined with the ansible/ansible provider:

resource "ansible_inventory" "default" {
  variables = {
    env = "prod"
  }
}

resource "ansible_group" "web" {
  name = "web"
  variables = {
    tier = "frontend"
  }
}

resource "ansible_host" "test1" {
  name   = "test1"
  groups = [ansible_group.web.name]
  variables = {
    ip = "192.168.1.10"
    os = "linux"
  }
}

Running the CLI against the state generated from this configuration yields:

YAML

all:
  vars:
    env: prod
  children:
    web:
      hosts:
        test1:
          ansible_host: 192.168.1.10
          os: linux
      vars:
        tier: frontend

INI

[all]

[all:vars]
env=prod

[web]
test1 ansible_host=192.168.1.10 os=linux

[web:vars]
tier=frontend

JSON

{
  "Hosts": {
    "test1": {
      "Name": "test1",
      "Variables": {
        "ip": "192.168.1.10",
        "os": "linux"
      },
      "Groups": ["web"],
      "Enabled": true,
      "Metadata": {}
    }
  },
  "Groups": {
    "web": {
      "Name": "web",
      "Variables": {"tier": "frontend"},
      "Children": null,
      "Hosts": ["test1"],
      "Parents": null
    }
  },
  "Vars": {"env": "prod"}
}

You can restrict output to specific hosts or groups using the --host and --group flags. Multiple values are allowed.

Contributing

  1. Fork & clone the repo
  2. Create a feature branch git checkout -b feature/myfeature
  3. Add tests under internal/*_test.go
  4. Ensure all tests pass
  5. Submit a PR

License

Apache-2.0 © Nick von Podewils