【问题标题】:How should I pass my s3 credentials to Python lambda function on AWS?我应该如何将我的 s3 凭证传递给 AWS 上的 Python lambda 函数?
【发布时间】:2017-08-26 23:16:29
【问题描述】:

我想从我用 Python 编写的 lambda 函数将文件写入 S3。但我很难传递我的 S3 ID 和密钥。

在我将本地 Python 环境变量 AWS_SHARED_CREDENTIALS_FILE 和 AWS_CONFIG_FILE 设置为指向我使用 AWS CLI 创建的本地文件后,以下内容可在我的本地计算机上运行。

session = boto3.session.Session(region_name='us-east-2') 
s3 = session.client('s3', 
     config=boto3.session.Config(signature_version='s3v4'))

以下适用于 Lambda,我在其中手动编码我的 ID 和密钥(在此处使用 ***):

AWS_ACCESS_KEY_ID = '***'
AWS_SECRET_ACCESS_KEY = '***'
session = boto3.session.Session(region_name='us-east-2') 
s3 = session.client('s3', 
     config=boto3.session.Config(signature_version='s3v4'),
     aws_access_key_id=AWS_ACCESS_KEY_ID,
     aws_secret_access_key=AWS_SECRET_ACCESS_KEY)

但是在阅读了来自亚马逊的best practices 之后,我知道这是不安全的。所以我尝试:

AWS_ACCESS_KEY_ID = os.environ['AWS_ACCESS_KEY_ID']
AWS_SECRET_ACCESS_KEY = os.environ['AWS_SECRET_ACCESS_KEY']
session = boto3.session.Session(region_name='us-east-2') 
s3 = session.client('s3', 
     config=boto3.session.Config(signature_version='s3v4'),
     aws_access_key_id=AWS_ACCESS_KEY_ID,
     aws_secret_access_key=AWS_SECRET_ACCESS_KEY)

但我收到一个错误:“您提供的 AWS 访问密钥 ID 不存在于我们的记录中。”我还尝试在 Lambda 控制台中定义这些变量,但随后我得到: “Lambda 无法配置您的环境变量,因为您提供的环境变量包含保留键。”

我有点惊讶我需要传递一个 ID 或密钥,因为我相信我用于创作 Lambda 函数的账户也有权写入 S3 账户(我手头的密钥和秘密代码来自 IAM同一个账户)。我读了下面的帖子也有同样的感觉: AWS Lambda function write to S3

【问题讨论】:

    标签: python amazon-web-services amazon-s3 lambda aws-lambda


    【解决方案1】:

    当您在另一个 AWS 资源中使用一个 AWS 资源时,您永远不需要使用 AWS 访问密钥。只需允许 Lambda 函数访问 S3 存储桶和您想要执行的任何操作(例如 PutObject)。如果您确保 Lambda 函数接收到具有允许此类访问的策略的角色,则开发工具包将让您无需进行所有身份验证。

    如果您确实需要在 Lambda 中使用任何密钥,例如第三方系统或 AWS RDS 数据库(非 Aurora),您可能想看看 AWS KMS。这与 Lambda 配合得很好。但同样:在 Lambda 中使用 S3 应该在 IAM 中使用正确的角色/策略来处理。

    【讨论】:

      【解决方案2】:

      您的帐户有权“写入”到 S3 帐户这一事实并不意味着您可以这样做。 AWS 有一项名为 IAM 的服务,它将处理您的 lambda(以及许多其他服务)对其他 AWS 资源执行操作所必须的权限。

      您很可能缺少与您的 lambda 关联的相关 IAM 角色/策略来写入 S3 存储桶。

      正如AWS Lambda Permissions Model 中所指出的,您需要在创建 lambda 时创建并关联一个 IAM 角色。您可以从控制台或using CloudFormation 执行此操作。

      一旦您为您的 lambda 设置了相关权限,您就不需要处理密钥或身份验证。

      【讨论】:

      • 谢谢!我进入了我的 Lambda 函数的配置面板并创建了一个具有 S3 写入权限的自定义角色。 (我最初在 IAM 中授予了我的 IAM 用户 S3 写入权限,但也许这个权限没有传递给我的 Lambda 函数?)
      • 抱歉回复晚了,也许正如您所说,您的用户缺少将角色传递给 AWS 服务的权限:docs.aws.amazon.com/IAM/latest/UserGuide/…
      【解决方案3】:

      顺便说一句,如果我在从 AWS Lambda 访问 AWS DynamoDB 时显式传递 ACCESS_KEY 和 SECRET_ACCESS_KEY 而不是让 Lambda 通过环境变量自动找到我的凭证,我很想知道 AWS 验证我的时间是否会更少。例如,以下是来自 AWS Cloudwatch 的日志条目:

      [INFO] 2018-12-23T15:34:56.174Z 4c399add-06c8-11e9-8970-3b3cbb83cd9c 找到 环境变量中的凭据。

      我这样做是因为当我从使用带有 MySQL 的 AWS RDS 切换到 DynamoDB 时,完成一些简单的表读取和更新需要花费近 1000 毫秒的时间。作为参考,我对 AWS RDS MySQL 的调用明确传递了凭证,例如:

      conn = pymysql.connect(host=db_host, port=db_port, user=db_user, \
                                  passwd=db_pass, db=db_name, connect_timeout=5)
      

      所以,我认为这可能是问题所在,因为在连接到 DynamoDB 时我使用的是:

      db = boto3.resource('dynamodb')
      table = db.Table(dynamo_db_table)
      

      我决定尝试以下方法,看看我的身份验证时间是否减少了:

      session = boto3.Session(
                  aws_access_key_id=AWS_ACCESS_KEY_ID,
                  aws_secret_access_key=AWS_SECRET_ACCESS_KEY
                  )
      
      db = session.resource('dynamodb')
      table = db.Table(dynamo_db_table)
      

      最终结果是明确地提供了我的访问密钥,平均而言节省了不到 100 毫秒,因此我回到让 Lambda 执行环境动态确定我的访问凭据。仍在努力理解为什么 MySQL 对我的简单表 {key:value} 查询和更新用例的速度要快得多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-09-17
        • 2018-07-13
        • 1970-01-01
        • 2017-10-26
        • 2017-12-25
        • 1970-01-01
        • 2016-04-10
        相关资源
        最近更新 更多