腾讯云SCF云函数多环境配置

背景

小伙伴们应该已经体验到了Serverless给我们开发带来的不曾有过的便利。那么接下来一个必然会问到的问题:我的业务开发完了,如何管理不同环境的配置呢?比如测试环境的数据库配置和正式环境的如何切换?这个领域,有一篇经典的文章《Serverless 多环境配置方案探索》见参考文档。但我探索下来,其实有更简单的方式。这里抛转引玉,给出我的解决方案,来跟大家一起学习和探讨。

注意哦,这里是多环境配置,之前我写的那篇文章,是多环境部署。

目标

多环境配置主要解决:

  1. 编译构建过程中,serverless.yml文件中的多环境配置,比如,发布到上海地区还是广州地区,命名空间是什么,内存大小、初始化时间等等;
  2. 代码运行过程中,代码文件中的多环境配置,比如,连接哪个数据库,用户名和密码是什么等等。

整体方案的处理逻辑是:在执行sls deploy阶段通过参数--stage选择不同的.env文件,导入配置信息,输入serverless.yml文件中的{env:配置Key}对应配置Key的Value,解决serverless.yml文件中的多环境配置。

通过serverless.yml文件中的inputs-environment-variables解决代码文件中的多环境配置。

environment: # 环境变量

代码语言:txt
复制
variables: #  环境变量对象
代码语言:txt
复制
  mysqlHost: ${env:mysqlHost}
代码语言:txt
复制
  mysqlUser: ${env:mysqlUser}
代码语言:txt
复制
  mysqlPassword: ${env:mysqlPassword}

代码结构及配置代码内容

以A项目为例,见下图。

A项目代码结构

.env.release和.env.test 文件中的格式为 配置Key=配置Value ,cup项目示例如下:

代码语言:txt
复制
timeout=10
region=ap-guangzhou
memorySize=128
memoryBigSize=1024
vpcId=vpc-***
subnetId=subnet-***
mysqlHost=IP地址
mysqlUser=cup
mysqlPassword=数据库密码
serviceName=buzzfrog_cn
serviceId=service-***
cupAppId=api-***

serverless.yml中最关键的部分为:

代码语言:yaml
复制
stage: ${env.STAGE}
inputs:
  name: ${name}-${stage}-${app}
  region: ${env:region}
  namespace: ${stage}
  environment: #  环境变量
    variables: #  环境变量对象,可以将这些keyvalue传入到node.js和typescript代码中
      mysqlHost: ${env:mysqlHost}
      mysqlUser: ${env:mysqlUser}
      mysqlPassword: ${env:mysqlPassword}

cup项目的serverless.yml的示例如下:

代码语言:yaml
复制
org: buzzfrog # 组织名称。留空则则使用默认值为用户appid
app: A #(可选) 该应用名称。留空则默认取当前组件的实例名称为app名称。
stage: ${env.STAGE} #(可选) 用于区分环境信息,默认值为 dev
component: scf # (必选) 组件名称,在该实例中为scf
name: main # (必选) 组件实例名称。

inputs:

name: # 云函数名称,默认为 {name}--$

src:
src: ./dist
exclude:
- .env
type: web
entryFile: main.js
region: ${env:region}
runtime: Nodejs12.16
namespace: ${stage}
memorySize: ${env:memoryBigSize}
timeout: ${env:timeout}
environment: # 环境变量
variables: # 环境变量对象
mysqlHost: ${env:mysqlHost}
mysqlUser: ${env:mysqlUser}
mysqlPassword: ${env:mysqlPassword}
vpcConfig: # 私有网络配置
vpcId: ${env:vpcId} # 私有网络的Id
subnetId: ${env:subnetId} # 子网ID
layers: #layer配置
- name: koaNodeModules # layer名称
version: 4 # 版本
events:
- apigw:
parameters:
serviceName: ${env:serviceName}
serviceId: ${env:serviceId}
protocols:
- http
- https
environment: release
endpoints:
- path: /A
apiId: ${env:aAppId}
apiName: A服务
method: ANY
enableCORS: false
responseType: JSON
isBase64Encoded: false
isBase64Trigger: false
serviceTimeout: 10
function:
isIntegratedResponse: false
functionQualifier: $LATEST
functionName: {name}-{stage}-${app}
functionType: HTTP

代码中,这样使用环境变量配置:

代码语言:javascript
复制
const mySQLPoolConnector:MySQLPoolConnector = new MySQLPoolConnector({
host: process.env.mysqlHost,
user: process.env.mysqlUser,
password: process.env.mysqlPassword,
database: 'aDatabase',
});

在执行部署时,如果需要使用.env.test,则deploy时执行

代码语言:shell
复制
sls deploy --stage test

如果需要使用.env.release,则deploy时执行

代码语言:shell
复制
sls deploy --stage release

以上方案,无需引入dotenv,逻辑简单,但需要使用serverless.yml文件做跳板中转环境变量配置,即,配置Key需要配置两遍的问题(每个环境的配置Value只需要配置一遍,在.env文件中)。

参考文档

Serverless 多环境配置方案探索 https://cloud.tencent.com/developer/article/1610209

腾讯云SCF云函数命令行多环境部署 https://cloud.tencent.com/developer/article/2249275