Terraform CloudWatch保留逻辑

时间:2019-03-19 21:28:19

标签: lambda terraform serverless

我正在尝试向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组并仅更新保留策略而不是尝试创建日志组?

3 个答案:

答案 0 :(得分:1)

  1. 注释掉name参数

上面的例子,例如:

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. 取消注释“ name”参数并运行terraform plan,您的日志组现在由terraform ... phew管理!

答案 1 :(得分:0)

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

我的感觉是lambda的IAM角色,策略已获得logs:CreateLogGroup的许可。因此,lambda函数将处理creating log group if not exist

更新时,此日志组不受terraform管理,它将报告问题。

您能否删除权限logs:CreateLogGroup并删除日志组,然后重试?

答案 2 :(得分:0)

技术上可以检测它是否存在并且可以选择不创建它。假设,您可以创建一个数据块来导入一个预先存在的日志组,然后一个具有动态计数的资源来打开或关闭创建。但是你不会想那样做,那个奇怪的黑客将永远存在于你的基础代码中。您希望保持 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