如何使用cloud-init和Terraform设置主机名?

问题描述 投票:0回答:4

我从 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
资源,这看起来有点痛苦。你不能重复使用它们吗?这应该就是模板的目的吧?

我一定错过了什么,但我找不到答案。 谢谢。

terraform cloud-init
4个回答
10
投票

将 Terraform

provisioner
local-exec
块一起使用将在 Terraform 正在应用的设备上执行它:文档。特别注意这一行:

这会调用运行 Terraform 的计算机上的进程,而不是资源上的进程。请参阅远程执行配置程序以在资源上运行命令。

因此,将

provisioner
local-exec
切换为
remote-exec

provisioner "remote-exec" {
  inline = ["sudo hostnamectl set-hostname friendly.example.com"]
}

应该可以解决设置主机名的问题。


3
投票

既然您将标签作为字符串提供给实例,为什么不直接将其设为 var?

将实例资源和数据模板中的字符串

friendly.example.com
替换为
${var.instance-name}
。然后设置变量:

variable "instance-name" {
    default="friendly.example.com"
}

0
投票

我相信你的

user-data.conf
应该是bash脚本,从
#!/usr/bin/env bash
开始。

它应该看起来像

#!/usr/bin/env bash
hostname ${hostname}

0
投票

如果您想将主机名设置为资源名称,那么您现在可以使用在 AWS Provider v4.20.0 或更高版本中发布的 private_dns_name_options 资源块直接在 Terraform 中执行此操作,而不必与 cloudinit 或用户混淆-数据

注意:如果您的服务器已经存在并且正在运行,您可能需要重新启动或可能使用这些新选项重新创建它

resource "aws_instance" "server" {
...

  private_dns_name_options {
    hostname_type = "resource-name"
  }
}
© www.soinside.com 2019 - 2024. All rights reserved.