如何使用 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.

因此,将 provisionerlocal-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}