如何使用 cloud-init 和 Terraform 设置主机名?
How to set hostname with cloud-init and Terraform?
我从 Terraform 开始。我试图让它设置一个友好的主机名,而不是 AWS 使用的通常的 ip-10.10.10.10
。但是,我还没有找到如何去做。
我试过像这样使用配置器:
provisioner "local-exec" {
command = "sudo hostnamectl set-hostname friendly.example.com"
}
但这不起作用,主机名没有更改。
所以现在,我正在尝试这个:
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}"
}
}
在 user-data.conf
中,我有一行使用变量,如下所示:
hostname = ${hostname}
但这给了我一个循环依赖:
$ terraform apply
Error: Error asking for user input: 1 error(s) occurred:
* Cycle: aws_instance.example, data.template_file.user_data
此外,这意味着我必须为每个实例创建不同的 user_data
资源,这似乎有点麻烦。你不能重复使用它们吗?这应该是模板的目的吧?
我一定是遗漏了什么,但我找不到答案。
谢谢。
既然您将标签作为字符串提供给实例,为什么不直接将其设为 var?
将实例资源和数据模板中的字符串 friendly.example.com
替换为 ${var.instance-name}
。然后设置变量:
variable "instance-name" {
default="friendly.example.com"
}
使用带有 local-exec
块的 Terraform provisioner
将在应用 Terraform 的设备上执行它:documentation。特别注意这一行:
This invokes a process on the machine running Terraform, not on the resource. See the remote-exec provisioner to run commands on the resource.
因此,将 provisioner
从 local-exec
切换为 remote-exec
:
provisioner "remote-exec" {
inline = ["sudo hostnamectl set-hostname friendly.example.com"]
}
应该可以通过设置主机名解决您的问题。
我认为您的 user-data.conf
应该是 bash 脚本,以 #!/usr/bin/env bash
开头。
它应该看起来像
#!/usr/bin/env bash
hostname ${hostname}
我从 Terraform 开始。我试图让它设置一个友好的主机名,而不是 AWS 使用的通常的 ip-10.10.10.10
。但是,我还没有找到如何去做。
我试过像这样使用配置器:
provisioner "local-exec" {
command = "sudo hostnamectl set-hostname friendly.example.com"
}
但这不起作用,主机名没有更改。
所以现在,我正在尝试这个:
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}"
}
}
在 user-data.conf
中,我有一行使用变量,如下所示:
hostname = ${hostname}
但这给了我一个循环依赖:
$ terraform apply
Error: Error asking for user input: 1 error(s) occurred:
* Cycle: aws_instance.example, data.template_file.user_data
此外,这意味着我必须为每个实例创建不同的 user_data
资源,这似乎有点麻烦。你不能重复使用它们吗?这应该是模板的目的吧?
我一定是遗漏了什么,但我找不到答案。 谢谢。
既然您将标签作为字符串提供给实例,为什么不直接将其设为 var?
将实例资源和数据模板中的字符串 friendly.example.com
替换为 ${var.instance-name}
。然后设置变量:
variable "instance-name" {
default="friendly.example.com"
}
使用带有 local-exec
块的 Terraform provisioner
将在应用 Terraform 的设备上执行它:documentation。特别注意这一行:
This invokes a process on the machine running Terraform, not on the resource. See the remote-exec provisioner to run commands on the resource.
因此,将 provisioner
从 local-exec
切换为 remote-exec
:
provisioner "remote-exec" {
inline = ["sudo hostnamectl set-hostname friendly.example.com"]
}
应该可以通过设置主机名解决您的问题。
我认为您的 user-data.conf
应该是 bash 脚本,以 #!/usr/bin/env bash
开头。
它应该看起来像
#!/usr/bin/env bash
hostname ${hostname}