Integration & Automation
Run code before terminating an EC2 Auto Scaling instance
Often times, you may want to execute some code and actions before terminating an Amazon Elastic Compute Cloud (Amazon EC2) instance that is part of an Amazon EC2 Auto Scaling group. For example, you can remove the instance from the domain and create a snapshot or Amazon Machine Image (AMI) of it before the instance is terminated by dynamic scaling.
One way to execute code and actions before terminating an instance is to create a lifecycle hook that puts the instance in Terminating:Wait
status. This allows you to perform any desired actions before immediately terminating the instance within the Auto Scaling group. The Terminating:Wait
status can be monitored by an Amazon CloudWatch event, which triggers an AWS Systems Manager automation document to perform the action you want. In this blog post, I create an AMI and remove the Amazon EC2 Windows instance from its domain before terminating it.
In this post, I describe how to manually create this mechanism. If you want to skip directly to the solution, download a copy of the AWS CloudFormation template.
Prerequisites
- An Amazon EC2 Auto Scaling group.
- A string parameter for the domain user. The user must have permission to remove the computer from the domain. I call this parameter
DomainUserName
. - A secure string parameter that contains the
DomainUserName
password. I call this parameterDomainPassword
.
Walkthrough
The following are the steps for manually creating the CloudFormation template.
- Add a lifecycle hook.
- Create a Systems Manager automation document.
- Create AWS Identity and Access Management (IAM) policies and a role to delegate permissions to the Systems Manager automation document.
- Create IAM policies and a role to delegate permissions to CloudWatch Events, which invokes the Systems Manager automation document.
- Create a CloudWatch Events rule.
- Add a Systems Manager automation document as a CloudWatch Event target.
Note: The code in this post is intended for the Windows command line interface (CLI). For Linux, replace any occurrences of ^
with \
.
Step 1: Add a lifecycle hook
I use the put-lifecycle-hook
command to add a lifecycle hook named my-lifecycle-hook
to my Auto Scaling group, My_AutoScalingGroup
.
Step 2: Create a Systems Manager automation document
In this step, I create an automation document named LifeCycleHookDoc
. The automation document goes through the following steps.
- Run a Windows PowerShell script to remove the computer from the domain.
- Create an AMI of the EC2 instance.
- Terminate the instance.
To perform these steps, the automation document includes the following parameters.
automationAssumeRole
— The Amazon Resource Name (ARN) of the role that allows the automation to execute (CloudWatch Events passes this parameter automatically).ASGName
— The Auto Scaling group (CloudWatch Events passes this parameter automatically).LCHName
— The lifecycle hook (CloudWatch Events passes this parameter automatically).DomainUserName
— The string parameter for the domain user. The domain user must have permission to remove the computer from the domain. This parameter was created in the prerequisites section.DomainPassword
— The SecureString parameter that has the DomainUserName password. This parameter was created in the prerequisites section.
Step 3: Create IAM policies and a role to delegate permissions to the Systems Manager automation document
I create two policies for this role. The first policy is called SSM-automation-Permission-to-CompleteLifecycle-Policy
, and it provides permission to CompleteLifecycleAction
for any instance within My_AutoScalingGroup
. The second policy is called SSM-automation-Policy
, and it provides permissions for all the actions needed for the automation document.
Lastly, I create a Systems Manager role called SSM-automation-Role
, which must have a trust relationship with AWS Systems Manager. For more information, see Editing the Trust Relationship for an Existing Role.
In SSM-automation-Permission-to-CompleteLifecycle-Policy
, update the ARN to match your Auto Scaling group.
In SSM-automation-Policy
, update the AWS Region in the ARN of the AWS-RunPowerShellScript
document.
Step 4: Create IAM policies and a role to delegate permissions to CloudWatch Events
I call this role Invoke-SSM-automation-from-CloudWatch-Event
, and it contains two policies:
- A policy called
Start-SSM-automation-Policy
that provides permission to execute the automation documentLifeCycleHookDoc
(from step 2). - A policy called
Pass-Role-SSM-Automation-Policy
that allowsInvoke-SSM-automation-from-CloudWatch-Event
to useSSM-automation-Role
(from step 3). This is used to invokeLifeCycleHookDoc
. For more information, see Pass Role Permissions.
Note: The trust relationship policy must include the Amazon CloudWatch Events service.
In Start-SSM-automation-Policy
, update the ARN to reflect the correct Region, account ID, and name of the automation document (LifeCycleHookDoc
, from Step 2) that contains the PowerShell script.
In Pass-Role-SSM-Automation-Policy
, update the ARN to reflect your account ID.
Step 5: Create a CloudWatch Events rule
To trigger the target (from step 4) when an instance changes to Terminating:Wait
status, I create a CloudWatch Events rule called My_CloudWatchEvent
.
Step 6: Add a Systems Manager automation document as a CloudWatch Event target
I create a CloudWatch Events target using InputTransformer
. The InputTransformer
feature of CloudWatch Events customizes the text from an event before it is passed to the target of a rule. You can define variables that use the JSON path to reference values in the original event source. You can define multiple variables and assign each a value from the input. Then you can use those variables in the input template as <variable-name>
. For more information, see Transforming Target Input.
The following code block is used to configure the CloudWatch Events target. Copy and paste the code into your text editor, and save it as InputTransformer.json
. Ensure that you update the ARN for both the automation document and the IAM role to reflect your account information.
Run the following to use the InputTransformer.json
as a target for My_CloudWatchEvent
created above.
You can use CloudWatch to trigger the AWS Systems Manager automation process to create an AMI of the instance and automatically remove the computer from the domain before leaving the AutoScaling group.
Conclusion
In this post, I provided a CloudFormation template and explained how it is used for executing code before an Amazon EC2 Auto Scaling instance terminates. The goal of describing the manual process is to help users better understand the solution so they can modify the code to suit specific needs.
The included AWS CloudFormation template can perform the following tasks.
- Find Amazon EC2 instances that are being terminated within an Auto Scaling group.
- Execute an automation document to create an AMI.
- Remove a computer from a domain.
The template can be used as is, but I encourage you to develop more complicated workflows that further reduce the administrative effort behind unloading resources.
For more information about how to configure an EC2 instance to automatically join a Microsoft Active Directory domain, see How to Configure Your EC2 Instances to Automatically Join a Microsoft Active Directory Domain starting up an EC2 instance. For a way to manage your domain membership of dynamic EC2 instances, see Managing domain membership of dynamic fleet of EC2 instances.