Разрешение пути Terragrunt — модули с локальными ссылками — разделение на несколько сред

#amazon-web-services #terraform #terragrunt

#amazon-веб-службы #terraform #terragrunt

Вопрос:

По причинам, связанным с бизнесом, я не могу разделить свою инфраструктуру с помощью модулей с версиями. Поскольку разделение сред по-прежнему выгодно, и я хотел бы избежать копирования / вставки корневых модулей, которые в основном представляют собой просто создание экземпляров дочерних модулей, в нескольких каталогах, каждый из которых представляет свою собственную среду, я хотел бы указать источник корневого модуля в terragrunt.hcl

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

Текущая структура проекта выглядит следующим образом:

 ├── config
│   ├── common.tfvars
│   └── terragrunt.hcl
├── environments
│   └── dev
├── infrastructure-modules
│   └── ecs
├── terraform-modules
│   ├── terraform-aws-ecr
  

Вся моя инфраструктура описана в infrastructure-modules/ecs/*.tf файлах, которые в основном представляют собой просто создание экземпляров дочерних модулей, объявленных в terraform-modules/terraform-aws-*/ .

С помощью этого я могу просто выполнить terragrunt (команды terraform) из infrastructure-modules/ecs каталога.

Чтобы иметь возможность создать ту же среду в другой учетной записи, я ввел новый каталог environments/dev/eu-central-1/ecs , как показано на выводе дерева из корневого каталога.

environments/dev/eu-central-1/ecs , Состоит всего из двух файлов, terragrunt.hcl и common.tfvars.

Я предполагаю, что использование common.tfvars не требует пояснений, где мой terragrunt.hcl состоит из remote_state {} и terraform {} блоков.

Важная часть файла конфигурации terragrunt:

 remote_state {}

terraform {
  source = "../../../../infrastructure-modules/ecs"

  {...}
}
  

Выше я в основном ссылаюсь на свои корневые модули, объявленные в infrastructure-modules/ecs/*.tf . Где мои корневые модули создают экземпляры дочерних модулей, объявленных в terraform-modules/terraform-aws-*/ .

Дочерние модули из infrastructure-modules/ecs/*.tf создаются следующим образом:

 module my_module {
  source = "../../terraform-modules/terraform-aws-*"

  {...}
}
  

В идеальном мире я мог бы выполнять команды terragrunt (terraform) из environments/dev/eu-central-1/ecs каталога, но поскольку я использую локальные (относительные) пути, это не удается во время инициализации модулей, поскольку корневой модуль my_module загружает дочерний модуль со следующим относительным путем:

 module my_module {
  source = "../../terraform-modules/terraform-aws-*"

  {...}
}
  

This is causing a module instantiation in environments/dev/eu-central-1/ecs to fail as the relative path is different, based on parent module instantiation.

 Initializing modules...
- my_module in 

Error: Unreadable module directory

Unable to evaluate directory symlink: lstat ../../terraform-modules: no such
file or directory
  

Пока, согласно документации, path_relative_* , должна быть возможность возвращать относительный путь между путем, указанным в его включаемом блоке, и текущим terragrunt.hcl, но проблема здесь в том, что у меня нет никаких include {} блоков в моих terragrunt.hcl файлах, и поэтому этот подход не работает. Символические ссылки — это последний вариант.

Редактировать

Если я проверю .terragrunt-cache/* по пути environments/dev/eu-central-1/ecs , я могу подтвердить, что все «корневые» модули были загружены (скопированы) в каталог кэша.

Однако модуль создается подобным образом, и он пытается извлечь фактические модули (модули Terraform) из каталога двумя уровнями выше.

 module my_modules {
  source = "../..//terraform-modules/terraform-aws-ecr"
  

Итак, в принципе, мне нужно сказать Terragrunt загружать / извлекать модули с другого пути.

ПРАВКА 2:

Проверка .terragrunt-cache в каталоге, в котором я запускаю, init показывает, что terraform-modules никогда не загружаются в terraform-infrastructure/environments/dev/eu-central-1/ecs/.terragrunt-cache/ .

Если я изменю свой terraform-infrastructure/infrastructure-modules/ecs/ecr-repos.tf , из

 module ecr_lz_ingestion {
  source = "../../terraform-modules//terraform-aws-ecr"

{<MODULE_ARGUMENTS>}
  }
}
  

Для:

 module ecr_lz_ingestion {
  source = "../../../../../../../../terraform-modules//terraform-aws-ecr"

{<MODULE_ARGUMENTS>}
  }
}
  

Terraform может инициализировать дочерние модули, поскольку я указал относительный путь к terraform-modules/ в корневом каталоге, что, очевидно, является обходным решением.

Каким-то образом я ожидаю, что Terragrunt загрузит оба каталога, terraform-modules и infrastructure-modules чтобы относительные пути в создании экземпляра модуля работали.

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

1. Используете ли вы двойную косую черту в пути к модулю?

2. Я пробовал как с // , так и без.

Ответ №1:

Основываясь на предоставленной вами дополнительной информации, я понимаю, что это ваша текущая структура каталогов:

 terraform-infrastructure
├── config
│   ├── common.tfvars
│   └── terragrunt.hcl
├── environments
│   └── dev
│       └── eu-central-1
│           └── ecs
│               └── terragrunt.hcl
├── infrastructure-modules
│   └── ecs
├── terraform-modules
│   ├── terraform-aws-ecr
│   
├── terragrunt.hcl
  

Обратите внимание на terragrunt.hcl в родительском каталоге, который я добавил.

Это terragrunt.hcl считается родительским файлом и может включать код, который может быть общим для других файлов terragrunt.

Это может включать в себя что-то вроде этого:

 
remote_state {}

  

В вашей eu-central-1/ecs папке добавьте следующее в свой файл terragrunt:

 
include {
  // searches up the directory tree from the current terragrunt.hcl file 
  // and returns the absolute path to the first terragrunt.hcl
  path = find_in_parent_folders()
}

  // using the path relative from the path stated in the include block
terraform {
  source = "${path_relative_from_include()}//infrastructure-modules”
}

  

Это должно сохранить относительный путь неизменным при создании экземпляров дочерних модулей.

Редактировать:

Исходя из вашей проблемы с GitHub, было бы лучше либо переместить двойную косую черту туда, где модули имеют общий путь. Либо это, либо просто объединить ваши модули в одну папку.

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

1. Нет, родительского элемента нет terrragrunt.hcl . Однако в любом случае Terraform завершается с ошибкой, поскольку он не может разрешить модули в `infrastructure / modules / ecs.

2. Не могли бы вы добавить родительский файл terragrunt, чтобы использовать его в качестве привязки?

3. Каков родительский каталог всей коллекции папок?

4. Я думаю, что сейчас я вижу смысл. Родительский каталог — это terraform-infrastructure поскольку у меня внутри есть другие каталоги, связанные с docker.

5. Всегда, и удаление .terragrunt-кэша. Я смог решить проблему после открытия проблемы с Github. github.com/gruntwork-io/terragrunt/issues/1324.Feel свободно обновляйте ответ, и я с радостью приму его.