#amazon-web-services #terraform
#amazon-web-services #terraform
Вопрос:
Я хочу поделиться сценарием terraform, который будет использоваться в разных проектах. Я знаю, как создавать и совместно использовать модули, но эта настройка вызывает большое раздражение: когда я ссылаюсь на модуль в скрипте и выполняю a terraform apply
, если ресурс модуля не существует, он будет создан, но также, если я выполняю a terraform destroy
, этот ресурс будет уничтожен.
Если у меня есть два проекта, зависящих от одного и того же модуля, и в одном из них я вызываю a terraform destroy
, это может привести к несогласованному состоянию, поскольку модуль используется другим проектом. Сценарий может либо завершиться с ошибкой, поскольку он не может уничтожить ресурс, либо он уничтожит ресурс и повлияет на другой проект.
В моем сценарии я хочу совместно использовать сетевые сценарии между двумя проектами, и я хочу, чтобы сетевые ресурсы никогда не были уничтожены. Я не могу создать проект только для этого ресурса, потому что мне нужно как-то ссылаться на него в своих проектах, и единственный способ сделать это — использовать его идентификатор, который я понятия не имею, каким будет.
prevent_destroy
также не вариант, поскольку мне нужно уничтожить другие ресурсы, кроме общего ресурса сценария. Эта конфигурация приводит terraform destroy
к сбою.
Есть ли какой-либо способ ссылаться на ресурс, например, по его имени, или есть какой-либо другой лучший подход для достижения того, чего я хочу?
Ответ №1:
Если я вас правильно понял, у вас есть какой-то ресурс R
, который является «одноэлементным». То есть R
в вашей учетной записи AWS может существовать только один экземпляр can. Например, у вас может быть только одна aws_route53_zone с именем «foo.com «. Если вы включаете R
модуль в качестве модуля в двух разных местах, то любой из них может создать его при запуске terraform apply
, и любой из них может удалить его при запуске terraform destroy
. Вы хотели бы избежать этого, но вам все равно нужен какой-то способ получить выходной атрибут R
(например zone_id
, для aws_route53_zone
ресурса генерируется AWS, поэтому вы не можете догадаться об этом).
Если это так, то вместо использования a R
в качестве модуля вам следует:
- Создать
R
самостоятельно в собственном наборе шаблонов Terraform. Допустим, они находятся под/terraform/R
. -
Настройте
/terraform/R
использование удаленного состояния. Например, вот как вы можете настроить эти шаблоны для сохранения их удаленного состояния в корзине S3 (вам нужно будет указать имя / регион корзины, как указано):terraform remote config -backend=s3 -backend-config="bucket=(YOUR BUCKET NAME)" -backend-config="key=terraform.tfstate" -backend-config="region=(YOUR BUCKET REGION)" -backend-config="encrypt=true"
-
Определите все выходные атрибуты, которые вам нужны, в
R
качестве выходных переменных. Например:output "zone_id" { value = "${aws_route_53.example.zone_id}" }
- При запуске
terraform apply
/terraform/R
он сохранит свое состояние Terraform, включая этот вывод, в корзине S3. -
Теперь во всех других шаблонах Terraform, для которых требуется этот выходной атрибут
R
, вы можете извлечь его из корзины S3, используя источник данных terraform_remote_state . Например, предположим, что у вас есть некоторый шаблон/terraform/foo
, которому этотzone_id
параметр необходим для создания aws_route53_record (вам нужно будет указать имя / регион корзины, как указано):data "terraform_remote_state" "r" { backend = "s3" config { bucket = "(YOUR BUCKET NAME)" key = "terraform.tfstate" region = "(YOUR BUCKET REGION)" } } resource "aws_route53_record" "www" { zone_id = "${data.terraform_remote_state.r.zone_id}" name = "www.foo.com" type = "A" ttl = "300" records = ["${aws_eip.lb.public_ip}"] }
- Обратите внимание, что
terraform_remote_state
это источник данных, доступный только для чтения. Это означает, что при запускеterraform apply
илиterraform destroy
в любых шаблонах, использующих этот ресурс, они не будут иметь никакого эффектаR
.
Для получения дополнительной информации ознакомьтесь с разделом Как управлять состоянием terraform и Terraform: Up amp; Running.
Комментарии:
1. Вау! Это действительно хороший подход! Я понятия не имел, что вы можете получить удаленное состояние и использовать его в качестве источника данных.