Repository: serverless/serverless (JavaScript)
Date: 2016-11-22 19:45:18+00:00
Task type: Bug Fix

Issue:
Api Gateway Deployment Failure
<!--
1. If you have a question and not a bug/feature request please ask it at http://forum.serverless.com
2. Please check if an issue already exists so there are no duplicates
3. Check out and follow our Guidelines: https://github.com/serverless/serverless/blob/master/CONTRIBUTING.md
4. Fill out the whole template so we have a good overview on the issue
5. Do not remove any section of the template. If something is not applicable leave it empty but leave it in the Issue
6. Please follow the template, otherwise we'll have to ask you to update it
-->

This is a Bug Report

## Description

For bug reports:
* What went wrong?
Deploying API Gateway endpoints via cloud formation errors out in sls 1.2.  This seems to be an issue when upgrading from 1.1.

* What did you expect should have happened?
Should have deployed successfully as it did in sls 1.1

* What was the config you used?
```
functions:
  themes:
    handler: services/themes/handler.dispatch
    events:
      - http:
          path: themes
          method: get
          cors: true
      - http:
          path: themes/{themeId}
          method: get
          cors: true
```

* What stacktrace or error message from your provider did you see?

```
Serverless: Deployment failed!
 
  Serverless Error ---------------------------------------
 
     An error occurred while provisioning your stack: ApiGatewayResourceThemesThemeIdVar
     - Another resource with the same parent already has
     this name: {themeId}.
 
  Get Support --------------------------------------------
     Docs:          docs.serverless.com
     Bugs:          github.com/serverless/serverless/issues
 
  Your Environment Information -----------------------------
     OS:                 linux
     Node Version:       4.3.2
     Serverless Version: 1.2.0
```

## Additional Data

* ***Serverless Framework Version you're using***: 1.2 (saw the bug after upgrading from 1.1)
* ***Operating System***: Linux
* ***Stack Trace***:
* ***Provider Error messages***:



Issue discussion:
I am also getting this exact failure after upgrading to 1.2 from 1.1 with a near identical template.
Oh snap! Thanks for reporting! 👍 

We've refactored the API Gateway code recently. Removing the API Gateway and redeploying should resolve this issue.

Any ideas what caused this error @eahefnawy?
Use the sls diff plugin 😉
@nicka thanks for this pointer 👍 

@eahefnawy yep using https://github.com/nicka/serverless-plugin-diff will help here.

A `--noDeply` and then compare the `CloudFormation` output of Serverless v1.1.0 and the new one (v1.2.0) should show what the issue is.
small note

the command, with that plugin, is `serverless diff` not `serverless deploy diff` (as it currently says in the README)

Solution patch:
diff --git a/lib/plugins/aws/lib/naming.js b/lib/plugins/aws/lib/naming.js
index 2fd5020ede6..de9b501794f 100644
--- a/lib/plugins/aws/lib/naming.js
+++ b/lib/plugins/aws/lib/naming.js
@@ -12,9 +12,12 @@ module.exports = {
     return this.normalizeName(name.replace(/[^0-9A-Za-z]/g, ''));
   },
   normalizePathPart(path) {
-    return this.normalizeNameToAlphaNumericOnly(
-      path.replace(/-/g, 'Dash')
-        .replace(/\{(.*)\}/g, '$1Var'));
+    return _.upperFirst(
+      _.capitalize(path)
+        .replace(/-/g, 'Dash')
+        .replace(/\{(.*)\}/g, '$1Var')
+        .replace(/[^0-9A-Za-z]/g, '')
+    );
   },
 
   getServiceEndpointRegex() {


Test patch:
diff --git a/lib/plugins/aws/lib/naming.test.js b/lib/plugins/aws/lib/naming.test.js
index 7a106f9d1b7..6051fa5853a 100644
--- a/lib/plugins/aws/lib/naming.test.js
+++ b/lib/plugins/aws/lib/naming.test.js
@@ -44,7 +44,7 @@ describe('#naming()', () => {
     });
   });
 
-  describe('#normalizeNameToCapitalAlphaNumbericOnly()', () => {
+  describe('#normalizePathPart()', () => {
     it('converts `-` to `Dash`', () => {
       expect(sdk.naming.normalizePathPart(
         'a-path'
@@ -57,10 +57,10 @@ describe('#naming()', () => {
       )).to.equal('VariableVar');
     });
 
-    it('converts variable declarations prefixes to `VariableVarPath`', () => {
+    it('converts variable declarations prefixes to `VariableVarpath`', () => {
       expect(sdk.naming.normalizePathPart(
         '${variable}Path'
-      )).to.equal('VariableVarPath');
+      )).to.equal('VariableVarpath');
     });
 
     it('converts variable declarations suffixes to `PathvariableVar`', () => {
@@ -69,10 +69,10 @@ describe('#naming()', () => {
       )).to.equal('PathvariableVar');
     });
 
-    it('converts variable declarations in center to `PathvariableVarDir`', () => {
+    it('converts variable declarations in center to `PathvariableVardir`', () => {
       expect(sdk.naming.normalizePathPart(
         'path${variable}Dir'
-      )).to.equal('PathvariableVarDir');
+      )).to.equal('PathvariableVardir');
     });
   });