jdog
jdog

Reputation: 2539

CloudFormation created Lambda does not create LogStream/ Logs

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.

Upvotes: 5

Views: 3067

Answers (2)

Anurag Arya
Anurag Arya

Reputation: 111

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"
          }
        ]
      ]
    }
  }
}

Upvotes: 0

Pat Myron
Pat Myron

Reputation: 4628

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.

Upvotes: 1

Related Questions