I am trying to create a file with the public_ip addresses to use with ansible. So, I am looking to create a file to look like:
[server-type]
10.0.0.2
10.0.0.3
10.0.0.4
…
Is there a way to do this in terraform?
I am trying to create a file with the public_ip addresses to use with ansible. So, I am looking to create a file to look like:
[server-type]
10.0.0.2
10.0.0.3
10.0.0.4
…
Is there a way to do this in terraform?
Will your list of IPs change? Is this something you’ll want to do dynamically? I have actually done this using bash but I have a set list of instances.
I use bash to set env variables out of terraform outputs then SED a hosts file to replace placeholders with my env variables. Below is an example. hope this helps. I can provide more detail if needed.
# Create variables from Terraform output
echo "Generate env variables"
export INSTANCE_IP=$(terraform output instance_ip)
# SED Ansible hosts file
echo "SED hosts file"
sed -i'.original' -e "s/INSTANCE_IP/$INSTANCE_IP/g" hosts.txt
Now that I’m posting I bet you could do something similar by doing the SED command via local-exec. Then you can use interpolation to replace your placeholder with whatever the value is for your IP.
Look at the for-loop examples in the string template documentation
And use it to populate a local_file resource
Also this looks just about perfect.
Update: I was able to make it work with one IP. I imagine combining a for loop could get you the rest of the way. Hope this helps.
data "template_file" "init" {
template = file("hosts.tmpl")
vars = {
digitalocean_address = digitalocean_droplet.host.ipv4_address
}
}
resource "null_resource" "export_rendered_template" {
provisioner "local-exec" {
command = "cat > test_output.json <<EOL\n${join(",\n", data.template_file.init.*.rendered)}\nEOL"
}
}
starting template: hosts.tmpl
digitalocean ansible_ssh_host=${digitalocean_address}
ending rendered file: test_output.json
digitalocean ansible_ssh_host=167.99.225.2
Credits: https://blog.aurynn.com/2017/2/23-fun-with-terraform-template-rendering
So, In my template I have the following template and null_resource. I get the following error. Error: failed to render : <template_file>:1,14-24: Iteration over non-iterable value; A value of type string cannot be used as the collection in a ‘for’ expression.
data “template_file” “init” {
template = file("${path.module}/templates/test.tmpl")
count = length(aws_instance.web)
vars = {
public_ips = aws_instance.web[count.index].public_ip
}
}
resource “null_resource” “ansible_template” {
provisioner “local-exec” {
command = “cat > hosts <<EOL\n${data.template_file.init.*.rendered}\nEOL”
}
test.tmpl
locals {
ips = ["127.0.0.1","10.0.0.1","192.168.0.1","172.16.0.1"]
}
resource "local_file" "ip_list" {
filename = "playbook"
content = <<-EOT
[server-type]
%{ for ip in local.ips }${ip}
%{ endfor }
EOT
}
What if the ips are dynamic?
just make a list from the resources containing them, you can use the splat
ie aws_instance.web.*.public_ip