Терраформирование с зависимыми провайдерами

В моей инфраструктуре terraform я раскручиваю несколько кластеров Kubernetes на основе параметров, а затем устанавливаю некоторое стандартное содержимое в эти кластеры Kubernetes с помощью провайдера kubernetes.

Когда я изменяю параметры, и один из кластеров больше не нужен, terraform не может разорвать его, потому что поставщик и ресурсы находятся в модуле. Однако я не вижу альтернативы, потому что я создаю кластер kubernetes в этом же модуле, и все объекты kubernetes относятся к кластеру kubernetes.

Все решения, которые я могу придумать, включают добавление набора шаблонов к моей конфигурации terraform. Должен ли я подумать о создании моей конфигурации terraform из скрипта?


Я сделал git-репо, которое показывает именно те проблемы, которые у меня возникают:

https://github.com/bukzor/terraform-gke-k8s-demo

1 ответ

TL;DR

Два решения:

  1. Создайте два отдельных модуля с помощью Terraform
  2. Используйте интерполяции и зависимость_ между кодом, который создает ваш кластер Kubernetes, и ресурсами kubernetes:

    resource "kubernetes_service" "example" {
      metadata {
        name = "my-service"
      }
    
      depends_on = ["aws_vpc.kubernetes"]
    }
    
    resource "aws_vpc" "kubernetes" {
      ...
    }
    

При уничтожении ресурсов

Вы столкнулись с проблемой жизненного цикла зависимости

PS: я не знаю код, который вы использовали для создания / предоставления вашего кластера Kubernetes, но я думаю, что это выглядит так

  1. Написать код для кластера Kubernetes (создает VPC)
  2. Примени это
  3. Написать код для обеспечения Kubernetes (создайте Сервис, который создает ELB)
  4. Примени это
  5. Попробуй все уничтожить => Ошибка

Происходит то, что, создав Сервис LoadBalancer, Kubernetes предоставит ELB на AWS. Но Terraform этого не знает, и нет никакой связи между созданным ELB и любыми другими ресурсами, управляемыми Terraform. Поэтому, когда terraform пытается уничтожить ресурсы в коде, он попытается уничтожить VPC. Но этого не может быть, потому что внутри этого VPC есть ELB, о котором терраформ не знает. Первым делом нужно убедиться, что Terraform "депровизирует" кластер Kubernetes, а затем уничтожит сам кластер.

Два решения здесь:

  1. Используйте разные модули, чтобы не было жизненного цикла зависимостей. Например, первый модуль может быть k8s-infra а другой может быть k8s-resources, Первый управляет всем скелетом Кубернетеса и применяется первым / уничтожает последним. Второй управляет тем, что находится внутри кластера и применяется последним / уничтожить первым.

  2. Использовать depends_on параметр для явной записи жизненного цикла зависимости

При создании ресурсов

Вы также можете столкнуться с проблемой зависимости, когда terraform apply не может создавать ресурсы, даже если ничего еще не применено. Я приведу другой пример с postgres

  1. Написать код для создания сервера RDS PostgreSQL
  2. Примените это с Terraform
  3. Напишите код в том же модуле, чтобы предоставить этот экземпляр RDS провайдеру postgres terraform
  4. Примените это с Terraform
  5. Уничтожить все
  6. Попробуйте применить все => ОШИБКА

Отладив Terraform немного, я узнал, что все провайдеры инициализируются в начале plan / apply поэтому, если у вас недопустимая конфигурация (неправильные ключи API / недоступная конечная точка), Terraform завершится ошибкой.

Решением здесь является использование целевого параметра plan / apply команда. Terraform будет инициализировать только тех поставщиков, которые связаны с применяемыми ресурсами.

  1. Примените код RDS у провайдера AWS: terraform apply -target=aws_db_instance
  2. Применить все terraform apply, Поскольку экземпляр RDS уже доступен, поставщик PostgreSQL также может инициировать себя
Другие вопросы по тегам