Heya everyone! This might be more of a question a...
# help
t
Heya everyone! This might be more of a question about CDK than Serverless Stack... I'm trying to write a lambda@edge function to listen to viewer request events and run a cognito validator and index.html uri handler. I'm using @aws-cdk/aws-lambda-nodejs because it appears to be the only thing that will accept build parameters that include string replacements. Before hitting the NodeJs build step, I've created a Cognito User Pool and User Pool Client. I'd like to be able to use the IDs of those two in the lambda code. I'm trying to use the new NodeJsFunction params to "define" the userPoolId and clientId... but I just end up with unresolved tokens. Does anyone have insight on how to pull this off? Maybe I need to create two stacks and depend the one on the other? Anywho... thanks for any advice!
Sorry, I should add... I can get { "Ref": "xxxx" } objects, but these aren't what I want, either. Thanks!
v
You need 2 separate stacks. Do something like:
Copy code
// CognitoStack
const userPool = new UserPool(...);
this.userPoolId = userPool.userPoolId;
// in index.js
const edgeStack = new EdgeStack(app, 'edge-stack', {
  userPoolId: cognitoStack.userPoolId
});
It will recognize that the second stack has a dependency on the first.
t
wamp wamp... k! thank you so much.
I think the problem is that when I create the NodeJsFunction, the values that I need (e.g. userPoolId) are still tokenized. I don't know how to delay the NodeJsFunction creation & builder.define injection until a time when the tokens would be resolved.
v
I have a similar setup: I have an "infrastructure" stack with cognito UserPool/Client (Stack 1) Another stack defines my Apis. (Stack 2) If you set a class member to the user pool/client id in Stack 1, and pass it in via props in Stack 2, during build time, it will resolve those tokens. It is smart enough to see that Stack 2 has a dependency on Stack 1.
Copy code
// index.ts
const infrastructureStack = new InfrastructureStack(app, "application-stack");
const deviceApiStack = new DeviceApiStack(app, 'device-api-stack', {
  dynamodb: infrastructureStack.dynamodb,
  userPool: infrastructureStack.userPool,
  userPoolClient: infrastructureStack.userPoolClient,
  environment: lambdaEnvironment
});

// infrastructure.ts
const [userPool, userPoolClient, cognitoAuthDomain] = this.createCognito(namespace);
this.userPool = userPool;
this.userPoolClient = userPoolClient;

// api.ts
this.httpApi = new Api(this, 'device-api', {
  defaultAuthorizationType: ApiAuthorizationType .JWT,
  defaultAuthorizer: new HttpUserPoolAuthorizer({
    userPool: props.userPool,
    userPoolClients: [props.userPoolClient],
  }),
  defaultAuthorizationScopes: ["user.id", "user.email"],
  cors: {
    allowMethods: [
      CorsHttpMethod.ANY
    ],
  }
});
I haven't had a situation where I've needed to explicitly use
addDependency
yet.
Also if you're trying to create a lambda@edge function, why not use ``@aws-cdk/aws-cloudfront` » 
experimental
 » 
EdgeFunction
instead of
NodeJsFunction
t
I'm using NodeJsFunction because EdgeFunction doesn't seem to provide the "builder" properties that handle string replacement.
I'm concluding that I'd need to use a custom resource to pull this off.