2
votes

I have an API Gateway that triggers a lambda function specified by a stage variable stageVariables.lbfunc.

enter image description here

How can I create this kind of integration request with AWS CDK?

It looks like that I should create a special handler for LambdaRestApi.

But I can't find any example code for doing this.

The following is my current code. I wish that LambdaIntegration's handler can be determined by a stage variable.

# dev_lambda_function should be replaced by something else
dev_lambda_function = lambda_.Function(self, "MyServiceHandler",
            runtime=lambda_.Runtime.PYTHON_3_7,
            code=lambda_.Code.asset("resources"),
            handler="lambda_function.lambda_handler",
            description="My dev lambda function"
            )
stage_options = apigateway.StageOptions(stage_name="dev", 
    description="dev environment", 
    variables=dict(lbfunc="my-func-dev")
)
# What should I pass to the handler variable so that LambdaRestApi triggers the lambda function specified by the stage variable "stageVariables.lbfunc"?
api = apigateway.LambdaRestApi(self, "my-api",
            rest_api_name="My Service",
            description="My Service API Gateway",
            handler=dev_lambda_function,    
            deploy_options=stage_options)
1
I had to change the permission LambdaIntegration generated automatically, ended up extending the class by myself - stackoverflow.com/a/59716246/9931092 I don't know if this is what you are looking for ( it's also in typescript) but this might be helpful. If you can add more information i would be happy to help you :)Amit Baranes

1 Answers

0
votes

Just solved this recently, I just record down how I solved it here (before I forget)

The idea here is, when your API method get hit, it will make a POST request your lambda. So you make a "URL" of your lambda, so your API method can hit that. (Ok, I finally found it, you can read it here, for item No.6 in this link, look the URI there)

  1. Create a Construct called ApiIntegration:

    class ApiIntegration(core.Construct):
    
       @property
       def integration(self):
         return self._integration
    
        def __init__(self, scope: core.Construct, id: str, function: _lambda,  ** kwargs):
         super().__init__(scope, id, **kwargs)
    
         # Here you construct a "URL" for your lambda
         api_uri = (
             f"arn:aws:apigateway:"
             f"{core.Aws.REGION}"
             f":lambda:path/2015-03-31/functions/"
             f"{function.function_arn}"
             f":"
             f"${{stageVariables.lambdaAlias}}" # this will appear in the picture u provide
             f"/invocations"
         )
         # Then here make a integration 
         self._integration = apigateway.Integration(
             type=apigateway.IntegrationType.AWS_PROXY,
             integration_http_method="POST",
             uri=api_uri
         )
    
  2. In your MyStack(core.Stack) class you can use it like this:

          # Here u define lambda, I not repeat again 
          my_lambda = ur lambda you define
    
          # define stage option 
          dev_stage_options = apigateway.StageOptions(
                                stage_name="dev",
                                    variables={
                                       "lambdaAlias": "dev" # define ur variable here
                                })
          # create an API, put in the stage options
          api = apigateway.LambdaRestApi(
                   self, "MyLittleNiceApi",
                   handler=my_lambda,
                   deploy_options=dev_stage_options
                )
    
          # Now use the ApiIntegration you create 
          my_integration = ApiIntegration(
              self, "MyApiIntegration", function=my_lambda)
    
         # make a method call haha
         my_haha_method = api.root.add_resource("haha")
    
         # put in the integration that define inside the Construct 
         my_haha_post_method = my_method.add_method('POST',
                               integration=my_integration.integration,
                               #...then whatever here)
    

By now you check your console, your method will have Lambda function with stageVariable.

Now you should create the lambda alias, the idea is like this:

  • You have 1 lambda
  • Make 2 alias for the lambda, dev and prod
  • API stageVariable dev -> hit -> lambda dev alias
  • API stageVariable prod -> hit -> lambda prod alias

Each lambda alias will hit different version of your lambda, for example:

  • dev alias hit $Latest
  • prod alias hit version:12

I have talk about this in dev.to here

Now you have lambda:dev and lambda:prod 2 alias. In order to let your method to hit different alias lambda:dev and lambda:prod, you need (The main idea):

Lambda dev/prod alias give permission to method to hit on.

Create version, alias and permission stuff is whole different story, so didnt mention here.