Hi there! I’m currently porting an application fro...
# help
p
Hi there! I’m currently porting an application from serverless framework to SST, and I’ve hit a bit of a snag with MongoDB atlas authentication. In deployed environments, the data access layer relies on passwordless authentication using environment variables that are set by Lambda: https://docs.atlas.mongodb.com/security/passwordless-authentication/#aws-lambda instead of building the connection string using environment variables like https://serverless-stack.com/examples/how-to-use-mongodb-atlas-in-your-serverless-app.html you do in this guide. In serverless framework, each application has one lambda execution role, so I could just add the ARN for each stage’s execution role to MongoDB atlas and it would authenticate seamlessly - but SST seems to use one role per lambda (example:
arn:aws:sts::{id}:assumed-role/dev-{application-name}-ApiLambdaGET{endpointName}/*
) and obviously it’s not feasible for me to add all of these to atlas. So I think the resulting question I’ve got is: Is there a way to create and specify one role for all functions in an API? And if not, do you have any recommended patterns for passwordless authentication with atlas using Lambda’s IAM credentials?
t
you can use app.setDefaultFunctionProps to add default env variables + permissions to all functions, does that help?
p
Unfortunately not - the IAM specific environment variables the MongoDB driver looks for are already available to the lambda at execution time. The problem is that Atlas needs the lambda’s execution role ARN registered with it to permit the request, and each function appears to get its own execution role. I already use setDefaultFunctionProps to pass through DB credentials directly for local development but I’d like to avoid having prod DB credentials lying around in CI if at all possible.
t
Oh I see what you're saying, I didn't know mongodb supported this concept
ok what you can do is create a new role in cdk and then pass that to your functions. It won't autocreate the role if it's passed in
also the way I normally handle typical db credentials is to store them in SSM and load them at runtime. Avoids needing to put credentials in CI or anywhere exposed
f
@Patrick Michallet you can create an IAM role and have all ur functions to use it, ie.
Copy code
import * as iam from "aws-cdk-lib/aws-iam";

const role = new iam.Role(this, "Role", {
  assumedBy: new iam.ServicePrincipal("<http://lambda.amazonaws.com|lambda.amazonaws.com>"),
  ...,
});

new sst.Api(this, "Api", {
  defaultFunctionProps: {
    role,
  },
  routes: {
    ...
  },
});
Let me know if that works for you
p
It works perfectly - thank you both! I had to add this policy config to the role to make it work with the queue constructs I was using, and now everything appears to work exactly as I’d expect it to.
Copy code
managedPolicies: [{ managedPolicyArn: 'arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole'}]