Как уничтожить ресурсы в модуле Terraform с блоком provider (или как удалить блок provider)?

Вопрос или проблема

У меня есть модуль Terraform, который создает репозиторий на GitHub и ряд связанных ресурсов (используя github_repository, github_issue_labels и github_branch_protection). Это локальный модуль, и репозитории должны быть созданы в определенной организации, поэтому modules/common_repository/main.tf начинается с:

provider "github" {
  owner = "example_org"
}

resource "github_repository" "repo" {
  name          = var.name
  visibility    = var.visibility
  description   = var.description
  auto_init     = true
  has_issues    = true
  has_downloads = false
  has_projects  = false
  has_wiki      = false
}

# и т.д...

Я вызываю модуль следующим образом:

module "repo_sandbox" {
  source = "./modules/common_repository"
  name   = "sandbox"
  labels = local.common_labels
}

Я надеялся, что удаление этих ресурсов просто потребует удаления указанного блока module, но это приводит к следующей ошибке:

│ Ошибка: Конфигурация провайдера отсутствует
│
│ Для работы с module.repo_sandbox.github_repository.repo (orphan) требуется его оригинальная
│ конфигурация провайдера в
│ module.repo_sandbox.provider["registry.opentofu.org/hashicorp/github"],
│ но она была удалена. Это происходит в случае удаления конфигурации провайдера
│ в то время как объекты, созданные этим провайдером, все еще существуют в состоянии. Добавьте
│ конфигурацию провайдера заново для уничтожения
│ module.repo_sandbox.github_repository.repo (orphan), после чего вы снова сможете удалить
│ конфигурацию провайдера.

Я прочитал этот пост на форуме от 2022 года, в котором говорится, что:

Использование блоков провайдера в некорневых модулях не рекомендуется, так как это создает подобные ситуации, но Terraform, к сожалению, должен продолжать их поддерживать для обратной совместимости.

Однако я не уверен, как еще можно это написать; модуль, кажется, игнорирует конфигурацию провайдера в организации верхнего уровня. Если я удалю блок провайдера из модуля, он попытается создать репозитории в моем персональном пространстве имен GitHub.

Я попробовал предложение из того же поста, а именно заменить модуль новым, который пуст за исключением конфигурации провайдера; я создал modules/common_repository_destroy с main.tf, содержащим только:

provider "github" {
  owner = "example_org"
}

Затем я изменил вызывающий блок:

module "repo_sandbox" {
  source = "./modules/common_repository_destroy"
}

Но это все равно приводит к тем же ошибкам.

Есть ли чистый способ (или любой способ) заставить это работать?

Ответ или решение

Чтобы решить проблему удаления ресурсов в модуле Terraform, в который включён блок провайдера, важно понимать теоретическую основу работы Terraform и оптимальные практики для управления провайдерами и состоянием инфраструктуры.

Теория:

Terraform — это инструмент управления инфраструктурой, который позволяет определять ресурсы через код и управлять ими в декларативной форме. Каждая конфигурация Terraform использует провайдеры, такие как github, которые позволяют взаимодействовать с конкретными API для управления ресурсами — в вашем случае это репозитории GitHub.

Когда вы создаете ресурсы в Terraform, информация об этих ресурсах записывается в файл состояния. Это состояние необходимо для управления временем жизни ресурсов, включая их создание и удаление. Если вы просто удалите блок модуля из вашей конфигурации, Terraform потеряет связь с состоянием этих ресурсов, что приведет к ошибке, с которой вы столкнулись.

Пример:

В вашем случае проблема заключается в следующем: блок провайдера github прописан внутри модуля common_repository. Это не является хорошей практикой, так как провайдеры, определённые в модулях, создают жесткую связь между конфигурацией и схемой провайдера, что может осложнить управление инфраструктурой, особенно при удалении ресурсов.

Как вы сами отметили, документация Terraform и сообщество настоятельно рекомендуют не определять блоки провайдеров в модулях. Это связано с тем, что Terraform использует связь между состоянием и конфигурацией: если конфигурация провайдера удалена, Terraform теряет информацию, необходимую для взаимодействия с API.

Применение:

На практике, чтобы разрушить эти ресурсы, вам нужно временно вернуть привязку состояния. Для этого:

  1. Верните первоначальный блок провайдеров: Начните с возврата конфигурации провайдера github в ваш модуль. Это нужно для того, чтобы обеспечить Terraform доступ к API GitHub через провайдер.

  2. Используйте команду terraforms: Запустите terraform destroy -target=module.repo_sandbox в корне вашей конфигурации. Эта команда удалит все ресурсы, созданные модулем repo_sandbox.

  3. Проверьте состояние: После выполнения команды убедитесь, что состояние удалено корректно. Вы можете использовать terraform plan для подтверждения, что больше нет ресурсов, связанных с модулем.

  4. Перенесите провайдер на уровень корня: Переместите блоки провайдеров из модуля на уровень корневой конфигурации. Это не только упростит управление состоянием в будущем, но и позволит использовать один провайдер для нескольких модулей.

Следуя этим шагам, вы сможете корректно удалить ресурсы и минимизировать риск дальнейших ошибок, связанных с отсутствием конфигурации провайдера. Это также приведет ваш код в соответствие с лучшими практиками Terraform, что облегчит управление инфраструктурой в будущем.

Оцените материал
Добавить комментарий

Капча загружается...