

# Amazon EC2 Auto Scaling lifecycle hooks
<a name="lifecycle-hooks"></a>

Amazon EC2 Auto Scaling offers the ability to add lifecycle hooks to your Auto Scaling groups. These hooks let you create solutions that are aware of events in the Auto Scaling instance lifecycle, and then perform a custom action on instances when the corresponding lifecycle event occurs. A lifecycle hook provides a specified amount of time (one hour by default) to wait for the action to complete before the instance transitions to the next state.

As an example of using lifecycle hooks with Auto Scaling instances: 
+ When a scale-out event occurs, your newly launched instance completes its startup sequence and transitions to a wait state. While the instance is in a wait state, it runs a script to download and install the needed software packages for your application, making sure that your instance is fully ready before it starts receiving traffic. When the script is finished installing software, it sends the **complete-lifecycle-action** command to continue.
+ When a scale-in event occurs, a lifecycle hook pauses the instance before it is terminated and sends you a notification using Amazon EventBridge. While the instance is in the wait state, you can invoke an AWS Lambda function or connect to the instance to download logs or other data before the instance is fully terminated. 

A popular use of lifecycle hooks is to control when instances are registered with Elastic Load Balancing. By adding a launch lifecycle hook to your Auto Scaling group, you can ensure that your bootstrap scripts have completed successfully and the applications on the instances are ready to accept traffic before they are registered to the load balancer at the end of the lifecycle hook.

