How to set hostname with cloud-init and Terraform?
Solution 1
Using a Terraform provisioner
with the local-exec
block will execute it on the device from which Terraform is applying: documentation. Note specifically the line:
This invokes a process on the machine running Terraform, not on the resource. See the remote-exec provisioner to run commands on the resource.
Therefore, switching the provisioner
from a local-exec
to a remote-exec
:
provisioner "remote-exec" {
inline = ["sudo hostnamectl set-hostname friendly.example.com"]
}
should fix your issue with setting the hostname.
Solution 2
Since you are supplying the tag to the instance as a string, why not just make that a var?
Replace the string friendly.example.com
with ${var.instance-name}
in your instance resource and in your data template. Then set the var:
variable "instance-name" {
default="friendly.example.com"
}
ilvidel
Updated on June 17, 2022Comments
-
ilvidel almost 2 years
I am starting with Terraform. I am trying to make it set a friendly hostname, instead of the usual
ip-10.10.10.10
that AWS uses. However, I haven't found how to do it.I tried using provisioners, like this:
provisioner "local-exec" { command = "sudo hostnamectl set-hostname friendly.example.com" }
But that doesn't work, the hostname is not changed.
So now, I'm trying this:
resource "aws_instance" "example" { ami = "ami-XXXXXXXX" instance_type = "t2.micro" tags = { Name = "friendly.example.com" } user_data = "${data.template_file.user_data.rendered}" } data "template_file" "user_data" { template = "${file("user-data.conf")}" vars { hostname = "${aws_instance.example.tags.Name}" } }
And in
user-data.conf
I have a line to use the variable, like so:hostname = ${hostname}
But this gives me a cycle dependency:
$ terraform apply Error: Error asking for user input: 1 error(s) occurred: * Cycle: aws_instance.example, data.template_file.user_data
Plus, that would mean I have to create a different
user_data
resource for each instance, which seems a bit like a pain. Can you not reuse them? That should be the purpose of templates, right?I must be missing something, but I can't find the answer. Thanks.
-
ilvidel over 5 yearsok, that solves the cycle problem, and gets the correct hostname, yay! However, if I now add a second instance, I need to create a different variable, and a different user_data template, right? That doesn't seem very flexible.
-
James Woolfenden over 5 yearsLookup use count and then count.index to iterate through multiple instances. Also use aws_launch-configs not aws_instance
-
ydaetskcoR over 5 yearsThis would be a better answer if it was a more complete example showing how to refer to the variable/local and was properly formatted.
-
Eat at Joes over 4 yearsthe
remote-exec
provisioner usesinline
and notcommand
. Also make sure inline is an array of commands;inline = ['sudo hostnamectl set-hostname friendly.example.com']