---
tags: feature
author: Oliver.W
---
# Serverless Application Template
Owner: Oliver
Stakeholders: 3rd part Applicaiton developers, Tencent, Serverless China, Serverless
Currently Tencent is working with 3rd part company publish their own application template for end users to easy set up and deploy their own apllications. As the sametime, we like the 3rd part developers can using serverless to build the template while the end user will just need simple configure to start using their own application.
eg: Record service to record and replay the stream content in a short period of time (near realtime.)
* Using Components Solution: Developers cant benefit from exist components and get benefits of serverless.
* Using Templates Solution: No way to manage the template version and validation rules, also can't publish to registry, and hard to deploy through console.
### Current Template Implementation
当前 全景录制应用 需要配置的我内容
```md
* app:
* region:
* vpc:
* vpcId:
* subnetId:
* bucket:
* cfs:
* redis:
* host
* port
* password
* index
```
The currently serverless.yml for record service.
```yml
component: multi-scf
name: web_record
app: ${env:NAME}
inputs:
src:
src: ./
exclude:
- .env
- record/**
- node_modules/**
- transcode/**
- docker/**
- dist/**
- scripts/**
region: '${env:REGION}'
runtime: Nodejs12.16
role: SCF_QcsRole
memorySize: 256
isAutoPublish: true
timeout: 90
msgTTL: 21600
retryNum: 0
vpc:
vpcId: '${env:VPC_ID}'
subnetId: '${env:SUBNET_ID}'
environments:
- key: SLS_APP_NAME
value: '${app}'
- key: ENV
value: '${env:ENV}'
- key: APP_VERSION
value: '${env:APP_VERSION}'
- key: VPC_ID
value: '${env:VPC_ID}'
- key: SUBNET_ID
value: '${env:SUBNET_ID}'
- key: REGION
value: '${env:REGION}'
- key: COS_BUCKET
value: '${env:COS_BUCKET}'
- key: CDN_DOMAIN
value: '${env:CDN_DOMAIN}'
- key: REDIS_HOST
value: '${env:REDIS_HOST}'
- key: REDIS_PORT
value: '${env:REDIS_PORT}'
- key: REDIS_AUTH
value: '${env:REDIS_AUTH}'
- key: REDIS_INDEX
value: '${env:REDIS_INDEX}'
- key: CFS_ID
value: '${env:CFS_ID}'
- key: MOUNT_ID
value: '${env:MOUNT_ID}'
- key: RECORD_IMAGE_URL
value: '${env:RECORD_IMAGE_URL}'
- key: REGISTRY_ID
value: '${env:REGISTRY_ID}'
- key: TRANSCODE_IMAGE_URL
value: '${env:TRANSCODE_IMAGE_URL}'
functions:
- name: '${app}-callback'
src: ./callback
handler: index.main_handler
memorySize: 512
asyncRunEnable: true
traceEnable: true
- name: '${app}-upload'
src: ./upload
handler: index.main_handler
memorySize: 512
timeout: 7200
asyncRunEnable: true
traceEnable: true
cfs:
- cfsId: '${env:CFS_ID}'
mountInsId: '${env:MOUNT_ID}'
localMountDir: /mnt/
remoteMountDir: /
- name: '${app}-transcode'
memorySize: 3072
timeout: 7200
asyncRunEnable: true
traceEnable: true
image:
imageUrl: '${env:TRANSCODE_IMAGE_URL}'
imageType: public
registryId: '${env:REGISTRY_ID}'
cfs:
- cfsId: '${env:CFS_ID}'
mountInsId: '${env:MOUNT_ID}'
localMountDir: /mnt/
remoteMountDir: /
- name: '${app}-record'
memorySize: 3072
timeout: 86400
asyncRunEnable: true
traceEnable: true
image:
imageUrl: '${env:RECORD_IMAGE_URL}'
imageType: public
registryId: '${env:REGISTRY_ID}'
cfs:
- cfsId: '${env:CFS_ID}'
mountInsId: '${env:MOUNT_ID}'
localMountDir: /mnt/
remoteMountDir: /
- name: '${app}-dispatch'
memorySize: 256
src: ./dispatch
handler: index.main_handler
- name: '${app}-diagnose'
memorySize: 256
timeout: 150
src: ./diagnose
handler: index.main_handler
triggers:
- type: timer
function: '${app}-dispatch'
parameters:
name: dispatch_timer
cronExpression: 0 */10 * * * * *
enable: true
argument: Active
- type: timer
function: '${app}-diagnose'
parameters:
name: diagnose_timer
cronExpression: '*/30 * * * * * *'
enable: true
argument: argument
- type: timer
function: '${app}-record'
parameters:
name: record_timer
cronExpression: 0 */10 * * * * *
enable: true
argument: Active
- type: apigw
parameters:
name: web_record
protocols:
- http
- https
description: Serverless web-record API GW
environment: release
apis:
- path: /record
apiName: dispatch_api
method: POST
description: Serverless REST API
enableCORS: true
responseType: JSON
serviceTimeout: 90
authType: APP
function: '${app}-dispatch'
```
* The validation rules will still using the multi-scf rules.
* No way to manage the version of the template.
* It is hard for 3rd part developers build template and manage env configs.
## Objectives & Key Results
* 3rd part developer can use components to build Application Template and get benefits of Serverless.
* Application Template should have way to validte the config before deploy.
* Application Template should have way to define the version of it.
## Proposed Solution
* Add new application template for this use case.
* Similar to components config but can extend exist components
* End user can use application level config (serverless.yml) to deploy an applicaiton.
修改应用模板使用 组件模板 方式进行开发。如 创建新的 应用模板 `panorama-record` 后, 应用用户 通过 serverless.yml 进行实例配置, 应用开发者使用 serverless.components.yml 中的base 进行模板配置
### 使用 serverless.yml 进行配置
```
SDK.
image: node12lts
image: tencent-scf-node12lts.
api.get('blogs') => {
....
}
```
```yml
component: multi-scf
name: web_record
app: ${APP:app}
inputs:
src:
src: ./
exclude:
- .env
- record/**
- node_modules/**
- transcode/**
- docker/**
- dist/**
- scripts/**
runtime: Nodejs12.16
role: SCF_QcsRole
variable:
default: xxx
type: string
rules:
- regex: '^[a-zA-Z][a-zA-Z0-9(_)]{0,48}[a-zA-Z0-9]?$'
message: "字符不接受"
- min: 2
message: "长度过短"
- max: 60
message: "长度过长"
memorySize: 256
isAutoPublish: true
timeout: 90
msgTTL: 21600
retryNum: 0
functions:
triggers:
```
使用 新的[组件校验规则](https://hackmd.io/@serverless-cn/Sy-SRaU0d)完成 serverless.yml 的配置校验。
* 可以进行多个规则的校验
* 通过接口可以直接对配置信息进行校验。
* 在部署前进行校验
### 使用 serverless.application.yml 配置应用模板
```yml
name: panorama-record
version: 0.1.1
author: Tencent Cloud, Inc.
org: Tencent Cloud, Inc.
description: Deploy a serverless cloud function on Tencent Cloud.
keywords: tencent, serverless, SCF
repo: https://github.com/serverless-components/tencent-scf
readme: https://github.com/serverless-components/tencent-scf/tree/master/README.md
license: MIT
main: ./src
webDeployable: true
# 变量名称,变量类型,变量默认值。
template: will use as default value for end users when they init. serverless.yml
app: my-panorama-record-app
component: panorama-record
inputs:
region:ap-guangzhou
type: string
default:
allow:
- event
- web
...
vpc:
vpcId: ${output:${stage}:${app}:sls-demo-msn-vpc.vpcId}
subnetId: ${output:${stage}:${app}:sls-demo-msn-vpc.subnetId}
bucket: my-bucket
cfs:
cfsId: my-cfs
mountId: 1
redis:
host: my-cfs.host.com
port: 3022
password: ${env: RedisPassword}
index: 1
images:
transcodeUrl: mytrans.host.com
recordUrl: myrecord.host.com
registryId: 1
```
With this solution, The benefits are
* Easier for developer to config
* Set up each application config validation rules by reuse [components-types](https://github.com/serverless-components/tencent-types)
* Able to publish to registry and init through CLI.
## The future Serverless Architecture
* The application templates will be used like templates.
* End User can not modify the application template code beside make PR.
* End User need to config application app with `serverless.yml` as usual.
* Application Template config example defineds in `serverless.application.yml`

### 3rd pard developers UX
1. develop app as normal with `serverless.yml`
```yml
component: multi-scf
name: web_record
app: ${base:app}
inputs:
src:
src: ./
runtime: Nodejs12.16
role: SCF_QcsRole
memorySize: 256
isAutoPublish: true
timeout: 90
msgTTL: 21600
retryNum: 0
functions:
- name: '${app}-callback'
src: ./callback
handler: index.main_handler
memorySize: 512
asyncRunEnable: true
...
```
2. add `serverless.applicaiton.yml` to the application template.
* Application name, version etc info.
* Confing file(serverless.yml) template.
```yml
name: panorama-record
version: 0.1.1
author: Tencent Cloud, Inc.
org: Tencent Cloud, Inc.
description: Deploy a serverless cloud function on Tencent Cloud.
keywords: tencent, serverless, SCF
repo: https://github.com/serverless-components/tencent-scf
readme: https://github.com/serverless-components/tencent-scf/tree/master/README.md
license: MIT
main: ./src
webDeployable: true
default: # will use as default value for end users when they init.
app: my-panorama-record-app
component: panorama-record
inputs:
region:ap-guangzhou
vpc:
vpcId: ${output:${stage}:${app}:sls-demo-msn-vpc.vpcId}
subnetId: ${output:${stage}:${app}:sls-demo-msn-vpc.subnetId}
bucket: my-bucket
cfs:
cfsId: my-cfs
mountId: 1
redis:
host: my-cfs.host.com
port: 3022
password: ${env: RedisPassword}
index: 1
images:
transcodeUrl: mytrans.host.com
recordUrl: myrecord.host.com
registryId: 1
```
3. publish as serverless applicaiton template.
4. [optional]upload config validation into [components-types](https://github.com/serverless-components/tencent-types)
### end-user UX
1. init application with name registred
* through CLI `sls init panorama-record --name my-record-service`
* through Tencetn Console
2. fill the config file (serverless.yml)
```yml
# serverless.yml
app: my-panorama-record-app
component: panorama-record
inputs:
region:ap-guangzhou # 应用部署地区
vpc:
vpcId: ${output:${stage}:${app}:sls-demo-msn-vpc.vpcId}
subnetId: ${output:${stage}:${app}:sls-demo-msn-vpc.subnetId}
bucket: my-bucket
cfs:
cfsId: my-cfs
mountId: 1
redis:
host: my-cfs.host.com
port: 3022
password: ${env: RedisPassword}
index: 1
images:
transcodeUrl: mytrans.host.com
recordUrl: myrecord.host.com
registryId: 1
```
3. deploy the applicaiton.
* through CLI `sls deploy`
* through Tencent Console