Serverless plugin to export environment variables into a .env file




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:
1. It will automatically hook into the 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.
2. Invoke 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:
``shVia yarn
$ yarn add arabold/serverless-export-env --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:`yaml
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.$3
`sh
sls export-env
`This will export all project-wide environment variables into a
.env file in your project root folder.`sh
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.Referencing CloudFormation resources
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.$3
- Condition Functions
-
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$3
`yaml
provider:
environment:
S3_BUCKET_URL:
Fn::Join:
- ""
- - https://s3.amazonaws.com/
- Ref: MyBucket
`Or the short version:
`yaml
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).Configuration
The plugin supports various configuration options under
custom.export-env in your serverless.yml file:`yaml
custom:
export-env:
filename: .env
overwrite: false
enableOffline: true
`$3
| 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 |$3
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.`yaml
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.Command-Line Options
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:`sh
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. |
Provided lifecycle events
-
export-env:collect - Collect environment variables from Serverless
- export-env:resolve - Resolve CloudFormation references and import variables
- export-env:apply - Set environment variables when testing Lambda functions locally
- export-env:write - Write environment variables to fileMigrating from 1.x to 2.x
- Running
sls 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.
- By default, the plugin will no longer overwrite any existing .env file. To enable overwriting existing files, either specify --overwrite in the command-line or set the custom.export-env.overwrite configuration option.
- Resource 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.
- Running 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.
- The configuration options 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!Releases
$3
- Fixed error with latest
cfn-resolver-lib. Thanks to estahn for the fix.
- Updated dependencies to latest versions.$3
- Compatibility with Serverless v3.x
- Updated dependencies' minor versions
$3
- Removed optimistic variable resolution for
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.$3
- Added
--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.$3
- Complete rewrite of the variable resolver. We use the amazing cfn-resolver-lib lib now. This allows us to support not only
Ref and Fn::ImportValue as in previous releases, but we're able to resolve the most commonly used intrinsic functions automatically now.
1.x Releases
$3
- Reverted changes in 1.4.1. Unfortunately, we broke the semver contract by introducing a breaking feature in a patch update. This feature needs to be rethought and added back in a 1.5.x release as optional. Until then, I had to remove it again.
#### 1.4.3
- Internal version (not published)
$3
- Fixed some compatibility issues with the latest Serverless framework release. Thanks to pgrzesik for the necessary updates.
$3
- Disabled calls to the real aws infrastructure when running with Serverless Offline. Thanks to marooned071 for the contribution.
$3
- Collect and set resource values from actual Cloud Formation stack output. Thanks to andersquist for his contribution!
- Fix error when serverless.yml doesn't contain a custom section. Thanks to michael-wolfenden!
$3
- Explicitly set environment variables during local invocation of the Lambda (
sls invoke local)$3
- Support different output filename and path. Thanks to philiiiiiipp.
- Export
Outputs as environment variables. Thanks to lielran.
- Updated to latest dependencies$3
- Use operating-system-specific end-of-line when creating
.env file$3
- Fixed an issue with
AWS::AccountId being resolved as [Object Promise] instead of the actual value.$3
- Fixed an issue with CloudFormation resources not being resolved properly if the stack has more than 100 resources or exports.
$3
- Fix issue with multiple environment variables for function (thanks to @Nevon).
$3
- Support
Fn::Join operation (contribution by @jonasho)
- Support pseudo parameters AWS::Region, AWS::AccountId, AWS::StackId and AWS::StackName.$3
- The plugin now properly resolves and sets the environment variables if a Lambda function is invoked locally (
sls invoke local -f FUNCTION`). This allows seamless as if the function would be deployed on AWS.- Corrected plugin naming
- Improved documentation
- This is the initial release with all basic functionality