Как предоставить общий доступ к сценарию terraform без модульных зависимостей

#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 в качестве модуля вам следует:

  1. Создать R самостоятельно в собственном наборе шаблонов Terraform. Допустим, они находятся под /terraform/R .
  2. Настройте /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"
      
  3. Определите все выходные атрибуты, которые вам нужны, в R качестве выходных переменных. Например:

     output "zone_id" {
      value = "${aws_route_53.example.zone_id}"
    }
      
  4. При запуске terraform apply /terraform/R он сохранит свое состояние Terraform, включая этот вывод, в корзине S3.
  5. Теперь во всех других шаблонах 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}"]
    }
      
  6. Обратите внимание, что terraform_remote_state это источник данных, доступный только для чтения. Это означает, что при запуске terraform apply или terraform destroy в любых шаблонах, использующих этот ресурс, они не будут иметь никакого эффекта R .

Для получения дополнительной информации ознакомьтесь с разделом Как управлять состоянием terraform и Terraform: Up amp; Running.

Комментарии:

1. Вау! Это действительно хороший подход! Я понятия не имел, что вы можете получить удаленное состояние и использовать его в качестве источника данных.