AWS CloudFormation – Launch Server in ASG Behind LB and Deploy Code

amazon-cloudformationamazon-web-services

I am trying to create a quite simple infrastructure for DEV environments. Given restrictions are:

  • One ec2 instance only, based on standard ec2 linux
  • nginx server in Docker container serves healthcheck.html
  • Server has to be in an Autoscaling Group
  • Access from the web via aws application load balancer only

This is the intended architecture:

Load Balancer, ASG, Target Group, EC2 instance with Docker and Code Deploy

I got a nice cloudformation template, which fails. Error message:

Received 1 FAILURE signal(s) out of 1. Unable to satisfy 100% MinSuccessfulInstancesPercent requirement

This seems to be caused by a dependency loop:

Cloudformation stack fails

… or, in words:

The health check of the Target Group fails
… because the nginx docker container does not exist
… because CodeDeploy did not deploy the docker container
… because the cloudformation thinks, the ASG is not ready yet
… because the health check of the target group fails

Question: Would it be possible to break the loop by disabling the health checks on the target group? (I did not find such an option in aws). Which other options could help?

Best Answer

In your ASG template you can set the HealthCheck property to EC2. That way it won't depend on the ELB Health Checks and will mark the instance as healthy as soon as it completes the UserData script.

TestAutoScalingGroup:
  Type: AWS::AutoScaling::AutoScalingGroup
  Properties:
    [...]
    HealthCheckType: EC2

Then in your LaunchConfiguration.UserData you need to send a signal once the UserData script completes:

TestLaunchConfig:
  Type: AWS::AutoScaling::LaunchConfiguration
  Properties:
    [...]
    UserData:
      Fn::Base64:
        !Sub |
          #!/bin/bash -x
          [... some setup ...]
          # Signal the status from this instance
          /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} \
            --resource TestAutoScalingGroup --region ${AWS::Region}

Note that the --resource parameter must match the TestAutoScalingGroup resource name.

Hope that helps :)

Related Topic