Skip to content

Verify

Wait at least two intervals (about two minutes) after associate, plus the initialization grace (60 seconds in this lab).

Terminal window
aws ec2 describe-application-status --instance-ids "$INSTANCE_ID"

A healthy detail looks like ResponseCodeMatched and StatusCode 200. With aggregation excluded, overall CLI status is not-applicable. The console only rolls included checks into the instance card, so Application status there is None associated or included even though the check is associated and can already be passed.

Open the instance → Status and alarms.

Expand Application status details for the per-check line. excluded and passed together is expected.

Terminal window
aws ec2 describe-network-interfaces \
--filters "Name=vpc-id,Values=${VPC_ID}" \
--query 'NetworkInterfaces[].{Id:NetworkInterfaceId,Desc:Description,Managed:RequesterManaged,Ip:PrivateIpAddress}' \
--output table

Look for a requester-managed interface you did not create. The description filter *application status* is optional; it may be empty depending on how AWS labels the ENI.

Terminal window
aws ec2 modify-application-status-check \
--application-status-check-id "$ASC_ID" \
--aggregation included

Wait one interval. Overall status becomes ok. The Status and alarms card shows Application status as Check passed instead of None associated or included. impaired can replace Auto Scaling instances.

Details show the same check as Included and passed.

Stop the Python server and wait two intervals (failure threshold is 2):

Terminal window
aws ssm send-command \
--instance-ids "$INSTANCE_ID" \
--document-name AWS-RunShellScript \
--parameters 'commands=["pkill -f health.py || true"]'
sleep 120
aws ec2 describe-application-status --instance-ids "$INSTANCE_ID"

System, instance, and EBS stay passed; Application status fails. Details show ConnectionRefused (or ConnectionReset). Overall is impaired.

Start it again:

Terminal window
aws ssm send-command \
--instance-ids "$INSTANCE_ID" \
--document-name AWS-RunShellScript \
--parameters 'commands=["nohup python3 /usr/local/bin/health.py >/var/log/health.log 2>&1 &"]'

Wait two successes. Overall returns to ok; details show passed / ResponseCodeMatched again.

Instance-level. Pass a duration, or omit it to suppress until you disable. Auto Scaling does not act while overall is suppressed.

Terminal window
aws ec2 enable-application-status-check-suppression \
--instance-ids "$INSTANCE_ID" \
--duration-seconds 3600

Wait until describe-application-status shows overall suppressed. The instance card shows Application status Suppressed; the per-check line can still be passed.

Resume early:

Terminal window
aws ec2 disable-application-status-check-suppression \
--instance-ids "$INSTANCE_ID"

Overall returns to ok on the next interval. Exclude, disassociate, and when to use each option: Deploy and maintenance.

  • StatusCheckFailed_Application — overall status for included checks (0 pass, 1 fail).
  • StatusCheckFailed_Application_<check-id> — per-check metric.

Optional alarm after the check is included:

Terminal window
aws cloudwatch put-metric-alarm \
--alarm-name "${NAME}-app-status" \
--metric-name StatusCheckFailed_Application \
--namespace AWS/EC2 \
--statistic Maximum \
--period 60 \
--threshold 1 \
--comparison-operator GreaterThanOrEqualToThreshold \
--evaluation-periods 2 \
--dimensions Name=InstanceId,Value="$INSTANCE_ID"

Optional Auto Scaling replace demo, then teardown.