Repository: serverless/serverless (JavaScript)
Date: 2017-02-08 14:53:08+00:00
Task type: Bug Fix

Issue:
CloudWatch logs are not created in 1.6
<!--
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

When I deploy my service, the logs are not created. I think it is because of this piece of code: https://github.com/serverless/serverless/blob/master/lib/plugins/aws/deploy/lib/mergeIamTemplates.js#L18-L27 which in my case prematurely terminate the function on line 27 because of the if conditional on line 19 - I have defined custom role for lambda functions (i.e. I have `provider.role` in my serverless.yml, see https://github.com/keboola/developer-portal/blob/master/serverless.yml#L35). Why is there this code? I don't really understand it's reason.


## Additional Data

* ***Serverless Framework Version you're using***: 1.6.0
* ***Operating System***: macOS 12.12
* ***Stack Trace***:
* ***Provider Error messages***:



Issue discussion:
@JakubMatejka thanks for reporting. You're right, I think this is a bug. This is a legacy line from when we were handling logging implicitly before. But should be changed. I'll look into it asap

Solution patch:
diff --git a/lib/plugins/aws/deploy/lib/mergeIamTemplates.js b/lib/plugins/aws/deploy/lib/mergeIamTemplates.js
index 69c0886240b..ec158b4f766 100644
--- a/lib/plugins/aws/deploy/lib/mergeIamTemplates.js
+++ b/lib/plugins/aws/deploy/lib/mergeIamTemplates.js
@@ -11,6 +11,22 @@ module.exports = {
   },
 
   merge() {
+    this.serverless.service.getAllFunctions().forEach((functionName) => {
+      const functionObject = this.serverless.service.getFunction(functionName);
+      const logGroupLogicalId = this.provider.naming
+        .getLogGroupLogicalId(functionName);
+      const newLogGroup = {
+        [logGroupLogicalId]: {
+          Type: 'AWS::Logs::LogGroup',
+          Properties: {
+            LogGroupName: this.provider.naming.getLogGroupName(functionObject.name),
+          },
+        },
+      };
+      _.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
+        newLogGroup);
+    });
+
     if (!this.serverless.service.getAllFunctions().length) {
       return BbPromise.resolve();
     }
@@ -69,19 +85,8 @@ module.exports = {
       );
 
       this.serverless.service.getAllFunctions().forEach((functionName) => {
-        const functionObject = this.serverless.service.getFunction(functionName);
         const logGroupLogicalId = this.provider.naming
           .getLogGroupLogicalId(functionName);
-        const newLogGroup = {
-          [logGroupLogicalId]: {
-            Type: 'AWS::Logs::LogGroup',
-            Properties: {
-              LogGroupName: this.provider.naming.getLogGroupName(functionObject.name),
-            },
-          },
-        };
-        _.merge(this.serverless.service.provider.compiledCloudFormationTemplate.Resources,
-          newLogGroup);
 
         this.serverless.service.provider.compiledCloudFormationTemplate
           .Resources[this.provider.naming.getPolicyLogicalId()]


Test patch:
diff --git a/lib/plugins/aws/deploy/lib/mergeIamTemplates.test.js b/lib/plugins/aws/deploy/lib/mergeIamTemplates.test.js
index b0061354c4a..4c599c166f4 100644
--- a/lib/plugins/aws/deploy/lib/mergeIamTemplates.test.js
+++ b/lib/plugins/aws/deploy/lib/mergeIamTemplates.test.js
@@ -208,6 +208,29 @@ describe('#mergeIamTemplates()', () => {
     });
   });
 
+  it('should add a CloudWatch LogGroup resource if all functions use custom roles', () => {
+    awsDeploy.serverless.service.functions[functionName].role = 'something';
+    const normalizedName = awsDeploy.provider.naming.getLogGroupLogicalId(functionName);
+    return awsDeploy.mergeIamTemplates().then(() => {
+      expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
+        .Resources[normalizedName]
+      ).to.deep.equal(
+        {
+          Type: 'AWS::Logs::LogGroup',
+          Properties: {
+            LogGroupName: awsDeploy.provider.naming.getLogGroupName(functionName),
+          },
+        }
+      );
+
+      const roleLogicalId = awsDeploy.provider.naming.getRoleLogicalId();
+      expect(awsDeploy.serverless.service.provider.compiledCloudFormationTemplate
+        .Resources[roleLogicalId]
+      ).to.equal(undefined);
+      delete awsDeploy.serverless.service.functions[functionName].role;
+    });
+  });
+
   it('should update IamPolicyLambdaExecution with a logging resource for the function', () => {
     awsDeploy.serverless.service.functions = {
       func0: {