**Topics**
+ [

## Lifecycle hook availability
](#lifecycle-hooks-availability)
+ [Considerations and limitations](#lifecycle-hook-considerations)
+ [

## Related resources
](#lifecycle-hook-related-resources)
+ [

# How lifecycle hooks work in Auto Scaling groups
](lifecycle-hooks-overview.md)
+ [Prepare to add a lifecycle hook](prepare-for-lifecycle-notifications.md)
+ [

# Control instance retention with instance lifecycle policies
](instance-lifecycle-policy.md)
+ [Retrieve the target lifecycle state](retrieving-target-lifecycle-state-through-imds.md)
+ [

# Add lifecycle hooks to your Auto Scaling group
](adding-lifecycle-hooks.md)
+ [

# Complete a lifecycle action in an Auto Scaling group
](completing-lifecycle-hooks.md)
+ [Tutorial: Use instance metadata to retrieve lifecycle state](tutorial-lifecycle-hook-instance-metadata.md)
+ [

# Tutorial: Configure a lifecycle hook that invokes a Lambda function
](tutorial-lifecycle-hook-lambda.md)

## Lifecycle hook availability
<a name="lifecycle-hooks-availability"></a>

The following table lists the lifecycle hooks available for various scenarios.


| Event | Instance launch or termination¹ | [Maximum Instance Lifetime](asg-max-instance-lifetime.md): Replacement instances | [Instance Refresh](asg-instance-refresh.md): Replacement instances | [Capacity Rebalancing](ec2-auto-scaling-capacity-rebalancing.md): Replacement instances | [Warm Pools](ec2-auto-scaling-warm-pools.md): Instances entering and leaving the warm pool | 
| --- | --- | --- | --- | --- | --- | 
| Instance launching | ✓ | ✓ | ✓ | ✓ | ✓ | 
| Instance terminating | ✓ | ✓ | ✓ | ✓ | ✓ | 

¹ Applies to all launches and terminations, whether they are initiated automatically or manually such as when you call the `SetDesiredCapacity` or `TerminateInstanceInAutoScalingGroup` operations. Does not apply when you attach or detach instances, move instances in and out of standby mode, or delete the group with the force delete option.

## Considerations and limitations for lifecycle hooks
<a name="lifecycle-hook-considerations"></a>

When working with lifecycle hooks, keep in mind the following notes and limitations:
+ Amazon EC2 Auto Scaling provides its own lifecycle to help with the management of Auto Scaling groups. This lifecycle differs from that of other EC2 instances. For more information, see [Amazon EC2 Auto Scaling instance lifecycle](ec2-auto-scaling-lifecycle.md). Instances in a warm pool also have their own lifecycle, as described in [Lifecycle state transitions for instances in a warm pool](warm-pool-instance-lifecycle.md#lifecycle-state-transitions).
+  By default, termination lifecycle hooks operate on a best-effort basis. If a termination lifecycle hook times out, or is abandoned, Amazon EC2 Auto Scaling proceeds with terminating the instance immediately. You can combine termination lifecycle hooks with an instance lifecycle policy for instance retention. For more information, see [Control instance retention with instance lifecycle policies](instance-lifecycle-policy.md). 
+ You can use lifecycle hooks with Spot Instances, but a lifecycle hook does not prevent an instance from terminating in the event that capacity is no longer available, which can happen at any time with a two-minute interruption notice. For more information, see [Spot Instance interruptions](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/spot-interruptions.html) in the *Amazon EC2 User Guide*. However, you can enable Capacity Rebalancing to proactively replace Spot Instances that have received a rebalance recommendation from the Amazon EC2 Spot service, a signal that is sent when a Spot Instance is at elevated risk of interruption. For more information, see [Capacity Rebalancing in Auto Scaling to replace at-risk Spot Instances](ec2-auto-scaling-capacity-rebalancing.md).
+ Instances can remain in a wait state for a finite period of time. The default timeout for a lifecycle hook is one hour (heartbeat timeout). There is also a global timeout that specifies the maximum amount of time that you can keep an instance in a wait state. The global timeout is 48 hours or 100 times the heartbeat timeout, whichever is smaller.
+ The result of the lifecycle hook can be either abandon or continue. If an instance is launching, continue indicates that your actions were successful, and that Amazon EC2 Auto Scaling can put the instance into service. Otherwise, abandon indicates that your custom actions were unsuccessful, and that we can terminate and replace the instance. If an instance is terminating, both abandon and continue allow the instance to terminate. However, abandon stops any remaining actions, such as other lifecycle hooks, and continue allows any other lifecycle hooks to complete.
+ Amazon EC2 Auto Scaling limits the rate at which it allows instances to launch if the lifecycle hooks are failing consistently, so make sure to test and fix any permanent errors in your lifecycle actions. 
+ Creating and updating lifecycle hooks using the AWS CLI, CloudFormation, or an SDK provides options not available when creating a lifecycle hook from the AWS Management Console. For example, the field to specify the ARN of an SNS topic or SQS queue doesn't appear in the console, because Amazon EC2 Auto Scaling already sends events to Amazon EventBridge. These events can be filtered and redirected to AWS services such as Lambda, Amazon SNS, and Amazon SQS as needed.
+ You can add multiple lifecycle hooks to an Auto Scaling group while you are creating it, by calling the [CreateAutoScalingGroup](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_CreateAutoScalingGroup.html) API using the AWS CLI, CloudFormation, or an SDK. However, each hook must have the same notification target and IAM role, if specified. To create lifecycle hooks with different notification targets and different roles, create the lifecycle hooks one at a time in separate calls to the [PutLifecycleHook](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_PutLifecycleHook.html) API. 
+ If you add a lifecycle hook for instance launch, the health check grace period starts as soon as the instance reaches the `InService` state. For more information, see [Set the health check grace period for an Auto Scaling group](health-check-grace-period.md).

**Scaling considerations**
+ Dynamic scaling policies scale in and out in response to CloudWatch metric data, such as CPU and network I/O, that's aggregated across multiple instances. When scaling out, Amazon EC2 Auto Scaling doesn't immediately count a new instance towards the aggregated instance metrics of the Auto Scaling group. It waits until the instance reaches the `InService` state and the instance warmup has finished. For more information, see [Scaling performance considerations](ec2-auto-scaling-default-instance-warmup.md#scaling-performance-considerations) in the default instance warmup topic. 
+ On scale in, the aggregated instance metrics might not instantly reflect the removal of a terminating instance. The terminating instance stops counting toward the group's aggregated instance metrics shortly after the Amazon EC2 Auto Scaling termination workflow begins. 
+ In most cases when lifecycle hooks are invoked, scaling activities due to simple scaling policies are paused until the lifecycle actions have completed and the cooldown period has expired. Setting a long interval for the cooldown period means that it will take longer for scaling to resume. For more information, see [Lifecycle hooks can cause additional delays](ec2-auto-scaling-scaling-cooldowns.md#cooldowns-lifecycle-hooks) in the cooldown topic. In general, we recommend against using simple scaling policies if you can use either step scaling or target tracking scaling policies instead.

## Related resources
<a name="lifecycle-hook-related-resources"></a>

For an introduction video, see [AWS re:Invent 2018: Capacity Management Made Easy with Amazon EC2 Auto Scaling](https://youtu.be/PideBMIcwBQ?t=469) on *YouTube*.

We provide a few JSON and YAML template snippets that you can use to understand how to declare lifecycle hooks in your CloudFormation stack templates. For more information, see the [AWS::AutoScaling::LifecycleHook](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-autoscaling-lifecyclehook.html) reference in the *AWS CloudFormation User Guide*.

You can also visit our [GitHub repository](https://github.com/aws-samples/amazon-ec2-auto-scaling-group-examples) to download example templates and user data scripts for lifecycle hooks.

For examples of the use of lifecycle hooks, see the following blog posts. 
+ [Building a Backup System for Scaled Instances using Lambda and Amazon EC2 Run Command](https://aws.amazon.com/blogs/compute/building-a-backup-system-for-scaled-instances-using-aws-lambda-and-amazon-ec2-run-command/)
+ [Run code before terminating an EC2 Auto Scaling instance](https://aws.amazon.com/blogs/infrastructure-and-automation/run-code-before-terminating-an-ec2-auto-scaling-instance/).

# How lifecycle hooks work in Auto Scaling groups
<a name="lifecycle-hooks-overview"></a>

An Amazon EC2 instance transitions through different states from the time it launches until it is terminated. You can create custom actions for your Auto Scaling group to act when an instance transitions into a wait state due to a lifecycle hook.

The following illustration shows the transitions between Auto Scaling instance states when you use lifecycle hooks for scale out and scale in. 

![\[The transitions between Auto Scaling instance states when you use lifecycle hooks for scale out and scale in.\]](http://docs.aws.amazon.com/autoscaling/ec2/userguide/images/how-lifecycle-hooks-work.png)


As shown in the preceding diagram:

1. The Auto Scaling group responds to a scale-out event and begins launching an instance.

1. The lifecycle hook puts the instance into a wait state (`Pending:Wait`) and then performs a custom action.

   The instance remains in a wait state until you either complete the lifecycle action, or the timeout period ends. By default, the instance remains in a wait state for one hour, and then the Auto Scaling group continues the launch process (`Pending:Proceed`). If you need more time, you can restart the timeout period by recording a heartbeat. If you complete the lifecycle action when the custom action has completed and the timeout period hasn't expired yet, the period ends and the Auto Scaling group continues the launch process.

1. The instance enters the `InService` state and the health check grace period starts. However, before the instance reaches the `InService` state, if the Auto Scaling group is associated with an Elastic Load Balancing load balancer, the instance is registered with the load balancer, and the load balancer starts checking its health. After the health check grace period ends, Amazon EC2 Auto Scaling begins checking the health state of the instance.

1. The Auto Scaling group responds to a scale-in event and begins terminating an instance. If the Auto Scaling group is being used with Elastic Load Balancing, the terminating instance is first deregistered from the load balancer. If connection draining is enabled for the load balancer, the instance stops accepting new connections and waits for existing connections to drain before completing the deregistration process.

1. The lifecycle hook puts the instance into a wait state (`Terminating:Wait`) and then performs a custom action.

   The instance remains in a wait state either until you complete the lifecycle action, or until the timeout period ends (one hour by default). After you complete the lifecycle hook or the timeout period expires, the instance transitions to the next state (`Terminating:Proceed`).

1. The instance is terminated.

**Important**  
Instances in a warm pool also have their own lifecycle with corresponding wait states, as described in [Lifecycle state transitions for instances in a warm pool](warm-pool-instance-lifecycle.md#lifecycle-state-transitions).

## Lifecycle state transitions for instances undergoing root volume replacement
<a name="rvr-lifecycle-state-transitions"></a>

The following diagram shows the transition between Auto Scaling instance states when you use lifecycle hooks for replace root volume:

![\[The transitions between Auto Scaling instance states when you use lifecycle hooks for replace root volume.\]](http://docs.aws.amazon.com/autoscaling/ec2/userguide/images/root-volume-replacement-lifecycle-states.png)


As shown in the preceding diagram:

1. Auto Scaling group responds to an instance refresh and selects an instance for root volume replacement. The instance enters the `ReplacingRootVolume` state. If the instance is registered with a load balancer it is deregistered from the load balancer.

1. The lifecycle hook puts the instance into a wait state (`ReplacingRootVolume:Wait`) and then performs a custom action. The instance remains in a wait state until you either complete the lifecycle action, or the timeout period ends. If you complete the lifecycle action when the custom action has completed and the timeout period hasn't expired yet, the period ends and the Auto Scaling group continues the root volume replacement process.

1. The instance completes its root volume replacement and enters the `RootVolumeReplaced` state.

1. The instance enters the `Pending` state.

1. The lifecycle hook puts the instance into a wait state (`Pending:Wait`) and then performs a custom action. The instance remains in a wait state either until you complete the lifecycle action, or until the timeout period ends. After you complete the lifecycle hook or the timeout period expires, the instance transitions to the next state (`Pending:Proceed`).

1. The instance enters the `InService` state. However, before the instance reaches the `InService` state, if the Auto Scaling group is associated with an Elastic Load Balancing load balancer, the instance is registered with the load balancer.

# Prepare to add a lifecycle hook to your Auto Scaling group
<a name="prepare-for-lifecycle-notifications"></a>

Before you add a lifecycle hook to your Auto Scaling group, be sure that your user data script or notification target is set up correctly.
+ To use a user data script to perform custom actions on your instances as they are launching, you do not need to configure a notification target. However, you must have already created the launch template or launch configuration that specifies your user data script and associated it with your Auto Scaling group. For more information about user data scripts, see [Run commands on your Linux instance at launch](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html) in the *Amazon EC2 User Guide*. 
+ To signal Amazon EC2 Auto Scaling when the lifecycle action is complete, you must add the [CompleteLifecycleAction](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_CompleteLifecycleAction.html) API call to the script, and you must manually create an IAM role with a policy that allows Auto Scaling instances to call this API. Your launch template or launch configuration must specify this role using an IAM instance profile that gets attached to your Amazon EC2 instances at launch. For more information, see [Complete a lifecycle action in an Auto Scaling group](completing-lifecycle-hooks.md) and [IAM role for applications that run on Amazon EC2 instances](us-iam-role.md).
+ To allow Lambda to signal Amazon EC2 Auto Scaling when the lifecycle action is complete, you must add the [CompleteLifecycleAction](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_CompleteLifecycleAction.html) API call to the function code. You must also have attached an IAM policy to the function's execution role that gives Lambda permission to complete lifecycle actions. For more information, see [Tutorial: Configure a lifecycle hook that invokes a Lambda function](tutorial-lifecycle-hook-lambda.md).
+ To use a service such as a Amazon SNS or Amazon SQS to perform a custom action, you must have already created the SNS topic or SQS queue and have ready its Amazon Resource Name (ARN). You must also have already created the IAM role that gives Amazon EC2 Auto Scaling access to your SNS topic or SQS target and have ready its ARN. For more information, see [Configure a notification target for lifecycle notifications](#lifecycle-hook-notification-target). 
**Note**  
By default, when you add a lifecycle hook in the console, Amazon EC2 Auto Scaling sends lifecycle event notifications to Amazon EventBridge. Using EventBridge or a user data script is a recommended best practice. To create a lifecycle hook that sends notifications directly to Amazon SNS, Amazon SQS, or AWS Lambda, use the AWS CLI, AWS CloudFormation, or an SDK to add the lifecycle hook.

## Configure a notification target for lifecycle notifications
<a name="lifecycle-hook-notification-target"></a>

You can add lifecycle hooks to an Auto Scaling group to perform custom actions when an instance enters a wait state. You can choose a target service to perform these actions depending on your preferred development approach.

There are four different approaches for implementing notification targets for lifecycle hooks:
+ **Amazon EventBridge** — Receive the notifications and perform the actions that you want.
+ **Amazon Simple Notification Service (Amazon SNS)** — Create a topic for publishing notifications. Clients can subscribe to the SNS topic and receive published messages using a supported protocol.
+ **Amazon Simple Queue Service (Amazon SQS)** — Exchange messages through a polling model.
+ **AWS Lambda** — Invoke a Lambda function that performs the action you want.

As a best practice, we recommend that you use EventBridge. The notifications sent to Amazon SNS and Amazon SQS contain the same information as the notifications that Amazon EC2 Auto Scaling sends to EventBridge. Before EventBridge, the standard practice was to send a notification to SNS or SQS and integrate another service with SNS or SQS to perform programmatic actions. Today, EventBridge gives you more options for which services you can target and makes it easier to handle events using serverless architecture. 

Remember, if you have a user data script in your launch template or launch configuration that configures your instances when they launch, you do not need to receive notifications to perform custom actions on your instances.

The following procedures cover how to set up your notification target.

**Topics**
+ [

### Route notifications to Lambda using EventBridge
](#cloudwatch-events-notification)
+ [

### Receive notifications using Amazon SNS
](#sns-notifications)
+ [

### Receive notifications using Amazon SQS
](#sqs-notifications)
+ [

### Route notifications to AWS Lambda directly
](#lambda-notification)
+ [

### Notification message example
](#notification-message-example)

**Important**  
The EventBridge rule, Lambda function, Amazon SNS topic, and Amazon SQS queue that you use with lifecycle hooks must always be in the same Region where you created your Auto Scaling group.

### Route notifications to Lambda using EventBridge
<a name="cloudwatch-events-notification"></a>

You can configure an EventBridge rule to invoke a Lambda function when an instance enters a wait state. Amazon EC2 Auto Scaling emits a lifecycle event notification to EventBridge about the instance that is launching or terminating and a token that you can use to control the lifecycle action. For examples of these events, see [Amazon EC2 Auto Scaling event reference](ec2-auto-scaling-event-reference.md).

**Note**  
When you use the AWS Management Console to create an event rule, the console automatically adds the IAM permissions necessary to grant EventBridge permission to call your Lambda function. If you are creating an event rule using the AWS CLI, you need to grant this permission explicitly.   
For information about how to create event rules in the EventBridge console, see [Creating Amazon EventBridge rules that react to events](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-create-rule.html) in the *Amazon EventBridge User Guide*.  
– or –   
For an introductory tutorial that is directed towards console users, see [Tutorial: Configure a lifecycle hook that invokes a Lambda function](tutorial-lifecycle-hook-lambda.md). This tutorial shows you how to create a simple Lambda function that listens for launch events and writes them out to a CloudWatch Logs log.

**To create an EventBridge rule that invokes a Lambda function**

1. Create a Lambda function by using the [Lambda console](https://console.aws.amazon.com/lambda/home#/functions) and note its Amazon Resource Name (ARN). For example, `arn:aws:lambda:region:123456789012:function:my-function`. You need the ARN to create an EventBridge target. For more information, see [Getting started with Lambda](https://docs.aws.amazon.com/lambda/latest/dg/getting-started.html) in the *AWS Lambda Developer Guide*.

1. To create a rule that matches events for instance launch, use the following [put-rule](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/events/put-rule.html) command.

   ```
   aws events put-rule --name my-rule --event-pattern file://pattern.json --state ENABLED
   ```

   The following example shows the `pattern.json` for an instance launch lifecycle action. Replace the text in **italics** with the name of your Auto Scaling group.

   ```
   {
     "source": [ "aws.autoscaling" ],
     "detail-type": [ "EC2 Instance-launch Lifecycle Action" ],
     "detail": {
         "AutoScalingGroupName": [ "my-asg" ]
      }
   }
   ```

   If the command runs successfully, EventBridge responds with the ARN of the rule. Note this ARN. You'll need to enter it in step 4.

   To create a rule that matches for other events, modify the event pattern. For more information, see [Use EventBridge to handle Auto Scaling events](automating-ec2-auto-scaling-with-eventbridge.md).

1. To specify the Lambda function to use as a target for the rule, use the following [put-targets](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/events/put-targets.html) command.

   ```
   aws events put-targets --rule my-rule --targets Id=1,Arn=arn:aws:lambda:region:123456789012:function:my-function
   ```

   In the preceding command, *my-rule* is the name that you specified for the rule in step 2, and the value for the `Arn` parameter is the ARN of the function that you created in step 1.

1. To add permissions that allow the rule to invoke your Lambda function, use the following Lambda [add-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-permission.html) command. This command trusts the EventBridge service principal (`events.amazonaws.com`) and scopes permissions to the specified rule.

   ```
   aws lambda add-permission --function-name my-function --statement-id my-unique-id \
     --action 'lambda:InvokeFunction' --principal events.amazonaws.com --source-arn arn:aws:events:region:123456789012:rule/my-rule
   ```

   In the preceding command:
   + *my-function* is the name of the Lambda function that you want the rule to use as a target.
   + *my-unique-id* is a unique identifier that you define to describe the statement in the Lambda function policy.
   + `source-arn` is the ARN of the EventBridge rule.

   If the command runs successfully, you receive output similar to the following.

   ```
   {
     "Statement": "{\"Sid\":\"my-unique-id\",
       \"Effect\":\"Allow\",
       \"Principal\":{\"Service\":\"events.amazonaws.com\"},
       \"Action\":\"lambda:InvokeFunction\",
       \"Resource\":\"arn:aws:lambda:us-west-2:123456789012:function:my-function\",
       \"Condition\":
         {\"ArnLike\":
           {\"AWS:SourceArn\":
            \"arn:aws:events:us-west-2:123456789012:rule/my-rule\"}}}"
   }
   ```

   The `Statement` value is a JSON string version of the statement that was added to the Lambda function policy.

1. After you have followed these instructions, continue on to [Add lifecycle hooks to your Auto Scaling group](adding-lifecycle-hooks.md) as a next step.

### Receive notifications using Amazon SNS
<a name="sns-notifications"></a>

You can use Amazon SNS to set up a notification target (an SNS topic) to receive notifications when a lifecycle action occurs. Amazon SNS then sends the notifications to the subscribed recipients. Until the subscription is confirmed, no notifications published to the topic are sent to the recipients. 

**To set up notifications using Amazon SNS**

1. Create an Amazon SNS topic by using either the [Amazon SNS console](https://console.aws.amazon.com/sns/) or the following [create-topic](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sns/create-topic.html) command. Ensure that the topic is in the same Region as the Auto Scaling group that you're using. For more information, see [Getting started with Amazon SNS](https://docs.aws.amazon.com/sns/latest/dg/sns-getting-started.html) in the *Amazon Simple Notification Service Developer Guide*. 

   ```
   aws sns create-topic --name my-sns-topic
   ```

1. Note the topic Amazon Resource Name (ARN), for example, `arn:aws:sns:region:123456789012:my-sns-topic`. You need it to create the lifecycle hook.

1. Create an IAM service role to give Amazon EC2 Auto Scaling access to your Amazon SNS notification target.

    **To give Amazon EC2 Auto Scaling access to your SNS topic** 

   1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

   1. In the navigation pane on the left, choose **Roles**.

   1. Choose **Create role**.

   1. For **Select trusted entity**, choose **AWS service**.

   1. For your use case, under **Use cases for other AWS services**, choose **EC2 Auto Scaling** and then **EC2 Auto Scaling Notification Access**.

   1. Choose **Next** twice to go to the **Name, review, and create** page.

   1. For **Role name**, enter a name for the role (for example, **my-notification-role**) and choose **Create role**.

   1. On the **Roles** page, choose the role that you just created to open the **Summary** page. Make a note of the role **ARN**. For example, `arn:aws:iam::123456789012:role/my-notification-role`. You need it to create the lifecycle hook.

1. After you have followed these instructions, continue on to [Add lifecycle hooks (AWS CLI)](adding-lifecycle-hooks.md#adding-lifecycle-hooks-aws-cli) as a next step.

### Receive notifications using Amazon SQS
<a name="sqs-notifications"></a>

You can use Amazon SQS to set up a notification target to receive messages when a lifecycle action occurs. A queue consumer must then poll an SQS queue to act on these notifications.

**Important**  
FIFO queues are not compatible with lifecycle hooks.

**To set up notifications using Amazon SQS**

1. Create an Amazon SQS queue by using the [Amazon SQS console](https://console.aws.amazon.com/sqs/). Ensure that the queue is in the same Region as the Auto Scaling group that you're using. For more information, see [Getting started with Amazon SQS](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-getting-started.html) in the *Amazon Simple Queue Service Developer Guide*. 

1. Note the queue ARN, for example, `arn:aws:sqs:us-west-2:123456789012:my-sqs-queue`. You need it to create the lifecycle hook.

1. Create an IAM service role to give Amazon EC2 Auto Scaling access to your Amazon SQS notification target.

    **To give Amazon EC2 Auto Scaling access to your SQS queue** 

   1. Open the IAM console at [https://console.aws.amazon.com/iam/](https://console.aws.amazon.com/iam/).

   1. In the navigation pane on the left, choose **Roles**.

   1. Choose **Create role**.

   1. For **Select trusted entity**, choose **AWS service**.

   1. For your use case, under **Use cases for other AWS services**, choose **EC2 Auto Scaling** and then **EC2 Auto Scaling Notification Access**.

   1. Choose **Next** twice to go to the **Name, review, and create** page.

   1. For **Role name**, enter a name for the role (for example, **my-notification-role**) and choose **Create role**.

   1. On the **Roles** page, choose the role that you just created to open the **Summary** page. Make a note of the role **ARN**. For example, `arn:aws:iam::123456789012:role/my-notification-role`. You need it to create the lifecycle hook.

1. After you have followed these instructions, continue on to [Add lifecycle hooks (AWS CLI)](adding-lifecycle-hooks.md#adding-lifecycle-hooks-aws-cli) as a next step.

### Route notifications to AWS Lambda directly
<a name="lambda-notification"></a>

You can use a Lambda function as a notification target when a lifecycle action occurs. 

**To route notifications to AWS Lambda directly**

1. Open the [Functions page](https://console.aws.amazon.com/lambda/home#/functions) on the Lambda console.

1. Choose the Lambda function you want.

   If you want to create a new Lambda function, see [Create the Lambda function](lambda-custom-termination-policy.md#lambda-custom-termination-policy-create-function)

1. Choose the **Configuration** tab and then **Permissions**. 

1. Scroll down to **Resource-based policy** and then choose **Add permissions**. A resource-based policy is used to grant permissions to invoke your function to the principal that is specified in the policy. In this case, the principal will be the [Amazon EC2 Auto Scaling service-linked role](https://docs.aws.amazon.com/autoscaling/ec2/userguide/autoscaling-service-linked-role.html) that is associated with the Auto Scaling group.

1. In the **Policy statement** section, configure your permissions: 

   1. Choose **AWS account**.

   1. For **Principal**, enter the ARN of the calling service-linked role, for example, **arn:aws:iam::<aws-account-id>:role/aws-service-role/autoscaling.amazonaws.com/AWSServiceRoleForAutoScaling**.

   1. For **Action**, choose **lambda:InvokeFunction**.

   1. For **Statement ID**, enter a unique statement ID, such as **AllowInvokeByAutoScaling**.

   1. Choose **Save**. 

1. After you have followed these instructions, continue on to [Add lifecycle hooks (AWS CLI)](adding-lifecycle-hooks.md#adding-lifecycle-hooks-aws-cli) as a next step.

### Notification message example
<a name="notification-message-example"></a>

This section provides an example of notification for Amazon SNS,Amazon SQS, and AWS Lambda.

While the instance is in a wait state, a message is published to the Amazon SNS, Amazon SQS, and AWS Lambda notification target. 

The message includes the following information:
+ `Origin` — A place where an EC2 instance is coming from.
+ `Destination` — A place where an EC2 instance is going to.
+ `LifecycleActionToken` — The lifecycle action token.
+ `AccountId` — The AWS account ID.
+ `AutoScalingGroupName` — The name of the Auto Scaling group.
+ `LifecycleHookName` — The name of the lifecycle hook.
+ `EC2InstanceId` — The ID of the EC2 instance.
+ `LifecycleTransition` — The lifecycle hook type.
+ `NotificationMetadata` — The notification metadata.

The following is a notification message example.

```
Service: AWS Auto Scaling
Time: 2021-01-19T00:36:26.533Z
RequestId: 18b2ec17-3e9b-4c15-8024-ff2e8ce8786a
Origin: EC2
Destination: AutoScalingGroup
LifecycleActionToken: 71514b9d-6a40-4b26-8523-05e7ee35fa40
AccountId: 123456789012
AutoScalingGroupName: my-asg
LifecycleHookName: my-hook
EC2InstanceId: i-0598c7d356eba48d7
LifecycleTransition: autoscaling:EC2_INSTANCE_LAUNCHING
NotificationMetadata: hook message metadata
```

#### Test notification message example
<a name="test-notification-message-example"></a>

When you first add a lifecycle hook, a test notification message is published to the notification target. The following is a test notification message example.

```
Service: AWS Auto Scaling
Time: 2021-01-19T00:35:52.359Z
RequestId: 18b2ec17-3e9b-4c15-8024-ff2e8ce8786a
Event: autoscaling:TEST_NOTIFICATION
AccountId: 123456789012
AutoScalingGroupName: my-asg
AutoScalingGroupARN: arn:aws:autoscaling:us-west-2:123456789012:autoScalingGroup:042cba90-ad2f-431c-9b4d-6d9055bcc9fb:autoScalingGroupName/my-asg
```

**Note**  
For examples of the events delivered from Amazon EC2 Auto Scaling to EventBridge, see [Amazon EC2 Auto Scaling event reference](ec2-auto-scaling-event-reference.md).

# Control instance retention with instance lifecycle policies
<a name="instance-lifecycle-policy"></a>

 Instance lifecycle policies provide protection against Amazon EC2 Auto Scaling terminations when a termination lifecycle action is abandoned. Unlike lifecycle hooks alone, instance lifecycle policies are designed to ensure that instances move to a retained state when graceful shutdown procedures don't complete successfully. 

## When to use instance lifecycle policies
<a name="when-to-use-instance-lifecycle-policies"></a>

 Use instance lifecycle policies when graceful shutdown of your application is not optional but mandatory and failed shutdowns require manual intervention. Common use cases include: 
+  Stateful applications that must complete data persistence before termination. 
+  Applications requiring extended draining periods that may exceed the maximum lifecycle hook timeout of 48 hours. 
+  Workloads handling sensitive data where failed or incomplete cleanup could result in data loss or corruption. 
+  Mission-critical services where abrupt shutdown causes availability impact. 

 For more information on how to gracefully handle instance termination, see [Design your applications to gracefully handle instance termination](gracefully-handle-instance-termination.md). 

## How instance lifecycle policies work with termination lifecycle hooks
<a name="how-instance-lifecycle-policies-work"></a>

 Instance lifecycle policies work in combination with termination lifecycle hooks, not as a replacement. The process follows several stages: 

1.  **Termination lifecycle actions execute.** When Amazon EC2 Auto Scaling selects an instance for termination, your termination lifecycle hooks are invoked and the instance enters the `Terminating:Wait` state to begin executing the termination lifecycle actions. 

1.  **Graceful shutdown attempt begins.** Your application, either running on the instance or via a control plane, receives the terminatioin lifecycle action notification and begins graceful shutdown procedures such as draining connections, completing in-progress work, or transferring data. 

1.  **Termination lifecycle actions complete.** A termination lifecycle action can complete with `CONTINUE` or `ABANDON` result. 

1.  **The instance lifecycle policy evaluates the situation.** Without an instance lifecycle policy configured, the instance proceeds to termination immediately even if the termination lifecycle action was completed with `ABANDON` result. With an instance lifecycle policy configured to retain instances on `TerminateHookAbandon`, the instance moves to a retained state if the termination lifecycle action was completed with `ABANDON` result. 

1.  **Retained instances await manual action.** Instances in retained states continue to incur standard Amazon EC2 charges. These instances don't count toward your Auto Scaling group's desired capacity, so Auto Scaling launches replacement instances to maintain the desired size. Auto Scaling features such as instance refresh and max instance lifetime will also ignore retained instances. This allows you to complete cleanup procedures manually, recover data, or investigate why automated shutdown failed before manually terminating the instance. 

1.  **Manual termination occurs.** After you complete the necessary actions on the retained instance, you need to call the `TerminateInstanceInAutoScalingGroup` API to terminate the instance. 

# Configure instance retention
<a name="configure-instance-retention"></a>

Set up your Amazon EC2 Auto Scaling group to retain instances when termination lifecycle actions fail.

 To use instance lifecycle policies in your Auto Scaling group, you must also configure a termination lifecycle hook. If you configure an instance lifecycle policy but don't have any termination lifecycle hooks, the policy has no effect. Instance lifecycle policies will only apply when termination lifecycle actions are abandoned, not when they complete successfully with the `CONTINUE` result. 

 Instance lifecycle policies use retention triggers to determine when to retain an instance. The `TerminateHookAbandon` trigger causes retention in several scenarios: 
+  When you explicitly call the [ CompleteLifecycleAction ](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_CompleteLifecycleAction.html) API with the `ABANDON` result. 
+  When a termination lifecycle action with default result `ABANDON` times out because the heartbeat timeout is reached without receiving a heartbeat. 
+  When the global timeout is reached on a termination lifecycle action with default result `ABANDON`, which is 48 hours or 100 times the heartbeat timeout, whichever is smaller 

------
#### [ Console ]

**To configure instance retention**

1. Open the Amazon EC2 Auto Scaling console

1. Create your Auto Scaling group (instance lifecycle policy defaults to Terminate)

1. Go to your Auto Scaling group details page and choose the **Instance Management** tab

1. In **Instance lifecycle policy for lifecycle hooks**, choose **Retain**

1. Create your termination lifecycle hooks with:
   + Lifecycle transition set to **Instance terminate**
   + Default result set to **Abandon**

------
#### [ AWS CLI ]

**To configure instance retention**  
 Use the [create-auto-scaling-group](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/create-auto-scaling-group.html) command with an instance lifecycle policy: 

```
aws autoscaling create-auto-scaling-group \
--auto-scaling-group-name my-asg \
--launch-template LaunchTemplateName=my-template,Version='$Latest' \
--min-size 1 \
--max-size 3 \
--desired-capacity 2 \
--vpc-zone-identifier subnet-12345678 \
--instance-lifecycle-policy file://lifecycle-policy.json
```

Contents of lifecycle-policy.json:

```
{
    "RetentionTriggers": {
        "TerminateHookAbandon": "retain"
    }
}
```

**To add a termination lifecycle hook**  
Use the [put-lifecycle-hook](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/put-lifecycle-hook.html) command:

```
aws autoscaling put-lifecycle-hook \
--lifecycle-hook-name my-termination-hook \
--auto-scaling-group-name my-asg \
--lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING \
--default-result ABANDON \
--heartbeat-timeout 300
```

------

# Manage retained instances
<a name="manage-retained-instances"></a>

 Monitor and control Amazon EC2 instances that have been moved to a retained state. Use CloudWatch metrics to track retained instances, then manually terminate retained instances after completing your custom actions. 

 Retained instances do not count toward your Amazon EC2 Auto Scaling group's desired capacity. When an instance enters a retained state, Auto Scaling launches a replacement instance to maintain the desired capacity. For example, suppose your Auto Scaling group has a desired capacity of 10. When an instance enters the `Terminating:Retained` state, Auto Scaling launches a replacement instance to maintain the desired capacity of 10. You now have 11 running instances in total: 10 in your active group plus 1 retained instance. Standard Amazon EC2 charges for all 11 instances will apply until you manually terminate the retained instance. 

## Instance lifecycle states of retained instances
<a name="instance-lifecyle-states-of-retained-instances"></a>

 Understand how instances transition through lifecycle states when instance lifecycle policies are used. Instances follow a specific path from normal termination through retention to final termination. 

*When retention is triggered, instances transition through these states:*

1. `Terminating` - Normal termination begins

1. `Terminating:Wait` - Lifecycle hook executes

1. `Terminating:Proceed` - Lifecycle actions wrap up (whether they succeeded or failed)

1. `Terminating:Retained` - Hook fails, instance retained for manual intervention

Warm pool instances take different lifecycle state paths depending on the scenario:

*Instances scaling back into the warm pool:*

1. `Warmed:Pending` - Normal warm pool transition begins

1. `Warmed:Pending:Wait` - Lifecycle hook executes

1. `Warmed:Pending:Proceed` - Lifecycle actions wrap up (whether they succeeded or failed)

1. `Warmed:Pending:Retained` - Hook fails, instance retained for manual intervention

*Instances being terminated from the warm pool:*

1. `Warmed:Terminating` - Normal termination begins

1. `Warmed:Terminating:Wait` - Lifecycle hook executes

1. `Warmed:Terminating:Proceed` - Lifecycle actions wrap up (whether they succeeded or failed)

1. `Warmed:Terminating:Retained` - Hook fails, instance retained for manual intervention

## Monitor retained instances
<a name="monitor-retained-instances"></a>

 Because retained Amazon EC2 instances incur costs and require manual intervention, monitoring them is essential. Amazon EC2 Auto Scaling provides several CloudWatch metrics to track retained instances. 

Enable group metrics to track retained instances:

```
aws autoscaling enable-metrics-collection \
--auto-scaling-group-name my-asg \
--metrics GroupTerminatingRetainedInstances
```

The available metrics are:
+  `GroupTerminatingRetainedInstances` shows the number of instances in the `Terminating:Retained` state. 
+  `GroupTerminatingRetainedCapacity` shows the capacity units represented by instances in the `Terminating:Retained` state. 
+  `WarmPoolTerminatingRetainedCapacity` tracks retained instances terminating from the warm pool. 
+  `WarmPoolPendingRetainedCapacity` tracks retained instances returning to the warm pool. 

 You can also check your Amazon EC2 Auto Scaling group's scaling activities to understand why instances were retained. Look for termination activities with `StatusCode: Cancelled` and status reason messages indicating lifecycle hook failures: 

```
aws autoscaling describe-scaling-activities \
--auto-scaling-group-name my-asg
```

 We recommend creating CloudWatch alarms on these metrics to alert you when instances enter a retained state. This helps you track cost implications and ensures you don't forget to clean up instances that require manual intervention. 

## Terminate retained instances
<a name="terminate-retained-instances"></a>

After completing your custom actions, terminate your retained instances by calling the [ TerminateInstanceInAutoScalingGroup ](https://docs.aws.amazon.com/autoscaling/ec2/APIReference/API_TerminateInstanceInAutoScalingGroup.html) API: 

```
aws autoscaling terminate-instance-in-auto-scaling-group \
--instance-id i-1234567890abcdef0 \
--no-should-decrement-desired-capacity
```

# Retrieve the target lifecycle state through instance metadata
<a name="retrieving-target-lifecycle-state-through-imds"></a>

Each Auto Scaling instance that you launch goes through several lifecycle states. To invoke custom actions from within an instance that act on specific lifecycle state transitions, you must retrieve the target lifecycle state through instance metadata. 

For example, you might need a mechanism to detect instance termination from inside the instance to run some code on the instance before it's terminated. You can do this by writing code that polls for the lifecycle state of an instance directly from the instance. You can then add a lifecycle hook to the Auto Scaling group to keep the instance running until your code sends the **complete-lifecycle-action** command to continue. 

The Auto Scaling instance lifecycle has two primary steady states—`InService` and `Terminated`—and two side steady states—`Detached` and `Standby`. If you use a warm pool, the lifecycle has four additional steady states—`Warmed:Hibernated`, `Warmed:Running`, `Warmed:Stopped`, and `Warmed:Terminated`.

When an instance prepares to transition to one of the preceding steady states, Amazon EC2 Auto Scaling updates the value of the instance metadata item `autoscaling/target-lifecycle-state`. To get the target lifecycle state from within the instance, you must use the Instance Metadata Service to retrieve it from the instance metadata. 

**Note**  
*Instance metadata* is data about an Amazon EC2 instance that applications can use to query instance information. The *Instance Metadata Service* is an on-instance component that local code uses to access instance metadata. Local code can include user data scripts or applications running on the instance.

Local code can access instance metadata from a running instance using one of two methods: Instance Metadata Service Version 1 (IMDSv1) or Instance Metadata Service Version 2 (IMDSv2). IMDSv2 uses session-oriented requests and mitigates several types of vulnerabilities that could be used to try to access the instance metadata. For details about these two methods, see [Use IMDSv2](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/configuring-instance-metadata-service.html) in the *Amazon EC2 User Guide*.

------
#### [ IMDSv2 ]

```
[ec2-user ~]$ TOKEN=`curl -X PUT "http://169.254.169.254/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"` \
&& curl -H "X-aws-ec2-metadata-token: $TOKEN" -v http://169.254.169.254/latest/meta-data/autoscaling/target-lifecycle-state
```

------
#### [ IMDSv1 ]

```
[ec2-user ~]$ curl http://169.254.169.254/latest/meta-data/autoscaling/target-lifecycle-state
```

------

The following is example output.

```
InService
```

The target lifecycle state is the state that the instance is transitioning to. The current lifecycle state is the state that the instance is in. These can be the same after the lifecycle action is complete and the instance finishes its transition to the target lifecycle state. You cannot retrieve the current lifecycle state of the instance from the instance metadata.

Amazon EC2 Auto Scaling started generating the target lifecycle state on March 10, 2022. If your instance transitions to one of the target lifecycle states after that date, the target lifecycle state item is present in your instance metadata. Otherwise, it is not present, and you receive an HTTP 404 error.

For more information about retrieving instance metadata, see [Retrieve instance metadata](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html) in the *Amazon EC2 User Guide*.

For a tutorial that shows you how to create a lifecycle hook with a custom action in a user data script that uses the target lifecycle state, see [Tutorial: Use data script and instance metadata to retrieve lifecycle state](tutorial-lifecycle-hook-instance-metadata.md).

**Important**  
To ensure that you can invoke a custom action as soon as possible, your local code should poll IMDS frequently and retry on errors.

# Add lifecycle hooks to your Auto Scaling group
<a name="adding-lifecycle-hooks"></a>

To put your Auto Scaling instances into a wait state and perform custom actions on them, you can add lifecycle hooks to your Auto Scaling group. Custom actions are performed as the instances launch or before they terminate. Instances remain in a wait state until you either complete the lifecycle action, or the timeout period ends.

After you create an Auto Scaling group from the AWS Management Console, you can add one or more lifecycle hooks to it, up to a total of 50 lifecycle hooks. You can also use the AWS CLI, CloudFormation, or an SDK to add lifecycle hooks to an Auto Scaling group as you are creating it.

By default, when you add a lifecycle hook in the console, Amazon EC2 Auto Scaling sends lifecycle event notifications to Amazon EventBridge. Using EventBridge or a user data script is a recommended best practice. To create a lifecycle hook that sends notifications directly to Amazon SNS, Amazon SQS, or AWS Lambda you can use the [put-lifecycle-hook](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/put-lifecycle-hook.html) command, as shown in the examples in this topic.

**Topics**
+ [

## Add lifecycle hooks (console)
](#adding-lifecycle-hooks-console)
+ [

## Add lifecycle hooks (AWS CLI)
](#adding-lifecycle-hooks-aws-cli)

## Add lifecycle hooks (console)
<a name="adding-lifecycle-hooks-console"></a>

Follow these steps to add lifecycle hooks to your Auto Scaling group. To add lifecycle hooks for scaling out (instances launching) and scaling in (instances terminating or returning to a warm pool), you must create two separate hooks. 

Before you begin, confirm that you have set up a custom action, as needed, as described in [Prepare to add a lifecycle hook to your Auto Scaling group](prepare-for-lifecycle-notifications.md).

**To add a lifecycle hook for scale out**

1. Open the Amazon EC2 console at [https://console.aws.amazon.com/ec2/](https://console.aws.amazon.com/ec2/), and choose **Auto Scaling Groups** from the navigation pane.

1. Select the check box next to your Auto Scaling group. A split pane opens up in the bottom of the page. 

1. On the **Instance management** tab, in **Lifecycle hooks**, choose **Create lifecycle hook**.

1. To define a lifecycle hook for scale out (instances launching), do the following:

   1. For **Lifecycle hook name**, specify a name for the lifecycle hook.

   1. For **Lifecycle transition**, choose **Instance launch**.

   1. For **Heartbeat timeout**, specify the amount of time, in seconds, for instances to remain in a wait state when scaling out before the hook times out. The range is from `30` to `7200` seconds. Setting a long timeout period provides more time for your custom action to complete. Then, if you finish before the timeout period ends, send the [complete-lifecycle-action](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/complete-lifecycle-action.html) command to allow the instance to proceed to the next state. 

   1. For **Default result**, specify the action to take when the lifecycle hook timeout elapses or when an unexpected failure occurs. You can choose to either **CONTINUE** or **ABANDON**.
      + If you choose **CONTINUE**, the Auto Scaling group can proceed with any other lifecycle hooks and then put the instance into service.
      + If you choose **ABANDON**, the Auto Scaling group stops any remaining actions and terminates the instance immediately.

   1. (Optional) For **Notification metadata**, specify other information that you want to include when Amazon EC2 Auto Scaling sends a message to the notification target. 

1. Choose **Create**.

**To add a lifecycle hook for scale in**

1. Choose **Create lifecycle hook** to continue where you left off after creating a lifecycle hook for scale out.

1. To define a lifecycle hook for scale in (instances terminating or returning to a warm pool), do the following:

   1. For **Lifecycle hook name**, specify a name for the lifecycle hook.

   1. For **Lifecycle transition**, choose **Instance terminate**. 

   1. For **Heartbeat timeout**, specify the amount of time, in seconds, for instances to remain in a wait state when scaling out before the hook times out. We recommend a short timeout period of `30` to `120` seconds, depending on how much time you need to perform any final tasks, such as pulling EC2 logs from CloudWatch.

   1. For **Default result**, specify the action that the Auto Scaling group takes when the timeout elapses or if an unexpected failure occurs. Both **ABANDON** and **CONTINUE** let the instance terminate. 
      + If you choose **CONTINUE**, the Auto Scaling group can proceed with any remaining actions, such as other lifecycle hooks, before termination. 
      + If you choose **ABANDON**, the Auto Scaling group terminates the instance immediately. 

   1. (Optional) For **Notification metadata**, specify other information that you want to include when Amazon EC2 Auto Scaling sends a message to the notification target.

1. Choose **Create**.

## Add lifecycle hooks (AWS CLI)
<a name="adding-lifecycle-hooks-aws-cli"></a>

Create and update lifecycle hooks using the [put-lifecycle-hook](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/put-lifecycle-hook.html) command.

To perform an action on scale out, use the following command.

```
aws autoscaling put-lifecycle-hook --lifecycle-hook-name my-launch-hook  \
  --auto-scaling-group-name my-asg \
  --lifecycle-transition autoscaling:EC2_INSTANCE_LAUNCHING
```

To perform an action on scale in, use the following command instead.

```
aws autoscaling put-lifecycle-hook --lifecycle-hook-name my-termination-hook  \
  --auto-scaling-group-name my-asg \
  --lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING
```

To receive notifications using Amazon SNS or Amazon SQS, add the `--notification-target-arn` and `--role-arn` options. To receive notifications using AWS Lambda, add the `--notification-target-arn`.

The following example creates a lifecycle hook that specifies an SNS topic named `my-sns-topic` as the notification target.

```
aws autoscaling put-lifecycle-hook --lifecycle-hook-name my-termination-hook  \
  --auto-scaling-group-name my-asg \
  --lifecycle-transition autoscaling:EC2_INSTANCE_TERMINATING \
  --notification-target-arn arn:aws:sns:region:123456789012:my-sns-topic \
  --role-arn arn:aws:iam::123456789012:role/my-notification-role
```

The topic receives a test notification with the following key-value pair.

```
"Event": "autoscaling:TEST_NOTIFICATION"
```

By default, the [put-lifecycle-hook](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/put-lifecycle-hook.html) command creates a lifecycle hook with a heartbeat timeout of `3600` seconds (one hour). 

To change the heartbeat timeout for an existing lifecycle hook, add the `--heartbeat-timeout` option, as shown in the following example.

```
aws autoscaling put-lifecycle-hook --lifecycle-hook-name my-termination-hook \
  --auto-scaling-group-name my-asg --heartbeat-timeout 120
```

If an instance is already in a wait state, you can prevent the lifecycle hook from timing out by recording a heartbeat, using the [record-lifecycle-action-heartbeat](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/record-lifecycle-action-heartbeat.html) CLI command. This extends the timeout period by the timeout value specified when you created the lifecycle hook. If you finish before the timeout period ends, you can send the [complete-lifecycle-action](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/complete-lifecycle-action.html) CLI command to allow the instance to proceed to the next state. For more information and examples, see [Complete a lifecycle action in an Auto Scaling group](completing-lifecycle-hooks.md).

# Complete a lifecycle action in an Auto Scaling group
<a name="completing-lifecycle-hooks"></a>

When an Auto Scaling group responds to a lifecycle event, it puts the instance in a wait state and sends an event notification. You can perform a custom action while the instance is in a wait state.

Completing the lifecycle action with a result of `CONTINUE` is helpful if you finish before the timeout period has expired. If you don't complete the lifecycle action, the lifecycle hook goes to the status that you specified for **Default result** after the timeout period ends.

**Topics**
+ [

## Complete a lifecycle action (manual)
](#completing-lifecycle-hooks-aws-cli)
+ [

## Complete a lifecycle action (automatic)
](#completing-lifecycle-hooks-automatic)

## Complete a lifecycle action (manual)
<a name="completing-lifecycle-hooks-aws-cli"></a>

The following procedure is for the command line interface and is not supported in the console. Information that must be replaced, such as the instance ID or the name of an Auto Scaling group, are shown in italics. 

**To complete a lifecycle action (AWS CLI)**

1. If you need more time to complete the custom action, use the [record-lifecycle-action-heartbeat](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/record-lifecycle-action-heartbeat.html) command to restart the timeout period and keep the instance in a wait state. For example, if the timeout period is one hour, and you call this command after 30 minutes, the instance remains in a wait state for an additional hour, or a total of 90 minutes. 

   You can specify the lifecycle action token that you received with the [notification](prepare-for-lifecycle-notifications.md#notification-message-example), as shown in the following command.

   ```
   aws autoscaling record-lifecycle-action-heartbeat --lifecycle-hook-name my-launch-hook \
     --auto-scaling-group-name my-asg --lifecycle-action-token bcd2f1b8-9a78-44d3-8a7a-4dd07d7cf635
   ```

   Alternatively, you can specify the ID of the instance that you received with the [notification](prepare-for-lifecycle-notifications.md#notification-message-example), as shown in the following command.

   ```
   aws autoscaling record-lifecycle-action-heartbeat --lifecycle-hook-name my-launch-hook \
     --auto-scaling-group-name my-asg --instance-id i-1a2b3c4d
   ```

1. If you finish the custom action before the timeout period ends, use the [complete-lifecycle-action](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/complete-lifecycle-action.html) command so that the Auto Scaling group can continue launching or terminating the instance. You can specify the lifecycle action token, as shown in the following command.

   ```
   aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE \
     --lifecycle-hook-name my-launch-hook --auto-scaling-group-name my-asg \
     --lifecycle-action-token bcd2f1b8-9a78-44d3-8a7a-4dd07d7cf635
   ```

   Alternatively, you can specify the ID of the instance, as shown in the following command.

   ```
   aws autoscaling complete-lifecycle-action --lifecycle-action-result CONTINUE \
     --instance-id i-1a2b3c4d --lifecycle-hook-name my-launch-hook \
     --auto-scaling-group-name my-asg
   ```

## Complete a lifecycle action (automatic)
<a name="completing-lifecycle-hooks-automatic"></a>

If you have a user data script that configures your instances after they launch, you do not need to manually complete lifecycle actions. You can add the [complete-lifecycle-action](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/autoscaling/complete-lifecycle-action.html) command to the script. The script can retrieve the instance ID from the instance metadata and signal Amazon EC2 Auto Scaling when the bootstrap scripts have completed successfully. 

If you are not doing so already, update your script to retrieve the instance ID of the instance from the instance metadata. For more information, see [Retrieve instance metadata](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/instancedata-data-retrieval.html) in the *Amazon EC2 User Guide*.

If you use Lambda, you can also set up a callback in your function's code to let the lifecycle of the instance proceed if the custom action is successful. For more information, see [Tutorial: Configure a lifecycle hook that invokes a Lambda function](tutorial-lifecycle-hook-lambda.md).

# Tutorial: Use data script and instance metadata to retrieve lifecycle state
<a name="tutorial-lifecycle-hook-instance-metadata"></a>

A common way to create custom actions for lifecycle hooks is to use notifications that Amazon EC2 Auto Scaling sends to other services, such as Amazon EventBridge. However, you can avoid having to create additional infrastructure by instead using a user data script to move the code that configures instances and completes the lifecycle action into the instances themselves. 

The following tutorial shows you how to get started using a user data script and instance metadata. You create a basic Auto Scaling group configuration with a user data script that reads the [target lifecycle state](retrieving-target-lifecycle-state-through-imds.md) of the instances in your group and performs a callback action at a specific phase of an instance's lifecycle to continue the launch process.

The following illustration summarizes the flow for a scale-out event when you use a user data script to perform a custom action. After an instance launches, the lifecycle of the instance is paused until the lifecycle hook is completed, either by timing out or by Amazon EC2 Auto Scaling receiving a signal to continue. 

![\[The flow for a scale-out event when you use a user data script to perform a custom action.\]](http://docs.aws.amazon.com/autoscaling/ec2/userguide/images/lifecycle-hook-user-data-script.png)


**Topics**
+ [

## Step 1: Create an IAM role with permissions to complete lifecycle actions
](#instance-metadata-create-iam-role)
+ [

## Step 2: Create a launch template and include the IAM role and a user data script
](#instance-metadata-create-hello-world-function)
+ [

## Step 3: Create an Auto Scaling group
](#instance-metadata-create-auto-scaling-group)
+ [

## Step 4: Add a lifecycle hook
](#instance-metadata-add-lifecycle-hook)
+ [

## Step 5: Test and verify the functionality
](#instance-metadata-testing-hook)
+ [

## Step 6: Clean up
](#instance-metadata-lifecycle-hooks-tutorial-cleanup)
+ [

## Related resources
](#instance-metadata-lifecycle-hooks-tutorial-related-resources)

## Step 1: Create an IAM role with permissions to complete lifecycle actions
<a name="instance-metadata-create-iam-role"></a>

When you use the AWS CLI or an AWS SDK to send a callback to complete lifecycle actions, you must use an IAM role with permissions to complete lifecycle actions. 

**To create the policy**

1. Open the [Policies page](https://console.aws.amazon.com/iam/home?#/policies) of the IAM console, and then choose **Create policy**.

1. Choose the **JSON** tab.

1. In the **Policy Document** box, copy and paste the following policy document into the box. Replace the **sample text** with your account number and the name of the Auto Scaling group that you want to create (**TestAutoScalingEvent-group**).

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "autoscaling:CompleteLifecycleAction"
         ],
         "Resource": "arn:aws:autoscaling:*:123456789012:autoScalingGroup:*:autoScalingGroupName/TestAutoScalingEvent-group"
       }
     ]
   }
   ```

------

1. Choose **Next**. 

1. For **Policy name**, enter **TestAutoScalingEvent-policy**. Choose **Create policy**.

When you finish creating the policy, you can create a role that uses it.

**To create the role**

1. In the navigation pane on the left, choose **Roles**.

1. Choose **Create role**.

1. For **Select trusted entity**, choose **AWS service**.

1. For your use case, choose **EC2** and then choose **Next**. 

1. Under **Add permissions**, choose the policy that you created (**TestAutoScalingEvent-policy**). Then, choose **Next**. 

1. On the **Name, review, and create** page, for **Role name**, enter **TestAutoScalingEvent-role** and choose **Create role**. 

## Step 2: Create a launch template and include the IAM role and a user data script
<a name="instance-metadata-create-hello-world-function"></a>

Create a launch template to use with your Auto Scaling group. Include the IAM role you created and the provided sample user data script.

**To create a launch template**

1. Open the [Launch templates page](https://console.aws.amazon.com/ec2/v2/#LaunchTemplates) of the Amazon EC2 console.

1. Choose **Create launch template**.

1. For **Launch template name**, enter **TestAutoScalingEvent-template**.

1. Under **Auto Scaling guidance**, select the check box. 

1. For **Application and OS Images (Amazon Machine Image)**, choose Amazon Linux 2 (HVM), SSD Volume Type, 64-bit (x86) from the **Quick Start** list. 

1. For **Instance type**, choose a type of Amazon EC2 instance (for example, "t2.micro").

1. For **Advanced details**, expand the section to view the fields. 

1. For **IAM instance profile**, choose the IAM instance profile name of your IAM role (**TestAutoScalingEvent-role**). An instance profile is a container for an IAM role that allows Amazon EC2 to pass the IAM role to an instance when the instance is launched.

   When you used the IAM console to create an IAM role, the console automatically created an instance profile with the same name as its corresponding role.

1. For **User data**, copy and paste the following sample user data script into the field. Replace the sample text for `group_name` with the name of the Auto Scaling group that you want to create and `region` with the AWS Region you want your Auto Scaling group to use.

   ```
   #!/bin/bash
   
   function token {
       echo "X-aws-ec2-metadata-token: $(curl -X PUT 'http://169.254.169.254/latest/api/token' -H 'X-aws-ec2-metadata-token-ttl-seconds: 21600')"
   }
   
   function get_target_state {
       echo $(curl -H "$(token)" -s http://169.254.169.254/latest/meta-data/autoscaling/target-lifecycle-state)
   }
   
   function get_instance_id {
       echo $(curl -H "$(token)" -s http://169.254.169.254/latest/meta-data/instance-id)
   }
   
   function complete_lifecycle_action {
       instance_id=$(get_instance_id)
       group_name='TestAutoScalingEvent-group'
       region='us-west-2'
    
       echo $instance_id
       echo $region
       echo $(aws autoscaling complete-lifecycle-action \
         --lifecycle-hook-name TestAutoScalingEvent-hook \
         --auto-scaling-group-name $group_name \
         --lifecycle-action-result CONTINUE \
         --instance-id $instance_id \
         --region $region)
   }
   
   function main {
       while true
       do
           target_state=$(get_target_state)
           if [ \"$target_state\" = \"InService\" ]; then
               # Change hostname
               export new_hostname="${group_name}-$instance_id"
               hostname $new_hostname
               # Send callback
               complete_lifecycle_action
               break
           fi
           echo $target_state
           sleep 5
       done
   }
   
   main
   ```

   This simple user data script does the following:
   + Calls the instance metadata to retrieve the target lifecycle state and instance ID from the instance metadata
   + Retrieves the target lifecycle state repeatedly until it changes to `InService`
   + Changes the hostname of the instance to the instance ID prepended with the name of the Auto Scaling group, if the target lifecycle state is `InService`
   + Sends a callback by calling the **complete-lifecycle-action** CLI command to signal Amazon EC2 Auto Scaling to `CONTINUE` the EC2 launch process

1. Choose **Create launch template**.

1. On the confirmation page, choose **Create Auto Scaling group**.

**Note**  
For other examples that you can use as a reference for developing your user data script, see the [GitHub repository](https://github.com/aws-samples/amazon-ec2-auto-scaling-group-examples) for Amazon EC2 Auto Scaling.

## Step 3: Create an Auto Scaling group
<a name="instance-metadata-create-auto-scaling-group"></a>

After you create your launch template, create an Auto Scaling group.

**To create an Auto Scaling group**

1. On the **Choose launch template or configuration** page, for **Auto Scaling group name**, enter a name for your Auto Scaling group (**TestAutoScalingEvent-group**).

1. Choose **Next** to go to the **Choose instance launch options** page. 

1. For **Network**, choose a VPC.

1. For **Availability Zones and subnets**, choose one or more subnets from one or more Availability Zones.

1. In the **Instance type requirements** section, use the default setting to simplify this step. (Do not override the launch template.) For this tutorial, you will launch only one On-Demand Instance using the instance type specified in your launch template. 

1. Choose **Skip to review** at the bottom of the screen. 

1. On the **Review** page, review the details of your Auto Scaling group, and then choose **Create Auto Scaling group**.

## Step 4: Add a lifecycle hook
<a name="instance-metadata-add-lifecycle-hook"></a>

Add a lifecycle hook to hold the instance in a wait state until your lifecycle action is complete.

**To add a lifecycle hook**

1. Open the [Auto Scaling groups page](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups) of the Amazon EC2 console.

1. Select the check box next to your Auto Scaling group. A split pane opens up in the bottom of the page. 

1. In the lower pane, on the **Instance management** tab, in **Lifecycle hooks**, choose **Create lifecycle hook**.

1. To define a lifecycle hook for scale out (instances launching), do the following:

   1. For **Lifecycle hook name**, enter **TestAutoScalingEvent-hook**.

   1. For **Lifecycle transition**, choose **Instance launch**.

   1. For **Heartbeat timeout**, enter **300** for the number of seconds to wait for a callback from your user data script.

   1. For **Default result**, choose **ABANDON**. If the hook times out without receiving a callback from your user data script, the Auto Scaling group terminates the new instance.

   1. (Optional) Keep **Notification metadata** blank.

1. Choose **Create**.

## Step 5: Test and verify the functionality
<a name="instance-metadata-testing-hook"></a>

To test the functionality, update the Auto Scaling group by increasing the desired capacity of the Auto Scaling group by 1. The user data script runs and starts to check the instance's target lifecycle state soon after the instance launches. The script changes the hostname and sends a callback action when the target lifecycle state is `InService`. This usually takes only a few seconds to finish.

**To increase the size of the Auto Scaling group**

1. Open the [Auto Scaling groups page](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups) of the Amazon EC2 console.

1. Select the check box next to your Auto Scaling group. View details in a lower pane while still seeing the top rows of the upper pane. 

1. In the lower pane, on the **Details** tab, choose **Group details**, **Edit**.

1. For **Desired capacity**, increase the current value by 1.

1. Choose **Update**. While the instance is being launched, the **Status** column in the upper pane displays a status of *Updating capacity*. 

After increasing the desired capacity, you can verify that your instance has successfully launched and is not terminated from the description of scaling activities. 

**To view the scaling activity**

1. Return to the **Auto Scaling groups** page and select your group.

1. On the **Activity** tab, under **Activity history**, the **Status** column shows whether your Auto Scaling group has successfully launched an instance. 

1. If the user data script fails, after the timeout period passes, you see a scaling activity with a status of `Canceled` and a status message of `Instance failed to complete user's Lifecycle Action: Lifecycle Action with token e85eb647-4fe0-4909-b341-a6c42EXAMPLE was abandoned: Lifecycle Action Completed with ABANDON Result`.

## Step 6: Clean up
<a name="instance-metadata-lifecycle-hooks-tutorial-cleanup"></a>

If you are done working with the resources that you created for this tutorial, use the following steps to delete them.

**To delete the lifecycle hook**

1. Open the [Auto Scaling groups page](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups) of the Amazon EC2 console.

1. Select the check box next to your Auto Scaling group.

1. On the **Instance management** tab, in **Lifecycle hooks**, choose the lifecycle hook (`TestAutoScalingEvent-hook`).

1. Choose **Actions**, **Delete**.

1. Choose **Delete** again to confirm.

**To delete the launch template**

1. Open the [Launch templates page](https://console.aws.amazon.com/ec2/v2/#LaunchTemplates) of the Amazon EC2 console.

1. Select your launch template (`TestAutoScalingEvent-template`) and then choose **Actions**, **Delete template**.

1. When prompted for confirmation, type **Delete** to confirm deleting the specified launch template and then choose **Delete**.

If you are done working with the example Auto Scaling group, delete it. You can also delete the IAM role and permissions policy that you created.

**To delete the Auto Scaling group**

1. Open the [Auto Scaling groups page](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups) of the Amazon EC2 console.

1. Select the check box next to your Auto Scaling group (`TestAutoScalingEvent-group`) and choose **Delete**. 

1. When prompted for confirmation, type **delete** to confirm deleting the specified Auto Scaling group and then choose **Delete**.

   A loading icon in the **Name** column indicates that the Auto Scaling group is being deleted. It takes a few minutes to terminate the instances and delete the group. 

**To delete the IAM role**

1. Open the [Roles page](https://console.aws.amazon.com/iam/home?#/roles) of the IAM console.

1. Select the function's role (`TestAutoScalingEvent-role`).

1. Choose **Delete**.

1. When prompted for confirmation, type the name of the role and then choose **Delete**.

**To delete the IAM policy**

1. Open the [Policies page](https://console.aws.amazon.com/iam/home?#/policies) of the IAM console.

1. Select the policy that you created (`TestAutoScalingEvent-policy`).

1. Choose **Actions**, **Delete**.

1. When prompted for confirmation, type the name of the policy and then choose **Delete**.

## Related resources
<a name="instance-metadata-lifecycle-hooks-tutorial-related-resources"></a>

The following related topics can be helpful as you develop code that invokes actions on instances based on data available in the instance metadata.
+ [Retrieve the target lifecycle state through instance metadata](retrieving-target-lifecycle-state-through-imds.md). This section describes the lifecycle state for other use cases, such as instance termination.
+ [Add lifecycle hooks (console)](adding-lifecycle-hooks.md#adding-lifecycle-hooks-console). This procedure shows you how to add lifecycle hooks for both scale out (instances launching) and scale in (instances terminating or returning to a warm pool).
+ [Instance metadata categories](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html#instancedata-data-categories) in the *Amazon EC2 User Guide*. This topic lists all categories of instance metadata that you can use to invoke actions on EC2 instances.

For a tutorial that shows you how to use Amazon EventBridge to create rules that invoke Lambda functions based on events that happen to the instances in your Auto Scaling group, see [Tutorial: Configure a lifecycle hook that invokes a Lambda function](tutorial-lifecycle-hook-lambda.md).

# Tutorial: Configure a lifecycle hook that invokes a Lambda function
<a name="tutorial-lifecycle-hook-lambda"></a>

In this exercise, you create an Amazon EventBridge rule that includes a filter pattern that when matched, invokes an AWS Lambda function as the rule target. We provide the filter pattern and sample function code to use. 

If everything is configured correctly, at the end of this tutorial, the Lambda function performs a custom action when instances launch. The custom action simply logs the event in the CloudWatch Logs log stream associated with the Lambda function.

The Lambda function also performs a callback to let the lifecycle of the instance proceed if this action is successful, but lets the instance abandon the launch and terminate if the action fails.

The following illustration summarizes the flow for a scale-out event when you use a Lambda function to perform a custom action. After an instance launches, the lifecycle of the instance is paused until the lifecycle hook is completed, either by timing out or by Amazon EC2 Auto Scaling receiving a signal to continue. 

![\[The flow for a scale-out event when you use a Lambda function to perform a custom action.\]](http://docs.aws.amazon.com/autoscaling/ec2/userguide/images/lifecycle-hook-lambda-function.png)


**Note**  
Depending on your use case, you can configure a lifecycle hook by following the steps below and creating an EventBridge rule. Or, you can use a Lambda function to configure a lifecycle hook directly without creating an EventBridge rule.

**Topics**
+ [

## Prerequisites
](#lambda-hello-world-tutorial-prerequisites)
+ [

## Step 1: Create an IAM role with permissions to complete lifecycle actions
](#lambda-create-iam-role)
+ [

## Step 2: Create a Lambda function
](#lambda-create-hello-world-function)
+ [

## Step 3: Create an EventBridge rule
](#lambda-create-rule)
+ [

## Step 4: Add a lifecycle hook
](#lambda-add-lifecycle-hook)
+ [

## Step 5: Test and verify the event
](#lambda-testing-hook-notifications)
+ [

## Step 6: Clean up
](#lambda-lifecycle-hooks-tutorial-cleanup)
+ [

## Related resources
](#lambda-lifecycle-hooks-tutorial-related-resources)

## Prerequisites
<a name="lambda-hello-world-tutorial-prerequisites"></a>

Before you begin this tutorial, create an Auto Scaling group, if you don't have one already. To create an Auto Scaling group, open the [Auto Scaling groups page](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups) of the Amazon EC2 console and choose **Create Auto Scaling group**.

## Step 1: Create an IAM role with permissions to complete lifecycle actions
<a name="lambda-create-iam-role"></a>

Before you create a Lambda function, you must first create an execution role and a permissions policy to allow Lambda to complete lifecycle hooks.

**To create the policy**

1. Open the [Policies page](https://console.aws.amazon.com/iam/home?#/policies) of the IAM console, and then choose **Create policy**.

1. Choose the **JSON** tab.

1. In the **Policy Document** box, paste the following policy document into the box, replacing the text in **italics** with your account number and the name of your Auto Scaling group.

------
#### [ JSON ]

****  

   ```
   {
     "Version":"2012-10-17",		 	 	 
     "Statement": [
       {
         "Effect": "Allow",
         "Action": [
           "autoscaling:CompleteLifecycleAction"
         ],
         "Resource": "arn:aws:autoscaling:*:123456789012:autoScalingGroup:*:autoScalingGroupName/my-asg"
       }
     ]
   }
   ```

------

1. Choose **Next**. 

1. For **Policy name**, enter **LogAutoScalingEvent-policy**. Choose **Create policy**.

When you finish creating the policy, you can create a role that uses it.

**To create the role**

1. In the navigation pane on the left, choose **Roles**.

1. Choose **Create role**.

1. For **Select trusted entity**, choose **AWS service**.

1. For your use case, choose **Lambda** and then choose **Next**. 

1. Under **Add permissions**, choose the policy that you created (**LogAutoScalingEvent-policy**) and the policy named **AWSLambdaBasicExecutionRole**. Then, choose **Next**. 
**Note**  
The **AWSLambdaBasicExecutionRole** policy has the permissions that the function needs to write logs to CloudWatch Logs.

1. On the **Name, review, and create** page, for **Role name**, enter **LogAutoScalingEvent-role** and choose **Create role**.

## Step 2: Create a Lambda function
<a name="lambda-create-hello-world-function"></a>

Create a Lambda function to serve as the target for events. The sample Lambda function, written in Node.js, is invoked by EventBridge when a matching event is emitted by Amazon EC2 Auto Scaling.

**To create a Lambda function**

1. Open the [Functions page](https://console.aws.amazon.com/lambda/home#/functions) on the Lambda console.

1. Choose **Create function**, **Author from scratch**.

1. Under **Basic information**, for **Function name**, enter **LogAutoScalingEvent**.

1. For **Runtime**, choose **Node.js 18.x**.

1. Scroll down and choose **Change default execution role**, and then for **Execution role**, choose **Use an existing role**.

1. For **Existing role**, choose **LogAutoScalingEvent-role**.

1. Leave the other default values.

1. Choose **Create function**. You are returned to the function's code and configuration. 

1. With your `LogAutoScalingEvent` function still open in the console, under **Code source**, in the editor, paste the following sample code into the file named index.mjs.

   ```
   import { AutoScalingClient, CompleteLifecycleActionCommand } from "@aws-sdk/client-auto-scaling";
   export const handler = async(event) => {
     console.log('LogAutoScalingEvent');
     console.log('Received event:', JSON.stringify(event, null, 2));
     var autoscaling = new AutoScalingClient({ region: event.region });
     var eventDetail = event.detail;
     var params = {
       AutoScalingGroupName: eventDetail['AutoScalingGroupName'], /* required */
       LifecycleActionResult: 'CONTINUE', /* required */
       LifecycleHookName: eventDetail['LifecycleHookName'], /* required */
       InstanceId: eventDetail['EC2InstanceId'],
       LifecycleActionToken: eventDetail['LifecycleActionToken']
     };
     var response;
     const command = new CompleteLifecycleActionCommand(params);
     try {
       var data = await autoscaling.send(command);
       console.log(data); // successful response
       response = {
         statusCode: 200,
         body: JSON.stringify('SUCCESS'),
       };
     } catch (err) {
       console.log(err, err.stack); // an error occurred
       response = {
         statusCode: 500,
         body: JSON.stringify('ERROR'),
       };
     }
     return response;
   };
   ```

   This code simply logs the event so that, at the end of this tutorial, you can see an event appear in the CloudWatch Logs log stream that's associated with this Lambda function. 

1. Choose **Deploy**. 

## Step 3: Create an EventBridge rule
<a name="lambda-create-rule"></a>

Create an EventBridge rule to run your Lambda function. For more information about using EventBridge, see [Use EventBridge to handle Auto Scaling events](automating-ec2-auto-scaling-with-eventbridge.md).

**To create a rule using the console**

1. Open the [EventBridge console](https://console.aws.amazon.com/events/).

1. In the navigation pane, choose **Rules**.

1. Choose **Create rule**.

1. For **Define rule detail**, do the following:

   1. For **Name**, enter **LogAutoScalingEvent-rule**.

   1. For **Event bus**, choose **default**. When an AWS service in your account generates an event, it always goes to your account's default event bus.

   1. For **Rule type**, choose **Rule with an event pattern**.

   1. Choose **Next**.

1. For **Build event pattern**, do the following:

   1. For **Event source**, choose **AWS events or EventBridge partner events**.

   1. Scroll down to **Event pattern**, and do the following:

   1. 

      1. For **Event source**, choose **AWS services**.

      1. For **AWS service**, choose **Auto Scaling**.

      1. For **Event type**, choose **Instance Launch and Terminate**.

      1. By default, the rule matches any scale-in or scale-out event. To create a rule that notifies you when there is a scale-out event and an instance is put into a wait state due to a lifecycle hook, choose **Specific instance event(s)** and select **EC2 Instance-launch Lifecycle Action**.

      1. By default, the rule matches any Auto Scaling group in the Region. To make the rule match a specific Auto Scaling group, choose **Specific group name(s)** and select the group.

      1. Choose **Next**.

1. For **Select target(s)**, do the following:

   1. For **Target types**, choose **AWS service**.

   1. For **Select a target**, choose **Lambda function**.

   1. For **Function**, choose **LogAutoScalingEvent**.

   1. Choose **Next** twice.

1. On the **Review and create** page, choose **Create rule**.

## Step 4: Add a lifecycle hook
<a name="lambda-add-lifecycle-hook"></a>

In this section, you add a lifecycle hook so that Lambda runs your function on instances at launch.

**To add a lifecycle hook**

1. Open the [Auto Scaling groups page](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups) of the Amazon EC2 console.

1. Select the check box next to your Auto Scaling group. A split pane opens up in the bottom of the page. 

1. In the lower pane, on the **Instance management** tab, in **Lifecycle hooks**, choose **Create lifecycle hook**.

1. To define a lifecycle hook for scale out (instances launching), do the following:

   1. For **Lifecycle hook name**, enter **LogAutoScalingEvent-hook**.

   1. For **Lifecycle transition**, choose **Instance launch**.

   1. For **Heartbeat timeout**, enter **300** for the number of seconds to wait for a callback from your Lambda function.

   1. For **Default result**, choose **ABANDON**. This means that the Auto Scaling group will terminate a new instance if the hook times out without receiving a callback from your Lambda function.

   1. (Optional) Leave **Notification metadata** empty. The event data that we pass to EventBridge contains all of the necessary information to invoke the Lambda function.

1. Choose **Create**.

## Step 5: Test and verify the event
<a name="lambda-testing-hook-notifications"></a>

To test the event, update the Auto Scaling group by increasing the desired capacity of the Auto Scaling group by 1. Your Lambda function is invoked within a few seconds after increasing the desired capacity.

**To increase the size of the Auto Scaling group**

1. Open the [Auto Scaling groups page](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups) of the Amazon EC2 console.

1. Select the check box next to your Auto Scaling group to view details in a lower pane and still see the top rows of the upper pane. 

1. In the lower pane, on the **Details** tab, choose **Group details**, **Edit**.

1. For **Desired capacity**, increase the current value by 1.

1. Choose **Update**. While the instance is being launched, the **Status** column in the upper pane displays a status of *Updating capacity*. 

After increasing the desired capacity, you can verify that your Lambda function was invoked.

**To view the output from your Lambda function**

1. Open the [Log groups page](https://console.aws.amazon.com/cloudwatch/home#logs:) of the CloudWatch console.

1. Select the name of the log group for your Lambda function (`/aws/lambda/LogAutoScalingEvent`).

1. Select the name of the log stream to view the data provided by the function for the lifecycle action.

Next, you can verify that your instance has successfully launched from the description of scaling activities.

**To view the scaling activity**

1. Return to the **Auto Scaling groups** page and select your group.

1. On the **Activity** tab, under **Activity history**, the **Status** column shows whether your Auto Scaling group has successfully launched an instance. 
   + If the action was successful, the scaling activity will have a status of "Successful".
   + If it failed, after waiting a few minutes, you will see a scaling activity with a status of "Cancelled" and a status message of "Instance failed to complete user's Lifecycle Action: Lifecycle Action with token e85eb647-4fe0-4909-b341-a6c42EXAMPLE was abandoned: Lifecycle Action Completed with ABANDON Result".

**To decrease the size of the Auto Scaling group**  
If you do not need the additional instance that you launched for this test, you can open the **Details** tab and decrease **Desired capacity** by 1.

## Step 6: Clean up
<a name="lambda-lifecycle-hooks-tutorial-cleanup"></a>

If you are done working with the resources that you created just for this tutorial, use the following steps to delete them.

**To delete the lifecycle hook**

1. Open the [Auto Scaling groups page](https://console.aws.amazon.com/ec2/v2/home?#AutoScalingGroups) of the Amazon EC2 console.

1. Select the check box next to your Auto Scaling group.

1. On the **Instance management** tab, in **Lifecycle hooks**, choose the lifecycle hook (`LogAutoScalingEvent-hook`).

1. Choose **Actions**, **Delete**.

1. Choose **Delete** again to confirm.

**To delete the Amazon EventBridge rule**

1. Open the [Rules page](https://console.aws.amazon.com/events/home?#/rules) in the Amazon EventBridge console.

1. Under **Event bus**, choose the event bus that is associated with the rule (`Default`).

1. Select the check box next to your rule (`LogAutoScalingEvent-rule`).

1. Choose **Delete**.

1. When prompted for confirmation, type the name of the rule and then choose **Delete**.

If you are done working with the example function, delete it. You can also delete the log group that stores the function's logs, and the execution role and permissions policy that you created.

**To delete a Lambda function**

1. Open the [Functions page](https://console.aws.amazon.com/lambda/home#/functions) on the Lambda console.

1. Choose the function (`LogAutoScalingEvent`).

1. Choose **Actions**, **Delete**.

1. When prompted for confirmation, type **delete** to confirm deleting the specified function and then choose **Delete**.

**To delete the log group**

1. Open the [Log groups page](https://console.aws.amazon.com/cloudwatch/home#logs:) of the CloudWatch console.

1. Select the function's log group (`/aws/lambda/LogAutoScalingEvent`).

1. Choose **Actions**, **Delete log group(s)**.

1. In the **Delete log group(s)** dialog box, choose **Delete**.

**To delete the execution role**

1. Open the [Roles page](https://console.aws.amazon.com/iam/home?#/roles) of the IAM console.

1. Select the function's role (`LogAutoScalingEvent-role`).

1. Choose **Delete**.

1. When prompted for confirmation, type the name of the role and then choose **Delete**.

**To delete the IAM policy**

1. Open the [Policies page](https://console.aws.amazon.com/iam/home?#/policies) of the IAM console.

1. Select the policy that you created (`LogAutoScalingEvent-policy`).

1. Choose **Actions**, **Delete**.

1. When prompted for confirmation, type the name of the policy and then choose **Delete**.

## Related resources
<a name="lambda-lifecycle-hooks-tutorial-related-resources"></a>

The following related topics can be helpful as you create EventBridge rules based on events that happen to the instances in your Auto Scaling group.
+ [Use EventBridge to handle Auto Scaling events](automating-ec2-auto-scaling-with-eventbridge.md). This section shows you examples of events for other use cases, including events for scale in.
+ [Add lifecycle hooks (console)](adding-lifecycle-hooks.md#adding-lifecycle-hooks-console). This procedure shows you how to add lifecycle hooks for both scale out (instances launching) and scale in (instances terminating or returning to a warm pool).

For a tutorial that shows you how to use the Instance Metadata Service (IMDS) to invoke an action from within the instance itself, see [Tutorial: Use data script and instance metadata to retrieve lifecycle state](tutorial-lifecycle-hook-instance-metadata.md).