Repository: aws/chalice

Issue:
Multiple references to managed layer
In case application uses `"automatic_layer": true` along with some existing layers in stage definition, generated SAM template has multiple references to managed layer. It impedes deployment, as AWS limits the number of layers to 5.

So, I have `config.json` like this:
```json
{
  "version": "2.0",
  "app_name": "appname",
  "automatic_layer": true,
  "stages": {
    "dev": {
      "layers": [
        "arn:aws:lambda:region:account:layer:somelayer"
      ]
    }
}
```
I run `chalice package` and my SAM has this:
```json
    "Smoke": {
      "Type": "AWS::Serverless::Function",
      "Properties": {
        "Runtime": "python3.7",
        "Handler": "app.on_smoke",
        "CodeUri": "./deployment.zip",
        "Tags": {
          "aws-chalice": "version=1.21.3:stage=dev:app=appname"
        },
        "Tracing": "PassThrough",
        "Timeout": 300,
        "MemorySize": 128,
        "Layers": [
          {
            "Ref": "ManagedLayer"
          },
          {
            "Ref": "ManagedLayer"
          },
          {
            "Ref": "ManagedLayer"
          },
          {
            "Ref": "ManagedLayer"
          },
          {
            "Ref": "ManagedLayer"
          },
          "arn:aws:lambda:region:account:layer:somelayer"
        ]
      }
    }
```
Number of unwanted refs seems to match the number of lambda functions in the app.

Discussion:

Patch:
diff --git a/.changes/next-release/45843828685-bugfix-Layers-14950.json b/.changes/next-release/45843828685-bugfix-Layers-14950.json
new file mode 100644
index 0000000..4a85eed
--- /dev/null
+++ b/.changes/next-release/45843828685-bugfix-Layers-14950.json
@@ -0,0 +1,5 @@
+{
+  "type": "bugfix",
+  "category": "Layers",
+  "description": "Ensure single reference to managed layer (#1563)"
+}
diff --git a/chalice/package.py b/chalice/package.py
index 9d5c094..de648d8 100644
--- a/chalice/package.py
+++ b/chalice/package.py
@@ -272,7 +272,7 @@ class SAMTemplateGenerator(TemplateGenerator):
             lambdafunction_definition['Properties'].update(
                 reserved_concurrency_config)
 
-        layers = resource.layers or []  # type: List[Any]
+        layers = list(resource.layers) or []  # type: List[Any]
         if self._chalice_layer:
             layers.insert(0, {'Ref': self._chalice_layer})
 


Test patch:
diff --git a/tests/unit/test_package.py b/tests/unit/test_package.py
index 3ac9296..45867e8 100644
--- a/tests/unit/test_package.py
+++ b/tests/unit/test_package.py
@@ -890,6 +890,37 @@ class TestSAMTemplate(TemplateTestBase):
             {'Ref': 'ManagedLayer'}
         ]
 
+    def test_adds_single_layer_for_multiple_lambdas(self, sample_app):
+        config = Config.create(chalice_app=sample_app,
+                               app_name='testapp',
+                               project_dir='.',
+                               automatic_layer=True,
+                               layers=['arn:aws:mylayer'],
+                               api_gateway_stage='api')
+
+        @sample_app.lambda_function()
+        def first(event, context):
+            pass
+
+        @sample_app.lambda_function()
+        def second(event, context):
+            pass
+
+        template = self.generate_template(config)
+        managed_layer = template['Resources']['ManagedLayer']
+        assert managed_layer == {
+            'Type': 'AWS::Serverless::LayerVersion',
+            'Properties': {
+                'CompatibleRuntimes': [config.lambda_python_version],
+                'LayerName': 'testapp-dev-managed-layer',
+                'ContentUri': models.Placeholder.BUILD_STAGE,
+            }
+        }
+        assert template['Resources']['First']['Properties']['Layers'] == [
+            {'Ref': 'ManagedLayer'},
+            'arn:aws:mylayer',
+        ]
+
     def test_supports_precreated_role(self):
         builder = DependencyBuilder()
         resources = builder.build_dependencies(