У меня есть две среды: «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» могло бы решить эту проблему. Но мне нужно использовать то же имя.
Это происходит потому, что вы используете одно и то же состояние и конфигурацию для двух разных сред. Обычно здесь используются рабочие пространства, сопоставленные со средами: developer.hashicorp.com/terraform/language/state/workspaces . Затем вы можете использовать одну и ту же конфигурацию для двух разных сред, использовать собственную переменную workspace
вместо var.env
и полностью удалить блок lifecycle
.
Похоже, что в 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 да, просто прочитай его ответ. В Azure вы можете использовать блокировки на уровне группы ресурсов, чтобы предотвратить случайное удаление.
Функция 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». это верно. Спасибо!
как этот
terraform_state
использовался? Я думаю, вам нужно изменить использованиеterraform_state
, потому что это явно не будет работать с тем же именем.