Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

623
Views
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 answers
Answer question

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 Report

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 Report

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 Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!