Variables and plugins
Variables are the values that can be passed to the configuration values within the serverless.yml while running the Serverless Framework command. They need to pass reference values enclosed in ${} brackets, but you can use variables in property values rather than in the property keys. The following code shows how this is added in the serverless.yml file:
provider:
name: aws
stage: ${opt:stage, 'dev'}
In the following statement, we pass the parameter to the CLI and the stage value is populated in the serverless.yml file:
$ serverless deploy --stage qa
The variables can be used recursively as reference properties—that is, we can combine multiple values and variable sources, as shown in the following environment variable:
environment: SERV_SECRET: ${file(../config.${self:provider.stage}.json):CREDS}
We can reference environment variables as well (as shown in the following code), but it is insecure to add sensitive data to environment variables, because they can be accessed through build logs or in the serverless CloudFormation templates:
functions:
myfunction:
name: ${env:FUNC_PREFIX}-myfunction
handler: handler.myfunction
Let's look at a few tutorials for doing this. Make sure that you have the latest Serverless Framework installed and working:
- Create a simple hello project with the Serverless AWS template, then open this project in your favorite editor:
$ serverless create --template aws-nodejs --path env-variable-service
- Replace the serverless.yml file and handler, as shown in the following code. Here, we are adding an environment variable by the name of MY_VAR, and in the handler, we display the environment variable in the message output:
$ cat serverless.yml
service: env-variable-service
# You can pin your service to only deploy with a specific Serverless version
# Check out our docs for more details
# frameworkVersion: "=X.X.X"
provider:
name: aws
runtime: nodejs6.10
# you can define service wide environment variables here
environment:
MY_VAR: Lion
functions:
hello:
handler: handler.hello
$ less handler.js
'use strict';
module.exports.hello = (event, context, callback) => {
const response = {
statusCode: 200,
body: JSON.stringify({
message: `my favourite animal is ${process.env.MY_VAR}`,
input: event,
}),
};
callback(null, response);
};
- Let's invoke locally and look at the result. If you look in the message section, you can see the value of the environment variable that we defined, as shown in the following code:
$ serverless invoke local -f hello
{
"statusCode": 200,
"body": "{\"message\":\"my favourite animal is Lion\",\"input\":\"\"}"
}
As we discussed earlier for nonsensitive data, adding a variable into the serverless.yml file should be fine, but how do we add sensitive data into an environment variable, like a database connection. Let's look into the steps needed to do this:
- Create a new file in the env-variable-service folder and name it serverless.env.yml. Then add the following details into it, as shown in the following code. Here, we are creating a secret variable as per the environment:
$ less serverless.env.yml
dev:
MYSECRET_VAR: 'It is at secret den'
- Let's add one more environment variable in the serverless.yml file, but this time the value will be pulled from the file, so you need to add the highlighted line as the environment variable. This way, Serverless Framework will read through the file and refer it to the specific environment:
# serverless.yml
# you can define service wide environment variables here
environment:
MY_VAR: Lion
MYSECRET_VAR: ${file(./serverless.env.yml):dev.MYSECRET_VAR}
- Let's change the response of the handler to display the secret through the message. Ideally, we should be displaying the secret over the screen, but for this tutorial, I am doing it manually. So let's replace the message body with the one displayed in the following code:
# handler.js
message: `my favourite animal is ${process.env.MY_VAR} and ${process.env.MYSECRET_VAR}`,
- Invoke the function locally and look at the output:
$ serverless invoke local -f hello
{
"statusCode": 200,
"body": "{\"message\":\"my favourite animal is Lion and It is at secret den\",\"input\":\"\"}"
}
Finally, like I said, we can have multiple environment variables for each deployment stage, such as dev, sit,uat, and prod. The following steps show us how we can add them:
- Let's add one more environment variable for prod to the serverless.env.yml file. Then, we can use them dynamically within the serverless.yml file, as shown in the following code:
$ less serverless.env.yml
dev:
MYSECRET_VAR: 'It is at secret dev den'
prod:
MYSECRET_VAR: 'It is at secret prod den'
- Now, we need to makes changes to the serverless.yml file to dynamically pick up the environment variable on the basis of the stage that we set at the time of the invocation or deployment of the function, which is the replacement of the MYSECRET_VAR line with the following line:
#serverless.yml
MYSECRET_VAR: ${file(./serverless.env.yml):${opt:stage}.MYSECRET_VAR}
- We will now invoke the function locally and look at the output for a different stage:
$ serverless invoke local -f hello -s dev
{
"statusCode": 200,
"body": "{\"message\":\"my favourite animal is Lion and It is at secret dev den\",\"input\":\"\"}"
}
$ serverless invoke local -f hello -s prod
{
"statusCode": 200,
"body": "{\"message\":\"my favourite animal is Lion and It is at secret Prod den\",\"input\":\"\"}"
}
https://github.com/shzshi/env-variable-service.git
The plugins are custom JavaScript code that provide extension to existing CLI commands within Serverless Framework. The framework itself is a group of plugins that is provided in the core. We can build our own custom plugin; Serverless Framework provides documentation for this plugin as well. The plugin can be installed using the following code:
$ npm install --save custom-serverless-plugin
We also need to call them within the serverless service, using the following code:
serverless.yml file
plugins:
- custom-serverless-plugin
https://github.com/serverless/plugins