Serverless Framework 进阶:深入剖析 serverless.yml 配置文件
Serverless Framework 作为一款流行的 Serverless 框架,极大地简化了 Serverless 应用的开发和部署。而 serverless.yml 文件,作为 Serverless Framework 的核心配置文件,承载着定义服务、函数、资源以及各种配置的重任。今天,咱们就来深入剖析一下 serverless.yml,聊聊它的配置项、最佳实践和一些进阶技巧,希望能帮助你更好地驾驭 Serverless Framework。
初识 serverless.yml: 配置文件概览
serverless.yml 文件通常位于 Serverless 项目的根目录下,采用 YAML 格式编写。它描述了整个 Serverless 服务的配置信息,Serverless Framework 会根据这个文件来构建、部署和管理你的应用。
一个典型的 serverless.yml 文件结构如下:
service: my-service # 服务名称
provider:
name: aws # 云服务提供商
runtime: nodejs16.x # 运行环境
region: ap-southeast-1 # 部署区域
# ... 其他 provider 相关配置
functions:
hello:
handler: handler.hello # 函数入口
events:
- http:
path: /hello
method: get
# ... 其他函数相关配置
resources:
Resources:
MyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-unique-bucket-name
# ... 其他资源定义
# ... 其他全局配置,如 plugins, custom 等
从上面的示例可以看出,serverless.yml 主要包含以下几个核心部分:
service: 定义服务名称,它是整个 Serverless 应用的标识。provider: 定义云服务提供商(如 AWS、Azure、Google Cloud 等)以及与提供商相关的配置,如运行时环境、部署区域、IAM 角色等。functions: 定义 Serverless 函数,包括函数的入口文件、触发事件、环境变量等。resources: 定义云服务资源,如 S3 存储桶、DynamoDB 表、API Gateway 等。这部分通常使用 CloudFormation 语法(AWS)或其他云厂商的资源描述方式。plugins: 插件配置,用于拓展 Serverless Framework 的功能。custom: 自定义配置,用户可以在这里添加一些自定义的变量或配置。
接下来,咱们就来详细聊聊这些核心配置项。
provider:云服务提供商配置
provider 部分是 serverless.yml 中至关重要的一部分,它决定了你的 Serverless 应用将部署到哪个云平台上,以及使用哪些基础设置。
name:云服务提供商
name 属性指定了云服务提供商。常见的选项包括:
aws:亚马逊云服务(AWS)azure:微软 Azuregoogle:谷歌云平台(GCP)tencentcloud: 腾讯云aliyun: 阿里云
runtime:运行时环境
runtime 属性指定了函数的运行环境。不同的云服务提供商支持的运行时环境有所不同。例如,对于 AWS,常见的运行时环境包括:
nodejs16.x、nodejs18.xpython3.8、python3.9java11、java17go1.xruby2.7.NET Core 3.1、.NET 6
region:部署区域
region 属性指定了 Serverless 应用部署的地理区域。选择合适的区域可以降低延迟、提高可用性,并满足合规性要求。例如,对于 AWS:
us-east-1(弗吉尼亚北部)us-west-2(俄勒冈)ap-southeast-1(新加坡)eu-central-1(法兰克福)
IAM 角色配置 (以 AWS 为例)
在 AWS 上,Serverless 函数需要具有相应的 IAM 角色才能访问其他 AWS 资源。provider 部分可以配置 IAM 角色相关的设置。
iamRoleStatements: 用于定义 IAM 角色的权限策略。你可以直接在这里定义权限,也可以引用已有的 IAM 角色。provider: iamRoleStatements: - Effect: Allow Action: - s3:GetObject - s3:PutObject Resource: "arn:aws:s3:::my-bucket/*"role: 引用已有的 IAM 角色。如果你已经创建了 IAM 角色,可以直接在这里指定角色的 ARN。provider: role: arn:aws:iam::123456789012:role/my-serverless-role
其他 provider 配置
provider 部分还可以包含其他特定于云服务提供商的配置,如:
stage: 部署阶段(如 dev、test、prod),默认为dev。profile: 使用的 AWS 配置文件(如果使用多个 AWS 账户)。environment: 全局环境变量,会被所有函数继承。memorySize: 函数的默认内存大小(AWS Lambda)。timeout: 函数的默认超时时间(AWS Lambda)。vpc: 如果你的函数需要访问 VPC 内的资源,可以在这里配置 VPC。
functions:函数配置
functions 部分定义了你的 Serverless 应用中的各个函数。每个函数都是一个独立的执行单元,可以由不同的事件触发。
handler:函数入口
handler 属性指定了函数的入口文件和处理函数。例如:
functions:
myFunction:
handler: src/handlers/myFunction.handler
上面的配置表示,当 myFunction 被触发时,Serverless Framework 会执行 src/handlers/myFunction.js 文件中的 handler 函数。
events:触发事件
events 属性定义了触发函数的事件。Serverless Framework 支持多种事件类型,常见的包括:
http: HTTP 请求事件,通常与 API Gateway 集成。events: - http: path: /users/{id} method: get cors: true # 启用 CORSschedule: 定时任务事件,类似于 Cron 表达式。events: - schedule: rate(5 minutes) # 每 5 分钟执行一次 - schedule: cron(0 12 * * ? *) # 每天中午 12 点执行s3: S3 对象存储事件。events: - s3: bucket: my-bucket event: s3:ObjectCreated:* rules: - prefix: uploads/ - suffix: .jpgsns: SNS 消息通知事件。events: - sns: my-topicsqs: SQS 消息队列事件。events: - sqs: arn:aws:sqs:region:account-id:queue-namedynamodb: DynamoDB 数据流事件。stream: Kinesis 数据流事件websocket: WebSocket 事件
其他 functions 配置
functions 部分还可以包含其他函数级别的配置,如:
environment: 函数级别的环境变量,会覆盖provider中定义的全局环境变量。memorySize: 函数的内存大小(覆盖provider中的默认值)。timeout: 函数的超时时间(覆盖provider中的默认值)。layers: AWS Lambda 层,用于共享代码和依赖。package: 函数的打包配置。
resources:资源配置
resources 部分用于定义 Serverless 应用所需的云服务资源。对于 AWS,这部分通常使用 CloudFormation 语法来描述资源。
示例:创建一个 S3 存储桶
resources:
Resources:
MyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: my-unique-bucket-name-${self:provider.stage} # 使用变量
上面的示例创建了一个名为 my-unique-bucket-name 的 S3 存储桶。注意,这里使用了 ${self:provider.stage} 变量来引用 provider 部分定义的 stage。
示例:创建一个 DynamoDB 表
resources:
Resources:
MyDynamoDBTable:
Type: AWS::DynamoDB::Table
Properties:
TableName: my-table
AttributeDefinitions:
- AttributeName: id
AttributeType: S
KeySchema:
- AttributeName: id
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
上面的示例创建了一个名为 my-table 的 DynamoDB 表,其中 id 作为主键。
资源引用
在 functions 或其他地方,你可以使用 CloudFormation 的 Ref 或 Fn::GetAtt 函数来引用 resources 部分定义的资源。
functions:
myFunction:
environment:
BUCKET_NAME: !Ref MyS3Bucket # 引用 S3 存储桶名称
TABLE_NAME:
Fn::GetAtt: [ MyDynamoDBTable, Arn ] # 引用 DynamoDB 表的 ARN
plugins: 插件
plugins配置,允许你添加各种插件来扩展 Serverless Framework 的功能。 比如常用的serverless-offline(本地模拟运行环境)、 serverless-webpack(打包优化)等。
plugins:
- serverless-offline
- serverless-webpack
custom:自定义配置
custom 部分允许你定义一些自定义的变量或配置,这些变量可以在 serverless.yml 文件的其他地方引用。
custom:
myVariable: myValue
apiGatewayName: my-api-${self:provider.stage}
functions:
myFunction:
environment:
MY_VAR: ${self:custom.myVariable} # 引用自定义变量
最佳实践和进阶技巧
1. 使用变量
serverless.yml 支持多种变量引用方式,可以帮助你实现配置的复用和动态化。
self: 引用serverless.yml文件自身的内容。opt: 引用命令行选项。env: 引用环境变量。file: 引用外部文件中的变量。- AWS CloudFormation 变量
custom:
bucketName: my-bucket-${opt:stage, self:provider.stage} # 优先使用命令行选项
resources:
Resources:
MyS3Bucket:
Type: AWS::S3::Bucket
Properties:
BucketName: ${self:custom.bucketName}
2. 模块化配置
当 serverless.yml 文件变得庞大时,可以考虑将其拆分为多个模块化的配置文件,然后使用 file 变量引用。
# serverless.yml
service: my-service
provider:
# ...
functions:
${file(./functions.yml)}
resources:
${file(./resources.yml)}
# functions.yml
myFunction1:
handler: ...
myFunction2:
handler: ...
3. 使用 Serverless Framework Variables
Serverless Framework Variables 提供了一种更强大和灵活的方式来引用变量,不仅可以从本地文件、环境变量、命令行选项中获取变量,还可以从 AWS SSM Parameter Store、S3 等地方获取。
# 从 SSM Parameter Store 获取变量
custom:
secret: ${ssm:/my-app/my-secret}
functions:
myFunction:
environment:
MY_SECRET: ${self:custom.secret}
4. 条件配置
你可以使用 Fn::If、Fn::Equals 等 CloudFormation 条件函数来实现条件配置。
resources:
Conditions:
CreateDevResources: !Equals [ ${self:provider.stage}, dev ]
Resources:
MyS3Bucket:
Type: AWS::S3::Bucket
Condition: CreateDevResources # 仅在 dev 阶段创建
Properties:
BucketName: my-dev-bucket
5. 优化函数打包
Serverless Framework 默认会将整个项目目录打包上传。你可以通过 package 配置来优化打包过程,排除不必要的文件,减小部署包的大小。
functions:
myFunction:
package:
individually: true # 每个函数单独打包
exclude:
- node_modules/**
- .git/**
- .vscode/**
include:
- src/handlers/myFunction.js
6. 使用 serverless-webpack 或 serverless-esbuild 插件
对于 Node.js 项目,可以使用 serverless-webpack 或 serverless-esbuild 插件来优化代码打包,进一步减小部署包的大小,并利用 Tree Shaking 等技术移除未使用的代码。
7. 使用 serverless-offline 插件
serverless-offline 插件可以在本地模拟 AWS Lambda 和 API Gateway 的运行环境,方便你在本地进行开发和测试。
8. 监控和日志
Serverless 应用的监控和日志非常重要。你可以使用 AWS CloudWatch、Azure Monitor、Google Cloud Operations Suite 等云服务提供的监控和日志服务,也可以集成第三方工具,如 Datadog、New Relic 等。
9. 安全性
- 遵循最小权限原则,为每个函数配置独立的 IAM 角色,只授予必要的权限。
- 使用环境变量或 Secrets Manager 等服务来存储敏感信息,不要将敏感信息硬编码在代码或配置文件中。
- 定期审查和更新依赖项,避免使用存在安全漏洞的组件。
- 对于 API Gateway,可以配置 Web Application Firewall (WAF) 来防御常见的 Web 攻击。
- 启用 API Gateway 的访问日志记录,监控 API 的调用情况。
10. CI/CD
将 Serverless Framework 与 CI/CD 工具集成,可以实现自动化的构建、测试和部署。常见的 CI/CD 工具包括:
- Jenkins
- GitLab CI
- GitHub Actions
- AWS CodePipeline
- Azure DevOps
通过 CI/CD,你可以实现:
- 自动化测试:在每次代码提交时运行单元测试、集成测试等。
- 自动化部署:将应用部署到不同的环境(dev、test、prod)。
- 回滚:在部署失败时自动回滚到上一个版本。
总结
serverless.yml 文件是 Serverless Framework 的核心,掌握它的配置和使用技巧对于构建高效、可靠、安全的 Serverless 应用至关重要。希望通过今天的分享,你对 serverless.yml 有了更深入的理解。如果你在使用 Serverless Framework 过程中遇到任何问题,欢迎随时交流,咱们一起探讨!
Serverless 的世界变化很快,新的特性和最佳实践层出不穷。保持学习的热情,不断探索,你一定能成为 Serverless 领域的专家!