DEV Community

bardawilpeter
bardawilpeter

Posted on

Integrating SSM with serverless Applications

We always think about ways to include env vars for different environments where they can be used by various team members and stored in one place.
Using AWS SSM will help you achieve that.

In this article, I'll be taking you into the steps to create a serverless app that can use SSM for env vars on different environments.

To create a serverless framework app, let's make sure that you have the package installed globally by running serverless

  • Pick AWS - Node.js - Starter to create a starter kit app Image description
  • Choose a name for the project in "What do you want to call this project?"
  • Put "no" as an answer for the next steps, as we don't need to log in or deploy.

After those steps, you should have a serverless starter app created for you.

Let's use the AWS CLI to create an SSM param but first, ensure you have the CLI installed locally.

Create two SSM params for dev and prod:
Dev:

aws ssm put-parameter \
    --name "/api/dev/url" \
    --value "http://prod.api.com" \
    --type String

Prod:

aws ssm put-parameter \
    --name "/api/prod/url" \
    --value "http://prod.api.com" \
    --type String

`
To confirm that the param is created, you can get one of the created params:

aws ssm get-parameter --name "/api/prod/url"

To use those params in our serverless app, let's create two files in the serverless app project having:
env.dev.yml:

API_URL: ${ssm:/api/dev/url}

env.prod.yml:

API_URL: ${ssm:/api/dev/url}

Edit your serverless.yml to be:

service: aws-demo-serverless-project

frameworkVersion: '3'

provider:
  stage: ${opt:stage, "dev"}
  name: aws
  runtime: nodejs14.x
  environment: ${file(./env.${self:provider.stage}.yml)}

custom:
  serverless-offline:
    httpPort: 4000

functions:
  hello:
    handler: handler.hello
    events:
      - http:
          path: hello
          method: get

plugins:
  - serverless-offline

To run the app locally, install the serveless-offline package. You can create this package.json file in your demo project and run npm install:

{
  "name": "serverless-ssm-demo",
  "version": "1.0.0",
  "description": "",
  "main": "handler.js",
  "devDependencies": {
    "serverless-offline": "^11.1.3"
  },
  "scripts": {
    "serve": "serverless offline"
  },
  "author": "",
  "license": "ISC"
}

As you can already see, we added a serve script in the app, which will use the serverless-offline package to run the application offline.

Now we can start using the above-created env var API_URL in our application. To do so, we can update the existing handler.js file:

'use strict';

module.exports.hello = async (event) => {
  return {
    statusCode: 200,
    body: JSON.stringify(
      {
        message: process.env.API_URL
      },
      null,
      2
    ),
  };
};

Let's test that printing the value of the API_URL will work by running yarn serve.
After a successful run, you can check the output of the app by opening http://localhost:4000/dev/hello in your browser or running curl http://localhost:4000/dev/hello using your terminal:

{
  "message": "http://dev.api.com"
}

Awesome! 👏 we are ready to deploy our app to different environments where each one has different env vars values
Add some scripts to your existing package.json:

  1. "deploy:env": "sls deploy --stage $NODE_ENV"
  2. "deploy:dev": "NODE_ENV=stage yarn deploy:env"
  3. "deploy:production": "NODE_ENV=production yarn deploy:env"

Or replace this below ready package.json with the existing one:

{
  "name": "serverless-ssm-demo",
  "version": "1.0.0",
  "description": "",
  "main": "handler.js",
  "devDependencies": {
    "serverless-offline": "^11.1.3"
  },
  "scripts": {
    "serve": "serverless offline",
    "deploy:env": "sls deploy --stage $NODE_ENV",
    "deploy:dev": "NODE_ENV=dev yarn deploy:env",
    "deploy:production": "NODE_ENV=production yarn deploy:env"
  },
  "author": "",
  "license": "ISC"
}

Let's start deploying to the dev environment by running yarn deploy:dev
After a success, serverless will return an endpoint for you in the terminal, copy it, and open it in your browser. You should see the value of the dev env var:

{
  "message": "http://dev.api.com"
}

Repeat the same by running yarn deploy:production and opening the new prod endpoint in your browser. Now you should see the production env var instead:

{
  "message": "http://prod.api.com"
}

Congrats! 🥳 now you can use the same solution to add more env vars with the ability to be used in different environments.

Link to the GitHub repo: https://github.com/bardawilpeter/integrating-ssm-serverless-framework

Top comments (0)