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.
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}
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
Pour multi severs:
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"
}
[kube-master]
${k8s_master_name}
résultat final
[kube-master]
k8s-master-01
k8s-master-02
k8s-master-03
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.