close
close
use ssm params in serverless framework

use ssm params in serverless framework

3 min read 22-01-2025
use ssm params in serverless framework

The Serverless Framework is a powerful tool for building and deploying serverless applications. One common need is securely managing sensitive information like API keys, database credentials, and other secrets. Storing these directly in your code is a significant security risk. AWS Systems Manager Parameter Store (SSM) offers a robust solution for managing these secrets securely. This article will guide you through integrating SSM parameters into your Serverless Framework applications.

Why Use SSM Parameters?

Using SSM Parameter Store offers several advantages:

  • Enhanced Security: Secrets are stored encrypted, reducing the risk of exposure.
  • Centralized Management: Manage all your application secrets in a single, consistent location.
  • Version Control: SSM allows you to track changes and revert to previous versions if necessary.
  • Access Control: Fine-grained access control through IAM policies ensures only authorized users can access your secrets.
  • Improved Security Posture: Avoids hardcoding sensitive data directly into your code, reducing the attack surface of your application.

Integrating SSM Parameters with Serverless

The Serverless Framework doesn't directly support SSM Parameter Store retrieval within functions. However, we can leverage the AWS SDK to fetch parameters during deployment or runtime. Let's explore both approaches.

Method 1: Fetching Parameters During Deployment (Recommended)

This method retrieves parameters during the deployment process and injects them into your function's environment variables. This is generally preferred for better security as the secrets never reside within the function code itself.

  1. Configure the Serverless Framework: First, you need to define the parameters you want to retrieve from SSM. Within your serverless.yml file, add a custom section:
custom:
  ssm:
    DATABASE_URL: /my-app/database-url  #SSM Parameter Path
    API_KEY: /my-app/api-key
  1. Create a Custom Plugin (Recommended): For better maintainability and reusability, create a custom plugin. This plugin will handle the retrieval and injection of SSM parameters. Create a file named ssm-plugin.js:
const AWS = require('aws-sdk');

class SsmPlugin {
  constructor(serverless, options) {
    this.serverless = serverless;
    this.options = options;
    this.provider = this.serverless.getProvider('aws');
    this.hooks = {
      'before:deploy:deploy': this.fetchParameters.bind(this),
    };
  }

  async fetchParameters() {
    const ssm = new AWS.SSM();
    const ssmParams = this.serverless.service.custom.ssm;
    const params = [];

    for (const key in ssmParams) {
      params.push({ Name: ssmParams[key], WithDecryption: true });
    }

    const response = await ssm.getParameters({ Parameters: params }).promise();

    const environmentVariables = {};
    response.Parameters.forEach(param => {
      environmentVariables[key] = param.Value;
    });

    this.serverless.service.provider.environment = {
        ...this.serverless.service.provider.environment,
        ...environmentVariables
    };

  }
}

module.exports = SsmPlugin;
  1. Register the Plugin: In your serverless.yml file, add the plugin:
plugins:
  - ssm-plugin.js
  1. Access Parameters in Your Function: Now, you can access the parameters within your function using process.env:
const databaseUrl = process.env.DATABASE_URL;
const apiKey = process.env.API_KEY;

Method 2: Fetching Parameters at Runtime

This approach retrieves parameters directly within your function code at runtime. While simpler to implement initially, it adds runtime overhead and can potentially expose secrets in logs if not handled carefully.

  1. Install AWS SDK: Make sure you have the AWS SDK installed: npm install aws-sdk

  2. Retrieve Parameters in Your Function:

const AWS = require('aws-sdk');
const ssm = new AWS.SSM();

exports.handler = async (event) => {
  try {
    const data = await ssm.getParameter({
      Name: '/my-app/database-url',
      WithDecryption: true,
    }).promise();
    const databaseUrl = data.Parameter.Value;
    // ...use databaseUrl...
  } catch (error) {
    console.error('Error fetching SSM parameter:', error);
    // ...handle error...
  }
};

Important Considerations:

  • IAM Roles: Ensure your Lambda function's IAM role has the necessary permissions to access the SSM parameters. You'll need to grant ssm:GetParameters permission at a minimum.
  • Error Handling: Implement robust error handling to gracefully manage situations where parameter retrieval fails.
  • Security: Always use WithDecryption: true when retrieving encrypted parameters.

Conclusion

Utilizing SSM Parameter Store with the Serverless Framework significantly enhances the security of your serverless applications. While both methods are viable, fetching parameters during deployment (Method 1) offers superior security and is the recommended approach. Remember to properly configure IAM roles and handle errors appropriately for a secure and robust solution. Choose the method that best suits your application's needs and security requirements. Remember to replace placeholder parameter paths with your actual paths in SSM.

Related Posts