9

使用无服务器框架,我正在尝试构建一个 Lambda 函数,该函数会定期轮换存储在 AWS Secrets Manager 中的密钥。

我在配置 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 控制台中的角色并没有发现任何对我来说似乎有问题的地方。

在这种情况下如何正确配置角色设置?

4

3 回答 3

10

我今天有同样的问题。我跑了这个,它对我有用:

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

于 2019-07-19T20:20:04.610 回答
9

文档中解释了为轮换 AWS Secrets Manager 密钥的 lambda 函数设置权限的过程。[1]

简而言之,您需要两个步骤:

  • 向 lambda 函数添​​加信任策略。这可以使用 serverless.yml 文件中的 CloudFormation 资源AWS::Lambda::Permission来实现。但是,设置它有点棘手,因为您需要依赖于正在创建的函数。这就是为什么DependsOn是必要的,并且它的值必须按如下结构构成:<function-name-with-first-letter-uppercase>LambdaFunction.
  • 为 lambda 函数添​​加语句以调用 AWS Secrets Manager API 来更新密钥。在以下示例中,我将这些语句(对于单用户轮换案例 - 请参阅文档 [1])添加到名为rotateKeysPolicy的客户管理策略中。

注意:函数名称在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

于 2019-07-23T01:56:50.610 回答
-1

你的政策不正确。该服务是 secretsmanager,但您定义的操作是来自 AWS Security Token Service 的 sts:AssumeRole。

完整的访问策略是:

Effect: "Allow"
Action: "secretsmanager:*"
Resource: "*"

但是您应该限制 lambda 可以使用的操作和资源。为此,您可以使用IAM->Policies 中 的策略构建器。政策制定者

在编辑器中创建策略后,您可以单击 JSON 选项卡并查看格式。然后您需要将其调整为您的无服务器 yaml 格式。

我希望我能帮助你!

多米尼克

于 2019-07-22T15:34:22.043 回答