# AWS-函数

如果您使用AWS作为提供程序,则服务内的所有函数都是AWS Lambda函数。

# 配置

您的serverless服务中的所有Lambda函数都可以在 serverless.yml 文件中,functions 属性下找到。

# serverless.yml
service: myService

provider:
  name: aws
  runtime: nodejs12.x
  memorySize: 512 # 可选,以MB为单位,默认为1024
  timeout: 10 # 可选,以秒为单位,默认为6
  versionFunctions: false # 可选,默认为true
  tracing:
    lambda: true # 可选,启用对所有函数的跟踪 (can be true (true equals 'Active') 'Active' or 'PassThrough')

functions:
  hello:
    handler: handler.hello # 必需,在AWS Lambda中设置处理程序
    name: ${self:provider.stage}-lambdaName # 可选,已部署的Lambda名称
    description: Description of what the lambda function does # 可选,发布到AWS的说明
    runtime: python2.7 # 可选覆盖,默认为 provider 运行时
    memorySize: 512 # 可选,以MB为单位,默认为1024
    timeout: 10 # 可选,以秒为单位,默认为6
    provisionedConcurrency: 3 # 可选,已配置的lambda实例数
    reservedConcurrency: 5 # 此函数的可选保留并发限制。默认情况下,AWS使用帐户并发限制
    tracing: PassThrough # 可选,覆盖, can be 'Active' or 'PassThrough'

handler 属性指向要在函数中运行的代码的文件和模块。

// handler.js
module.exports.functionOne = function(event, context, callback) {};

您可以在此属性中添加任意数量的函数。

# serverless.yml

service: myService

provider:
  name: aws
  runtime: nodejs12.x

functions:
  functionOne:
    handler: handler.functionOne
    description: optional description for your Lambda
  functionTwo:
    handler: handler.functionTwo
  functionThree:
    handler: handler.functionThree

您的函数可以继承 provider 中的属性。

# serverless.yml
service: myService

provider:
  name: aws
  runtime: nodejs12.x
  memorySize: 512 # 将被所有函数继承

functions:
  functionOne:
    handler: handler.functionOne

或者,您可以在函数级别指定属性。

# serverless.yml
service: myService

provider:
  name: aws
  runtime: nodejs12.x

functions:
  functionOne:
    handler: handler.functionOne
    memorySize: 512 # function specific

您可以指定一个函数数组,如果将函数分隔到不同的文件中,这将非常有用:

# serverless.yml
---
functions:
  - ${file(../foo-functions.yml)}
  - ${file(../bar-functions.yml)}
# foo-functions.yml
getFoo:
  handler: handler.foo
deleteFoo:
  handler: handler.foo

# 权限

每个AWS Lambda函数都需要获得权限才能与您帐户中的其他AWS基础设施资源进行交互。 这些权限是通过 AWS IAM 角色设置的。 您可以通过 provider.iamRoleStatements 属性在此角色内设置权限策略声明。

# serverless.yml
service: myService

provider:
  name: aws
  runtime: nodejs12.x
  iamRoleStatements: # 所有函数的权限都可以在这里设置
    - Effect: Allow
      Action: # 允许在特定区域使用DynamoDB表
        - dynamodb:DescribeTable
        - dynamodb:Query
        - dynamodb:Scan
        - dynamodb:GetItem
        - dynamodb:PutItem
        - dynamodb:UpdateItem
        - dynamodb:DeleteItem
      Resource: 'arn:aws:dynamodb:us-east-1:*:*'

functions:
  functionOne:
    handler: handler.functionOne
    memorySize: 512

另一个例子:

# serverless.yml
service: myService
provider:
  name: aws
  iamRoleStatements:
    - Effect: 'Allow'
      Action:
        - 's3:ListBucket'
      # 您可以在这里编写CloudFormation语法。
      # 记住,所有这些都转换为CloudFormation。
      Resource: { 'Fn::Join': ['', ['arn:aws:s3:::', { 'Ref': 'ServerlessDeploymentBucket' }]] }
    - Effect: 'Allow'
      Action:
        - 's3:PutObject'
      Resource:
        Fn::Join:
          - ''
          - - 'arn:aws:s3:::'
            - 'Ref': 'ServerlessDeploymentBucket'
            - '/*'

functions:
  functionOne:
    handler: handler.functionOne
    memorySize: 512

还可以通过在 role 属性中添加 IAM角色ARN 来使用现有的 IAM角色。例如:

# serverless.yml
service: new-service
provider:
  name: aws
  role: arn:aws:iam::YourAccountNumber:role/YourIamRole

有关函数级别IAM角色,请参阅有关IAM的文档。

# VPC配置

通过在函数配置中添加 VPC 对象属性,可以将 VPC 配置添加到 serverless.yml 中的特定函数。此对象应包含构造此函数的 VPC 所需的 securityGroupIdssubnetIds 数组属性。下面是一个配置示例:

# serverless.yml
service: service-name
provider: aws

functions:
  hello:
    handler: handler.hello
    vpc:
      securityGroupIds:
        - securityGroupId1
        - securityGroupId2
      subnetIds:
        - subnetId1
        - subnetId2

或者如果要将 VPC 配置应用于服务中的所有函数,可以将配置添加到更高级别的 provider 对象,并在函数级别覆盖这些服务级别配置。例如:

# serverless.yml
service: service-name
provider:
  name: aws
  vpc:
    securityGroupIds:
      - securityGroupId1
      - securityGroupId2
    subnetIds:
      - subnetId1
      - subnetId2

functions:
  hello: # 此函数将覆盖上面的服务级别vpc配置
    handler: handler.hello
    vpc:
      securityGroupIds:
        - securityGroupId1
        - securityGroupId2
      subnetIds:
        - subnetId1
        - subnetId2
  users: #  此函数将继承上面的服务级别vpc配置
    handler: handler.users

然后,当您运行 serverless deploy时,VPC配置将与您的lambda函数一起部署。

# VPC IAM权限

Lambda函数执行角色必须具有创建、描述和删除弹性网络接口(ENI)的权限。当提供VPC配置时,默认的AWS AWSLambdaVPCAccessExecutionRole 将与您的Lambda执行角色相关联。如果提供了自定义角色,请确保包含正确的ManagedPolicyArns。有关更多信息,请参考配置 Lambda 函数以访问 VPC 中的资源

# VPC Lambda互联网访问

默认情况下,当一个Lambda函数在 VPC 中执行时,它会失去 internet 访问,AWS中的一些资源可能会变得不可用。为了让S3资源和DynamoDB资源可用于在VPC中运行的Lambda函数,需要创建一个VPC端点。有关更多信息,请查看Amazon S3的VPC端点。为了使其他服务(如Kinesis streams)可用,需要在用于运行Lambda的子网内为用于执行Lambda的VPC配置NAT网关。有关更多信息,请参考在VPC启用外接Internet访问

# 环境变量

可以将环境变量配置添加到 serverless.yml 中的特定函数。在函数配置中添加一个 environment 对象属性。这个对象应该包含一个字符串键值对:

# serverless.yml
service: service-name
provider: aws

functions:
  hello:
    handler: handler.hello
    environment:
      TABLE_NAME: tableName

或者,如果您希望将环境变量配置应用于服务中的所有函数,则可以将该配置添加到更高级别的 provider 对象。在函数级配置的环境变量与在 provider 级配置的环境变量合并,因此具有特定环境变量的函数也可以访问在 provider 级定义的环境变量。如果在函数和提供程序级别定义了具有相同键的环境变量,则特定于函数的值将覆盖 provider 级别的默认值。例如:

# serverless.yml
service: service-name
provider:
  name: aws
  environment:
    SYSTEM_NAME: mySystem
    TABLE_NAME: tableName1

functions:
  hello:
    # 继承 provider 中的环境变量
    handler: handler.hello
  users:
    # 继承 provider 中的环境变量
    # 覆盖 继承自 provider 中的环境变量 TABLE_NAME
    handler: handler.users
    environment:
      TABLE_NAME: tableName2

如果希望函数的环境变量与计算机的环境变量具有相同的值,请参考Referencing Environment Variables

# 标签

使用 标签 配置可以将 键/值 标签添加到函数中。

这些标签将显示在您的AWS控制台中,使您可以更轻松地按标签对功能进行分组或者查找具有公共标签的函数。

functions:
  hello:
    handler: handler.hello
    tags:
      foo: bar

或者,如果您希望将 标签 配置应用于服务中的所有函数,可以类似 environment,则可以将该配置添加到更高级别的 provider 对象。并且行为与 environment 一直。

# serverless.yml
service: service-name
provider:
  name: aws
  tags:
    foo: bar
    baz: qux

functions:
  hello:
    # 此函数将继承上面的服务级别标签配置
    handler: handler.hello
  users:
    # 该函数将覆盖foo标签并继承baz标签
    handler: handler.users
    tags:
      foo: quux

