5

I have a CloudFormation Template including a lambda function. The relevant parts are

AWSTemplateFormatVersion: 2010-09-09
Parameters:
  Environment:
    Description: Environment name
    Type: String
    Default: Prod
Resources:
  LambdaExecutionRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - lambda.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Policies:
        - PolicyName: !Join [ '-', ['lambda-log', !Ref Environment, 'sqs-distributor'] ]
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - 'logs:CreateLogStream'
                  - 'logs:PutLogEvents'
                Resource: !GetAtt LambdaLogGroup.Arn
  SqsDistributor:
    Type: 'AWS::Lambda::Function'
    Properties:
      Code:
        ZipFile: !Sub
          ...
          ...
      Handler: index.handler
      Role: !GetAtt LambdaExecutionRole.Arn
      Runtime: nodejs8.10
      Timeout: 120
      MemorySize: 128
  LambdaLogGroup:
    Type: 'AWS::Logs::LogGroup'
    Properties:
      RetentionInDays: 7

The lambda function does not work as expected, but also does not log anything to a stream when created through cloudformation

I have checked the Lambda function for syntax errors and also the ExecutionRole, which when created looks like this

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "arn:aws:logs:us-east-1:765121849689:log-group:ProdSQSDistributor-LambdaLogGroup-1CVWUP6CZHAWX:*",
            "Effect": "Allow"
        }
    ]
}

The Log group is also in place as expected.

DV82XL
  • 5,350
  • 5
  • 30
  • 59
jdog
  • 2,465
  • 6
  • 40
  • 74
  • 2
    Unrelated but `!Join [ '-', ['lambda-log', !Ref Environment, 'sqs-distributor'] ]` can be written more clearly as `!Sub lambda-log-${Environment}-sqs-distributor` – 404 Jul 29 '19 at 10:44
  • Could you include the lambda function section of the template? Wondering about the value of the `Role` property https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-role – Pat Myron Aug 04 '19 at 17:46

2 Answers2

1

A LogGroup is created and that Role has permissions to perform actions on that LogGroup, but I don't see anything in that AWS::Lambda::Function definition specifying it will use that LogGroup:

Specify log group for an AWS lambda?

The AWS-managed IAM policy arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Provides write permissions to CloudWatch Logs:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "logs:CreateLogGroup",
                "logs:CreateLogStream",
                "logs:PutLogEvents"
            ],
            "Resource": "*"
        }
    ]
}

Using that policy will allow it to create a LogGroup that it will use.

DV82XL
  • 5,350
  • 5
  • 30
  • 59
Pat Myron
  • 4,437
  • 2
  • 20
  • 39
  • 1
    thanks also for the insightful link. I had not realised the bottleneck that would be created by specifying the log group name – jdog Aug 14 '19 at 01:32
0

Please use below code to resolve your issue. You need to replace LambdaFunction with your lambda function name. In your code you are not giving access to create Log group. Due to log group creation access is not there.. log stream can not be create. Also allow a policy to access/invoke your lambda if you have a requirement for it.

Below policy/code in json, you can convert to Yaml as per your requirement.

"LambdaCommon": {
  "Type": "AWS::IAM::Role",
  "Properties": {
    "RoleName": "lambda_common",
    "AssumeRolePolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "Service": [
              "lambda.amazonaws.com"
            ]
          },
          "Action": [
            "sts:AssumeRole"
          ]
        }
      ]
    },
    "Path": "/"
  }
},
"LambdaBasicPolicy": {
  "DependsOn": [
    "LambdaCommon"
  ],
  "Type": "AWS::IAM::Policy",
  "Properties": {
    "PolicyName": "lambda_basic_policy",
    "Roles": [
      {
        "Ref": "LambdaCommon"
      }
    ],
    "PolicyDocument": {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Action": [
            "lambda:InvokeFunction",
            "lambda:ListVersionsByFunction",
            "lambda:ListTags",
            "lambda:GetFunction",
            "lambda:ListAliases",
            "lambda:GetFunctionConfiguration",
            "lambda:GetAlias",
            "lambda:GetPolicy",
            "logs:*",
            "ec2:CreateNetworkInterface",
            "ec2:DescribeNetworkInterfaces",
            "ec2:DeleteNetworkInterface"
          ],
          "Resource": "*"
        }
      ]
    }
  }
},
"LambdaLogGroup": {
  "Type": "AWS::Logs::LogGroup",
  "DependsOn": "LambdaFunction",
  "Properties": {
    "LogGroupName": {
      "Fn::Join": [
        "",
        [
          "/aws/lambda/",
          {
            "Ref": "LambdaFunction"
          }
        ]
      ]
    }
  }
}
DV82XL
  • 5,350
  • 5
  • 30
  • 59
Anurag Arya
  • 111
  • 4