更灵活的 serverless framework 配置文件

news/2025/1/12 6:11:47/

bg

更灵活的 serverless framework 配置文件

前言

再经过前置教程的部署之后,不知道你有没有注意这样一个问题,就是我们部署的函数名,以及 API网关endpoint,它们的名称和路径都带一个 dev?

这个就是 stage 导致的了,我们执行 sls deploy 部署的时候,由于没有指定 --stage 的参数,导致它默认就是 dev,所以我们之前部署的函数名称,网关里面都带它。

那么它有什么作用呢?实际上这个值就是用来给你的函数,以及对应的服务去区分阶段/环境的。

比如我们一个提供 web 服务的函数,我们自己人为划分出三个环境:

  1. dev 用于给开发者自行测试
  2. sit 用于进行集成测试
  3. prod 生产环境

不同的环境,它们各自的 API网关 分配的 endpoint 也是不同的。

假如你有一个域名,你就可以把域名多配置一些主或多级域名,把它们的 CNAME 解析到指定的 API网关 地址来使用。当然你仅仅在域名控制台,直接解析是不生效的,因为API网关有个双重验证,你必须进入API网关自定义域名界面,创建自定义域名,并绑定 ACM 证书,审核通过后解析才能生效。

什么是 ACM证书ACM完整名称为Amazon Certificate Manager,点击这里查看更多

放心,ACM 证书 申请和颁发非常简单,它的功能和申请流程和我们申请免费的 SSL/TLS 证书是一致的,都是我们域名多解析一个 CNAME的事情。

这时候我们自然可以利用 cli option 去设置:

"scripts": {"deploy:dev": "sls deploy","deploy:sit": "sls deploy -s sit","deploy:prod": "sls deploy -s prod"
},

但是随着项目的日益复杂,你会发现使用 CLI 命令,不断的去增加配置项,这种方式既繁琐,又效率低下,有什么方式可以用一个变量去控制大量的配置呢?

serverless framework里,通常我们可以使用 动态变量 的方式去解决这个问题。

动态变量

什么是动态变量?实际上它们就是特殊写法的字符串罢了。变量常见的写法如下所示:

${variableSource}
${sls:stage}-lambdaName
${env:MY_API_KEY}
${file(create_request.json)}
${self:service}:${sls:stage}:UsersTableArn

serverless.yml 支持使用上述变量的方式,来实现配置的引用与读取,它们是非常有用的,毕竟你不可能把某些配置项,诸如 secret 什么的直接 inline 写在 yml 文件里。

其中 ${} 就是变量引用的写法,会在 sls cli 运行的时候,把它们替换成真正的值。

# ${} 第二个参数是默认值
otherYamlKey: ${variableSource, defaultValue}

这里介绍一些常用的变量:

self

首先必须要讲的就是 self 了,它是我们应用配置自身其他值的关键,self 指向的就是我们 yml 配置的根节点。这里我给出一个示例,相信聪明的你可以一眼看出它的用法。

service: new-service
provider: aws
custom:globalSchedule: rate(10 minutes)# 引用的第一行 service: new-serviceserviceName: ${self:service}# 引用的上一行 serviceName: ${self:service}exportName: ${self:custom.serviceName}-exportfunctions:hello:handler: handler.helloevents:# ${self:someProperty} # self 指向的就是 yml 配置的根节点,所以才能 - schedule: ${self:custom.globalSchedule}
resources:Outputs:NewServiceExport:Value: 'A Value To Export'Export:Name: ${self:custom.exportName}

env

顾名思义,使用系统配置的环境变量:

service: new-service
provider: aws
functions:hello:name: ${env:FUNC_PREFIX}-hellohandler: handler.hello

这个一般配合 dotenv 等工具比较好用。

sls

这个变量可以获取一些 Serverless Core 值,比如 instanceIdstage,用例如下

service: new-service
provider: awsfunctions:func1:name: function-1handler: handler.func1environment:APIG_DEPLOYMENT_ID: ApiGatewayDeployment${sls:instanceId}STAGE: ${sls:stage}

其中 ${sls:stage} 指令的实质实际上是 ${opt:stage, self:provider.stage, "dev"} 的缩写形式,所以你也明白为什么默认值是 dev 了。

opt

这个变量就是去取 CLI 传入的 Options 里面的值:

service: new-service
provider: aws
functions:hello:name: ${opt:stage}-hellohandler: handler.hello

file

模块化配置的核心方法/变量,使用这个变量方法可以去读取文件,并进行引用,例如我们可以在这里引入另外的 yml,json,js文件:

# 你甚至可以引入整个yml文件作为配置
custom: ${file(./myCustomFile.yml)}
provider:name: awsenvironment:# 引入 json 文件MY_SECRET: ${file(./config.${opt:stage, 'dev'}.json):CREDS}functions:hello:handler: handler.helloevents:- schedule: ${file(./myCustomFile.yml):globalSchedule} # Or you can reference a specific propertyworld:handler: handler.worldevents:# 甚至可以引入 `js` 文件- schedule: ${file(./scheduleConfig.js):rate}

这时候它就会根据我们传入的 stage 参数,去读取相对路径下不同的配置文件了。

其中引入 js 文件的代码有一定的限制,它必须是 commonjs 格式,且必须导出一个js对象,或者是导出一个function。导出对象方式很简单且泛用性不强,我们这里以方法为例:

