При запуске из AMI, в котором установлен cloud-init (что часто встречается во многих официальных дистрибутивах Linux), мы можем используйте write_files
модуль cloud-init для размещения произвольных файлов в файловой системы, если они достаточно малы, чтобы соответствовать ограничениям аргумента user_data
вместе со всеми другими данными cloud-init
.
Как и все модули cloud-init, мы настраиваем write_files
с помощью облака Формат конфигурации на основе YAML -init, который начинается со специальной строки маркера #cloud-config
в отдельной строке, за которой следует структура данных YAML. Поскольку JSON является подмножеством YAML, мы можем использовать jsonencode
Terraform для создания допустимое значение [1].
locals {
cloud_config_config = <<-END
#cloud-config
${jsonencode({
write_files = [
{
path = "/etc/example.txt"
permissions = "0644"
owner = "root:root"
encoding = "b64"
content = filebase64("${path.module}/example.txt")
},
]
})}
END
}
Модуль write_files
может принимать данные в формате base64, когда мы устанавливаем encoding = "b64"
, поэтому мы используем это вместе с Terraform's _ 10_ для включения содержимого внешнего файла. Здесь возможны другие подходы, такие как динамическое создание строки с использованием шаблонов Terraform и использование base64encode
< / a>, чтобы закодировать его как содержимое файла.
Если вы можете выразить все, что вы хотите, чтобы cloud-init делал в одном файле конфигурации, как указано выше, вы можете напрямую назначить local.cloud_config_config
в качестве своего экземпляра user_data
, и cloud-config распознает и обработает его при загрузке системы:
user_data = local.cloud_config_config
Если вместо этого вам нужно объединить создание файла с некоторыми другими действиями, такими как запуск сценария оболочки, вы можете использовать multipart archive для кодирования нескольких" файлов "для обработки cloud-init. У Terraform есть cloudinit
провайдер, который содержит источник данных для простого создания многостраничного архива для cloud-init:
data "cloudinit_config" "example" {
gzip = false
base64_encode = false
part {
content_type = "text/cloud-config"
filename = "cloud-config.yaml"
content = local.cloud_config_config
}
part {
content_type = "text/x-shellscript"
filename = "example.sh"
content = <<-EOF
#!/bin/bash
echo "Hello World"
EOT
}
}
Этот источник данных создаст единственную строку в cloudinit_config.example.rendered
, которая представляет собой составной архив, подходящий для использования в качестве user_data
для cloud-init:
user_data = cloudinit_config.example.rendered
EC2 устанавливает максимальное количество пользовательских данных размер 64 килобайта, поэтому все закодированные данные вместе должны соответствовать этому пределу. Если вам нужно разместить большой файл, который приближается к этому пределу или превышает его, вероятно, было бы лучше использовать другую промежуточную систему для передачи этого файла, например, чтобы Terraform записал файл в корзину Amazon S3 и поместил программное обеспечение в ваш экземпляр получает эти данные с помощью профиля экземпляра учетные данные. Однако в этом не должно быть необходимости для небольших файлов данных, используемых для конфигурации системы.
Важно отметить, что с точки зрения Terraform и EC2 содержимое user_data
- это просто произвольная строка. Любые проблемы при обработке строки необходимо отлаживать в самой целевой операционной системе, читая журналы cloud-init, чтобы увидеть, как она интерпретировала конфигурацию и что произошло, когда она попыталась выполнить эти действия.
[1]: мы также потенциально можем использовать _21 _, но в то время, когда я пишу это, у этой функции есть предупреждение о том, что ее точное форматирование может измениться в будущих версиях Terraform, и это нежелательно для user_data
, потому что это приведет к замене экземпляра. Если вы читаете это в будущем и этого предупреждения больше нет в yamldecode
документах, рассмотрите возможность использования вместо этого yamlencode
.
person
Martin Atkins
schedule
30.05.2020