mschuchard / terraform-local-ansible-inv

Terraform module for dynamically generating a variety of Ansible inventories

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

terraform-local-ansible-inv

terraform-local-ansible-inv is a Terraform module for converting objects representing instances and their attributes into dynamically configured Ansible inventories suitable for ingestion by Ansible. In an immutable infrastructure pipeline, the infrastructure provisioning performed by Terraform is typically followed by per-instance customization by Ansible from the standardized image artifact created by Packer. This module facilitates a brokering of information between Terraform and Ansible in that process.

Usage

Typically you would want to map the Terraform outputs and/or exported attributes to input arguments in the module declarations. This will enable automatic inventory generation based on the changing state of your infrastructure.

# example declaration
module "ansible_inv" {
  source  = "mschuchard/ansible-inv/local"
  version = "~> 1.3.0"

  formats   = ["yaml"]
  instances = {
    "my_group" = {
      children = []
      hosts = [
        {
          name = "localhost"
          ip   = "127.0.0.1"
          vars = { "ansible_connection" = "local", "foo" = "bar" }
        },
        {
          name = "also_localhost"
          ip   = "127.0.0.1"
          vars = { "ansible_connection" = "local", "baz" = "bat" }
        }
      ]
    },
    "other_group" = {
      children = ["my_group"]
      hosts = [
        {
          name = instance.this.hostname
          ip   = instance.this.ip
          vars = instance.this.tags
        }
      ]
    }
  }
  group_vars = {
    "my_group" = { "number" = 1 },
    "all"      = { "terraform" = true }
  }
}

The module manages the inventory files at the location ${path.root}/<prefix>inventory.<format>. It also assigns the inventory content to the respective <format> module output.

This module also supports direct mapping of provider-specific resource objects to module arguments. For example: the following config would automatically create a single inventory with your custom defined instances, and your platform provider instances.

resource "aws_instance" "this" {
  for_each = var.my_instances_aws
  ...
}

resource "google_compute_instance" "this" {
  for_each = var.my_instances_gcp
  ...
}

resource "azurerm_linux_virtual_machine" "this" {
  for_each = var.my_instances_azr
  ...
}

resource "vsphere_virtual_machine" "this" {
  for_each = var.my_instances_vsp
  ...
}

module "ansible_inv" {
  source = "mschuchard/ansible-inv/local"

  formats       = ["json", "ini"]
  instances     = local.instances
  instances_aws = aws_instance.this
  instances_gcp = google_compute_instance.this
  instances_azr = azurerm_linux_virtual_machine.this
  instances_vsp = vsphere_virtual_machine.this
  group_vars    = {
    "aws" = { "platform" = "aws" },
    "vsp" = { "on_prem" = true }
  }
  extra_hostvars = {
    aws = {
      "my_aws_instance" = { "environment" = "production" }
    }
    gcp = {}
    azr = {
      "my_azr_instance" = { "datacenter" = "east" }
    }
    vsp = {}
  }
}

Note also that correspondingly named groups will automatically be created for each platform as children of the all group, and the groups will also contain all of the specified instances as hosts. For example, all of the AWS instances will automatically be placed in a child aws group within the all group.

AWS

In this situation the ansible_host will be set to the instance private IP address. The host entry key will be set to the Name tag, and will default to the instance id otherwise. The instance tags will also propagate as key value pairs for the host variables. If an exported attribute for password_data is found, then the ansible_transport will be set to winrm for the host.

GCP

The ansible_host will be set to the instance private IP address as determined by the network_config attribute. The host entry key will be set to the name argument.

The tags will propagate as key value pairs for the host variables. This is determined by the existence of exactly two groups of characters in each tag that match the pattern [-\w]+. If these exist in the tag, then it will be converted to a host variable key value pair. Otherwise, the tag will be ignored. Example of converted tags include:

name=myhost
ansible_connection winrm
foo:bar

The labels and metadata will also propagate as key value pairs for the host variables.

Azure

In this situation the ansible_host will be set to the instance primary private IP address. The host entry key will be set to the name argument. The ansible_become_user will be set to the username of the admin_ssh_key block if it exists; otherwise it will be set to the admin_username argument. The instance tags will also propagate as key value pairs for the host variables. If the string Windows is found in the value for the offer argument in the source_image_reference block, then the ansible_transport will be set to winrm for the host.

VSphere

The ansible_host will be set to the default_ip_address attribute (the primary reachable IP address as determined by VSphere). The host entry will be set to the name argument. The ansible_become_user will be set to the full_name of the windows_options block of the customize block of the clone block if it exists. The properties map from vapp will propagate as key value pairs for the host variables. If the block windows_options is found in the customize block in the clone block, then the ansible_transport will be set to winrm for the host.

Requirements

Name Version
terraform ~> 1.0
local ~> 2.0

Providers

None

Modules

No modules.

Resources

Name Type
local_file.ansible_inventory resource

Inputs

Name Description Type Default Required
extra_hostvars An object comprising additional host variables to append to the variables automatically derived from the directly mapped provider instances' attributes. The format of the maps for each provider platform key should be key=HOST value={VARNAME = VARVALUE}.
object({
aws = map(map(string))
gcp = map(map(string))
azr = map(map(string))
vsp = map(map(string))
})
{
"aws": {},
"azr": {},
"gcp": {},
"vsp": {}
}
no
formats The set of formats in which to output the Ansible inventory. Supported formats are: 'ini', 'yaml', and 'json'. set(string) [] no
group_vars The map of Ansible group variables. Each key in the map is the name of a group (this includes support for the 'all' group), and each value is the object representing the pairs of group variable names and values. map(any) {} no
instances The instances and their attributes used to populate the Ansible inventory file. The map keys will be used to construct Ansible inventory groups with the paired 'hosts' object values as the group host members.
map(object({
children = set(string)
hosts = set(
object({
name = string
ip = string
vars = map(string)
})
)
}))
{} no
instances_aws The 'aws_instance.this' map of objects comprising multiple instances to populate the Ansible inventory file. any {} no
instances_azr The 'azurerm_linux|windows_virtual_machine.this' map of objects comprising multiple instances to populate the Ansible inventory file. any {} no
instances_gcp The 'google_compute_instance.this' map of objects comprising multiple instances to populate the Ansible inventory file. any {} no
instances_vsp The 'vsphere_virtual_machine.this' map of objects comprising multiple instances to populate the Ansible inventory file. any {} no
inv_file_perms The file permissions octal mode for the output Ansible inventory file(s). string "0644" no
manage_file Whether or not to manage a local file per inventory format with the content of each inventory. If this is set to false, then the inventory content will only be available from the Terraform outputs. bool true no
prefix A prefix to prepend to the name of the output inventory files. For example: the INI inventory will be named 'PREFIXinventory.ini'. This is primarily useful for unique naming schemes between module declarations. string "" no

Outputs

Name Description
ini The Ansible INI format inventory content.
inv_files The list of inventory file output paths.
json The Ansible JSON format inventory content.
yaml The Ansible YAML format inventory content.

About

Terraform module for dynamically generating a variety of Ansible inventories

License:MIT License


Languages

Language:HCL 83.7%Language:Go 16.3%