首页 文章

无服务器框架:尝试为lambda定义角色会产生未定义的资源错误

提问于
浏览
0

我正在写一个lambda来更新RDS实例 . 显然,RDS实例必须位于VPC中,并且lambda必须位于VPC中,以便它可以访问RDS . 好吧那么 . 所以我将lambda配置为VPC,然后它没有权限在EC2上打开网络接口,所以我必须给lambda一个具有这些权限的角色 .

这是我的serverless.yml:

service: users-to-rds

plugins:
  - serverless-plugin-typescript

provider:
  name: aws
  runtime: nodejs6.10
  stage: dev
  timeout: 30
  region: ap-southeast-2
  iamRoleStatements:
    - Effect: Allow
      Action:
        - "S3:*"
      Resource: arn:aws:s3:::*
    - Effect: Allow
      Action:
        - "rds:*"
      Resource: "*"
  vpc:
    securityGroupIds:
      - sg-stuff
    subnetIds:
      - subnet-stuff
      - subnet-stuff
      - subnet-stuff

functions:
  writeToDB:
    handler: write-users-to-rds.writeToDB
    events:
      - sns: userlists
    role:
      Fn::GetAtt: [ "doStuffFromInsideVPC", "Arn" ]

Resources:
  SNSInvokeLambdaPermission:
    Type: "AWS::Lambda::Permission"
    Properties:
      Action: "lambda:InvokeFunction"
      Principal: "sns.amazonaws.com"
      SourceArn:
        Ref: UserListNotification
      FunctionName:
        Fn::GetAtt: [ "UserListToRDS", "Arn" ]
  doStuffFromInsideVPC:
    Type: "AWS::IAM::Role"
    Properties:
      AssumeRolePolicyDocument:
        Version: '2017'
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action: sts:AssumeRole
      Policies:
        - PolicyName: doStuffFromInsideVPCPolicy
          PolicyDocument:
            Version: '2017'
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource:
                  - 'Fn::Join':
                    - ':'
                    - - 'arn:aws:logs'
                      - Ref: 'AWS::Region'
                      - Ref: 'AWS::AccountId'
                      - 'log-group:/aws/lambda/*:*:*'
              - Effect: Allow
                Action:
                  - ec2:CreateNetworkInterface
                  - ec2:DescribeNetworkInterfaces
                  - ec2:DetachNetworkInterface
                  - ec2:DeleteNetworkInterface
                Resource: "*"

当我进行无服务器部署时,它会将zip上传到AWS,然后我被告知:

CloudFormation模板无效:模板错误:Fn :: GetAtt的实例引用未定义的资源doStuffFromInsideVPC

这当然完全是胡说八道 . 就在那里 . 显然曾经有一个错误,CloudFormation没有及时创建角色资源,所以无服务器更新后添加了DependsOn,导致它等到角色存在 . 看看.serverless / cloudformation-template-update-stack.json它似乎有一个需要它的DependsOn .

{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "The AWS CloudFormation template for this Serverless application",
  "Resources": {
    "ServerlessDeploymentBucket": {
      "Type": "AWS::S3::Bucket",
      "Properties": {
        "AccelerateConfiguration": {
          "AccelerationStatus": "Suspended"
        }
      }
    },
    "WriteToDBLogGroup": {
      "Type": "AWS::Logs::LogGroup",
      "Properties": {
        "LogGroupName": "/aws/lambda/users-to-rds-dev-writeToDB"
      }
    },
    "WriteToDBLambdaFunction": {
      "Type": "AWS::Lambda::Function",
      "Properties": {
        "Code": {
          "S3Bucket": {
            "Ref": "ServerlessDeploymentBucket"
          },
          "S3Key": "serverless/users-to-rds/dev/1515307801502-2018-01-07T06:50:01.502Z/users-to-rds.zip"
        },
        "FunctionName": "users-to-rds-dev-writeToDB",
        "Handler": "write-users-to-rds.writeToDB",
        "MemorySize": 1024,
        "Role": {
          "Fn::GetAtt": [
            "doStuffFromInsideVPC",
            "Arn"
          ]
        },
        "Runtime": "nodejs6.10",
        "Timeout": 30,
        "VpcConfig": {
          "SecurityGroupIds": [
            "sg-stuff"
          ],
          "SubnetIds": [
            "subnet-stuff",
            "subnet-stuff",
            "subnet-stuff"
          ]
        }
      },
      "DependsOn": [
        "WriteToDBLogGroup",
        "doStuffFromInsideVPC"
      ]
    },
    "WriteToDBLambdaVersionAOwtYsOPCw4hVAkxPXSzE66bZXvdbu2xQUzGAe58E": {
      "Type": "AWS::Lambda::Version",
      "DeletionPolicy": "Retain",
      "Properties": {
        "FunctionName": {
          "Ref": "WriteToDBLambdaFunction"
        },
        "CodeSha256": "7gOzejhkEn37BviNCIVy1lw32IwPs9/oyeaPBQjlqVA="
      }
    },
    "SNSTopicUserlists": {
      "Type": "AWS::SNS::Topic",
      "Properties": {
        "TopicName": "userlists",
        "DisplayName": "",
        "Subscription": [
          {
            "Endpoint": {
              "Fn::GetAtt": [
                "WriteToDBLambdaFunction",
                "Arn"
              ]
            },
            "Protocol": "lambda"
          }
        ]
      }
    },
    "WriteToDBLambdaPermissionUserlistsSNS": {
      "Type": "AWS::Lambda::Permission",
      "Properties": {
        "FunctionName": {
          "Fn::GetAtt": [
            "WriteToDBLambdaFunction",
            "Arn"
          ]
        },
        "Action": "lambda:InvokeFunction",
        "Principal": "sns.amazonaws.com",
        "SourceArn": {
          "Fn::Join": [
            "",
            [
              "arn:aws:sns:",
              {
                "Ref": "AWS::Region"
              },
              ":",
              {
                "Ref": "AWS::AccountId"
              },
              ":",
              "userlists"
            ]
          ]
        }
      }
    }
  },
  "Outputs": {
    "ServerlessDeploymentBucketName": {
      "Value": {
        "Ref": "ServerlessDeploymentBucket"
      }
    },
    "WriteToDBLambdaFunctionQualifiedArn": {
      "Description": "Current Lambda function version",
      "Value": {
        "Ref": "WriteToDBLambdaVersionAOwtYsOPCw4hVAkxPXSzE66bZXvdbu2xQUzGAe58E"
      }
    }
  }
}

任何想法,任何人?谢谢 .

1 回答

  • 1

    根据serverless.yaml reference,资源应按以下方式定义:

    resources:
      Resources:
        YourResource:
        ...
    

    在你的情况下尝试这个:

    resources:
      Resources:
        SNSInvokeLambdaPermission:
          Type: "AWS::Lambda::Permission"
          ...
    

相关问题