简体   繁体   English

设置 IAM 角色以在 AWS Lambda 中运行 AWS CLI Python 子进程

[英]Set IAM role to run AWS CLI Python subprocess in AWS Lambda

I created a Lambda layer that contains the AWS CLI because the aws sync command is not available in boto3 and the copy function was too slow to complete the s3 to s3 transfer prior to hitting the maximum Lambda time out.我创建了一个包含 AWS CLI 的 Lambda 层,因为aws sync命令在 boto3 中不可用,并且副本 function 速度太慢,无法在达到最大 Lambda 超时之前完成 s3 到 s3 的传输。

I can run AWS CLI commands (ls, sync, etc) as the execution role for the Lambda. I need to run aws sync from Lambda to sync two s3 buckets as a different IAM user that has access to the source and destination buckets.我可以运行 AWS CLI 命令(ls、sync 等)作为 Lambda 的执行角色。我需要从 Lambda 运行aws sync以作为有权访问源和目标存储桶的不同 IAM 用户同步两个 s3 存储桶。

How do I configure the CLI to run as a particular user?如何配置 CLI 以特定用户身份运行?

The commands below configure the user successfully locally but when run using the subprocess function in Lambda, the output of get-caller-identity is still the ARN of the Lambda role.下面的命令在本地成功配置了用户,但是当使用 Lambda 中的子进程 function 运行时,get-caller-identity 的 output 仍然是 Lambda 角色的 ARN。

/opt/aws configure set aws_access_key_id <id>
/opt/aws configure set aws_secret_access_key <key>
/opt/aws sts get-caller-identity

In order to run the configure set id and key commands, I had to set an environmental variable to bypass the read only Lambda file system to write the credentials to the /temp directory.为了运行 configure set id 和 key 命令,我必须设置一个环境变量以绕过只读的 Lambda 文件系统以将凭据写入 /temp 目录。

Environmental Variable:环境变量:

key: HOME
value: /tmp

Note: There is a populated credentials file written to: /temp/.aws/credentials注意:有一个填充的凭据文件写入:/temp/.aws/credentials

Lambda: Lambda:

import logging
import subprocess

logger = logging.getLogger()
logger.setLevel(logging.INFO)

def run_command(command):
    command_list = command.split(' ')
    try:
        logger.info("Running shell command: \"{}\"".format(command))
        result = subprocess.run(command_list, stdout=subprocess.PIPE);
        logger.info("Command output:\n---\n{}\n---".format(result.stdout.decode('UTF-8')))
    except Exception as e:
        logger.error("Exception: {}".format(e))
        return False

    return True

def lambda_handler(event, context):
    run_command('/opt/aws configure set aws_access_key_id <id>')
    run_command('/opt/aws configure set aws_secret_access_key <key>')
    # not set to new IAM user
    run_command('/opt/aws sts get-caller-identity')

Thanks for reading!谢谢阅读!

Pass the IAM access credentials as environment variables to the subprocess, instead of trying to run aws configure :将 IAM 访问凭证作为环境变量传递给子进程,而不是尝试运行aws configure

result = subprocess.run(command_list, stdout=subprocess.PIPE, env={
  'AWS_ACCESS_KEY_ID': <id>,
  'AWS_SECRET_ACCESS_KEY': <id>,
});

Explanation:解释:

The Lambda runtime environment has the environment variables set for the role it is using, documented here , and those environment variables are taking precedence over anything you are trying to do via the aws configure command. Lambda 运行时环境为其使用的角色设置了环境变量, 记录在此处,并且这些环境变量优先于您尝试通过aws configure命令执行的任何操作。 So the easiest way to fix that is to just override the environment variables that are passed to the subprocess via the env argument.因此,解决这个问题的最简单方法是覆盖通过env参数传递给子进程的环境变量。

I don't think your calls to aws configure are working anyway, since all that does is write to a ~/.aws/credentials file, and that file isn't writeable inside the AWS Lambda environment, only /tmp is writeable.我认为您对aws configure的调用无论如何都不起作用,因为所做的只是写入~/.aws/credentials文件,并且该文件在 AWS Lambda 环境中不可写,只有/tmp是可写的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM