【发布时间】:2020-05-28 21:17:01
【问题描述】:
我正在尝试使用 AWS 自动化数据处理。我在 python 中设置了一个 AWS lambda 函数:
- 由 S3 PUT 事件触发
- 使用 paramiko 层通过 SSH 连接到 EC2 实例
- 将存储桶中的新对象复制到实例中的某个文件夹中,解压缩实例中的文件并运行清理 csv 文件的 python 脚本。
问题是用于将 s3 存储桶与 ec2 文件夹同步的 aws cli 调用不起作用,但是当我手动 ssh 进入 ec2 实例并运行它的命令时它可以工作。我的 aws-cli 配置了我的 access_keys 并且 ec2 有允许其完全访问的 s3 角色。
import boto3
import time
import paramiko
def lambda_handler(event, context):
#create a low level client representing s3
s3 = boto3.client('s3')
ec2 = boto3.resource('ec2', region_name='eu-west-a')
instance_id = 'i-058456c79fjcde676'
instance = ec2.Instance(instance_id)
------------------------------------------------------'''
#start instance
instance.start()
#allow some time for the instance to start
time.sleep(30)
# Print few details of the instance
print("Instance id - ", instance.id)
print("Instance public IP - ", instance.public_ip_address)
print("Instance private IP - ", instance.private_ip_address)
print("Public dns name - ", instance.public_dns_name)
print("----------------------------------------------------")
print('Downloading pem file')
s3.download_file('some_bucket', 'some_pem_file.pem', '/tmp/some_pem_file.pem')
# Allowing few seconds for the download to complete
print('waiting for instance to start')
time.sleep(30)
print('sshing to instsnce')
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
privkey = paramiko.RSAKey.from_private_key_file('/tmp/some_pem_file.pem')
# username is most likely 'ec2-user' or 'root' or 'ubuntu'
# depending upon yor ec2 AMI
#s3_path = "s3://some_bucket/" + object_name
ssh.connect(
instance.public_dns_name, username='ubuntu', pkey=privkey)
print('inside machine...running commands')
stdin, stdout, stderr = ssh.exec_command('aws s3 sync s3://some_bucket/ ~/ec2_folder;\
bash ~/ec2_folder/unzip.sh; python3 ~/ec2_folder/process.py;')
stdin.flush()
data = stdout.read().splitlines()
for line in data:
print(line)
print('done, closing ssh session')
ssh.close()
# Stop the instance
instance.stop()
return('Triggered')
【问题讨论】:
-
paramiko 连接时,是否使用与连接时相同的用户名?否则,它可能没有相同的默认目录,因此无法找到您的凭据。
-
是的,默认用户名是 ubuntu
-
为什么 Lambda 函数会停止实例?这表明它正在等待 EC2 实例上的脚本完成运行。如果是这样,为什么不让 Lambda 在不使用 EC2 实例的情况下处理文件?或者,如果您需要使用 EC2 实例,您可以让实例在处理完成后自行关闭。见:How to automatically start, execute and stop EC2?
-
实例需要在处理结束时停止,我不从 Lamba 本身执行此操作的原因是因为我正在处理的文件需要大量计算能力,并且需要我用来处理解压后的 csv 的所有库都有很多层,平均 16GB 以上。
-
所以这就是为什么它不与我的存储桶同步的原因我只是打印了 stderr 而不是 stdout:aws: command not found 有趣的是机器上安装了 aws-cli,当我手动 ssh 和执行它会运行,但是当我的 lambda 通过 paramiko 执行命令时,它说找不到 aws 命令。
标签: python-3.x amazon-ec2 aws-lambda paramiko