web-dev-qa-db-fra.com

Meilleur moyen actuellement de créer un inventaire ansible à partir de terraform

J'ai une longue liste de machines, qui sont toutes un peu différentes dans la fonctionnalité d'un système. Je voudrais organiser ces machines et les ajouter automatiquement à un fichier d'inventaire d'hôtes afin de pouvoir exécuter ansible et gérer l'inventaire. Existe-t-il de bonnes solutions pour cela?

Je pense que les hôtes ansibles devraient ressembler à quelque chose comme ...

[webservers]
someip
someip
[integration]
someip
someip

etc..

Après avoir posé la question, je fais actuellement des recherches sur les variables de sortie et les utilise pour rendre un modèle à partir d'un fichier.

16
DrM

Je l'ai compris.

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"
  }
}

Créez ensuite un modèle dans le fichier référencé précédemment

Contenu de l'exemple dev_hosts.cfg

[public]
${api_public}


[private]
${api_internal}
19
DrM

Notre approche est légèrement différente. Nous définissons un module Terraform (terraform-null-ansible) qui appelle ansible chaque fois que nous voulons exécuter un playbook sur un hôte en utilisant un inventaire dynamique.

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

Il s'agit d'une approche très terraform-centric mais conduit à une intégration très propre. De plus, en calculant la somme de contrôle du playbook, nous n'appelons le provisionneur ansible que lorsque le playbook a changé.

L'utilisation est assez simple:

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
}

Plus de documents sont sur le GitHub README.md

10
Erik Osterman

Pour multi severs:

Inventaire du fichier.tf

data  "template_file" "k8s" {
    template = "${file("./templates/k8s.tpl")}"
    vars {
        k8s_master_name = "${join("\n", azurerm_virtual_machine.k8s-master.*.name)}"
    }
}

resource "local_file" "k8s_file" {
  content  = "${data.template_file.k8s.rendered}"
  filename = "./inventory/k8s-Host"
}

Fichier k8s.tpl

[kube-master]
${k8s_master_name}

résultat final

[kube-master]
k8s-master-01
k8s-master-02
k8s-master-03
1
Roy Zeng

Mon approche: du modèle au fichier d'inventaire, utilisez template_file pour restituer le contenu et utilisez local_file pour sortir un fichier.

fichier modèle:

## file inventory.tpl

[frontend]
${bastion_pub_ip}

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

rendu et sortie:

## 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"
}

Cela fonctionne pour un seul serveur, si vous avez une liste, je ne trouve pas un moyen approprié de le faire.

1
Roy Zeng