简体   繁体   English

使用 Terraform 将 AWS Lambda 日志写入 CloudWatch 日志组

[英]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.我正在尝试将 lambda function 的日志写入由 terraform 创建的 CloudWatch 日志组。

This is the lambda policy json -这是 lambda 政策 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 -这是 lambda 承担政策 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 -我已将其添加到 lambda.tf 文件中 -

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.虽然 CloudWatch 日志组 '/test/logs/${var.lambda_function_name}' 是通过 terraform 创建的,但我无法将 lambda function 的日志写入该组。

If I change the lambda policy json to this -如果我将 lambda 政策 json 更改为此 -

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

Then It automatically stores the log in /aws/lambda/ directory.然后它会自动将日志存储在 /aws/lambda/ 目录中。

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?我如何确保将 lambda 日志写入我创建的 CloudWatch 日志组中,而不是写入由 lambda 本身创建的 /aws/lambda/ 组中?

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.如果您希望 Terraform 管理 CloudWatch 日志组,您必须提前使用 Lambda 函数将用于其日志组的确切名称创建日志组。 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.然后在您的 Terraform 中,您需要使日志组成为 Lambda 函数的依赖项,以确保 Terraform 有机会在 Lambda 自动创建日志组之前创建它。

Just adding the log group as a dependency to the lambda is not enough.仅将日志组作为依赖项添加到 lambda 是不够的。 You also have to attach the IAM policy to the lambda role .您还必须将 IAM 策略附加到 lambda 角色

The steps are following:步骤如下:

  1. Define the IAM role for lambda:为 lambda 定义 IAM 角色:
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定义允许 lambda 创建日志流和放置日志事件的 IAM 策略
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'通过创建新资源“aws_iam_role_policy_attachment”将策略附加到在步骤 1 中创建的 IAM 角色
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:使用 depends_on 参数定义您的 lambda function:
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. IAM 策略创建和附件来自这篇文章,rest 来自我为我工作的个人项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM