More flexible serverless framework configuration file
Foreword
After the deployment of the pre-tutorial, I wonder if you have noticed such an issue, that is, the function name we deployed, and the endpoint
of API gateway
, their names and The paths all contain a dev
?
This is caused by stage
. When we execute sls deploy
deployment, because the --stage
parameter is not specified, it defaults to dev
, so the function name we deployed before is included in the gateway.
So what does it do? In fact, this value is used to distinguish stages/environments for your functions and corresponding services.
For example, for a function that provides web
services, we artificially divide into three environments:
dev
is used for developers to test themselvessit
is used for integration testingprod
production environment
Different environments have different endpoint
allocated by their respective API gateway
.
If you have a domain name, you can configure the domain name with some more primary or multi-level domain names, and resolve their
CNAME
to the specifiedAPI gateway
address for use. Of course, if you are only in the domain name console, direct resolution will not take effect, becauseAPI Gateway
has a two-factor verification, and you must enter theCustom Domain Name< of
API Gateway
. /code>interface, create a custom domain name and bind theACM certificate
. The resolution will take effect only after passing the review.What is
ACM Certificate
? The full name ofACM
isAmazon Certificate Manager
, click here to see moreDon’t worry, applying for and issuing an
ACM certificate
is very simple. Its functions and application process are the same as our application for a freeSSL/TLS
certificate, which is one more resolution of our domain name.CNAME
thing.
At this time we can naturally use cli option
to set:
"scripts": {<!-- --> "deploy:dev": "sls deploy", "deploy:sit": "sls deploy -s sit", "deploy:prod": "sls deploy -s prod" },
But as the project becomes more and more complex, you will find that using the CLI
command to continuously add configuration items is both cumbersome and inefficient. Is there any way to use one variable to control a large number of configuration items? What about configuration?
In serverless framework
, we can usually use dynamic variables
to solve this problem.
Dynamic variables
What are dynamic variables? In fact, they are just strings written in a special way. Common ways of writing variables are as follows:
${<!-- -->variableSource} ${<!-- -->sls:stage}-lambdaName ${<!-- -->env:MY_API_KEY} ${<!-- -->file(create_request.json)} ${<!-- -->self:service}:${<!-- -->sls:stage}:UsersTableArn
serverless.yml
supports the use of the above variables to reference and read configurations. They are very useful. After all, you cannot put certain configuration items, such as secret
Write directly inline
in the yml
file.
Among them, ${}
is the way to write variable references, which will replace them with real values when sls cli
is run.
# ${} The second parameter is the default value otherYamlKey: ${<!-- -->variableSource, defaultValue}
Here are some commonly used variables:
self
The first thing we must talk about is self
. It is the key for our application to configure other values of itself. self
points to the root of our yml
configuration. node. Here I give an example, I believe you are smart enough to see its usage at a glance.
service: new-service provider: aws custom: globalSchedule: rate(10 minutes) # The first line quoted service: new-service serviceName: ${<!-- -->self:service} # The previous line quoted serviceName: ${self:service} exportName: ${<!-- -->self:custom.serviceName}-export functions: hello: handler: handler.hello events: # ${self:someProperty} # self points to the root node of the yml configuration, so it can - schedule: ${<!-- -->self:custom.globalSchedule} resources: Outputs: NewServiceExport: Value: 'A Value To Export' Export: Name: ${<!-- -->self:custom.exportName}
env
As the name suggests, use system-configured environment variables:
service: new-service provider: aws functions: hello: name: ${<!-- -->env:FUNC_PREFIX}-hello handler: handler.hello
This is generally easier to use with tools such as dotenv
.
sls
This variable can get some Serverless Core
values, such as instanceId
and stage
, the use example is as follows
service: new-service provider: aws functions: func1: name: function-1 handler: handler.func1 environment: APIG_DEPLOYMENT_ID: ApiGatewayDeployment${<!-- -->sls:instanceId} STAGE: ${<!-- -->sls:stage}
The essence of the ${sls:stage}
command is actually the abbreviation of ${opt:stage, self:provider.stage, "dev"}
, so You also understand why the default value is dev
.
opt
This variable is used to get the value in Options passed in by the CLI:
service: new-service provider: aws functions: hello: name: ${<!-- -->opt:stage}-hello handler: handler.hello
file
The core method/variable of modular configuration. Use this variable method to read files and reference them. For example, we can introduce additional yml
, json
, js
file:
# You can even import the entire yml file as a configuration custom: ${<!-- -->file(./myCustomFile.yml)} provider: name: aws environment: #Introduce json file 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: # You can even import `js` files - schedule: ${<!-- -->file(./scheduleConfig.js):rate}
At this time, it will read different configuration files under relative paths based on the stage
parameter we passed in.
There are certain restrictions on the code that introduces js
files. It must be in commonjs
format, and must export a js
object, or export a function
. The method of exporting objects is very simple and not very versatile. Here we take the method as an example:
//Currently it must be in commonjs format and return an object as the value // The method can be synchronous or asynchronous 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' } }
We can get other variables in it and perform additional calculations, or we can request remote data acquisition here as additional configuration for deployment.
More
In addition, it can also reference variables of more services, such as CloudFormation
, S3
, SSM
and other services, and more For comprehensive variables, please see: Official variable directory address
Configure other supported formats
In fact, the current serverless cli
not only accepts serverless.yml
, but also accepts serverless.ts
, serverless.json
code>, serverless.js
format.
Here the author only recommends two formats serverless.yml
and serverless.js
Why not serverless.json
? Because the expressiveness of json
files is weak, and even jsonc
is required to support comments, so I gave up.
Why not serverless.ts
? Because it will cause errors if used directly. See issues/48 for details, which is not worry-free. It is better to use the combination of js
+ jsdoc
. There are smart prompts and flexibility.
So let’s summarize the advantages of serverless.yml
and serverless.js
:
-
serverless.yml
: Simple enough, more flexible with dynamic variables -
serverless.js
: You can usenodejs api
, or it can be used with dynamic variables, which is more flexible, and the configuration can use the nativejs
writing method.
Here we take the serverless.js
configuration file as an example:
Smart prompt, requires
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
Of course, since it is a nodejs
runtime, you can split the configuration file into multiple files and then use commonjs
to reference them natively. You can also use environment variables, node:fs
, node:path
and other modules to dynamically generate configuration files based on conditions, or even use some third-party libraries to do some additional It’s such a flexible job!
Next Chapter
Now you have just scratched the surface of serverless framework dynamic configuration files.
The next article, “Combining with traditional nodejs web framework”, will introduce in detail how to deploy express/koa
and serverless based on them
application, welcome to read.2
Complete examples and article warehouse address
https://github.com/sonofmagic/serverless-aws-cn-guide
If you encounter any problems or find any errata, please submit issue
to me