Терраформирование с зависимыми провайдерами
В моей инфраструктуре terraform я раскручиваю несколько кластеров Kubernetes на основе параметров, а затем устанавливаю некоторое стандартное содержимое в эти кластеры Kubernetes с помощью провайдера kubernetes.
Когда я изменяю параметры, и один из кластеров больше не нужен, terraform не может разорвать его, потому что поставщик и ресурсы находятся в модуле. Однако я не вижу альтернативы, потому что я создаю кластер kubernetes в этом же модуле, и все объекты kubernetes относятся к кластеру kubernetes.
Все решения, которые я могу придумать, включают добавление набора шаблонов к моей конфигурации terraform. Должен ли я подумать о создании моей конфигурации terraform из скрипта?
Я сделал git-репо, которое показывает именно те проблемы, которые у меня возникают:
1 ответ
TL;DR
Два решения:
- Создайте два отдельных модуля с помощью Terraform
Используйте интерполяции и зависимость_ между кодом, который создает ваш кластер Kubernetes, и ресурсами kubernetes:
resource "kubernetes_service" "example" { metadata { name = "my-service" } depends_on = ["aws_vpc.kubernetes"] } resource "aws_vpc" "kubernetes" { ... }
При уничтожении ресурсов
Вы столкнулись с проблемой жизненного цикла зависимости
PS: я не знаю код, который вы использовали для создания / предоставления вашего кластера Kubernetes, но я думаю, что это выглядит так
- Написать код для кластера Kubernetes (создает VPC)
- Примени это
- Написать код для обеспечения Kubernetes (создайте Сервис, который создает ELB)
- Примени это
- Попробуй все уничтожить => Ошибка
Происходит то, что, создав Сервис LoadBalancer, Kubernetes предоставит ELB на AWS. Но Terraform этого не знает, и нет никакой связи между созданным ELB и любыми другими ресурсами, управляемыми Terraform. Поэтому, когда terraform пытается уничтожить ресурсы в коде, он попытается уничтожить VPC. Но этого не может быть, потому что внутри этого VPC есть ELB, о котором терраформ не знает. Первым делом нужно убедиться, что Terraform "депровизирует" кластер Kubernetes, а затем уничтожит сам кластер.
Два решения здесь:
Используйте разные модули, чтобы не было жизненного цикла зависимостей. Например, первый модуль может быть
k8s-infra
а другой может бытьk8s-resources
, Первый управляет всем скелетом Кубернетеса и применяется первым / уничтожает последним. Второй управляет тем, что находится внутри кластера и применяется последним / уничтожить первым.Использовать
depends_on
параметр для явной записи жизненного цикла зависимости
При создании ресурсов
Вы также можете столкнуться с проблемой зависимости, когда terraform apply
не может создавать ресурсы, даже если ничего еще не применено. Я приведу другой пример с postgres
- Написать код для создания сервера RDS PostgreSQL
- Примените это с Terraform
- Напишите код в том же модуле, чтобы предоставить этот экземпляр RDS провайдеру postgres terraform
- Примените это с Terraform
- Уничтожить все
- Попробуйте применить все => ОШИБКА
Отладив Terraform немного, я узнал, что все провайдеры инициализируются в начале plan
/ apply
поэтому, если у вас недопустимая конфигурация (неправильные ключи API / недоступная конечная точка), Terraform завершится ошибкой.
Решением здесь является использование целевого параметра plan
/ apply
команда.
Terraform будет инициализировать только тех поставщиков, которые связаны с применяемыми ресурсами.
- Примените код RDS у провайдера AWS:
terraform apply -target=aws_db_instance
- Применить все
terraform apply
, Поскольку экземпляр RDS уже доступен, поставщик PostgreSQL также может инициировать себя