Как заставить Terraform ждать завершения работы cloudinit?

В моем модуле Terraform AWS Docker Swarm я использую cloud-init для инициализации экземпляр EC2. Однако Terraform сообщает, что ресурс готов до завершения cloud-init. Есть ли способ заставить его ждать завершения cloud-init в идеале без SSHing или проверки наличия порта с использованием ресурса null.


person Archimedes Trajano    schedule 31.05.2020    source источник
comment
Это большой вопрос. На днях я думал об этом для Пакера. Вероятно, аналогичное решение существует для обоих. Я подумаю и постараюсь ответить на этот вопрос.   -  person Alain O'Dea    schedule 31.05.2020


Ответы (1)


Ваши менеджеры и оба используют template_cloud. У них также есть ec2: CreateTags.

Вы можете использовать тег ресурса EC2, например trajano / terraform-docker-swarm-aws / cloudinit-complete, чтобы указать, что cloudinit завершено.

Вы можете добавить эту последнюю часть к каждому, чтобы вызвать сценарий тегирования:

часть {filename = "tag_complete.sh" content = local.tag_complete_script content_type = "text / x-shellscript"}

И объявите tag_complete_script следующим образом:

locals {
  tag_complete_script = <<-EOF
  #!/bin/bash
  instance_id="${TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/instance-id}"
  aws ec2 create-tags --resources "$instance_id" --tags 'Key=trajano/terraform-docker-swarm-aws/cloudinit-complete,Value=true'
  EOF
}

Затем с помощью null_resource вы ждете появления тега (написали это на моем телефоне, поэтому используйте его для общего представления, но я не ожидаю, что он будет работать без тестирования и редактирования):

resource "null_resource" "wait_for_cloudinit" {
  provisioner "local-exec" {
    command = <<-EOF
    #!/bin/bash
    poll_tags="aws ec2 describe-tags --filters 'Name=resource-id,Values=${join(",", aws_instance.managers[*].id)}' 'Name=key,Values=trajano/terraform-docker-swarm-aws/cloudinit-complete' --output text --query 'Tags[*].Value'"
    expected='${join(",", formatlist("true", aws_instance.managers[*].id))}'
    $tags="$($poll_tags)"
    while [[ "$tags" != "$expected" ]] ; do
      $tags="$($poll_tags)"
    done
    EOF
  }
}

Таким образом, у вас могут быть зависимости null_resource.wait_for_cloudinit от любых ресурсов, которые необходимо запустить после завершения работы cloudinit.

person Alain O'Dea    schedule 31.05.2020
comment
Предполагается, что ваш локальный компьютер - UNIX, но мне нравится эта идея. - person Archimedes Trajano; 31.05.2020
comment
Хорошая точка зрения! Возможно, было бы лучше вызвать Python в local-exec кроссплатформенным способом и просто обратите внимание, что Python является предварительным условием. Было бы довольно легко написать этот опросчик, используя boto3 напрямую, а не AWS CLI. - person Alain O'Dea; 31.05.2020
comment
Да, я думал об использовании SSH remote_exec в соответствии с моим OP, но я также хотел избежать этого, потому что предполагал, что закрытый ключ для службы доступен в терраформере. - person Archimedes Trajano; 31.05.2020
comment
Действительно. Я ломал голову над тем, как обойти ssh или проверки портов. Теги показались мне достойным вариантом. Запуск сборки Terraform в контейнере Docker или WSL кажется приемлемым требованием для пользователей Windows, но я не использовал Windows для работы в течение нескольких лет, поэтому мне, вероятно, не следует говорить от имени этой пользовательской базы. - person Alain O'Dea; 31.05.2020
comment
В реализации тега может быть ошибка, если тег применяется к управляемому ресурсу terraform, так как он будет отключен. - person Archimedes Trajano; 31.05.2020
comment
Если в состоянии Terraform есть точный ключ тега для этих экземпляров EC2, он будет конфликтовать с неуправляемым тегом, применяемым cloudinit. AFAIK, теги ресурсов обрабатываются поставщиком индивидуально по ключу, а не как группа. У меня там может быть плохое предположение. - person Alain O'Dea; 01.06.2020
comment
Я думаю, что хороший способ тестирования - это запустить приложение дважды, чтобы увидеть, есть ли какие-либо изменения. - person Archimedes Trajano; 01.06.2020
comment
То, что я предлагаю, сломалось после того, как вы запустили его дважды? Если нет, можете ли вы принять это как ответ здесь. - person Alain O'Dea; 05.06.2020