我应该如何将我的s3凭据传递给AWS上的Python lambda函数?

时间:2017-04-01 20:37:21

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

我想从用Python编写的lambda函数向S3写一个文件。但我很难通过我的S3 ID和Key。

在我将本地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 Access密钥ID在我们的记录中不存在。”我还尝试在Lambda控制台中定义这些变量,但我得到: " Lambda无法配置您的环境变量,因为您提供的环境变量包含保留键。"

我有点惊讶我需要传递一个ID或密钥,因为我认为我创建Lambda函数的帐户也有权写入S3帐户(密钥和秘密我手工代码来自IAM为此同一帐户)。通过阅读以下帖子我有同样的感觉: AWS Lambda function write to S3

3 个答案:

答案 0 :(得分:5)

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

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

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

一旦您拥有适用于lambda的相关权限,您就不需要处理密钥或身份验证。

答案 1 :(得分:3)

当您在另一个AWS资源中使用一个AWS资源时,您永远不需要使用AWS访问密钥。只需允许Lambda函数访问S3存储桶以及您要采取的任何操作(例如PutObject)。如果您确保Lambda函数接收具有允许这种访问的策略的角色,则SDK将取消您的所有身份验证。

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

答案 2 :(得分:0)

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

  

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

之所以这样做是因为,当我从使用带有MySQL的AWS RDS切换到DynamoDB时,它花费了将近1000ms的时间来完成一些简单的表读取和更新。作为参考,我对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执行环境动态确定我的访问凭据的方式。仍在努力理解为什么对于我的简单表{key:value}查询和更新用例,MySQL如此之快。