使用无服务器框架,我正在尝试构建 一个定期轮换存储在 AWS Secrets Manager 中的秘密 的 Lambda 函数。
我在配置 Secret Manager 执行 Lambda 所需的角色时遇到问题。在我的
serverless.yml
中,我定义了以下资源:
resources:
Resources:
RotateKeysRole:
Type: AWS::IAM::Role
Properties:
RoleName: rotate-keys-role
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
- secretsmanager.amazonaws.com
Action: sts:AssumeRole
并像这样将这个角色附加到旋转 Lambda 上:
functions:
rotateKeys:
handler: lambdas.rotate_keys.handler
role: RotateKeysRole
然而,当我尝试设置 Secrets Manager 以使用此 Lambda 轮换秘密时,我将收到以下错误消息:
Secrets Manager 无法调用指定的 Lambda 函数。确保 函数策略授予对主体的访问权限 secretsmanager.amazonaws.com
这让我很困惑,因为指定了这个校长。在 IAM 控制台中检查角色并没有发现任何我认为不对的地方。
如何在这种情况下正确配置角色设置?
文档中解释了为轮换 AWS Secrets Manager 机密的 lambda 函数设置权限的过程。 [1]
简而言之,需要两个步骤:
<function-name-with-first-letter-uppercase>LambdaFunction
.注意:函数名称在DependsOn 属性中引用。它也在条件 StringEquals 和属性 FunctionName 中被引用为:
arn:aws:lambda:${self:custom.region}:${self:custom.accountId}:function:${self:service}-${self:provider.stage}-rotateKeys
。如果您更改函数名称,请记住更改它们。
这是 serverless.yml 文件的样子:
service:
name: <your-service-name>
provider:
name: aws
region: '<your-region>'
custom:
region: ${self:provider.region}
accountId: <your-account-id>
resources:
Resources:
FunctionRole:
Type: AWS::IAM::Role
Properties:
RoleName: basic-function-role
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
- PolicyName: rotateKeysPolicy
PolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Action:
- secretsmanager:DescribeSecret
- secretsmanager:GetSecretValue
- secretsmanager:PutSecretValue
- secretsmanager:UpdateSecretVersionStage
Resource: '*'
Condition:
StringEquals:
'secretsmanager:resource/AllowRotationLambdaArn': "arn:aws:lambda:${self:custom.region}:${self:custom.accountId}:function:${self:service}-${self:provider.stage}-rotateKeys"
- Effect: Allow
Action:
- secretsmanager:GetRandomPassword
Resource: '*'
- Effect: Allow
Action:
- ec2:CreateNetworkInterface
- ec2:DeleteNetworkInterface
- ec2:DescribeNetworkInterfaces
Resource: '*'
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- lambda.amazonaws.com
Action: sts:AssumeRole
LambdaInvokePermission:
Type: AWS::Lambda::Permission
DependsOn: RotateKeysLambdaFunction
Properties:
FunctionName: "arn:aws:lambda:${self:custom.region}:${self:custom.accountId}:function:${self:service}-${self:provider.stage}-rotateKeys"
Action: lambda:InvokeFunction
Principal: 'secretsmanager.amazonaws.com'
functions:
rotateKeys:
handler: lambdas.rotate_keys.handler
role: FunctionRole
您必须替换
<your-service-name>
、<your-region>
、<your-account-id>
并使用例如上传您的旋转代码package -> include
属性。
注意:有更新秘密的 lambda 函数模板。 [2][3]
还请记住正确配置您的 VPC,以便 lambda 函数能够通过网络访问 AWS Secrets Manager 服务。 [4]
[1] https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets-required-permissions.html
[2] https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotating-secrets-create-generic-template.html
[3] https://github.com/aws-samples/aws-secrets-manager-rotation-lambdas
[4] https://docs.aws.amazon.com/secretsmanager/latest/userguide/rotation-network-rqmts.html
我今天遇到了同样的问题。我运行了这个,它对我有用:
aws lambda add-permission \
--function-name ARN_of_lambda_function \
--principal secretsmanager.amazonaws.com \
--action lambda:InvokeFunction \
--statement-id SecretsManagerAccess
https://docs.aws.amazon.com/secretsmanager/latest/userguide/troubleshoot_rotation.html
我通过添加以下 aws_lambda_permission 资源解决了这个问题
resource "aws_lambda_permission" "example_permission" {
statement_id = "AllowSecretsManagerToInvokeFunction"
action = "lambda:InvokeFunction"
function_name = module.moduleName.aws_lambda_function.lambda_handler
principal = "secretsmanager.amazonaws.com"
}
您的政策不正确。 该服务是 secretsmanager,但您定义的操作是 sts:AssumeRole,它来自 AWS Security Token Service。
完全访问策略是:
Effect: "Allow"
Action: "secretsmanager:*"
Resource: "*"
但是您应该限制lambda可以使用的操作和资源。 为此,您可以使用 policy builder,它可以在 IAM->Policies 中找到。
在编辑器中创建策略后,您可以单击 JSON 选项卡并查看格式。然后你需要让它适应你的无服务器 yaml 格式。
希望能帮到你!
多米尼克