更灵活的 serverless framework 配置文件

news/2024/5/20 6:11:56 标签: serverless, 数据库, 服务器

bg

serverless_framework__3">更灵活的 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-service
  serviceName: ${self:service}
  # 引用的上一行 serviceName: ${self:service}
  exportName: ${self:custom.serviceName}-export

functions:
  hello:
    handler: handler.hello
    events:
      # ${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}-hello
    handler: handler.hello

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

sls

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

service: new-service
provider: aws
 
functions:
  func1:
    name: function-1
    handler: handler.func1
    environment:
      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}-hello
    handler: handler.hello

file

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

# 你甚至可以引入整个yml文件作为配置
custom: ${file(./myCustomFile.yml)}
provider:
  name: aws
  environment:
    # 引入 json 文件
    MY_SECRET: ${file(./config.${opt:stage, 'dev'}.json):CREDS}
 
functions:
  hello:
    handler: handler.hello
    events:
      - schedule: ${file(./myCustomFile.yml):globalSchedule} # Or you can reference a specific property
  world:
    handler: handler.world
    events:
      # 甚至可以引入 `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.niftyadmin.cn/n/5011811.html

相关文章

AR Project APP技术支持

介绍 用于AR绘图的一款App 联系方式 mail: 995263379qq.com

FastViT实战:使用FastViT实现图像分类任务(一)

文章目录 摘要安装包安装timm安装 grad-cam安装mmcv 数据增强Cutout和MixupEMA项目结构计算mean和std生成数据集补充一个知识点:torch.jit两种保存方式 摘要 论文翻译:https://wanghao.blog.csdn.net/article/details/132407722?spm1001.2014.3001.550…

【备战csp-j】 csp常考题目详解(4)

四.数值转换与编码 1. 十进制数 11/128 可用二进制数码序列表示为( ) 。 A.1011/1000000 B.1011/100000000 C.0.001011 D.0.0001011 答案:D 解析:暂时未找到解决方法,以后会解决。 2. 算式(2047)10 - (3FF)16 + …

使用P5.js来制作一个快乐的小风车动画

p5.js简介 前一段时间偶然了解到一个觉得很好玩儿的东西p5.js,于是就去了解了一下,发现可以自己设计一些有趣的动画效果,设计出来的动画可以放置到页面当中,而且也是简单易学的。 下面是一段官方的介绍: p5.js是一个以 Processi…

靶场溯源第二题

关卡描述:1. 网站后台登陆地址是多少?(相对路径) 首先这种确定的网站访问的都是http或者https协议,搜索http看看。关于http的就这两个信息,然后172.16.60.199出现最多,先过滤这个ip看看 这个很…

2023年中秋节和国庆节连在一起吗?放假安排用待办软件定时提醒

进入2023年的9月份,有不少网友都开始期待下个节日的到来了,这就是中秋节和国庆节。那么今年的中秋节和国庆节连在一起吗?答案是肯定的,中秋节是公历9月29日,和国庆节临近,所以的中秋节和国庆节将会连在一起…

2023年5月| 红帽RHCE考试战报-微思红帽官方授权培训中心

2023.5.25/26 新出炉一波红帽考试战报 恭喜微思20位学员顺利PASS红帽认证考试 通过RHCE认证 不仅从专业技术上证明了你的能力 在职场上更是一块进入Linux行业的“敲门砖” 让你在职场竞争中更具竞争力 微思红帽官方授权培训中心--全国直播,就近安排考试&#…

GO语言网络编程(并发编程)并发介绍,Goroutine

GO语言网络编程(并发编程)并发介绍,Goroutine 1、并发介绍 进程和线程 A. 进程是程序在操作系统中的一次执行过程,系统进行资源分配和调度的一个独立单位。 B. 线程是进程的一个执行实体,是CPU调度和分派的基本单位,它是比进程更…