How do I grant a rotation Lambda access to AWS Secrets Manager

非 Y 不嫁゛ 提交于 2020-01-24 13:04:06

问题


Using the serverless framework, I am trying to build a Lambda function that periodically rotates a secret stored in AWS Secrets Manager.

I am having trouble configuring the roles needed for the Secret Manager to execute the Lambda. In my serverless.yml I have defined the following resources:

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

and attach this role to the rotation Lambda like this:

functions:
  rotateKeys:
    handler: lambdas.rotate_keys.handler
    role: RotateKeysRole

Yet, when I try to set up Secrets Manager to use this Lambda for rotating secrets I will get the following error message:

Secrets Manager cannot invoke the specified Lambda function. Ensure that the function policy grants access to the principal secretsmanager.amazonaws.com

which puzzles me as this principal is specified. Inspecting the role in the IAM console did not reveal anything that seemed wrong to me.

How do I correctly configure the role setup in this scenario?


回答1:


The procedure of setting up permissions for a lambda function which rotates AWS Secrets Manager secrets is explained in the docs. [1]

To put it in a nutshell, you need two steps:

  • Add a trust policy to the lambda function. This can be achieved using the CloudFormation resource AWS::Lambda::Permission in the serverless.yml file. However, it is a little bit tricky to set this up, because you need to depend on the function being created. That is why the DependsOn is necessary and its value must be structured as follows: <function-name-with-first-letter-uppercase>LambdaFunction.
  • Add statements for the lambda function to call the AWS Secrets Manager API to update the secret. In the following example, I added these statements (for the Single user rotation case - see docs [1]) to the customer managed policy called rotateKeysPolicy.

Note: The function name is referenced in the DependsOn attribute. It is also referenced in the condition StringEquals and the attribute FunctionName as: arn:aws:lambda:${self:custom.region}:${self:custom.accountId}:function:${self:service}-${self:provider.stage}-rotateKeys. Keep in mind to change them if you change your function name.

Here is how the serverless.yml file should look like:

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

You have to replace <your-service-name>, <your-region>, <your-account-id> and upload your rotation code using e.g. the package -> include attributes.

Note: There are templates for the lambda function which update the secrets. [2][3]

Please also keep in mind to configure your VPC correctly for the lambda function being able to access the AWS Secrets Manager service over the network. [4]

References

[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




回答2:


I had the same issue today. I ran this and it worked for me: 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




回答3:


Your policy is incorrect. The service is secretsmanager but the action you defined is sts:AssumeRole which is from AWS Security Token Service.

A full access policy would be:

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

But you should limit the actions and the Resource the lambda can use. For this you can use the policy builder which can be found in IAM->Policies.

After creating a policy in the editor you can click on the JSON Tab and see the format. Then you need to adapt it to your serverless yaml format.

I hope I can help you!

Dominik



来源:https://stackoverflow.com/questions/57118962/how-do-i-grant-a-rotation-lambda-access-to-aws-secrets-manager

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!