Reputation: 818
I am newbie to EC2 and boto. I have an EC2 running instance and I want to execute a shell command like e.g. apt-get update
through boto.
I searched a lot and found a solution using user_data
in the run_instances command, but what if the instance is already launched?
I don't even know if it is possible. Any clue in this reference will be a great help.
Upvotes: 13
Views: 16792
Reputation: 1482
Yes, you can do this with AWS Systems manager. AWS Systems Manager Run Command allows you to remotely and securely run set of commands on EC2 as well on-premise server. Below are high-level steps to achieve this.
Attach Instance IAM role: The ec2 instance must have IAM role with policy AmazonSSMFullAccess. This role enables the instance to communicate with the Systems Manager API.
Install SSM Agent: The EC2 instance must have SSM agent installed on it. The SSM Agent process the run command requests & configure the instance as per command.
Execute command : Example usage via AWS CLI:
Execute the following command to retrieve the services running on the instance. Replace Instance-ID with ec2 instance id.
aws ssm send-command --document-name "AWS-RunShellScript" --comment "listing services" --instance-ids "Instance-ID" --parameters commands="service --status-all" --region us-west-2 --output text
More detailed information: https://www.justdocloud.com/2018/04/01/run-commands-remotely-ec2-instances/
Upvotes: 1
Reputation: 45906
The boto.manage.cmdshell module can be used to do this. To use it, you must have the paramiko package installed. A simple example of it's use:
import boto.ec2
from boto.manage.cmdshell import sshclient_from_instance
# Connect to your region of choice
conn = boto.ec2.connect_to_region('us-west-2')
# Find the instance object related to my instanceId
instance = conn.get_all_instances(['i-12345678'])[0].instances[0]
# Create an SSH client for our instance
# key_path is the path to the SSH private key associated with instance
# user_name is the user to login as on the instance (e.g. ubuntu, ec2-user, etc.)
ssh_client = sshclient_from_instance(instance,
'<path to SSH keyfile>',
user_name='ec2-user')
# Run the command. Returns a tuple consisting of:
# The integer status of the command
# A string containing the output of the command
# A string containing the stderr output of the command
status, stdout, stderr = ssh_client.run('ls -al')
That was typed from memory but I think it's correct.
You could also check out Fabric (http://docs.fabfile.org/) which has similar functionality but also has much more sophisticated features and capabilities.
Upvotes: 21
Reputation:
I think you can use fabric for your requirements. Just check the fabric wrapper once . You can execute the command on remote server shell through fabric library.
It is very easy to use and you can integrate both boto and fabric . Together they work brilliant.
Plus the same command can executed to n number of nodes. Which I believe could be your requirements
Just check it out.
Upvotes: 3