AWS Systems Manager is a collection of capabilities that helps you automate management tasks. This post describe how to send command to an EC2 instance using python boto3
1. Systems Manager prerequisites
1.1 Install SSM agent
-
SSM Agent is installed, by default, on the following EC2 instances and Amazon Machine Images (AMIs):
- Amazon Linux
- Amazon Linux 2
- Amazon Linux 2 ECS-Optimized AMIs
- Ubuntu Server 16.04, 18.04, and 20.04
There's manual way to install it Manually install SSM Agent on EC2 instances for Linux
How to check if the target instance installed SSM agent
dev:/home/ubuntu# systemctl status snap.amazon-ssm-agent.amazon-ssm-agent.service
● snap.amazon-ssm-agent.amazon-ssm-agent.service - Service for snap application amazon-ssm-agent.amazon-ssm-agent
Loaded: loaded (/etc/systemd/system/snap.amazon-ssm-agent.amazon-ssm-agent.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2020-11-19 20:47:31 UTC; 4 weeks 1 days ago
Main PID: 27709 (amazon-ssm-agen)
Tasks: 23 (limit: 4915)
CGroup: /system.slice/snap.amazon-ssm-agent.amazon-ssm-agent.service
├─27709 /snap/amazon-ssm-agent/2996/amazon-ssm-agent
└─27837 /snap/amazon-ssm-agent/2996/ssm-agent-worker
1.2 Setup IAM role so that user/client has SSM permission
{
"Effect": "Allow",
"Action": [
"ssm:*"
],
"Resource": [
"arn:aws:ec2:us-east-1:123456789012:instance/*"
]
}
2. Using boto3 to send SSM command
import boto3
import time
def send_cmd(region):
""" Use describe instance information to get instance id base on region """
ssm_filter = [{'Key': 'tag:SSM', 'Values': ['ssm-cmd']}]
ssm = boto3.client('ssm', region_name=region)
instance_info = ssm.describe_instance_information(Filters=ssm_filter).get('InstanceInformationList', {})[0]
instance_id = instance_info.get('InstanceId', '')
cmd1 = "echo 'Start running services'"
cmd2 = 'whoami'
response = ssm.send_command(InstanceIds=[instance_id],
DocumentName='AWS-RunShellScript',
Parameters={"commands": [cmd1, cmd2]}
)
command_id = response.get('Command', {}).get("CommandId", None)
while True:
""" Wait for SSM response """
response = ssm.list_command_invocations(CommandId=command_id, Details=True)
""" If the command hasn't started to run yet, keep waiting """
if len(response['CommandInvocations']) == 0:
time.sleep(1)
continue
invocation = response['CommandInvocations'][0]
if invocation['Status'] not in ('Pending', 'InProgress', 'Cancelling'):
break
time.sleep(1)
command_plugin = invocation['CommandPlugins'][-1]
output = command_plugin['Output']
print(f"Complete running, output: {output}")
send_cmd('us-east-1')
- Run
~/⚡ $ python ssm-send-cmd.py
Complete running, output: Start running services
root
Top comments (0)