We are using CDK to build our infrastructure configuration. Moreover, I create my template.yml
for SAM with cdk synth <stack_name> --no-staging > template.yml
if it helps. I am using AWS Toolkit to invoke/debug my lambda functions on Intellij which works fine. However, if I run sam local start-api
on terminal and send a request to one of my functions then it returns an error with stacktrace;
Traceback (most recent call last):
File "/usr/local/Cellar/aws-sam-cli/0.53.0/libexec/lib/python3.7/site-packages/flask/app.py", line 2317, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/Cellar/aws-sam-cli/0.53.0/libexec/lib/python3.7/site-packages/flask/app.py", line 1840, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/Cellar/aws-sam-cli/0.53.0/libexec/lib/python3.7/site-packages/flask/app.py", line 1743, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/Cellar/aws-sam-cli/0.53.0/libexec/lib/python3.7/site-packages/flask/_compat.py", line 36, in reraise
raise value
File "/usr/local/Cellar/aws-sam-cli/0.53.0/libexec/lib/python3.7/site-packages/flask/app.py", line 1838, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/Cellar/aws-sam-cli/0.53.0/libexec/lib/python3.7/site-packages/flask/app.py", line 1824, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/usr/local/Cellar/aws-sam-cli/0.53.0/libexec/lib/python3.7/site-packages/samcli/local/apigw/local_apigw_service.py", line 203, in _request_handler
self.lambda_runner.invoke(route.function_name, event, stdout=stdout_stream_writer, stderr=self.stderr)
File "/usr/local/Cellar/aws-sam-cli/0.53.0/libexec/lib/python3.7/site-packages/samcli/commands/local/lib/local_lambda.py", line 84, in invoke
function = self.provider.get(function_name)
File "/usr/local/Cellar/aws-sam-cli/0.53.0/libexec/lib/python3.7/site-packages/samcli/lib/providers/sam_function_provider.py", line 65, in get
raise ValueError("Function name is required")
ValueError: Function name is required
This is the command I run
sam local start-api --env-vars env.json --docker-network test
which gives the output
Mounting None at http://127.0.0.1:3000/v1 [GET, OPTIONS, POST]
Mounting None at http://127.0.0.1:3000/v1/user [GET, OPTIONS, POST]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
2020-08-22 16:32:46 * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
2020-08-22 16:33:03 Exception on /v1/user [OPTIONS]
And here is the env.json I am using as environment variables for my functions
{
"tenantGetV1Function54F63CB9": {
"db": "alpha",
"connectionString": "mongodb://mongo"
},
"tenantPostV1FunctionA56822D0": {
"db": "alpha",
"connectionString": "mongodb://mongo"
},
"userGetV1Function7E6E55C2": {
"db": "alpha",
"connectionString": "mongodb://mongo"
},
"userPostV1FunctionEB035EB0": {
"db": "alpha",
"connectionString": "mongodb://mongo"
}
}
I am also running Docker Desktop on macOS operating system.
EDIT: Here you can find the simplified template.yml with only one endpoint (one function definition) which is for tenantGetV1Function54F63CB9
function. It will map to GET /v1 endpoint. I didnt want include the whole template for 4 functions which makes around a thousand lines of .yml code.
https://gist.github.com/flexelem/d887136484d508e313e0a745c30a2d97
The problem solved if I create LambdaIntegration
by passing the Function
instance instead of its Alias
instance in CDK. So, we are creating lambdas along with an alias. Then, we pass the alias to their associated Resource
instance from Api Gateway.
This is the way are creating;
Function tenantGetV1Function = Function.Builder.create(this, "tenantGetV1Function")
.role(roleLambda)
.runtime(Runtime.JAVA_8)
.code(lambdaCode)
.handler("com.yolda.tenant.lambda.GetTenantHandler::handleRequest")
.memorySize(512)
.timeout(Duration.minutes(1))
.environment(environment)
.description(Instant.now().toString())
.build();
Alias tenantGetV1Alias = Alias.Builder.create(this, "tenantGetV1Alias")
.aliasName("live")
.version(tenantAdminGetV1Function.getCurrentVersion())
.provisionedConcurrentExecutions(provisionedConcurrency)
.build();
Resource v1Resource = v1Resource.addResource("{tenantId}");
v1Resource.addMethod("GET", LambdaIntegration.Builder.create(tenantGetV1Alias).build(), options);
And if I replace tenantGetV1Alias
with tenantGetV1Function
then sam build
command successfully builds all the functions which will make sam local start-api
to spin up them.
Resource v1Resource = v1Resource.addResource("{tenantId}");
v1Resource.addMethod("GET", LambdaIntegration.Builder.create(tenantGetV1Function).build(), options);
Somehow, SAM is not able to get function name property from CloudFormation templates if we assign aliases.