The Serverless Framework offers a very powerful feature: You can reference AWS resources anywhere from within your serverless.yml
and it will automatically resolve them to their respective values during deployment. However, this only works properly once your code is deployed to AWS. The Serverless Export Env Plugin extends the Serverless Framework's built-in variable solution capabilities by adding support many additional CloudFormation intrinsic functions (Fn::GetAtt
, Fn::Join
, Fn::Sub
, etc.) as well as variable references (AWS::Region
, AWS::StackId
, etc.).
The Serverless Export Env Plugin helps solve two main use cases:
sls invoke local
and sls offline start
(see Serverless Offline Plugin) and help resolve your environment variables. This is fully transparent to your application and other plugins.sls export-env
from the command line to generate a .env
file on your local filesystem. Then use a library such as dotenv to import it into your code, e.g. during local integration tests.Add the npm package to your project:
# Via yarn
$ yarn add arabold/serverless-export-env --dev
# Via npm
$ npm install arabold/serverless-export-env --save-dev
Add the plugin to your serverless.yml
. It should be listed first to ensure it can resolve your environment variables before other plugins see them:
plugins:
- serverless-export-env
That's it! You can now call sls export-env
in your terminal to generate the .env
file. Or, you can run sls invoke local -f FUNCTION
or sls offline start
to run your code locally as usual.
sls export-env
This will export all project-wide environment variables into a .env
file in your project root folder.
sls export-env --function MyFunction --filename .env-MyFunction
This will export environment variables of the MyFunction
Lambda function into a .env-MyFunction
file in your project root folder.
As mentioned before, the Serverless Framework allows you to reference AWS resources anywhere from within your serverless.yml
and it will automatically resolve them to their respective values during deployment. However, Serverless' built-in variable resolution is limited and will not always work when run locally. The Serverless Export Env Plugin extends this functionality and automatically resolves commonly used intrinsic functions and initializes your local environment properly.
Fn::And
Fn::Equals
Fn::If
Fn::Not
Fn::Or
Fn::FindInMap
Fn::GetAtt
Fn::GetAZs
Fn::Join
Fn::Select
Fn::Split
Fn::Sub
(at the moment only key-value map subtitution is supported)Fn::ImportValue
Ref
provider:
environment:
S3_BUCKET_URL:
Fn::Join:
- ""
- - https://s3.amazonaws.com/
- Ref: MyBucket
Or the short version:
provider:
environment:
S3_BUCKET_URL: !Join ["", [https://s3.amazonaws.com/, Ref: MyBucket]]
You can then access the environment variable in your code the usual way (e.g. process.env.S3_BUCKET_URL
).
The plugin supports various configuration options under custom.export-env
in your serverless.yml
file:
custom:
export-env:
filename: .env
overwrite: false
enableOffline: true
Option | Default | Description |
---|---|---|
filename | .env |
Target file name where to write the environment variables to, relative to the project root. |
enableOffline | true |
Evaluate the environment variables when running sls invoke local or sls offline start . |
overwrite | false |
Overwrite the file even if it exists already. |
refMap | {} |
Mapping of resource resolutions for the Ref function |
getAttMap | {} |
Mapping of resource resolutions for the Fn::GetAtt function |
importValueMap | {} |
Mapping of resource resolutions for the Fn::ImportValue function |
The plugin will try its best to resolve resource references like Ref
, Fn::GetAtt
, and Fn::ImportValue
for you. However, sometimes this might fail, or you might want to use mocked values instead. In those cases, you can override those values using the refMap
, getAttMap
, and importValueMap
options.
refMap
takes a mapping of resource name to value pairs.getAttMap
takes a mapping of resource name to attribute/value pairs.importValueMap
takes a mapping of import name to value pairs.custom:
export-env:
refMap:
# Resolve `!Ref MyDynamoDbTable` as `mock-myTable`
MyDynamoDbTable: "mock-myTable"
getAttMap:
# Resolve `!GetAtt MyElasticSearchInstance.DomainEndpoint` as `localhost:9200`
MyElasticSearchInstance:
DomainEndpoint: "localhost:9200"
importValueMap:
# Resolve `!ImportValue MyLambdaFunction` as `arn:aws:lambda:us-east-2::function:my-lambda-function`
MyLambdaFunction: "arn:aws:lambda:us-east-2::function:my-lambda-function"
👉 Generally, it is recommended to avoid the use of intrinsic functions in your environment variables. Often, the same can be achieved by simply predefining a resource name and then manually construct the desired variable values. To share resources between different Serverless services, check out the
${cf:stackName.outputKey}
variable resolution mechanism.
Running sls export-env
will, by default, only export global environment variables into your .env
file (those defined under provider.environment
in your serverless.yml
). If you want to generate the .env
file for a specific function, pass the function name as a command-line argument as follows:
sls export-env --function hello --filename .env-hello
Option | Description |
---|---|
filename | Target filename where to write the environment variables to, relative to the project root. |
overwrite | Overwrite the file even if it exists already. |
function | Name of a function for which to generate the .env file. |
all | Merge environment variables of all functions into a single .env file. |
export-env:collect
- Collect environment variables from Serverlessexport-env:resolve
- Resolve CloudFormation references and import variablesexport-env:apply
- Set environment variables when testing Lambda functions locallyexport-env:write
- Write environment variables to filesls invoke local
or sls offline start
will no longer create or update your .env
file. If you want to create an .env
file, simply run sls export-env
instead..env
file. To enable overwriting existing files, either specify --overwrite
in the command-line or set the custom.export-env.overwrite
configuration option.Outputs
values (resources.Resources.Outputs.*
) are no longer getting exported automatically. This has always been a workaround and causes more problems than it solved. The plugin will try its best to resolve Fn::GetAtt
and other references for you now, so there should be little need for the old behavior anymore. Add the desired value as an environment variable to provider.environment
instead.sls export-env
will no longer merge the environment variables of all functions into a single .env
file. Instead, pass the name of the desired function as --function
argument to the command line. If no function name is specified, only project-wide environment variables will get exported. To bring back the old behavior, pass --all
in command line and it will generate a file including all environment variables of all functions. However, please be aware that the behavior is undefined if functions use conflicting values for the same environment variable name.filename
and pathFromRoot
have been merged to filename
now. You can specify relative paths in filename
such as ./dist/.env
now. Make sure the target folder exists!cfn-resolver-lib
. Thanks to estahn for the fix.Fn::GetAtt
as it was not working properly and caused hard to solve issues. If you rely on Fn::GetAtt
in your environment variables, define a custom resolution using the getAttMap
configuration option.--all
command line parameter to merge the environment variables of all functions into a single .env
file. Please note that the behavior is undefined if functions use conflicting values for the same environment variable name.Ref
and Fn::ImportValue
as in previous releases, but we're able to resolve the most commonly used intrinsic functions automatically now.