Reputation: 13571
I have an API Gateway that triggers a lambda function specified by a stage variable stageVariables.lbfunc
.
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)
Upvotes: 3
Views: 2790
Reputation: 2662
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)
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
)
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:
dev
and prod
dev
aliasprod
aliasEach 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 tomethod
to hit on.
Create version, alias and permission stuff is whole different story, so didnt mention here.
Upvotes: 1