šŸ¶
Terraform

Create Ansible Inventory from Terraform: Best Methods in 2023

By Filip on 10/07/2024

Learn the most effective methods for dynamically generating Ansible inventories from your Terraform infrastructure, enabling seamless provisioning and configuration management.

Create Ansible Inventory from Terraform: Best Methods in 2023

Table of Contents

Introduction

This guide outlines how to dynamically generate Ansible inventory files using Terraform, ensuring your inventory stays up-to-date with your infrastructure. We'll use the local_file resource and the templatefile function to achieve this.

Step-by-Step Guide

To dynamically generate Ansible inventory files using Terraform, you can leverage the local_file resource and the templatefile function. This approach allows you to create and update your inventory based on the resources provisioned by Terraform.

  1. Gather Information from Terraform:

    • Utilize Terraform outputs or data sources to retrieve the necessary information about your infrastructure, such as IP addresses, hostnames, or any other relevant details.
  2. Create an Ansible Inventory Template:

    • Design a template file (e.g., inventory.tpl) that defines the structure of your Ansible inventory.
    • Use template variables (e.g., ${var.instance_ips}) to represent the dynamic values you'll fetch from Terraform.
  3. Utilize templatefile Function:

    • Within your Terraform configuration, employ the templatefile function to populate the template with data from Terraform.
    • Pass the gathered information as arguments to the templatefile function.
  4. Define local_file Resource:

    • Use the local_file resource to create the actual inventory file.
    • Set the content attribute to the output of the templatefile function.
    • Specify the desired filename and path for your inventory file.
  5. Establish Dependencies:

    • Ensure that the local_file resource depends on the Terraform resources providing the dynamic data. This guarantees that the inventory file is generated after the infrastructure is provisioned.

Example:

resource "local_file" "ansible_inventory" {
  content = templatefile("${path.module}/inventory.tpl", {
    instance_ips = module.ec2_instance.public_ip
  })
  filename = "./inventory.ini"
  depends_on = [module.ec2_instance]
}

Template (inventory.tpl):

[webservers]
${instance_ips}

This setup generates an Ansible inventory file named inventory.ini with a group called "webservers" containing the public IP addresses of the EC2 instances provisioned by the ec2_instance module.

Remember to adapt the template and variable names according to your specific infrastructure and desired inventory structure.

Code Example

This Terraform code provisions an Azure virtual machine and dynamically generates an Ansible inventory file. It uses a template file to define the inventory structure and populates it with the virtual machine's hostname and IP address. The generated inventory file can then be used by Ansible to manage the provisioned virtual machine.

main.tf:

# Configure the Azure Provider
terraform {
  required_providers {
    azurerm = {
      source  = "hashicorp/azurerm"
      version = "~> 3.0"
    }
  }
}

provider "azurerm" {
  features {}
}

# Configure the Azure Resource Group
resource "azurerm_resource_group" "example" {
  name     = "ansible_inventory_rg"
  location = "West Europe"
}

# Configure the Azure Virtual Network
resource "azurerm_virtual_network" "example" {
  name                = "ansible_inventory_vnet"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  address_space       = ["10.0.0.0/16"]
}

# Configure the Azure Subnet
resource "azurerm_subnet" "example" {
  name                 = "internal"
  resource_group_name  = azurerm_resource_group.example.name
  virtual_network_name = azurerm_virtual_network.example.name
  address_prefixes     = ["10.0.2.0/24"]
}

# Configure the Azure Network Interface
resource "azurerm_network_interface" "example" {
  name                = "ansible_inventory_nic"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location
  ip_configuration {
    name                          = "internal"
    subnet_id                     = azurerm_subnet.example.id
    private_ip_address_allocation = "Dynamic"
  }
}

# Configure the Azure Linux Virtual Machine
resource "azurerm_linux_virtual_machine" "example" {
  name                            = "ansible_inventory_vm"
  resource_group_name             = azurerm_resource_group.example.name
  location                        = azurerm_resource_group.example.location
  size                            = "Standard_B2ms"
  network_interface_ids           = [azurerm_network_interface.example.id]
  os_disk {
    caching              = "ReadWrite"
    storage_account_type = "Standard_LRS"
  }
  source_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "18.04-LTS"
    version   = "latest"
  }
}

