Search code examples
amazon-web-servicesaws-lambdaterraformamazon-cloudwatch

Cannot capture CloudWatch logs of Lambda function after Terraform deployment


I ran terraform apply successfully, but none the console.log statements seem to be sent to CloudWatch. I followed this solution: https://stackoverflow.com/a/75157142/9105207 I do see the CloudWatch log group created, but no log streams at all.

This is my code:

CloudWatch file:

resource "aws_cloudwatch_log_group" "store_url_cloudwatch_log_group" {
  name              = "/aws/lambda/${aws_lambda_function.store_url_lambda.function_name}"
  retention_in_days = 14

  lifecycle {
    prevent_destroy = false
  }

  tags = merge(
    var.common_tags,
    {
      Name  = "${var.project}-Store-URL-CloudWatch-Log-Group"
      Stack = "Backend"
    }
  )
}

resource "aws_iam_policy" "store_url_logging_policy" {
  name = "Store-url-logging-policy"

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

  tags = merge(
    var.common_tags,
    {
      Name  = "${var.project}-Store-URL-Logging-Policy"
      Stack = "Backend"
    }
  )
}

resource "aws_iam_role_policy_attachment" "store_url_logging_policy_attachment" {
  role       = aws_iam_role.iam_for_lambda_store_url.id
  policy_arn = aws_iam_policy.store_url_logging_policy.arn
}

Lambda function file:

data "aws_iam_policy_document" "store_url_lambda_assume_role" {
  statement {
    effect = "Allow"

    principals {
      type        = "Service"
      identifiers = ["lambda.amazonaws.com"]
    }

    actions = ["sts:AssumeRole"]
  }
}

resource "aws_iam_role" "iam_for_lambda_store_url" {
  name               = "IAM-for-lambda-store-url"
  assume_role_policy = data.aws_iam_policy_document.store_url_lambda_assume_role.json

  tags = merge(
    var.common_tags,
    {
      Name  = "${var.project}-Store-URL-Lambda-IAM-Role"
      Stack = "Backend"
    }
  )
}

resource "aws_lambda_function" "store_url_lambda" {
  function_name    = "store-url-lambda"
  role             = aws_iam_role.iam_for_lambda_store_url.arn
  handler          = "index.handler"
  runtime          = "nodejs20.x"
  source_code_hash = data.archive_file.lambda_store_url_zip.output_base64sha256
  s3_bucket        = module.s3_store_url_lambda_bucket.s3_bucket_id
  s3_key           = aws_s3_object.store_url_lambda_s3_object.key
  depends_on       = [aws_cloudwatch_log_group.store_url_cloudwatch_log_group]

  environment {
    variables = {
      S3_BUCKET = module.s3_store_url_lambda_bucket.s3_bucket_id
    }
  }

  tags = merge(
    var.common_tags,
    {
      Name  = "${var.project}-Store-URL-Lambda-Function"
      Stack = "Backend"
    }
  )
}

I removed irrelevant blocks. In my Lambda function there are console.log statements. Example:

import crypto from 'node:crypto';
import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3';
import RequestBody from './schemas/request-body';
import { doesObjectExist } from './utils/s3';
export const handler = async (event) => {
    const requestBody = event.body;
    console.log(`Request body is: ${requestBody}`);

Solution

  • The fact that you don’t see your console.log statements output to CloudWatch does not mean that it does not have permissions. Maybe the function has yet to begin due to some prior error. Try to test it via the AWS console manually, and check whether some errors are emitted during this test.