Serverless Plugin for Exporting Environment Variables and Stack Outputs

// 1 comment

I recently published my serverless-exports-plugin for the Serverless Framework. While it shares similarities with existing plugins like serverless-export-env and serverless-export-outputs, my plugin supports to export both environment variables and stack outputs.

What It Does

The plugin retrieves environment variables and stack outputs specified in Serverless.yaml and saves them to local files during deployment.

Here's a sample Serverless project to illustrate:

service: acme-service frameworkVersion: '3' plugins: - serverless-exports-plugin custom: exports: environment: file: .env.${sls:stage} format: env overwrite: true stack: file: .serverless/stack-outputs.txt format: env overwrite: true provider: name: aws runtime: nodejs18.x environment: FOO: bar STAGE: ${sls:stage} REGION: ${aws:region} SERVICE: ${self:service} functions: hello: handler: index.handler resources: Resources: bucket: Type: AWS::S3::Bucket Properties: BucketName: ${self:service}-${sls:stage}-bucket Outputs: Foo: Value: bar BucketName: Value: !Ref bucket

When deployed using serverless deploy --stage dev:

/

The defined environment variables are saved in a file .env.dev:

# .env.dev FOO: bar STAGE: dev REGION: us-east-1 SERVICE: acme-service

The outputs from the stack are written to the .serverless/stack-outputs.txt file.

# .serverless/stack-outputs.txt ServerlessDeploymentBucketName: acme-service-dev-serverlessdeploymentbuck-ab4cd786 HelloLambdaFunctionQualifiedArn: arn:aws:lambda:us-east-1:000000000000:function:acme-service-dev-hello:1 Foo: bar BucketName: acme-service-dev-bucket

The stack outputs contain additional keys from the Serverless Framework that have not been explicitly defined.

Why I Created It

Although I designed it for a specific need, there are numerous other applications. For instance, I've set up an S3 bucket and a CloudFront distribution in a Serverless project to host a website. When I need to deploy the website — whether locally or in CI — I first deploy the infrastructure resources and then upload the web assets (HTML, JS, CSS) to S3. To streamline this into a single script, I needed the Serverless environment variables and stack outputs with their evaluated values.

The deploy script is as follows:

#!/bin/bash # Verify if the STAGE environment variables is set if [ -z "$STAGE" ]; then echo "Environment variable STAGE is not defined" exit 1 fi # Deploy Serverless service # This produces a .env.<STAGE> file and a .serverless/stack-outputs.txt file serverless deploy --stage "$STAGE" # Build Vite application # This loads the .env.<STAGE> file with mode=<STAGE> vite build --mode "$STAGE" # Stack outputs are generated during the Serverless deployment # These include the S3 bucket name STACK_OUTPUTS_FILE=".serverless/stack-outputs.txt" # Read the file and set each line as an environment variable while IFS="=" read -r key value; do export "$key=$value" done < "$STACK_OUTPUTS_FILE" # Upload the bundled app to the S3 bucket # $BucketName is an output from the stack outputs aws s3 sync "dist/" "s3://$BucketName" # Additional steps # ...

What’s Ahead

There are several features I'm still working on. At present, only the .env format is available for exporting. However, I plan to add support for other formats, including JSON, TOML, and YAML. To provide even greater versatility, exports might be relayed to a JavaScript handler function rather than being saved to a file.

Furthermore, only globally specified environment variables are currently exported. I intend to ensure function-level variables are also exported. In addition, I plan to implement support for including and excluding specific keys that are exported.

There are likely many bugs I'm not yet aware of, so contributions and feedback are very welcome!