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

9

我将尝试将一个Lambda函数的日志写入由terraform创建的CloudWatch日志组中。

这是Lambda策略JSON-

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

这是lambda假设策略json -

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


我已将此添加到lambda.tf文件中。
resource "aws_cloudwatch_log_group" "example" {
  name              = "/test/logs/${var.lambda_function_name}"
}

虽然 CloudWatch 日志组 '/test/logs/${var.lambda_function_name}' 是通过 terraform 创建的,但我无法将 Lambda 函数的日志写入此组。
如果我将 Lambda 策略 JSON 更改为以下内容 -
{
    "Version": "2012-10-17",
    "Statement": [{
        "Sid": "Stmt1580204738067",
        "Action": "logs:*",
        "Effect": "Allow",
        "Resource": "*"
    }]
}

然后它会自动将日志存储在 /aws/lambda/ 目录中。

我该如何确保 Lambda 日志被写入我创建的 CloudWatch 日志组,而不是 Lambda 自身创建的 /aws/lambda/ 组?


2
Lambda函数的日志组名称无法进行配置。您可能需要阅读https://docs.aws.amazon.com/lambda/latest/dg/monitoring-functions-logs.html和https://www.terraform.io/docs/providers/aws/r/lambda_function.html#cloudwatch-logging-and-permissions。 - ydaetskcoR
@ydaetskcoR:截至2023年11月16日,这已不再是事实:AWS CLI现在具备--logging-config开关,其中之一是支持设置日志组名称。 - undefined
3个回答

9
仅将日志组添加为Lambda的依赖关系是不够的。您还需要将IAM策略附加到Lambda角色。
步骤如下:
1. 为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
}

定义IAM策略,允许Lambda创建日志流并记录日志事件。
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. 通过创建新资源 '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
}

定义日志组。
resource "aws_cloudwatch_log_group" "lambda_log_group" {
  name              = "/aws/lambda/${var.lambda.function_name}"
  retention_in_days = 7
  lifecycle {
    prevent_destroy = false
  }
}

使用depends_on参数定义您的lambda函数:
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"
}

IAM政策的创建和附加来自这篇文章,其余内容来自我个人的项目,为我工作。


5
如果您想让Terraform管理CloudWatch日志组,您必须提前创建与Lambda函数将要使用的日志组名称完全相同的日志组。您无法更改名称。然后在您的Terraform中,您需要将日志组设置为Lambda函数的依赖项,以确保Terraform有机会在Lambda自动创建之前创建日志组。

0
你可以跟随大多数,如果不是全部,milieere所做的,并且它会做到。一个快速的捷径是使用由AWS管理的AWSLambdaBasicExecution策略。这只是简化了步骤2,在这一步中你需要创建一个策略文档。你可以将其定义为一个data资源。
data "aws_iam_policy" "lambda_basic_execution_policy" {
  arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

您可以将其作为附件使用,就像这样。
resource "aws_iam_role_policy_attachment" "lambda_flow_log_cloudwatch" {
  role       = aws_iam_role.lambda.name
  policy_arn = data.aws_iam_policy.lambda_basic_execution_policy.arn
}

只是在我看来稍微干净一点而已。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接