Aws lambda python 3 6 ssm to ec2 executes commands as root rather than user

When working with AWS Lambda functions in Python, you may encounter a situation where you need to execute commands on an EC2 instance using the SSM service. However, you might notice that the commands are executed as the root user instead of the desired user. In this article, we will explore three different solutions to this problem and determine which one is the best option.

Solution 1: Using the AWS Systems Manager Run Command

The first solution involves using the AWS Systems Manager Run Command to execute commands on the EC2 instance. This service allows you to run commands remotely and provides options to specify the user context in which the commands should be executed.


import boto3

def execute_command_on_ec2_instance(instance_id, command, username):
    ssm_client = boto3.client('ssm')
    
    response = ssm_client.send_command(
        InstanceIds=[instance_id],
        DocumentName='AWS-RunShellScript',
        Parameters={'commands': [command]},
        CloudWatchOutputConfig={'CloudWatchLogGroupName': '/aws/ssm', 'CloudWatchOutputEnabled': True},
        OutputS3BucketName='your-s3-bucket',
        OutputS3KeyPrefix='ssm-output',
        ServiceRoleArn='your-service-role-arn',
        MaxConcurrency='50',
        MaxErrors='0',
        TargetLocations=[{'Accounts': ['your-aws-account-id'], 'Regions': ['your-aws-region']}],
        Targets=[{'Key': 'InstanceIds', 'Values': [instance_id]}],
        TimeoutSeconds=3600,
        Comment='Executing command as {}'.format(username),
        Parameters={'runAsUser': [username]}
    )
    
    return response

# Usage example
instance_id = 'your-ec2-instance-id'
command = 'your-command'
username = 'your-username'

response = execute_command_on_ec2_instance(instance_id, command, username)
print(response)

This solution leverages the AWS-RunShellScript document provided by the AWS Systems Manager. By specifying the desired username in the runAsUser parameter, the command will be executed as the specified user on the EC2 instance.

Solution 2: Using the AWS CLI with AssumeRole

The second solution involves using the AWS CLI with the AssumeRole feature to execute commands on the EC2 instance. This approach requires you to assume a role that has the necessary permissions to execute commands as the desired user.


import subprocess

def execute_command_on_ec2_instance(instance_id, command, username):
    assume_role_command = 'aws sts assume-role --role-arn your-role-arn --role-session-name your-session-name'
    execute_command = 'aws ssm send-command --instance-ids {} --document-name AWS-RunShellScript --parameters "commands=[{}]" --comment "Executing command as {}" --parameters "runAsUser=[{}]"'.format(instance_id, command, username, username)
    
    subprocess.run(assume_role_command, shell=True)
    subprocess.run(execute_command, shell=True)

# Usage example
instance_id = 'your-ec2-instance-id'
command = 'your-command'
username = 'your-username'

execute_command_on_ec2_instance(instance_id, command, username)

This solution uses the subprocess module to execute the AWS CLI commands. It first assumes the specified role using the aws sts assume-role command and then executes the aws ssm send-command command with the desired parameters. By specifying the runAsUser parameter, the command will be executed as the specified user on the EC2 instance.

Solution 3: Using Paramiko SSH Library

The third solution involves using the Paramiko SSH library to establish an SSH connection with the EC2 instance and execute commands as the desired user. This approach requires you to have SSH access to the EC2 instance and the necessary credentials to authenticate.


import paramiko

def execute_command_on_ec2_instance(instance_ip, username, password, command):
    ssh_client = paramiko.SSHClient()
    ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh_client.connect(instance_ip, username=username, password=password)
    
    stdin, stdout, stderr = ssh_client.exec_command(command)
    
    output = stdout.read().decode('utf-8')
    error = stderr.read().decode('utf-8')
    
    ssh_client.close()
    
    return output, error

# Usage example
instance_ip = 'your-ec2-instance-ip'
username = 'your-username'
password = 'your-password'
command = 'your-command'

output, error = execute_command_on_ec2_instance(instance_ip, username, password, command)
print(output)
print(error)

This solution uses the Paramiko SSH library to establish an SSH connection with the EC2 instance. It then executes the specified command as the desired user and retrieves the output and error streams. By providing the appropriate username and password, the command will be executed as the specified user on the EC2 instance.

After exploring these three solutions, it is evident that Solution 1, which utilizes the AWS Systems Manager Run Command, is the best option. It leverages the native capabilities of AWS and provides a more secure and controlled approach to executing commands on EC2 instances. Solutions 2 and 3 require additional setup and may introduce security risks if not implemented correctly. Therefore, Solution 1 is recommended for executing commands as a specific user on EC2 instances using AWS Lambda functions in Python.

Rate this post

8 Responses

  1. Comment: I personally think Solution 2 is a total game-changer! Using the AWS CLI with AssumeRole is so much more efficient and hassle-free than the other options. #LifeSaver

Leave a Reply

Your email address will not be published. Required fields are marked *

Table of Contents