Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

620
Vistas
Terraform: espere hasta que la instancia sea "accesible"

Tengo un código de Terraform con aws_instance y null_resource :

 resource "aws_instance" "example" { ami = data.aws_ami.server.id instance_type = "t2.medium" key_name = aws_key_pair.deployer.key_name tags = { name = "example" } vpc_security_group_ids = [aws_security_group.main.id] } resource "null_resource" "example" { provisioner "local-exec" { command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -T 300 -i ${aws_instance.example.public_dns}, --user centos --private-key files/id_rsa playbook.yml" } }

Funciona un poco, pero a veces hay un error (probablemente cuando la instancia está en un estado pendiente). Cuando vuelvo a ejecutar Terraform, funciona como se esperaba.

Pregunta: ¿Cómo puedo ejecutar local-exec solo cuando la instancia se está ejecutando y acepta una conexión SSH?

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

Actualmente, null_resource solo esperará hasta que se complete el recurso aws_instance , que a su vez solo espera hasta que la API de AWS indique que se encuentra en estado Running . Hay una gran brecha desde allí hasta que la instancia inicia el sistema operativo y luego puede aceptar conexiones SSH antes de que su aprovisionador local-exec pueda conectarse.

Una forma de manejar esto es usar el aprovisionador remote-exec en la instancia primero, ya que tiene la capacidad de esperar a que la instancia esté lista. Cambiar su código existente para manejar esto se vería así:

 resource "aws_instance" "example" { ami = data.aws_ami.server.id instance_type = "t2.medium" key_name = aws_key_pair.deployer.key_name tags = { name = "example" } vpc_security_group_ids = [aws_security_group.main.id] } resource "null_resource" "example" { provisioner "remote-exec" { connection { host = aws_instance.example.public_dns user = "centos" file = file("files/id_rsa") } inline = ["echo 'connected!'"] } provisioner "local-exec" { command = "ANSIBLE_HOST_KEY_CHECKING=False ansible-playbook -T 300 -i ${aws_instance.example.public_dns}, --user centos --private-key files/id_rsa playbook.yml" } }

Primero intentará conectarse a la dirección DNS pública de la instancia como usuario centos con la clave privada files/id_rsa . Una vez que esté conectado, ejecutará echo 'connected!' como un comando simple antes de pasar a su aprovisionador local-exec existente que ejecuta Ansible en la instancia.

Tenga en cuenta que el simple hecho de poder conectarse a través de SSH puede no ser suficiente para que pueda aprovisionar la instancia. Si su secuencia de comandos de Ansible intenta interactuar con su administrador de paquetes, es posible que descubra que está bloqueada desde la ejecución de la secuencia de comandos de datos de usuario de la instancia. Si este es el caso, primero deberá ejecutar de forma remota un script que espere a que se complete cloud-init . Un script de ejemplo se ve así:

 #!/bin/bash while [ ! -f /var/lib/cloud/instance/boot-finished ]; do echo -e "\033[1;36mWaiting for cloud-init..." sleep 1 done
over 4 years ago · Santiago Trujillo Denunciar

0

Hay una solución específica ansible para este problema. Agregue este código a su libro de jugadas (hay una cláusula previa a la tarea si usa roles)

 - name: will wait till reachable hosts: all gather_facts: no # important tasks: - name: Wait for system to become reachable wait_for_connection: - name: Gather facts for the first time setup:
over 4 years ago · Santiago Trujillo Denunciar

0

Para los casos en los que las instancias no están expuestas externamente (alrededor del 90 % del tiempo en la mayoría de mis proyectos), y el agente de SSM está instalado en la instancia de destino (las AMI de AWS más nuevas vienen precargadas ), puede aprovechar SSM para sondear el instancia. Aquí hay un código de muestra:

 instanceId=$1 echo "Waiting for instance to bootstrap ..." tries=0 responseCode=1 while [[ $responseCode != 0 && $tries -le 10 ]] do echo "Try # $tries" cmdId=$(aws ssm send-command --document-name AWS-RunShellScript --instance-ids $instanceId --parameters commands="cat /tmp/job-done.txt # or some other validation logic" --query Command.CommandId --output text) sleep 5 responseCode=$(aws ssm get-command-invocation --command-id $cmdId --instance-id $instanceId --query ResponseCode --output text) echo "ResponseCode: $responseCode" if [ $responseCode != 0 ]; then echo "Sleeping ..." sleep 60 fi (( tries++ )) done echo "Wait time over. ResponseCode: $responseCode"

Suponiendo que tiene la CLI de AWS instalada localmente, puede solicitar este recurso nulo antes de actuar en la instancia. En mi caso, estaba construyendo una AMI.

 resource "null_resource" "wait_for_instance" { depends_on = [ aws_instance.my_instance ] triggers = { always_run = "${timestamp()}" } provisioner "local-exec" { command = "${path.module}/scripts/check-instance-state.sh ${aws_instance.my_instance.id}" } }
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda