vibhor
vibhor

Reputation: 818

Boto Execute shell command on ec2 instance

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

Answers (3)

ExploringApple
ExploringApple

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

garnaat
garnaat

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

user1687072
user1687072

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

Related Questions