【问题标题】:Terraform cloudwatch retention logicTerraform cloudwatch 保留逻辑
【发布时间】:2019-08-10 12:39:09
【问题描述】:

我正在尝试向我的 terraform 脚本添加逻辑,以便在创建 lambda 时添加 CW 保留逻辑,以便我们的日志在 30 天后清除。我看到的是,当运行 terraform 以更新现有 lambda(在添加我的新保留逻辑之前部署)时,我的工作失败并出现以下错误。

  • aws_cloudwatch_log_group.lambda-deploy:发生 1 个错误:

  • aws_cloudwatch_log_group.lambda-deploy:创建 CloudWatch 日志组失败:ResourceAlreadyExistsException:指定的日志组已存在状态代码:400,请求 ID:e500eb50-4a81-11e9-9c08-7152b4a0ad31:CloudWatch 日志组'/aws/lambda /{lambda-name}' 已经存在。

以下是我设置 terraform 代码的方式:

resource "aws_lambda_function" "lambda-deploy" {
  filename      = "${var.filename}"
  function_name = "${var.functionname}"
  role          = "${var.role}"
  handler       = "${var.handler}"
  runtime       = "${var.runtime}"
  publish       = "${var.publish}"
  memory_size   = "${var.memory_size}"
  timeout       = "${var.timeout}"
  description   = "${var.description}"

  layers = "${var.layers}"

  environment {
    variables = "${var.envVars}"
  }

  tags {
    PLATFORM        = "${var.tag_PLATFORM}"
    BUSINESS_UNIT   = "${var.tag_BUSINESS_UNIT}"
    CLIENT          = "${var.tag_CLIENT}"
    BUSINESS_REGION = "${var.tag_BUSINESS_REGION}"
  }

  vpc_config {
    subnet_ids         = "${var.subnet_ids}"
    security_group_ids = "${var.security_group_ids}"
  }
}

#Below logic will add cloud watch retention logic so logs rotate after 30 days.
resource "aws_cloudwatch_log_group" "lambda-deploy" {
  name              = "/aws/lambda/${aws_lambda_function.lambda-deploy.function_name}"
  retention_in_days = "30"
}

我的问题是,aws_cloudwatch_log_group 资源是否可以检查是否已创建 cloudwatch 组并仅更新保留策略而不是尝试创建日志组?

【问题讨论】:

    标签: lambda terraform serverless


    【解决方案1】:
    1. 注释掉名称参数

    如上例:

    resource "aws_cloudwatch_log_group" "lambda-deploy" {
      name = "/aws/lambda/${aws_lambda_function.lambda-deploy.function_name}"
      retention_in_days = "30"
    }  
    

    变成:

    resource "aws_cloudwatch_log_group" "lambda-deploy" {
      #name = "/aws/lambda/${aws_lambda_function.lambda-deploy.function_name}"
      retention_in_days = "30"
    }
    
    1. 导入资源

      terraform import aws_cloudwatch_log_group.lambda-deploy /aws/lambda/${aws_lambda_function.lambda-deploy.function_name}

    ${aws_lambda_function.lambda-deploy.function_name} 是您在 AWS 中所拥有的。

    1. 取消注释您的“名称”参数并运行terraform plan,您的日志组现在由 terraform 管理...唷!

    【讨论】:

    • 不清楚您所说的“${aws_lambda_function.lambda-deploy.function_name} 是 AWS 中的内容”是什么意思。你能详细说明一下吗?
    • 我不明白你为什么注释掉这个名字然后又取消注释它。这是没有必要的(如果您的日志组是从标记的 git repos 深度加载的 1 个或多个模块,那么这将是一个严重的麻烦)。只需使用 /aws/lambda/function_name 名称创建日志组,像 #2 中一样导入它,然后应用到同步内容。
    【解决方案2】:

    由于您没有向我们展示 lambda 函数的 iam 角色策略,我不得不猜测。

    我的感觉是 lambda 的 iam 角色和策略具有 logs:CreateLogGroup 权限。所以 lambda 函数会处理creating log group if not exist

    当你更新时,这个日志组不是由 terraform 管理的,它会报告问题。

    你能不能把logs:CreateLogGroup的权限去掉,把日志组去掉,再试试?

    【讨论】:

    • 您也可以导入现有的日志组,而不是删除它并让 Terraform 重新创建它。
    【解决方案3】:

    它在技术上可以检测它是否存在并且可以选择不创建它。假设,您可以创建一个数据块来导入预先存在的日志组,然后使用具有动态计数的资源来打开或关闭创建。但是你不想那样做,那个奇怪的黑客将永远存在于你的基础代码中。您希望保持您的 terraform 干净并适合从头开始重新创建您的基础架构。

    假设您已经有一个 lambda,那个带有 AWSLambdaBasicExecutionRole 的 lambda 在没有保留设置的情况下在 terraform 之外创建了自己的日志组,而现在您想向 terraform 添加保留设置控制,您手头上有一点麻烦。 Terraform 将希望创建该日志组,因为它不知道它存在,但不能因为名称正在使用中。

    因此您必须导入现有的日志组以映射到您在 terraform 中所做的资源声明。然后当你申请时,terraform 会将现有的日志组调整为你的 TF 配置。

    今天早上我遇到了这种情况,我的 lambdas(和其他东西)是在一个模块中创建的,该模块被加载到大约 10 个不同的堆栈(在 3 个环境中)中,我不想完全手动完成,所以我将分享我整理的这组 bash 命令以使其更容易。这是 hacky 并且取决于(不断变化的)terraform 控制台输出,但对我来说,今天在 Terraform v0.14.4 上,应用的输出会像这样失败:

    您要执行这些操作吗? Terraform 将执行 上述动作。只有“是”才会接受批准。

    输入一个值:是

    module.api_gateway.aws_cloudwatch_log_group.this:正在创建...

    错误:创建 CloudWatch 日志组失败: ResourceAlreadyExistsException:指定的日志组已经 存在:CloudWatch 日志组 'API-Gateway-Execution-Logs_7pnv677kwa/0' 已经存在。

    以下命令将捕获该应用输出,从最后两行解析资源命名空间和 aws 名称,然后执行导入。这不是一个优化的脚本,只是我为了完成工作而拼凑起来的。

    terraform apply 2>&1 | tee out.txt
    resource=$(cat out.txt | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g" | grep Creating | grep cloudwatch | cut -f 1 -d:)
    name=$(cat out.txt | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g" | grep Creating | grep exists | cut -f 2 -d\')
    terraform import $resource $name
    terraform apply
    rm out.txt
    

    【讨论】:

      猜你喜欢
      • 2013-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-25
      • 2019-07-14
      • 2012-08-06
      • 2022-08-08
      • 1970-01-01
      相关资源
      最近更新 更多