Caching solution for AWS SSM parameter store to be used with dotnet lambdas

Viewed 3184

I have a lot of dotnet lambda microservices using SSM parameter store for configuration purposes. It's been quite adventageous over environment variables as I'm sharing a lot of configuration across different microservices. Though recently I've started pushing the limits of it. It now affects my throughput and started costing more than I'd like.

I've considered using the amazon extension for dotnet configuration manager, but it falls short for my requirements. I need the configuration to hot swap to keep the microservices running healthy at high uptime. Which won't happen with its current implementation. Deploying all microservices just for a configuration change is not an option either.

This lead me to research a cache solution that is able to at least invalidate the cache from outside, but I couldn't come accross anything that works with SSM parameter store out of box.

At worst, I'll need to come up with another microservice with it's own db that takes care of the configuration, but I don't wanna go down that path tbh.

What is the general approach that is being used this kind of scenarios?

3 Answers

You can use SSM in environment variables like

environment:
    VariableName: ${ssm:/serverless-VariableName}

and reference in your code from environment. We are using this approach.

This will store SSM when you deploy your app, and reuse it without calling SSM Store for every request

  • For reducing number of network calls to SSM parameter store, you can
    assign configuration values from SSM to static properties on
    application startup. And use these static properties for
    configuration values in your application instead of calling SSM parameter store again throughout the life of that particular instance of lambda. Changes to SSM parameters will reflect only in new instances of lambda.

  • If you are using provisioned concurrency on lambda then the above mentioned solution will not be helpful as the changes in SSM store parameters will not reflect to provisioned lambda as it is always kept in initialized state. For changes to reflect you need to redeploy or remove provision concurrency and add it back.

  • If you have a use case where parameter values get changed frequently and it should be reflected in your lambda code immediately then you can use secret manager to store such values and use aws provided client side caching support for secrets https://aws.amazon.com/blogs/security/how-to-use-aws-secrets-manager-client-side-caching-in-dotnet/.

I think that we need to deep into the architecture of your question.

Since you are using lambda, independently of your configuration, if you are not using provisioned concurrency, your container life cycle will be 5-10 minutes (common lifecycle of shared lambda container).

That said, if we are using another type of infrastructure, such as K8s (EKS for example), you could:

  1. Cache this SSM parameter in a distributed cache (Elasticache).
  2. Create a SSM parameter change event in cloudwatch events.
  3. Put a SNS as target.
  4. Subscribe http endpoint or a lambda function to clear this cache entry.

Now, with the cache invalidated, the first app that needs this parameter will fetch the value from SSM parameter and put into cache, and you can put a TTL here for invalidate in schedule.

But, because you are running with an serverless approach, create a TCP connection for each lambda container (you can share the tcp connection with elasticache across multiple invocations) maybe downgrade your performance, so, you need to make this tradeoff: Verify that connection with elasticache is a problem for your use case. If is, you can use a simple SSM parameter cache client and put a small TTL (for example 5 minutes), just to prevent your lambdas hit the SSM parameter limits.

Related