Tutorial: Configure a lifecycle hook that invokes a Lambda function - Amazon EC2 Auto Scaling

Tutorial: Configure a lifecycle hook that invokes a Lambda function

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.

For more information about using EventBridge, see Use EventBridge to handle Auto Scaling events.

Prerequisites

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 of the Amazon EC2 console and choose Create Auto Scaling group.

Step 1: Create an IAM role with permissions to complete lifecycle actions

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 of the IAM console, and then choose Create policy.

  2. Choose the JSON tab.

  3. 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.

    { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "autoscaling:CompleteLifecycleAction" ], "Resource": "arn:aws:autoscaling:*:123456789012:autoScalingGroup:*:autoScalingGroupName/my-asg" } ] }
  4. Choose Next:Tags, and then Next:Review.

  5. For 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.

  2. Choose Create role.

  3. For Select trusted entity, choose AWS service.

  4. For your use case, choose Lambda and then choose Next.

  5. 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.

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

Step 2: Create a Lambda function

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 on the Lambda console.

  2. Choose Create function, Author from scratch.

  3. Under Basic information, for Function name, enter LogAutoScalingEvent.

  4. Choose Change default execution role, and then for Execution role, choose Use an existing role.

  5. For Existing role, choose LogAutoScalingEvent-role.

  6. Leave the other default values.

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

  8. With your LogAutoScalingEvent function still open in the console, under Function code, in the editor, paste the following sample code into the file named index.js.

    var aws = require("aws-sdk"); exports.handler = (event, context, callback) => { console.log('LogAutoScalingEvent'); console.log('Received event:', JSON.stringify(event, null, 2)); var autoscaling = new aws.AutoScaling({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; autoscaling.completeLifecycleAction(params, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred response = { statusCode: 500, body: JSON.stringify('ERROR'), }; } else { console.log(data); // successful response response = { statusCode: 200, body: JSON.stringify('SUCCESS'), }; } }); 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.

  9. Choose Deploy.

Step 3: Create an EventBridge rule

Create an EventBridge rule to run your Lambda function.

To create a rule using the console

  1. Open the EventBridge console.

  2. In the navigation pane, choose Rules.

  3. Choose Create rule.

  4. For Define rule detail, do the following:

    1. For Name, enter LogAutoScalingEvent-rule.

    2. 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.

    3. For Rule type, choose Rule with an event pattern.

    4. Choose Next.

  5. For Build event pattern, do the following:

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

    2. For Event pattern, do the following:

      1. For Event source, choose AWS services.

      2. For AWS service, choose Auto Scaling.

      3. For Event type, choose Instance Launch and Terminate.

      4. 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.

      5. 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 one or more Auto Scaling groups.

      6. Choose Next.

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

    1. For Target types, choose AWS service.

    2. For Select a target, choose Lambda function.

    3. For Function, choose LogAutoScalingEvent.

    4. Choose Next twice.

  7. On the Review and create page, choose Create.

Step 4: Add a lifecycle hook

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 of the Amazon EC2 console.

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

    A split pane opens up in the bottom part of the Auto Scaling groups page.

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

  4. To define a lifecycle hook, do the following:

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

    2. For Lifecycle transition, choose Instance launch.

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

    4. 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.

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

  5. Choose Create.

Step 5: Test and verify the event

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 of the Amazon EC2 console.

  2. 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.

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

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

  5. 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 of the CloudWatch console.

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

  3. 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.

  2. 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: Next steps

Now that you have completed this tutorial, you can try creating a termination lifecycle hook. If instances in the Auto Scaling group terminate, an event is sent to EventBridge. For information about the event that is emitted when an instance terminates, see EC2 Instance-terminate Lifecycle Action.

Step 7: Clean up

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 of the Amazon EC2 console.

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

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

  4. Choose Actions, Delete.

  5. Choose Delete again to confirm.

To delete the Amazon EventBridge rule

  1. Open the Rules page in the Amazon EventBridge console.

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

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

  4. Choose Delete.

  5. 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 on the Lambda console.

  2. Choose the function (LogAutoScalingEvent).

  3. Choose Actions, Delete.

  4. 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 of the CloudWatch console.

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

  3. Choose Actions, Delete log group(s).

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

To delete the execution role

  1. Open the Roles page of the IAM console.

  2. Select the function's role (LogAutoScalingEvent-role).

  3. Choose Delete.

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

To delete the IAM policy

  1. Open the Policies page of the IAM console.

  2. Select the policy that you created (LogAutoScalingEvent-policy).

  3. Choose Actions, Delete.

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