Python 尽管VPN、kms密钥和策略都是正确的,但lambda单独工作,但被另一个lambda调用时不工作
我在一个s3存储桶中有2个lambda和3个子目录。将文件上载到sub1时会触发第一个lambda。它生成一个写入sub2的输出。然后触发lambda2,它将输出写入sub3。lambdas的标准使用 S3 bucket上传使用kms密钥进行加密,每个lambda都将该密钥配置到其环境变量中,以便可以读取/写入S3 每个lambda都附带了几个策略,以便它可以工作:s3crud、VPCAccessPolicy(因为它们位于一个vpc和2个子网内)和LambdaInvokePolicy sub1中有20k个条目,因此我没有下载所有条目并重新上传,而是构建了另一个lambda,它从s3 sub dir读取所有条目,创建一个包含bucket和key的事件,并将其传递到lambda 1以触发该事件。此lambda具有相同的VPC、策略和kms密钥 步骤/lambda 1工作正常,并将预期输出写入sub2,但对于我得到的每个步骤2文件:Python 尽管VPN、kms密钥和策略都是正确的,但lambda单独工作,但被另一个lambda调用时不工作,python,amazon-web-services,amazon-s3,aws-lambda,aws-sam-cli,Python,Amazon Web Services,Amazon S3,Aws Lambda,Aws Sam Cli,我在一个s3存储桶中有2个lambda和3个子目录。将文件上载到sub1时会触发第一个lambda。它生成一个写入sub2的输出。然后触发lambda2,它将输出写入sub3。lambdas的标准使用 S3 bucket上传使用kms密钥进行加密,每个lambda都将该密钥配置到其环境变量中,以便可以读取/写入S3 每个lambda都附带了几个策略,以便它可以工作:s3crud、VPCAccessPolicy(因为它们位于一个vpc和2个子网内)和LambdaInvokePolicy sub1中
"An error occurred (AccessDenied) when calling the GetObject operation: Access Denied", "errorType": "ClientError"
真正奇怪的是,如果我从sam cli进行本地调用,通过event.json将文件名传递给lambda2,它工作正常,并将预期的文件写入sub3,这表明lambda没有问题。但是我不能大量使用lambda3调用lambda2,尽管它有相关的kms密钥、VPN访问和策略。为什么调用lambda 1而不是lambda-2会起作用?所有这些文件都在同一个存储桶中,使用相同的kms密钥加密,并且每个lambda具有相同的密钥访问权限,并且位于相同的VPN中
谁能想到为什么会这样
这是lambda 3:
import boto3
import json
import os
import time
s3_resource = boto3.resource('s3')
def lambda_handler(event, context):
# get list of files in sub dir
obj_list = []
bucket = s3_resource.Bucket(event['bucket'])
for obj in bucket.objects.filter(Prefix=event['prefix'],Delimiter='/'):
obj_list.append(str(obj.key))
# COUNT: 20440
# generate list of event.json to pass into lambdas
event_list = []
for key in obj_list[:5]:
x = make_template()
x['Records'][0]['s3']['object']['key'] = key
x['Records'][0]['s3']['bucket']['name'] = event['bucket']
event_list.append(x)
# invoke lambdas
# setup boto3 and inputs
involeLam = boto3.client("lambda", region_name="eu-west-1")
lambda_to_invoke = event['lambda_to_trigger']
# invoke the lambda
invocations = []
for payload in event_list:
response = involeLam.invoke(FunctionName = lambda_to_invoke, InvocationType = "RequestResponse", Payload = json.dumps(payload)) # initiate and await response
invocations.append(response)
time.sleep(60)
# parse the contents of the file from the lambda return
for i in invocations:
print(i["Payload"].read())
return {
"success": True
}
def make_template():
template = {
"Records":[
{
"s3":{
"bucket":{
"name":"mybucket"
},
"object":{
"key":"path/to/file.csv"
}
}
}
]
}
return template
以下是传递到此lambda的event.json:
{
"bucket": "mybucket",
"prefix": "path/to/my/",
"lambda_to_trigger":"arn:aws:lambda:eu-west-1:number:function:MyFunction"
}
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
triggermultiplelambda
Sample SAM Template for triggermultiplelambda
Globals:
Function:
Timeout: 120
Resources:
TriggerMultipleLambdaFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: triggermultiplelambda/
Handler: triggerMultipleLambda.lambda_handler
Runtime: python3.6
KmsKeyArn: !Sub arn:aws:kms:eu-west-1:number:key/code-for-key
Policies:
- S3CrudPolicy:
BucketName: "*"
- VPCAccessPolicy: {}
- LambdaInvokePolicy:
FunctionName: "*"
Outputs:
TriggerMultipleLambdaFunction:
Description: "TriggerMultipleLambda Lambda Function ARN"
Value: !GetAtt TriggerMultipleLambdaFunction.Arn
TriggerMultipleLambdaFunctionIamRole:
Description: "Implicit IAM Role created for TriggerMultipleLambda function"
Value: !GetAtt TriggerMultipleLambdaFunctionRole.Arn
下面是用于构建此lambda的template.yaml:
{
"bucket": "mybucket",
"prefix": "path/to/my/",
"lambda_to_trigger":"arn:aws:lambda:eu-west-1:number:function:MyFunction"
}
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
triggermultiplelambda
Sample SAM Template for triggermultiplelambda
Globals:
Function:
Timeout: 120
Resources:
TriggerMultipleLambdaFunction:
Type: AWS::Serverless::Function
Properties:
CodeUri: triggermultiplelambda/
Handler: triggerMultipleLambda.lambda_handler
Runtime: python3.6
KmsKeyArn: !Sub arn:aws:kms:eu-west-1:number:key/code-for-key
Policies:
- S3CrudPolicy:
BucketName: "*"
- VPCAccessPolicy: {}
- LambdaInvokePolicy:
FunctionName: "*"
Outputs:
TriggerMultipleLambdaFunction:
Description: "TriggerMultipleLambda Lambda Function ARN"
Value: !GetAtt TriggerMultipleLambdaFunction.Arn
TriggerMultipleLambdaFunctionIamRole:
Description: "Implicit IAM Role created for TriggerMultipleLambda function"
Value: !GetAtt TriggerMultipleLambdaFunctionRole.Arn
如果我还需要发布其他内容,请告诉我。非常感谢,我终于明白了。因此,template.yaml需要修改如下: 这一行(我已经弄明白了)需要添加到参考资料中:Function:Properties:
KmsKeyArn: !Sub arn:aws:kms:eu-west-1:number:key/code-for-key
需要将策略添加到策略部分:
- KMSDecryptPolicy:
KeyId: code-for-key
根据用于访问S3的boto3 api,需要将以下行添加到lambda中的import语句中:
from botocore.client import Config
# EITHER
s3_resource = boto3.resource('s3', config=Config(signature_version='s3v4'))
# OR
s3_client = boto3.client('s3', config=Config(signature_version='s3v4'))
通过这些语句,我现在可以从S3读取/下载/解密使用kms密钥加密的文件
要上载文件,我使用以下行:
s3_client.upload_file('/tmp/' + outputfilename, OUTPUTBUCKET, OUTPUTFOLDER+'/'+outputfilename,
ExtraArgs={"ServerSideEncryption": "aws:kms", "SSEKMSKeyId":"code-for-key"})
我从以下URL获得此解决方案:
非常感谢你的帮助jarmod,我希望这能帮助别人 我终于明白了。因此,template.yaml需要修改如下: 这一行(我已经弄明白了)需要添加到参考资料中:Function:Properties:
KmsKeyArn: !Sub arn:aws:kms:eu-west-1:number:key/code-for-key
需要将策略添加到策略部分:
- KMSDecryptPolicy:
KeyId: code-for-key
根据用于访问S3的boto3 api,需要将以下行添加到lambda中的import语句中:
from botocore.client import Config
# EITHER
s3_resource = boto3.resource('s3', config=Config(signature_version='s3v4'))
# OR
s3_client = boto3.client('s3', config=Config(signature_version='s3v4'))
通过这些语句,我现在可以从S3读取/下载/解密使用kms密钥加密的文件
要上载文件,我使用以下行:
s3_client.upload_file('/tmp/' + outputfilename, OUTPUTBUCKET, OUTPUTFOLDER+'/'+outputfilename,
ExtraArgs={"ServerSideEncryption": "aws:kms", "SSEKMSKeyId":"code-for-key"})
我从以下URL获得此解决方案:
非常感谢你的帮助jarmod,我希望这能帮助别人 这有两个部分。KMS密钥自身的策略是否允许Lambda的IAM角色对其进行解密?Lambda的IAM角色是否允许它解密KMS密钥。另请参阅感谢您的帮助,我不确定:我认为'KMS:'!子arn:aws:kms:eu-west-1:number:key/模板中“key”的代码。yaml将允许lambda解密。我没有设置密钥,所以不知道如何检查KMS密钥的策略?如果你没有权限阅读密钥策略来检查它,那么我会去找设置密钥策略的人。结果证明我有权限,所以不是那样。我已经弄明白了,将在下面发布。这有两个部分。KMS密钥自身的策略是否允许Lambda的IAM角色对其进行解密?Lambda的IAM角色是否允许它解密KMS密钥。另请参阅感谢您的帮助,我不确定:我认为'KMS:'!子arn:aws:kms:eu-west-1:number:key/模板中“key”的代码。yaml将允许lambda解密。我没有设置密钥,所以不知道如何检查KMS密钥的策略?如果你没有权限阅读密钥策略来检查它,那么我会去找设置密钥策略的人。结果证明我有权限,所以不是那样。我已经弄明白了,将在下面发布。好吧,听起来您案例中的具体问题是boto3默认为sigv2。好吧,听起来您案例中的具体问题是boto3默认为sigv2。