aws / aws/chalice

Using AWS CDK & Chalice construct received duplicated lambdas in synthed sam template

Open
#2,030 6 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
11.1k
Forks
1k
Avg merge
1d 22h
Merged PRs (30d)
2

Description

Hi,
on project we had single Chalice project for the whole API + pure lambdas (cloudwatch events, triggers etc) and as the project had grown, lambdas generated by project became bigger and bigger. We decided to split it into several chalice project that will be combined to single API under Custom domain name. For easy management&deploy we decided to put them in CDK project.
As a result I created next stack that contains declaration of all chalice constructs (component_with_stack_declaration.py):
```python
class RestApi(Stack):

def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None:
super().__init__(scope, construct_id, **kwargs)
...
code_dir = os.path.join(os.path.dirname(os.path.realpath(__file__)), "src")

app1 = Chalice(self, "App1", source_dir=os.path.join(code_dir, "app1"))
app2= Chalice(self, "App2", source_dir=os.path.join(code_dir, "app2"))
...
```

When I ran `cdk synth` I got next traceback:
```shell
Creating deployment package.
Creating deployment package.
jsii.errors.JavaScriptError:
@jsii/kernel.RuntimeError: Error: section 'Resources' already contains 'Lambda1LogicalID'
at Kernel._ensureSync (C:\....\AppData\Local\Temp\tmpgg97w2wj\lib\program.js:10364:27)
at Kernel.invoke (C:\....\AppData\Local\Temp\tmpgg97w2wj\lib\program.js:9764:34)
at KernelHost.processRequest (C:\....\AppData\Local\Temp\tmpgg97w2wj\lib\program.js:11539:36)
at KernelHost.run (C:\Users\....\Local\Temp\tmpgg97w2wj\lib\program.js:11499:22)
at Immediate._onImmediate (C:\....\AppData\Local\Temp\tmpgg97w2wj\lib\program.js:11500:46)
at processImmediate (node:internal/timers:466:21)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
File "B:\...\cdk_app\app.py", line 15, in
app.synth()
File "B:\....\cdk_app\venv\lib\site-packages\aws_cdk\__init__.py", line 20043, in synth
return typing.cast(_CloudAssembly_c693643e, jsii.invoke(self, "synth", [options]))
File "B:\....\cdk_app\venv\lib\site-packages\jsii\_kernel\__init__.py", line 149, in wrapped
return _recursize_dereference(kernel, fn(kernel, *args, **kwargs))
File "B:\....\cdk_app\venv\lib\site-packages\jsii\_kernel\__init__.py", line 399, in invoke
response = self.provider.invoke(
File "B:\....\cdk_app\venv\lib\site-packages\jsii\_kernel\providers\process.py", line 377, in invoke
return self._process.send(request, InvokeResponse)
File "B:\....\cdk_app\venv\lib\site-packages\jsii\_kernel\providers\process.py", line 339, in send
raise RuntimeError(resp.error) from JavaScriptError(resp.stack)
RuntimeError: Error: section 'Resources' already contains 'Lambda1LogicalID'
```

When I looked in the generated in cdk.out and chalice.out templates i saw that this lambda is actually declared twice.
Example from .sam_with_assets.json files in generated chalice.out folder:
```shell
Chalice app1
{
"AWSTemplateFormatVersion": "2010-09-09",
"Transform": "AWS::Serverless-2016-10-31",
"Outputs": {},
"Resources": {
"Lambda1LogicalID": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Runtime": "python3.9",
"Handler": "chalicelib.app1.handler.lambda1",
"CodeUri": {
"Bucket": "cdk-hnb659fds-assets-XXXXXXXXXXXX-us-east-1",
"Key": "963f64d496d61b07c0f89b0c476f7ff9a0ebdc17e4f8b80484a4f957eecca97e.zip"
},
"Tags": {
"aws-chalice": "version=1.27.3:stage=dev/RestApi:app=app1"
},
...

Chalice app2
{
"AWSTemplateFormatVersion": "2010-09-09",
"Transform": "AWS::Serverless-2016-10-31",
"Outputs": {},
"Resources": {
"Lambda1LogicalID": {
"Type": "AWS::Serverless::Function",
"Properties": {
"Runtime": "python3.9",
"Handler": "chalicelib.app1.handler.lambda1",
"CodeUri": {
"Bucket": "cdk-hnb659fds-assets-XXXXXXXXXXXX-us-east-1",
"Key": "972986e72385367de3787cc5004baa8efe91c8c98335a070ee636b9f7519afd7.zip"
},
"Tags": {
"aws-chalice": "version=1.27.3:stage=dev/RestApi:app=app2"
},
...
```
As you can see they are identical apart `aws-chalice` tag and key in bucket. I checked several times within generated .zip assets, they contained correct 2 different chalice project code, but for some reason template of second chalice project (app2) contains all the same lambdas as in the first project (app1) and doesnt contain any lambdas that are declared in code of the .zip archive that is created for it.
I tried to place Chalice constructs in separate inner stacks of RestApi stack, but got the same result - differect assets with code but same template with same lambdas' resources (apart tags).
Code is stored in the next order:
```shell
cdk_app
| - app.py
| - restapi_stack
| - component_with_stack_declaration.py
| - src
| - app1
| | - .chalice
| chalicelib
| app.py
| - app2
| - .chalice
chalicelib
app.py
```

Maybe someone had similar issue? I would be happy to receive your feedback

Contributor guide

Open the contributing guide

Research direction

Start with restapi_stack/component_with_stack_declaration.py and reproduce the issue with cdk synth. Compare the generated chalice.out .sam_with_assets.json files for app1 and app2, then trace how each Chalice construct contributes its SAM resources. Done means both projects retain their distinct Lambda resources and synthesis no longer fails with duplicate Lambda1LogicalID.

Written by the indexing model from the issue text.

Assessment

Tech stack
aws, python
Domain
cloud
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.