问题描述
出于业务相关原因,我无法使用版本控制模块拆分基础架构。由于拆分环境仍然是有益的,并且我想避免复制/粘贴根模块(基本上只是子模块的实例化),位于多个目录中,每个目录代表自己的环境,因此我想指定 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-*/
中声明的子模块。
这样,我可以简单地从infrastructure-modules/ecs
目录执行terragrunt(terraform命令)。
为了有可能在另一个帐户中创建相同的环境,我引入了一个新目录environments/dev/eu-central-1/ecs
,如根目录的树输出所示。
environments/dev/eu-central-1/ecs
仅由两个文件 terragrunt.hcl 和 common.tfvars 组成。
我猜想 common.tfvars 的用法是不言自明的,其中我的 terragrunt.hcl 由remote_state {}
和{{1 }}块。
terragrunt配置文件的重要部分:
terraform {}
上面,我基本上是在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)命令,但是由于我使用的是本地(相对)路径,因此在初始化期间失败>模块,因为根模块 my_module 使用以下相对路径加载子模块:
environments/dev/eu-central-1/ecs
这会导致module my_module {
source = "../../terraform-modules/terraform-aws-*"
{...}
}
中的模块实例化失败,因为基于父模块实例化的相对路径不同。
environments/dev/eu-central-1/ecs
到目前为止,根据文档Initializing modules...
- my_module in
Error: Unreadable module directory
Unable to evaluate directory symlink: lstat ../../terraform-modules: no such
file or directory
,应该能够返回其include块中指定的路径与当前terragrunt.hcl之间的相对路径,但是这里的问题是我没有我的path_relative_*
文件中的任何include {}
块,因此这种方法行不通。符号链接是最后的选择。
编辑
如果我检查路径terragrunt.hcl
上的.terragrunt-cache/*
,则可以确认所有“根”模块都已下载(复制)到缓存目录中。
但是,正在像这样实例化该模块,并且它尝试从上面两级目录中获取实际模块(terraform模块)。
environments/dev/eu-central-1/ecs
所以基本上,我需要告诉Terragrunt从其他路径下载/获取模块。
编辑2:
在我运行的module my_modules {
source = "../..//terraform-modules/terraform-aws-ecr"
目录中检查.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>}
}
}
terraform能够初始化子模块,因为我在目录根目录中给出了module ecr_lz_ingestion {
source = "../../../../../../../../terraform-modules//terraform-aws-ecr"
{<MODULE_ARGUMENTS>}
}
}
的相对路径,显然这是一种解决方法。
以某种方式,我期望Terragrunt下载两个目录terraform-modules/
和terraform-modules
以便模块实例化中的相对路径起作用。
解决方法
根据您提供的其他信息,我知道这是您当前的目录结构:
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问题中,最好将双斜杠移至模块共享公共路径的位置。要么只是将模块合并到一个文件夹中即可。