Skip to content

Instantly share code, notes, and snippets.

@Pabl0Aceved0
Last active June 5, 2025 01:31
Show Gist options
  • Save Pabl0Aceved0/3577b388fb253470d04b41f60b4e4b91 to your computer and use it in GitHub Desktop.
Save Pabl0Aceved0/3577b388fb253470d04b41f60b4e4b91 to your computer and use it in GitHub Desktop.
Below is a runbook for AWS Systems Manager Automation to terminate EC2 instances that have been stopped or unused for a specified duration. This runbook uses AWS Lambda to check the instance's stopped duration and terminates it if it exceeds a defined threshold (e.g., 7 days). The runbook is written in YAML, as is standard for AWS Systems Manage…
description: Terminates EC2 instances stopped for more than a specified number of days.
schemaVersion: '0.3'
assumeRole: "{{ AutomationAssumeRole }}"
parameters:
AutomationAssumeRole:
type: String
description: (Optional) The ARN of the role that allows Automation to perform the actions on your behalf.
default: ''
MaxStoppedDays:
type: Integer
description: Number of days an instance can remain stopped before termination.
default: 7
mainSteps:
- name: GetStoppedInstances
action: aws:executeAwsApi
inputs:
Service: ec2
Api: DescribeInstances
Filters:
- Name: instance-state-name
Values:
- stopped
outputs:
- Name: InstanceIds
Selector: $.Reservations[*].Instances[*].InstanceId
Type: StringList
- name: CheckStoppedDuration
action: aws:executeScript
inputs:
Runtime: python3.8
Handler: check_stopped_duration
Script: |
import boto3
from datetime import datetime, timezone
def check_stopped_duration(event, context):
instance_ids = event['InstanceIds']
max_stopped_days = int(event['MaxStoppedDays'])
ec2_client = boto3.client('ec2')
instances_to_terminate = []
for instance_id in instance_ids:
response = ec2_client.describe_instance_attribute(
Attribute='disableApiStop',
InstanceId=instance_id
)
stop_time = ec2_client.describe_instances(
InstanceIds=[instance_id]
)['Reservations'][0]['Instances'][0].get('StateTransitionReason')
if stop_time:
stop_time_str = stop_time.split('(')[1].split(')')[0]
stop_time = datetime.fromtimestamp(int(stop_time_str.split()[0]), timezone.utc)
days_stopped = (datetime.now(timezone.utc) - stop_time).days
if days_stopped >= max_stopped_days:
instances_to_terminate.append(instance_id)
return {'InstancesToTerminate': instances_to_terminate}
InputPayload:
InstanceIds: "{{ GetStoppedInstances.InstanceIds }}"
MaxStoppedDays: "{{ MaxStoppedDays }}"
outputs:
- Name: InstancesToTerminate
Selector: $.Payload.InstancesToTerminate
Type: StringList
- name: TerminateInstances
action: aws:executeAwsApi
inputs:
Service: ec2
Api: TerminateInstances
InstanceIds: "{{ CheckStoppedDuration.InstancesToTerminate }}"
isEnd: true
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment