无服务器部署 Lambda 无法假定现有的 IAM 角色

4

我觉得这个问题已经被问了很多次,但是当前的答案对我都没有用。

我正在尝试使用Serverless部署应用程序。 我的serverless.yml如下:

app: product-events-api

service: product-events
custom:
  secrets: ${ssm:/aws/reference/secretsmanager/serverless-product-events-${self:provider.stage}~true, ''}
  provider:
    name: aws
    runtime: nodejs10.x
    region: eu-west-1
    stage: ${opt:stage, 'preview'}
    timeout: 30
    # Role ARN must adhere to the RegEx: arn:(aws[a-zA-Z-]*)?:iam::\d{12}:role/?[a-zA-Z_0-9+=,.@\-_/]+
    role: arn:aws:iam::${self:custom.secrets.AWS_ACCOUNT_ID}:role/${self:custom.secrets.IAM_ROLE_NAME}
    vpc: ${self:custom.secrets.vpc}
    environment:
      STAGE: ${self:provider.stage}
      NODE_ENV: production
      DB_NAME: ${self:custom.secrets.DB_NAME}
      DB_URL: ${self:custom.secrets.DB_URL}

functions:
  getProductEvents:
    handler: src/routes/api/handler.events
    memorySize: 1024
    description: Get product event
    events:
      - http:
          path: /events
          method: get

role 的值为 arn:aws:iam::<Account ID>:role/lambda_basic_execution,是一个绝对 ARN。

运行 sls deploy --stage production 命令时,我遇到了以下错误:

An error occurred: GetProductEventsLambdaFunction - The role defined for the function cannot be assumed by Lambda. (Service: AWSLambdaInternal; Status Code: 400; Error Code: InvalidParameterValueException; Request ID: 4750b33e-329c-4383-abd4-a61ec4d326b2).

这个 IAM 角色被几乎所有的 Lambda 所使用。我想尝试在函数级别上定义 role,于是参考了这个答案,但出现了以下错误:

The CloudFormation template is invalid: Template error: instance of Fn::GetAtt references undefined resource lamba_basic_execution

如果我运行命令 aws iam get-role --role-name lambda_basic_execution,会返回如下信息:

{
    "Role": {
        "AssumeRolePolicyDocument": {
           "Version": "2012-10-17",
            "Statement": [
                {
                    "Action": "sts:AssumeRole",
                    "Principal": {
                        "Service": "lambda.amazonaws.com"
                    },
                    "Effect": "Allow",
                    "Sid": ""
                }
            ]
        },
        "MaxSessionDuration": 3600,
        "RoleId": "<Role ID>",
        "CreateDate": "2015-10-13T15:06:34Z",
        "RoleName": "lambda_basic_execution",
        "Path": "/",
        "Arn": "arn:aws:iam::<Account ID>:role/lambda_basic_execution"
    }
}

如果我从模板中删除role的声明,部署将正常进行,然后我可以通过控制台手动添加角色。我想这是一个无服务器问题。


我对你的问题有两个建议。首先,我会尝试使用以下角色:!Sub "arn:aws:iam::${self:custom.secrets.AWS_ACCOUNT_ID}:role/${self:custom.secrets.IAM_ROLE_NAME}"至于第二个建议,请参见下面的评论: - Anoop
@Anoop,那个建议会抛出错误:Unsupported role provided: "{"Fn::Sub":"arn:aws:iam::<Account ID>:role/lamba_basic_execution"}"。所以它正确地评估了字符串,只是不支持的格式,我猜? - wmash
1个回答

0
如您所提到的,您有几个使用相同 IAM 角色的 lambda 函数,我建议您在 serverless.yml 脚本中创建一个 IAM 角色。这种方法的好处是可以根据未来的需求轻松添加或删除任何权限。例如:
  YourIAMRole:
     Type: AWS::IAM::Role 
     Properties: 
       AssumeRolePolicyDocument: 
         Statement: 
          - Effect: Allow 
            Principal: 
              Service: lambda.amazonaws.com 
            Action: sts:AssumeRole 

       Path: / 
       ManagedPolicyArns: 
       - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole 
       Policies: 
         - # Any permission you want to add, For an example I am adding S3
          PolicyName: "resources_access" 
          PolicyDocument: 
            Version: "2012-10-17" 
            Statement: 
             - 
              Effect: "Allow" 
              Action: "s3:Get*" 
              Resource: !Join
                - ''
                - - "arn:aws:s3:::"
                  - !Ref YourParameteredBucketName

完成这个步骤后,你可以将这个角色分配给你的函数,如下所示:

 Role: !GetAtt YourIAMRole.Arn

1
我希望如果可能的话,避免创建另一个IAM角色。我们已经有很多IAM角色了,不需要再创建一个来增加混乱,并且本质上复制现有IAM角色的关系。 - wmash

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接