Cómo ejecutar el script ec2 UserData en la actualización de cloudformation

Oct 01 2020

Tengo un script ec2 userData que hace docker-compose pull and up.

Quiero ejecutar "aws cloudformation update-stack" y cargar nuevas imágenes de Docker. Cada vez que cambia la propiedad $ {imageTag}.

Esta es mi instancia de cloudformation yml:

 myInstance:
    Type: 'AWS::EC2::Instance'
    Metadata:
      'AWS::CloudFormation::Init':
        configSets:
          configs:
            - "configDockers"
            - "configOther"
        configDocker:
          commands:
            a:
              command: 'echo -e IMAGE_TAG=${imageTag} >> .env'
            b:
              command: 'docker-compose pull'
            c:
              command: 'docker-compose up'
    Properties:
      UserData:
        Fn::Base64:
          !Sub |
          runcmd:
           - /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource myInstance --region ${AWS::Region} -c configs
           - /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource myInstance --region ${AWS::Region}

Intenté agregar "docker-compose down", eliminar imágenes antiguas en el script UserData y agregar cloud_final_modules para ejecutar UserData en cada inicio:

 myInstance:
    Type: 'AWS::EC2::Instance'
    Metadata:
      'AWS::CloudFormation::Init':
        configSets:
          configs:
            - "configDockers"
            - "configOther"
        configDocker:
          commands:
            a:
              command: 'echo -e IMAGE_TAG=${imageTag} >> .env'
            b:
              command: 'docker-compose down'
            c:
              command: 'docker images -q | xargs -r sudo docker rmi'
            d:
              command: 'docker-compose pull'
            e:
              command: 'docker-compose up'
    Properties:
      UserData:
        Fn::Base64:
          !Sub |
          #cloud-config
          cloud_final_modules:
           - [scripts-user, always]
          runcmd:
           - /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource myInstance --region ${AWS::Region} -c configs
           - /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource myInstance --region ${AWS::Region}

Pero después de "aws cloudformation update-stack", el script no se ejecuta de nuevo a pesar de que imageTag cambia. solo se ejecuta si cambio algún valor en runcmd.

¿Cómo puedo ejecutar el script UserData cada vez que se ejecuta "aws cloudformation update-stack" (cada vez que cambia imageTag)?

¿Cómo puedo ejecutar algunos comandos de UserData solo en el primer inicio, otros comandos en cada reinicio y otros comandos en la instancia de detención?

por ejemplo: quiero ejecutar "docker-compose down" solo en la detención de la instancia, pero otros comandos comando: 'docker-compose pull / up' en cada reinicio de la instancia o "aws cloudformation update-stack" y algunos comandos iniciales solo en la primera configuración .

Respuestas

1 Marcin Oct 01 2020 at 07:14

¿Cómo puedo ejecutar algunos comandos de UserData solo en el primer inicio, otros comandos en cada reinicio y otros comandos en la instancia de detención?

No puedes. UserDataestá diseñado para ejecutarse solo en el lanzamiento de la instancia, no se reinicia, se inicia o se detiene (una excepción mencionada a continuación). Para hacerlo, debe implementar toda esta funcionalidad usted mismo.

Esto se hace comúnmente a través de la definición de archivos de unidades systemd personalizados . Por lo tanto, tendría que crear dichos archivos unitarios para su docker-compose.

La única excepción es, una forma bastante pirateada, de ejecutar datos de usuario en el inicio de la instancia descrita en una publicación reciente del blog de AWS:

  • ¿Cómo puedo utilizar los datos del usuario para ejecutar automáticamente un script con cada reinicio de mi instancia Amazon EC2?