Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Write AWS Lambda Logs to CloudWatch Log Group with Terraform

I am trying write the logs of a lambda function into a CloudWatch Log Group created by terraform.

This is the lambda policy json -

{
    "Version": "2012-10-17",
    "Statement": [
      {
        "Sid": "Stmt1580216411252",
        "Action": [
          "logs:CreateLogStream",
          "logs:CreateLogDelivery",
          "logs:PutLogEvents"
        ],
        "Effect": "Allow",
        "Resource": "arn:aws:logs:*:*:*"
      }
    ]
  }

This is the lambda assume policy json -

{
    "Version": "2012-10-17",
    "Statement": [{
        "Action": "sts:AssumeRole",
        "Principal": {
            "Service": "lambda.amazonaws.com"
        },
        "Effect": "Allow",
        "Sid": ""
    }]
}

I have added this to the lambda.tf file -

resource "aws_cloudwatch_log_group" "example" {
  name              = "/test/logs/${var.lambda_function_name}"
}

Although the CloudWatch Log Group '/test/logs/${var.lambda_function_name}' is getting created through terraform, I am unable to write the log of the lambda function to this group.

If I change the lambda policy json to this -

{
    "Version": "2012-10-17",
    "Statement": [{
        "Sid": "Stmt1580204738067",
        "Action": "logs:*",
        "Effect": "Allow",
        "Resource": "*"
    }]
}

Then It automatically stores the log in /aws/lambda/ directory.

How can I make sure that the lambda logs get written into a CloudWatch Log Group that I create and not in the /aws/lambda/ group created by lambda itself?

like image 321
Seeker90 Avatar asked Feb 22 '26 08:02

Seeker90


2 Answers

Just adding the log group as a dependency to the lambda is not enough. You also have to attach the IAM policy to the lambda role.

The steps are following:

  1. Define the IAM role for lambda:
resource "aws_iam_role" "iam_for_lambda" {
  name               = "iam_for_lambda"
  assume_role_policy = <<EOF
{
    "Version": "2012-10-17",
    "Statement": [{
        "Effect": "Allow",
        "Principal": {
            "Service": "lambda.amazonaws.com"
        },
        "Action": "sts:AssumeRole"
    }]
}
EOF
}
  1. Define the IAM policy that allows lambda to create log streams and put log events
resource "aws_iam_policy" "function_logging_policy" {
  name   = "function-logging-policy"
  policy = jsonencode({
    "Version" : "2012-10-17",
    "Statement" : [
      {
        Action : [
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ],
        Effect : "Allow",
        Resource : "arn:aws:logs:*:*:*"
      }
    ]
  })
}
  1. Attach the policy to the IAM role created in step 1, by creating new resource 'aws_iam_role_policy_attachment'
resource "aws_iam_role_policy_attachment" "function_logging_policy_attachment" {
  role       = aws_iam_role.iam_for_lambda.id
  policy_arn = aws_iam_policy.function_logging_policy.arn
}
  1. Define the log group
resource "aws_cloudwatch_log_group" "lambda_log_group" {
  name              = "/aws/lambda/${var.lambda.function_name}"
  retention_in_days = 7
  lifecycle {
    prevent_destroy = false
  }
}
  1. Define your lambda function with the depends_on parameter:
resource "aws_lambda_function" "lambda_function" {
  filename      = "../${var.lambda.function_filename}"
  function_name = "${var.lambda.function_name}"
  role          = aws_iam_role.iam_for_lambda.arn
  handler       = "${var.lambda.handler}"
  layers        = [aws_lambda_layer_version.lambda_layer.arn]
  depends_on    = [aws_cloudwatch_log_group.lambda_log_group]
  source_code_hash = filebase64sha256("../${var.lambda.function_filename}")
  runtime = "python3.9"
}

The IAM policy creation & attachment comes from this article, the rest is from my personal project that worked for me.

like image 149
milieere Avatar answered Feb 23 '26 23:02

milieere


If you want Terraform to manage the CloudWatch log group, you have to create the log group ahead of time with the exact name the Lambda function is going to use for its log group. You can't change the name at all. Then in your Terraform you need to make the log group a dependency of the Lambda function, to make sure Terraform has a chance to create the log group before Lambda creates it automatically.

like image 26
Mark B Avatar answered Feb 23 '26 23:02

Mark B



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!