Я пытаюсь добавить логику в свой скрипт terraform, чтобы при создании лямбды добавлялась логика сохранения CW, чтобы наши журналы очищались через 30 дней. Я вижу, что когда terraform запускается для обновления существующей лямбды (которая была развернута до добавления моей новой логики хранения), моя работа завершается с ошибкой ниже.
aws_cloudwatch_log_group.lambda-deploy: 1 error(s) occurred:
aws_cloudwatch_log_group.lambda-deploy: Creating CloudWatch Log Group failed: ResourceAlreadyExistsException: The specified log group already exists status code: 400, request id: e500eb50-4a81-11e9-9c08-7152b4a0ad31: The CloudWatch Log Group '/aws/lambda/{lambda-name}' already exists.
Ниже показано, как я настроил свой код 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 проверил, была ли создана группа облачных часов, и просто обновил политику хранения вместо того, чтобы пытаться создать группу журналов?

Поскольку вы не показываете нам политику роли iam для лямбда-функции, мне приходится догадываться.
Я чувствую, что роль iam и политика для лямбда имеют разрешение logs:CreateLogGroup. Так что лямбда-функция позаботится о creating log group if not exist.
При обновлении эта группа журналов не управляется terraform, она сообщит о проблеме.
Не могли бы вы удалить разрешение logs:CreateLogGroup и группу журнала, а затем повторить попытку?
Пример выше, например:
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"
}
Импортировать ресурс
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.
terraform plan, ваша группа журналов теперь управляется terraform ... уф!Непонятно, что вы подразумеваете под «Где ${aws_lambda_function.lambda-deploy.function_name} — это то, что находится в AWS». Не могли бы вы уточнить?
Я не понимаю, почему вы закомментировали имя, а затем раскомментировали его. В этом нет необходимости (и это будет СЕРЬЕЗНЫМ хлопотом, если ваша группа журналов состоит из 1 или более модулей с глубокой загрузкой из репозиториев git с тегами). Просто создайте группу журналов с именем /aws/lambda/имя_функции, импортируйте ее, как в пункте 2, а затем примените ее для синхронизации.
ТЕХНИЧЕСКИ возможно определить, существует ли он, и при желании не создавать его. Гипотетически можно создать блок данных для импорта уже существующей группы журналов, а затем ресурс с динамическим счетчиком, чтобы включить или выключить его создание. Но вы бы не хотели делать это таким образом, этот странный хак навсегда остался бы в вашем инфракоде. Вы хотите, чтобы ваша терраформа была чистой и ориентированной на воссоздание вашей инфраструктуры с нуля.
Предполагая, что у вас уже есть лямбда, эта лямбда с AWSLambdaBasicExecutionRole создала собственную группу журналов вне terraform без настроек хранения, и теперь вы хотите добавить управление настройками хранения в terraform, у вас есть небольшая проблема. Terraform захочет создать эту группу журналов, потому что не знает о ее существовании, но не может, потому что это имя уже используется.
Таким образом, вам нужно импортировать существующую группу журналов, чтобы сопоставить ее с объявлением ресурсов, которое вы сделали в terraform. Затем, когда вы подадите заявку, terraform настроит существующую группу журналов в соответствии с вашей конфигурацией TF.
Этим утром я был именно в такой ситуации: мои лямбды (и другие вещи) создаются в модуле, который загружается примерно в 10 различных стеков (в 3 средах), и я не хотел делать это полностью вручную, поэтому я поделитесь этим небольшим набором команд bash, которые я собрал, чтобы упростить задачу. Это хакерство и зависит от (постоянно меняющегося) вывода консоли terraform, но для меня сегодня на Terraform v0.14.4 вывод приложения будет терпеть неудачу следующим образом:
Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve.
Enter a value: yes
module.api_gateway.aws_cloudwatch_log_group.this: Creating...
Error: Creating CloudWatch Log Group failed: ResourceAlreadyExistsException: The specified log group already exists: The CloudWatch Log Group 'API-Gateway-Execution-Logs_7pnv677kwa/0' already exists.
Следующие команды будут захватывать выходные данные применения, анализировать пространство имен ресурса и имя 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
Вы также можете импортировать существующую группу журналов вместо того, чтобы удалять ее и заново создавать Terraform.