#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 свободно обновляйте ответ, и я с радостью приму его.