// 目前必须是 commonjs 格式,且返回一个对象作为值
// 方法同步/异步的都可以
module.exports = async ({ options, resolveVariable }) => {// We can resolve other variables via `resolveVariable`const stage = await resolveVariable('sls:stage');const region = await resolveVariable('opt:region, self:provider.region, "us-east-1"');...// Resolver may return any JSON value (null, boolean, string, number, array or plain object)return {prop1: 'someValue',prop2: 'someOther value'}
}

我们可以在里面获取到其他的变量,并进行额外的计算处理,或者我们可以在这里请求远端获取数据作为部署的额外配置。

更多

除此之外,它还能引用到更多服务的变量,诸如 CloudFormation,S3SSM 等等服务,更多更全面的变量详见:官方的变量大全地址

配置支持的其他格式

实际上目前的 serverless cli 不止可以接受 serverless.yml,也可以接受包括 serverless.ts, serverless.json, serverless.js 格式。

这里笔者只推荐两种格式 serverless.ymlserverless.js

为什么不是 serverless.json?因为 json 文件表现力弱,甚至要 jsonc 才支持注释,所以放弃。

为什么不是 serverless.ts,因为直接使用会出错,详见 issues/48,不够省心。这点不如使用 js + jsdoc 的组合,智能提示有了,灵活性也有了。

所以我们总结一下 serverless.ymlserverless.js 的优点:

  • serverless.yml: 足够简单,配合动态变量比较灵活

  • serverless.js: 可以使用 nodejs api,也可以配合动态变量,更加灵活,而且配置可以使用原生 js 写法。

这里我们以 serverless.js 配置文件为例:

智能提示, 需要 npm i -D @serverless/typescript

/*** @typedef {import('@serverless/typescript').AWS} AWS* @type {AWS}*/
const serverlessConfiguration = {service: 'aws-node-ts-hello-world',frameworkVersion: '3',provider: {// ...},functions: {// ...},
}module.exports = serverlessConfiguration

当然由于它是 nodejs 运行时的缘故,你可以把配置文件拆分成多个文件,再使用 commonjs 原生的方式去引用它们。你也可以使用环境变量,node:fsnode:path 等等模块去按条件动态去生成配置文件,甚至使用某些第三方库做一些额外的工作,这实在是太灵活了!

Next Chapter

现在你已经浅尝辄止了 serverless framework 动态配置文件。

下一篇,《与传统 nodejs web 框架的结合》中,将会详细介绍如何部署 express/koa 和以它们2个为基底的 serverless 应用,欢迎阅读。

完整示例及文章仓库地址

https://github.com/sonofmagic/serverless-aws-cn-guide

如果你遇到什么问题,或者发现什么勘误,欢迎提 issue 给我


http://www.ppmy.cn/news/1107846.html

相关文章

【LeetCode题目详解】第九章 动态规划part16 583. 两个字符串的删除操作 ● 72. 编辑距离 ● 编辑距离总结篇 (day56补)

本文章代码以c为例! 本文章转自代码随想录 一、力扣第583题:两个字符串的删除操作 题目: 给定两个单词 word1 和 word2 ,返回使得 word1 和 word2 相同所需的最小步数。 每步 可以删除任意一个字符串中的一个字符。 示例 1…

vite + react + typescript + uni-app + node 开发一个生态系统

简介 使用 vite react typescript uni-app node 来开发一个简易的生态系统案例,包含 APP,H5,微信小程序,控制台,服务端 开发 admin 技术栈:vite react typescript初始化控制台项目选择自定义预设…

5.后端·新建子模块与开发(自动模式)

文章目录 学习资料自动生成模式创建后端三层 学习资料 https://www.bilibili.com/video/BV13g411Y7GS?p11&spm_id_frompageDriver&vd_sourceed09a620bf87401694f763818a31c91e 自动生成模式创建后端三层 首先,运行起来若依的前后端整个项目,…

Python解析MDX词典数据并保存到Excel

原始数据和处理结果: https://gitcode.net/as604049322/blog_data/-/tree/master/mdx 下载help.mdx词典后,我们无法直接查看,我们可以使用readmdict库来完成对mdx文件的读取。 安装库: pip install readmdict对于Windows平台还…

1-4 AUTOSAR方法论

总目录——AUTOSAR入门详解AUTOSAR入门详解目录汇总:待续中。。。https://xianfan.blog.csdn.net/article/details/132818463 目录 一、前言 二、方法论 三、单个ECU开发流程 一、前言 汽车生产供应链上有以下角色:OEM、TIER1、TIER2,其主…

【IOC,AOP】spring的基础概念

IOC 控制反转 对象的创建控制权转交给外部实体,就是控制反转。外部实体便是IOC容器。其实就是以前创建java对象都是我们new一下,现在我们可以把这个new交给IOC容器来做,new出来的对象也会交由IOC容器来管理。这个new出来的对象则称为Bean。 …

2023年澳大利亚标普ASX200指数研究报告

第一章 指数概况 1.1 指数基本情况 澳大利亚标普ASX200(S&P/ASX200)指数是由标准普尔(S&P)和澳大利亚证券交易所(Australian Securities Exchange, ASX)共同编制的主要股票市场指数,简…

【Spring Boot系列】- Spring Boot侦听器Listener

【Spring Boot系列】- Spring Boot侦听器Listener 文章目录 【Spring Boot系列】- Spring Boot侦听器Listener一、概述二、监听器Listener分类2.1 监听ServletContext的事件监听器2.2 监听HttpSeesion的事件监听器2.3 监听ServletRequest的事件监听器 三、SpringMVC中的监听器3…