Run an SSM Command against a set of EC2 Instances
A quick script today to run an SSM Command against a set of EC2 Instances. You can selectively target instance based on a TAG.
import boto3
import os
from time import sleep
lambda_func_name = os.getenv("AWS_LAMBDA_FUNCTION_NAME", "")
if lambda_func_name == "": # We are not running in AWS
boto3.setup_default_session(profile_name='<profile_name>')
ec2_client = boto3.client('ec2', region_name='ap-southeast-2')
ssm_client = boto3.client('ssm', region_name='ap-southeast-2') # use region code in which you are working
sleep_duration = 2
def get_instances(os):
instances = []
# Check running or stopped instances
response = ec2_client.describe_instances(
Filters=[
{
'Name': 'instance-state-name',
'Values': ['running']
}
])
# Iterate over instance(s)
for r in response['Reservations']:
for inst in r['Instances']:
inst_id = inst['InstanceId']
tags = inst['Tags']
ins_tag = ""
for tag in tags:
if "OSFamily" in tag['Key']:
ins_tag = (tag['Value'])
break
else:
ins_tag = "NA"
if ins_tag == os:
instances.append(inst_id)
return instances
def ssm_run_command(instance_id, cmd, os_family):
document = "AWS-RunPowerShellScript"
if (os_family == "Linux"):
document = "AWS-RunShellScript"
response = ssm_client.send_command(
InstanceIds=[
instance_id # use instance id on which you want to execute, even multiple is allowed
],
DocumentName=document,
Parameters={
'commands': [
cmd
]
},
)
#print(response)
sleep(sleep_duration) # Seconds to wait for command to execute
command_id = response['Command']['CommandId']
output = ssm_client.get_command_invocation(CommandId = command_id, InstanceId = instance_id)
return output['StandardOutputContent']
def check_time_zone_windows():
os_family = "Windows"
instances = get_instances(os_family)
command = "[System.TimeZone]::CurrentTimeZone.StandardName"
instances_with_wrong_tz = []
for instance in instances:
print("Checking instance: " + instance)
time_zone = ssm_run_command(instance, command, os_family)
#print(time_zone)
if ( time_zone[0:3] != "AUS"):
instances_with_wrong_tz.append(instance)
result_str = ""
if (len(instances_with_wrong_tz) > 0):
result_str = "Following " + os_family + " instances have wrong Timezone:\n\n"
for instance in instances_with_wrong_tz:
result_str = result_str + instance + "\n\n"
return result_str
def check_time_zone_linux():
os_family = "Linux"
instances = get_instances(os_family)
command = 'date +"%Z"'
instances_with_wrong_tz = []
for instance in instances:
print("Checking instance: " + instance)
time_zone = ssm_run_command(instance, command, os_family)
#print(time_zone)
if (time_zone[0:2] != "AE"):
instances_with_wrong_tz.append(instance)
result_str = ""
if (len(instances_with_wrong_tz) > 0):
result_str = "Following " + os_family + " instances have wrong Timezone:\n\n"
for instance in instances_with_wrong_tz:
result_str = result_str + instance + "\n\n"
return result_str
def lambda_handler(event, context):
result_lin = check_time_zone_linux()
result_win = check_time_zone_windows()
result = result_lin + "\n\n" + result_win
print(result)
if __name__ == "__main__":
lambda_handler(0, 0)