# Dynamically generate Ansible inventory file
resource "local_file" "ansible_inventory" {
  content = templatefile("${path.module}/inventory.tpl",
    {
      webservers = azurerm_linux_virtual_machine.example.name,
      ip_address = azurerm_linux_virtual_machine.example.private_ip_address
  })
  filename = "./inventory.ini"
  depends_on = [
    azurerm_linux_virtual_machine.example
  ]
}

inventory.tpl:

[webservers]
${webservers} ansible_host=${ip_address}

Explanation:

  1. Gather Information: This example uses Azure resources to demonstrate the concept. It provisions a Linux VM and retrieves its private IP address and hostname.

  2. Template: The inventory.tpl file defines the structure of the Ansible inventory. It uses template variables ${webservers} and ${ip_address} to represent the dynamic values.

  3. templatefile Function: The templatefile function populates the inventory.tpl template with data from the Azure VM resource.

  4. local_file Resource: The local_file resource creates the inventory.ini file. Its content is set to the output of the templatefile function.

  5. Dependencies: The depends_on meta-argument ensures that the local_file resource is executed after the Azure VM is fully provisioned.

This setup generates an Ansible inventory file named inventory.ini with a group called "webservers" containing the private IP address and hostname of the provisioned Azure VM. You can adapt this example to your specific cloud provider and infrastructure setup.

Additional Notes

General Considerations:

  • Inventory Structure: The provided examples use a simple inventory structure. For complex scenarios with multiple environments, groups, and variables, consider using more advanced templating techniques and data structures in Terraform.
  • Alternative Templating: While templatefile is commonly used, you can explore other templating tools like consul-template or dedicated configuration management systems if your requirements become more intricate.
  • Security: Avoid storing sensitive information like passwords directly in your inventory files. Utilize Ansible Vault or dedicated secret management solutions for handling such data securely.
  • State Management: Remember that Terraform manages the lifecycle of the inventory file. Any manual changes to the generated file might be overwritten in subsequent Terraform runs.

Best Practices:

  • Modularity: Structure your Terraform code in modules to promote reusability and maintainability, especially for larger infrastructures.
  • Version Control: Keep your Terraform code, including inventory templates, in version control to track changes and collaborate effectively.
  • Testing: Implement automated tests to validate your infrastructure code and ensure the generated inventory files are accurate and consistent.

Beyond the Basics:

  • Dynamic Inventory Scripts: For more complex scenarios, explore creating dynamic inventory scripts that fetch data from external sources like cloud APIs or CMDBs.
  • Integration with Configuration Management: Combine Terraform-generated inventories with configuration management tools like Ansible, Chef, or Puppet to automate the provisioning and configuration of your infrastructure.

By following these notes and best practices, you can effectively leverage Terraform and Ansible together to manage your infrastructure as code in a scalable and maintainable manner.

Summary

This approach uses Terraform to generate Ansible inventory files dynamically, ensuring they stay updated with your infrastructure.

Steps:

Step Description
1. Gather Information Collect infrastructure details (IP addresses, hostnames) from Terraform outputs or data sources.
2. Create Template Design an Ansible inventory template file (e.g., inventory.tpl) with placeholders (template variables) for dynamic values.
3. Populate Template Use Terraform's templatefile function to fill the template with data gathered in step 1.
4. Create Inventory File Employ the local_file resource to generate the final inventory file. Set its content to the output of templatefile.
5. Manage Dependencies Make the local_file resource depend on the resources providing the dynamic data to ensure proper generation order.

Key Points:

  • Flexibility: Easily adapt the template and variables to match your infrastructure and desired inventory structure.
  • Automation: Inventory updates automatically as your infrastructure changes through Terraform.
  • Efficiency: Eliminates manual inventory management, reducing errors and saving time.

Conclusion

This approach simplifies the management of Ansible inventories by automating their creation and updates in sync with your Terraform-managed infrastructure, ultimately leading to more efficient and less error-prone infrastructure management. By combining the power of Terraform and Ansible, you can achieve robust and scalable infrastructure provisioning and configuration management. However, always consider security best practices and explore advanced techniques like dynamic inventory scripts and integration with configuration management tools for more complex scenarios. Remember to prioritize modularity, version control, and testing for maintainable and reliable infrastructure code.

References

  • Generate Ansible inventory file via Terraform. : r/Terraform Generate Ansible inventory file via Terraform. : r/Terraform | Posted by u/pleegor - 9 votes and 13 comments
  • How to Generate an Ansible Inventory with Terraform How to Generate an Ansible Inventory with Terraform | Creating and maintaining an inventory file is one of the common tasks we have to deal with when working with Ansible. When dealing with a large number of hosts, it can be complex to handle this task manually. There are some plugins available to automatically generate inventory files by interacting with most cloud providersā€™ APIs. [ā€¦]
  • terraform apply --> Ansible inventory : r/Terraform terraform apply --> Ansible inventory : r/Terraform | Posted by u/j0rmun64nd - 2 votes and 7 comments
  • Terraform to dynamically produce ansible inventory - Terraform ... Terraform to dynamically produce ansible inventory - Terraform ... | Hi , I am trying to use terraform to create an ansible inventory file dynamically. I have a terraform module which creates couple of ec2 instances using for_each. Then I am using the following code to create the inventory resource "local_file" "hosts_cfg" { content = templatefile("${path.module}/templates/hosts.tpl", { wg_clients = values(module.ec2_instance)[*].public_ip } ) filename = "./ansible/inventory/hosts.cfg" depends_on = [ module.ec2_instance ] } My template ...
  • How to use Ansible with Terraform | There is no magic here How to use Ansible with Terraform | There is no magic here | Mar 9, 2018 ... In a matter of a few days, I went from ā€œnever used AWSā€ to the ā€œI have a declarative way to create an isolated infrastructure in the cloudā€. I'mĀ ...
  • Terraform Template - create ansible inventory - Filter Hostname ... Terraform Template - create ansible inventory - Filter Hostname ... | Hello, Can anyone give me a tip? I am creating an inventory file for Ansible using Terraform and would like to filter out a specific hostname. Instances that have ā€œansibleā€ in their name should not end up in the list. main.tf: ... resource "local_file" "ansible_inventory" { depends_on = [module.openstack-instances] filename = "../Ansible/inventory.ini" content = templatefile("./ansible_inventory.tpl", { instances = module.openstack-instances.instance_info }) } ansible_invento...
  • AWX Terraform state integration - Get Help - Ansible AWX Terraform state integration - Get Help - Ansible | Hi, has anyone thought of a good way to integrate state management for terraform deployments into AWX? I am wondering how I can enable a secure seperation between teams while keeping state storage centralized so not every team needs to think about state-storage themselves. But I am failing to come up with a decent scenario that covers my security concerns. Greetings Klaas
  • Managing state when creating infrastructure with both Terraform and ... Managing state when creating infrastructure with both Terraform and ... | Iā€™ve got a handful of ā€œpureā€ ansible projects that run on Jenkins CI to fully manage (create and provision) elements of our SW Dev infrastructure which currently resides in an on-prem vSphere datacenter. Eventually I plan to migrate these projects to Terraform, as we improve and scale our infrastructure. The kind of infrastructure Iā€™m talking about here is Jenkins clusters, artifact management systems, individual development environments, server and serverless file shares for various caching an...
  • Proxmox with Terraform and Ansible | Proxmox Support Forum Proxmox with Terraform and Ansible | Proxmox Support Forum | Hi. Im trying to use Terraform to build VMs on proxmox and config them with Ansible. Does someone have a sample code or playbooks for ansible. I have some stuggels getting everything together. Hopefully someone can help me.

Were You Able to Follow the Instructions?

šŸ˜Love it!
šŸ˜ŠYes
šŸ˜Meh-gical
šŸ˜žNo
šŸ¤®Clickbait