Terraform не позволяет использовать переменную при создании ресурса. Как объехать?

У меня есть две среды: «dev» и «prod». Я хочу создать корзину AWS s3 для каждого из них, используя разные конфигурации жизненного цикла: «false» для «dev» и «true» для «prod». Обычно я использую переменные. Но Terraform не позволяет создавать переменную для «жизненного цикла». Так что я немного застрял. Пожалуйста помоги!

resource "aws_s3_bucket" "terraform_state" {
  bucket = "terraform-state-vpc-${var.env}"

  lifecycle {
    prevent_destroy = true
  }

  tags = {
    Name = "s3-state-file-${var.env}"
  }
}

Только я мог наткнуться на это. В этом же файле создайте:

resource "aws_s3_bucket" "terraform_state" {
  count = var.env == "prod" ? 1 : 0  # Create only if environment is 'prod'
  bucket = "terraform-state-vpc-${var.env}"

  lifecycle {
    prevent_destroy = true
  }

  tags = {
    Name = "s3-state-file-${var.env}"
  }
}

и

resource "aws_s3_bucket" "terraform_state" {
  count = var.env == "dev" ? 1 : 0  # Create only if environment is 'dev'
  bucket = "terraform-state-vpc-${var.env}"

  lifecycle {
    prevent_destroy = false
  }

  tags = {
    Name = "s3-state-file-${var.env}"
  }
}

но я не могу создать еще один ресурс для среды разработки. Потому что я получаю сообщение об ошибке: «Ошибка: повторяющаяся конфигурация ресурса «aws_s3_bucket». Изменение имени корзины: «terraform_state» могло бы решить эту проблему. Но мне нужно использовать то же имя.

как этот terraform_state использовался? Я думаю, вам нужно изменить использование terraform_state, потому что это явно не будет работать с тем же именем.

ha36d 28.06.2024 08:28

Это происходит потому, что вы используете одно и то же состояние и конфигурацию для двух разных сред. Обычно здесь используются рабочие пространства, сопоставленные со средами: developer.hashicorp.com/terraform/language/state/workspaces . Затем вы можете использовать одну и ту же конфигурацию для двух разных сред, использовать собственную переменную workspace вместо var.env и полностью удалить блок lifecycle.

Matthew Schuchard 28.06.2024 13:01
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
53
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Похоже, что в Prevent_destroy пока нет поддержки переменных, хотя эта функция была запрошена уже давно (август 2019 года).

Касательно

Потому что я получаю сообщение об ошибке: «Ошибка: повторяющаяся конфигурация ресурса «aws_s3_bucket». Изменение имени корзины: «terraform_state» могло бы решить эту проблему. Но мне нужно использовать то же имя.

<RESOURCE TYPE>.<NAME> представляет собой управляемый ресурс заданного типа и имени. Имена, очевидно, должны быть уникальными, иначе при использовании aws_s3_bucket.terraform_state как Terraform узнает, ссылаетесь ли вы на ресурс разработчика или продукта?

Вам придется использовать разные имена для каждого ресурса, например terraform_state_prod и terraform_state_dev:

resource "aws_s3_bucket" "terraform_state_prod" {
  count = var.env == "prod" ? 1 : 0  // Create only if environment is 'prod'
  bucket = "terraform-state-vpc-${var.env}"

  lifecycle {
    prevent_destroy = true
  }

  tags = {
    Name = "s3-state-file-${var.env}"
  }
}

resource "aws_s3_bucket" "terraform_state_dev" {
  count = var.env == "dev" ? 1 : 0  // Create only if environment is 'dev'
  bucket = "terraform-state-vpc-${var.env}"

  lifecycle {
    prevent_destroy = false
  }

  tags = {
    Name = "s3-state-file-${var.env}"
  }
}

Большое спасибо. Это может быть один из способов, если вы решите использовать эту функцию. Но, как сказал Мартин Аткинс, «… Amazon S3 имеет встроенную форму защиты от удаления сегментов, без необходимости какой-либо специальной настройки в Terraform». Это означает, что вы не можете «терраформировать уничтожение», а не пустой s3.

NME 28.06.2024 21:58

@NME да, просто прочитай его ответ. В Azure вы можете использовать блокировки на уровне группы ресурсов, чтобы предотвратить случайное удаление.

Rui Jarimba 28.06.2024 23:42
Ответ принят как подходящий

Функция prevent_destroy в Terraform весьма сомнительна, поскольку она применяется только внутри самого Terraform и только в том случае, если аргумент prevent_destroy = true присутствует в конфигурации на момент планирования уничтожения. Terraform продолжает поддерживать его для обратной совместимости, но есть более эффективные способы защитить ценный объект от уничтожения, поэтому я бы не рекомендовал использовать его в новых модулях Terraform.

В частности, для корзин S3 один из вариантов — вообще ничего не делать: API Amazon S3 не позволит вам удалить корзину, в которой есть объекты, поэтому вы сможете удалить любую из этих корзин, только предварительно удалив все объекты из них. Поэтому Amazon S3 имеет встроенную защиту от удаления сегментов, поэтому вам не требуется какая-либо специальная настройка в Terraform.

Если по какой-то причине этой встроенной защиты недостаточно, то, безусловно, наиболее надежным вариантом является использование политики IAM, управляемой в другой конфигурации Terraform (чтобы изменения в этой конфигурации не могли случайно уничтожить или отключить ее), которая запрещает доступ к действию s3:DeleteBucket, что означает, что API S3 отклонит любую попытку удалить этот сегмент независимо от того, есть ли в нем какие-либо объекты.

Защита от удаления, реализуемая удаленным API, намного превосходит защиту от удаления, реализуемую на стороне клиента, поскольку ее труднее случайно отключить или пропустить.

«Поэтому Amazon S3 имеет встроенную форму защиты от удаления сегментов, без необходимости какой-либо специальной настройки в Terraform». это верно. Спасибо!

NME 28.06.2024 21:52

Другие вопросы по теме

Использование AWS CloudFront для обслуживания HTTPS в корзинах AWS S3, но НЕКОТОРЫЕ изображения застревают в цикле перенаправления
HTML-аудиоэлемент отключен, хотя src верен
Загрузка файла на S3 через Node.js SDK. Результатом является пустой файл
Браузер не обновляет изображение, когда URL-адрес источника изображения изменен на URL-адрес изображения в корзине AWS S3
Снежинка — получайте уведомления о любых ошибках задачи, если для копии установлено значение «on_error = continue»
Ошибка чтения файла из S3: null (Служба: S3, код состояния: 502) с помощью GetObjectRequest
Scrapy TSV скачать файл. как конвертировать файл в паркет перед загрузкой на s3
Как мне подключить ssh-ключ для репозитория BitBucket к моему контейнеру, чтобы использовать ссылки ssh git в рабочих процессах Argo?
Проверка цели AWS DMS S3 застряла в состоянии «ожидающие записи»
Ошибка типа CSS MIME при обслуживании сайта из S3 через CloudFront