Best way currently to create an ansible inventory

2019-03-16 00:31发布

问题:

I have a long list of machines, all of which are a little different in functionality in a system. I'd like to organize these machines and add to a hosts inventory file automatically so I can run ansible and manage inventory. Are there good solutions out there for this?

I think ansible hosts should looks something like...

[webservers]
someip
someip
[integration]
someip
someip

etc..

After asking the question, I currently am researching output vars and using those to render a template from a file.

回答1:

I figured it out.

data "template_file" "dev_hosts" {
  template = "${file("${path.module}/templates/dev_hosts.cfg")}"
  depends_on = [
    "aws_instance.dev-api-gateway",
    "aws_instance.dev-api-gateway-internal",
    ....
  ]
  vars {
    api_public = "${aws_instance.dev-api-gateway.private_ip}"
    api_internal = "${aws_instance.dev-api-gateway-internal.private_ip}"
  }
}

resource "null_resource" "dev-hosts" {
  triggers {
    template_rendered = "${data.template_file.dev_hosts.rendered}"
  }
  provisioner "local-exec" {
    command = "echo '${data.template_file.dev_hosts.rendered}' > dev_hosts"
  }
}

Then create a template in the file referenced earlier

Contents of example dev_hosts.cfg

[public]
${api_public}


[private]
${api_internal}


回答2:

Our approach is slightly different. We define a Terraform Module (terraform-null-ansible) which calls ansible anytime we want to run a playbook on a host by using a dynamic inventory.

https://github.com/cloudposse/terraform-null-ansible

This is a very terraform-centric approach but leads to very clean integration. Plus, by calculating the checksum of the playbook, we only call the ansible provisioner when the playbook has changed.

Usage is quite easy:

module "web_provisioner" {
   source    = "git::https://github.com/cloudposse/terraform-null-ansible.git?ref=tags/0.3.8"

   arguments = ["--user=ubuntu"]
   envs      = ["host=${aws_instance.web.public_ip}"]
   playbook  = "../ansible/playbooks/test.yml"
   dry_run   = false
}

More docs are on the GitHub README.md



回答3:

My approach: from template to inventory file, use template_file to render the content and use local_file to output a file.

template file:

## file inventory.tpl

[frontend]
${bastion_pub_ip}

[all:vars]
ansible_ssh_private_key_file = ${key_path}
ansible_ssh_user = ubuntu

render and output:

## file inventory.tf

data "template_file" "inventory" {
    template = "${file("./test/inventory.tpl")}"

    vars {
       bastion_pub_ip = "${element(azurerm_public_ip.bastion.*.ip_address, count.index)}"
       key_path = "~/.ssh/id_rsa"
    }
}

resource "local_file" "save_inventory" {
  content  = "${data.template_file.inventory.rendered}"
  filename = "./myhost"
}

It works for single server, if you have a list, I don't find a proper way to do it.