Periodically delete old AMIs – SSM Automation runbook version
In the following pages, we have shown how to use DLM to periodically delete old AMIs.
We also showed how Step Functions can be used to periodically delete old AMIs.
This time, the same content as above is performed using the SSM Automation runbook.
Envrionment
Create a SSM Automation runbook.
The runbook executes the following
- Search for AMIs that have been created for more than one hour and tag them.
- Run AWS-DeleteImage, a runbook owned by AWS, on AMIs that have been tagged.
Create an EventBridge rule.
Set the runbook to run periodically (once an hour).
CloudFormation template files
The above configuration is built with CloudFormation.
The CloudFormation templates are placed at the following URL
https://github.com/awstut-an-r/awstut-soa/tree/main/02/005
Explanation of key points of template files
SSM Automation Runbook
Resources:
DeleteImageRunbook:
Type: AWS::SSM::Document
Properties:
Content:
assumeRole: "{{AutomationAssumeRole}}"
description: Create an AMI for an EC2 instance with a specific tag.
schemaVersion: "0.3"
parameters:
AutomationAssumeRole:
type: String
description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf.
default: !GetAtt DeleteImageRunbookRole.Arn
AccountId:
type: String
description: (Required) The ID of Account.
default: !Ref AWS::AccountId
Region:
type: String
description: (Required) The Region.
default: !Ref AWS::Region
TagKey:
type: String
description: (Required) The tag key of Image.
default: !Ref TagKey
TagValue:
type: String
description: (Required) The tag value of Image.
default: !Ref TagValue
ValidHours:
type: Integer
description: (Required) The expired hours.
default: !Ref ValidHours
mainSteps:
- name: setTagToExpiredImages
action: aws:executeScript
inputs:
Runtime: python3.8
Handler: handler
InputPayload:
AccountId: "{{AccountId}}"
Region: "{{Region}}"
TagKey: "{{TagKey}}"
TagValue: "{{TagValue}}"
ValidHours: "{{ValidHours}}"
Script: |-
import boto3
import datetime
import json
def handler(events, context):
account_id = events['AccountId']
region = events['Region']
tag_key = events['TagKey']
tag_value = events['TagValue']
valid_hours = int(events['ValidHours'])
client = boto3.client('ec2', region_name=region)
now = datetime.datetime.now(datetime.timezone.utc)
response = client.describe_images(
Owners=[account_id])
create_tags_results = []
for image in response['Images']:
creation_date_str = image['CreationDate']
creation_date_dt = datetime.datetime.fromisoformat(creation_date_str.replace('Z', '+00:00'))
diff = now - creation_date_dt
diff_hour = diff.seconds / (60 * 60)
if diff_hour > valid_hours:
result = client.create_tags(
Resources=[
image['ImageId']],
Tags=[
{
'Key': tag_key,
'Value': tag_value
}],
)
create_tags_results.append(result)
return {'createTagResults': json.dumps(create_tags_results)}
outputs:
- Name: createTagResults
Selector: $.Payload.creataTagResults
Type: String
- name: deleteTagedImages
action: aws:executeAutomation
maxAttempts: 1
timeoutSeconds: !Ref WaitForSuccessTimeoutSeconds
onFailure: Abort
inputs:
DocumentName: AWS-DeleteImage
TargetParameterName: ImageId
Targets:
- Key: "tag:{{TagKey}}"
Values:
- "{{TagValue}}"
outputs:
- Name: deleteImage
Selector: "$"
Type: String
DocumentFormat: YAML
DocumentType: Automation
Name: !Sub "${Prefix}-DeleteImageRunbook"
Code language: YAML (yaml)
Create a SSM Automation runbook to remove the old AMI.
For more information on how to create your own runbook, please see the following pages.
The point is the setting regarding steps.
First step
This step sets a tag on the old AMI.
You can execute any code by setting the actions property to “aws:executeScript”.
Runs the Python or PowerShell script provided using the specified runtime and handler.
aws:executeScript – Run a script
The code to be executed is generally similar to the Step Functions version.
The change is that if an AMI is found that has been created for more than one hour, a tag will be set.
The following tags will be set
- Tag Name:DeleteImage
- Tag Value:true
Second step
In this step, the AMI is deleted.
By setting the actions property to “aws:executeAutomation”, you can execute another runbook from within a runbook.
Delete an AMI by specifying “AWS-DeleteImage” for the DocumentName property in inputs.
By specifying the aforementioned tag information in the Targets property and “ImageId” in the TargetParameterName, AWS-DeleteImage is executed for the AMI to which the tag is assigned.
IAM Roles for Runbook
Resources:
DeleteImageRunbookRole:
Type: AWS::IAM::Role
DeletionPolicy: Delete
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service:
- ssm.amazonaws.com
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AmazonSSMAutomationRole
Policies:
- PolicyName: SetTagAndDeleteImagePolicy
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action:
- tag:GetResources
Resource:
- "*"
Code language: YAML (yaml)
In addition to the AWS management policy AmazonSSMAutomationRole, set an inline policy to allow tag:GetResources.
EventBridge Rule
Resources:
EventsRule:
Type: AWS::Events::Rule
Properties:
Name: !Sub "${Prefix}-EventsRule"
ScheduleExpression: rate(1 hour)
State: ENABLED
Targets:
- Arn: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${Runbook}:$DEFAULT"
Id: !Ref Runbook
RoleArn: !GetAtt EventsRuleRole.Arn
Code language: YAML (yaml)
Create an EventBridge rule to run the runbook periodically.
By specifying “rate(1 hour)” in the ScheduleExpression property, the runbook can be executed every hour.
Specify the aforementioned runbook ARN, etc. in the Targets property.
Resources:
EventsRuleRole:
Type: AWS::IAM::Role
DeletionPolicy: Delete
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: sts:AssumeRole
Principal:
Service: events.amazonaws.com
Policies:
- PolicyName: !Sub "${Prefix}-StartAutomationExecutionPolicy"
PolicyDocument:
Version: 2012-10-17
Statement:
- Effect: Allow
Action: ssm:StartAutomationExecution
Resource: !Sub "arn:aws:ssm:${AWS::Region}:${AWS::AccountId}:automation-definition/${Runbook}:$DEFAULT"
- Effect: Allow
Action: iam:PassRole
Resource: !Ref RunbookRoleArn
Code language: YAML (yaml)
Allow two actions in the inline policy.
The first is ssm:StartAutomationExecution.
Literally, this is what allows the runbook to be executed.
The second is iam:PassRole.
This is to pass the IAM role for the SSM Automation runbook that we just checked to the runbook.
Architecting
Use CloudFormation to build this environment and check its actual behavior.
Create a CloudFormation stacks and check the resources in the stacks
Create CloudFormation stacks.
For information on how to create stacks and check each stack, please refer to the following pages.
After reviewing the resources in each stack, information on the main resources created in this case is as follows
- SSM Automation runbook:soa-02-005-DeleteImageRunbook
- EventBridge rule:soa-02-005-EventsRule
Check various resources from the AWS Management Console.
Check the SSM Automaiton runbook.
The runbook has been successfully created.
Check the EventBridge rule.
The contents of the runbook are to be executed every hour.
Operation Check
AMI Creation
Create an AMI from any EC2 instance.
A snapshot was created along with the AMI.
1st runbook execution
The first runbook execution begins automatically.
Execution details.
You can see that the two steps in the run book have been successfully completed.
Check the status of both steps.
The first step.
Looking at Outputs, the result of the script execution is empty.
In other words, there were no AMIs that had been created for more than one hour, so the script terminated without performing any tagging or other processing.
Second step.
This step executes the SSM Automation runbook AWS-DeleteImage on an AMI with the tag name “DeleteImage” and the value “true”.
Below are the results of this runbook run.
Nothing was executed because there were no AMIs with the corresponding tag.
Thus, if there are no AMIs that meet the deletion criteria, the program exits without executing any action.
2nd runbook execution
After one hour, a second runbook execution will automatically begin.
Execution details.
Again, we see that the two steps in the run book were completed successfully.
Check the status of both steps.
The first step.
Looking at Outputs, there was one result of the script execution.
This means that more than an hour has passed since its creation and the AMI was tagged earlier.
Second step.
This step executes the SSM Automation runbook AWS-DeleteImage on an AMI with the tag name “DeleteImage” and the value “true”.
Below are the results of this runbook execution.
You can see the ID of the AMI you just generated in Step name.
Confirm the execution of the steps.
Runbook AWS-DeleteImage is now running.
Check what has been executed in this run book.
Deletion of tagged AMI was successfully performed.
Finally, check the AMI and snapshots.
Indeed, AMI and others have been removed.
Summary
We also showed how to use the SSM Automation runbook to periodically delete old AMIs.