我在使用Terragrunt的过程中遇到了问题,并找到了解决方法

这篇文章是2023年Terraform Advent Calendar中的第12天。

 

使用 Terragrunt 管理 Terraform 资源

最近,O’Reilly Japan 发布了《详解 Terraform 第3版》一书。

在那些中,因为有人推荐 Terragrunt,虽然我对管理 Terraform 资源并不感到太困扰,但我个人决定尝试引入它。

由于遇到了一些困难,我决定写一篇文章,希望能对他人有所参考。

在引入这项工作时,我们参考了以下文章。

 

我希望向作者表达感谢之情,并希望能够提供一篇补充性的文章。

请参考上述的文章和官方文档,了解Terragrunt是什么。

绊倒点

在每个环境中配置远程状态。

之前参考的一篇文章中提到,对于所有环境使用同一个S3存储桶来管理.tfstate文件,但由于我希望按照每个环境分别使用不同的存储桶来管理.tfstate文件,所以我进行了相关研究。

只要将 terragrunt.hcl 文件放置在每个环境目录中即可。

remote_state {
  backend = "gcs"
  config = {
    bucket  = "tfstate_bucket"
    prefix  = path_relative_to_include()
    project = "gcp-project-staging"
  }
  generate = {
    path      = "backend.tf"
    if_exists = "overwrite"
  }
}

您可以通过以下方式在模块的调用方写入以继承上述文件的设置。

include {
  path = find_in_parent_folders()
}

地图类型变量的引用

在 staging/env.hcl 文件中,我定义了一个 map 类型的变量,但是出现了错误。

locals {
  map_variable = {
    variable = 'value'
  }
}

当我看到错误时,感觉不太对劲。

  {
    variable = 'value'
  }

看起来你将其作为一个简单的字符串进行读取。
要解决这个错误,你需要在模块的 variables.tf 文件中定义类型。

可以执行的示例

modules/modA/variables
变量 “map_variable” {
描述 = “map 类型的变量”
类型 = map(any)
}

坏的例子

modules/modA/variables
变量 “map_variable” {
描述 = “映射类型的变量”
}

我懒得定义类型被发现了。
我们要好好定义类型。

在提供者的设置中,在EOF之前使用var。

我并没有遇到困难,但是当我试图使用以下定义中的变量时,我开始怀疑并进行了尝试,结果发现可以正常使用。

generate "provider" {
  path      = "provider.tf"
  if_exists = "overwrite_terragrunt"
  contents  = <<EOF
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.8.0"
    }
  }
}
provider "google" {
  project = var.project_id
  region  = var.region
}
EOF
}

由于被 EOF 包围着,我曾经担心 var 中定义的 project_id 和 region 不会被赋值,但实际上,在 .terragrunt-cache 中生成的 provider.tf 文件中,可以正常使用 var.project_id 和 var.region。尽管这很正常,但我在执行之前还是有些困惑。

# Generated by Terragrunt. Sig: 
terraform {
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = "5.8.0"
    }
  }
}
provider "google" {
  project = var.project_id
  region  = var.region
}

Terragrunt import 的用法如何使用?

当执行terraform import对module时,应按照以下方式编写:
terraform import module.modA.service_name.resource_name resource_id
同样的方式执行terragrunt import不起作用,但是只需将module.modA部分删除并执行即可成功。

实际可执行的例子:
terragrunt 导入服务名称.资源名称 资源ID

不可行的示例:

terragrunt 导入 module.modA.service_name.resource_name 根据 resource_id

总结

尽管Terragrunt非常实用,但日语技术文章还相对较少。希望这篇文章能对刚开始使用Terragrunt的人有所帮助。

目前,Terragrunt的最新版本是0.54.0,截止到2023年12月,它仍是一项新兴服务。我很期待Terragrunt本身和其应用案例的进一步发展。

bannerAds