Как установить имя хоста с помощью cloud-init и Terraform?

Я начинаю с Terraform. Я пытаюсь установить понятное имя хоста вместо обычного ip-10.10.10.10, которое использует AWS. Однако я не нашел, как это сделать.

Я пробовал использовать средства обеспечения, например:

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 ресурсы для каждого экземпляра, что немного похоже на боль. Вы не можете использовать их повторно? Это должно быть целью шаблонов, верно?

Должно быть, я что-то упускаю, но не могу найти ответа. Спасибо.


person ilvidel    schedule 23.01.2019    source источник
comment
Что касается первой попытки: local-exec выполняется на вашем локальном устройстве. Вы хотите remote-exec.   -  person Matt Schuchard    schedule 23.01.2019
comment
@MattSchuchard ах, спасибо! Я думал, что это локально для подготовленного экземпляра. Я попробую это.   -  person ilvidel    schedule 23.01.2019
comment
@MattSchuchard Я получил работу благодаря вашему предложению. Если вы опубликуете его как ответ, я помечу его как выбранное.   -  person ilvidel    schedule 23.01.2019


Ответы (3)


Использование Terraform provisioner с блоком local-exec запустит его на устройстве, с которого применяется Terraform: документация. Обратите внимание на строку:

Это вызывает процесс на машине, на которой выполняется Terraform, а не на ресурсе. См. Средство обеспечения удаленного выполнения для выполнения команд на ресурсе.

Следовательно, переключение provisioner с local-exec на remote-exec:

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

должен исправить вашу проблему с установкой имени хоста.

person Matt Schuchard    schedule 23.01.2019
comment
remote-exec провайдер использует inline, а не command. Также убедитесь, что inline - это массив команд; inline = ['sudo hostnamectl set-hostname friendly.example.com'] - person Eat at Joes; 21.11.2019

Поскольку вы предоставляете тег экземпляру в виде строки, почему бы просто не сделать это переменной?

Замените строку friendly.example.com на ${var.instance-name} в ресурсе экземпляра и в шаблоне данных. Затем установите var:

variable "instance-name" {
    default="friendly.example.com"
}
person James Woolfenden    schedule 23.01.2019
comment
хорошо, это решает проблему цикла и получает правильное имя хоста, ура! Однако, если я сейчас добавлю второй экземпляр, мне нужно будет создать другую переменную и другой шаблон user_data, верно? Это не кажется очень гибким. - person ilvidel; 23.01.2019
comment
Поиск использует count, а затем count.index для перебора нескольких экземпляров. Также используйте aws_launch-configs, а не aws_instance - person James Woolfenden; 24.01.2019
comment
Это был бы лучший ответ, если бы это был более полный пример, показывающий, как обращаться к переменной / local и был правильно отформатирован. - person ydaetskcoR; 24.01.2019

Я считаю, что ваш user-data.conf должен быть сценарием bash для начала с #!/usr/bin/env bash.

Это должно выглядеть так

#!/usr/bin/env bash
hostname ${hostname}
person Martin Hristov    schedule 31.07.2019