标签 功能有用的实际用例包括:

  • 成本估算(带有环境标签的标签函数:environment: Production)
  • 跟踪旧版代码(例如,使用过时的运行时的标记函数:runtime:nodejs0.10)
  • 等等...

# Layers 层

使用图层配置可以使您的函数使用Lambda图层

functions:
  hello:
    handler: handler.hello
    layers:
      - arn:aws:lambda:region:XXXXXX:layer:LayerName:Y

层可以与 runtime: provided 结合使用,以在AWS Lambda上实现您自己的自定义运行时。

要发布Lambda图层,请查看Layers 文档。

# 日志组资源

默认情况下,框架将为Lambdas创建LogGroup。这使得在删除服务的情况下清理日志组变得很容易,并使lambda IAM权限更加具体和安全。

# Versioning Deployed Functions

默认情况下,框架为每个部署创建函数版本。此行为是可选的,并且在不通过其限定符调用以前版本的情况下可以关闭。如果您想这样做,可以调用函数arn:aws:lambda:....:function/myFunc:3来调用版本3。

要关闭此功能,请设置 provider 级别的 versionFunctions 属性。

provider:
  versionFunctions: false

这些版本不会被serverless清除,所以请确保使用插件或其他工具来删除足够旧的版本。框架不能清理版本,因为它没有关于是否调用旧版本的信息。该特性增加了堆栈输出和资源的总数,因为函数版本是与其引用的函数相独立的资源。

# 死信队列(DLQ)

当AWS lambda函数失败时,会自动重试它们。如果重试也失败,AWS有一个功能可以将失败请求的信息发送到SNS主题或SQS队列,称为死信队列,您可以使用它来跟踪、诊断和响应lambda失败。

您可以借助SNS主题和onError config参数为无服务器功能设置死信队列。

注意:每个函数只能提供一个onError配置。

# DLQ与SNS

SNS主题需要预先创建,并在函数级别上作为arn提供。

service: service

provider:
  name: aws
  runtime: nodejs12.x

functions:
  hello:
    handler: handler.hello
    onError: arn:aws:sns:us-east-1:XXXXXX:test # Ref, Fn::GetAtt and Fn::ImportValue are supported as well

# DLQ with SQS

尽管“死信队列”同时支持SNS主题和SQS队列,但由于使用SQS队列arns和更新IAM角色时存在竞争条件,onError配置当前仅支持SNS主题arns。

我们正在努力解决问题,以便将来支持SQS队列。

# KMS键

AWS Lambda使用AWS Key Management Service(KMS)对您的静态环境变量进行加密。

awsKmsKeyArn 配置变量使您能够定义自己的KMS密钥,该密钥用于加密。

service:
  name: service-name
  awsKmsKeyArn: arn:aws:kms:us-east-1:XXXXXX:key/some-hash

provider:
  name: aws
  environment:
    TABLE_NAME: tableName1

functions:
  hello: # 此功能将覆盖上面的服务级别环境配置
    handler: handler.hello
    awsKmsKeyArn: arn:aws:kms:us-east-1:XXXXXX:key/some-hash
    environment:
      TABLE_NAME: tableName2
  goodbye: # 此功能将继承上面的服务级别环境配置
    handler: handler.goodbye

# 使用环境变量和KMS秘密

当在环境变量中存储机密时,AWS强烈建议对敏感信息进行加密。

# AWS X-Ray Tracing

您可以通过可选的 tracing 跟踪配置变量在Lambda函数上启用AWS X-Ray Tracing

service: myService

provider:
  name: aws
  runtime: nodejs12.x
  tracing:
    lambda: true

您还可以根据每个函数设置此变量。这将覆盖provider级别设置(如果存在):

functions:
  hello:
    handler: handler.hello
    tracing: Active
  goodbye:
    handler: handler.goodbye
    tracing: PassThrough

# Destinations 目的地

如果打算异步调用函数,则可能需要为其配置异步调用目标

异步调用目标可以是与服务一起部署的其他lambda函数,也可以是其他合格的目标(外部管理的lambda、EventBridge事件总线、SQS队列或SNS主题),可以通过其ARN寻址

functions:
  asyncHello:
    handler: handler.asyncHello
    destinations:
      onSuccess: otherFunctionInService
      onFailure: arn:aws:sns:us-east-1:xxxx:some-topic-name
更新时间: 5/18/2020, 7:43:58 PM