Terragrunt如何保持Terraform的backend DRY和可维护

举报
kaliarch 发表于 2022/11/12 22:08:31 2022/11/12
【摘要】 使用Terragrunt,可以与Terraform 0.12和HCL2一起使用,帮助您的代码DRY和可维护 保持backend配置DRYTerraform后端允许您将Terraform状态存储在团队中每个人都可以访问的共享位置,如S3桶,并提供状态文件的锁定,以防止竞争条件。若要使用Terraform后端,请将后端配置添加到Terraform代码中:# stage/frontend-app/...

使用Terragrunt,可以与Terraform 0.12和HCL2一起使用,帮助您的代码DRY和可维护

保持backend配置DRY

Terraform后端允许您将Terraform状态存储在团队中每个人都可以访问的共享位置,如S3桶,并提供状态文件的锁定,以防止竞争条件。若要使用Terraform后端,请将后端配置添加到Terraform代码中:

# stage/frontend-app/main.tf
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "stage/frontend-app/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "my-lock-table"
  }
}

上面的代码告诉Terraform将fronten-app模块的状态存储在路径stage/fronten-app/Terraform.tfstate下名为my-terraform-state的S3桶中,并使用名为my-lock-table的DynamoDB表进行锁定。这是每个Terraform团队用来协作的一个很好的特性,但它有一个主要的问题:后端配置不支持任何类型的变量或表达式。也就是说,以下做法行不通:

# stage/frontend-app/main.tf
terraform {
  backend "s3" {
    # Using variables does NOT work here!
    bucket         = var.terraform_state_bucket
    key            = var.terraform_state_key
    region         = var.terraform_state_region
    encrypt        = var.terraform_state_encrypt
    dynamodb_table = var.terraform_state_dynamodb_table
  }
}

这意味着您必须将相同的后端配置复制/粘贴到每个Terraform模块中。您不仅必须复制/粘贴,而且还必须非常小心地不要复制/粘贴键值,这样就不会有两个模块覆盖彼此的状态文件!例如,数据库模块的后端配置看起来与前端应用程序模块的后端配置几乎相同,只是键值不同:

# stage/mysql/main.tf
terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "stage/mysql/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "my-lock-table"
  }
}

Terragrunt允许您通过在根位置定义一次后端配置并在所有子模块中继承该配置来保持后端配置干枯(“不要重复自己”)。假设您的Terraform代码具有以下文件夹布局:

stage
├── frontend-app
│   └── main.tf
└── mysql
    └── main.tf

要使用Terragrunt,请将单个Terragrunt.hcl文件添加到repo的根目录中,在stage文件夹中,并在每个模块文件夹中添加一个Terragrunt.hcl文件:

stage
├── terragrunt.hcl
├── frontend-app
│   ├── main.tf
│   └── terragrunt.hcl
└── mysql
    ├── main.tf
    └── terragrunt.hcl

接下来,在您的每个Terraform模块中,删除后端配置的内容:


# stage/mysql/main.tf
terraform {
  # Intentionally empty. Will be filled by Terragrunt.
  backend "s3" {}
}

现在,只需在根Terragrunt.hcl文件中定义一次后端配置:

# stage/terragrunt.hcl
remote_state {
  backend = "s3"
  config = {
    bucket = "my-terraform-state"
    
    key = "${path_relative_to_include()}/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "my-lock-table"
  }
}

Terragrunt.HCL文件使用与Terraform(HCL)相同的配置语言,配置与每个模块中的后端配置大致相同,只是key值现在使用了path_relative_to_include()内置函数,该函数将自动将key设置为根Terragrunt.HCL和子模块之间的相对路径(因此,Terraform状态文件夹结构将与Terraform代码文件夹结构匹配,这使得从一个到另一个更容易)。
最后一步是更新每个子Terragrunt.hcl文件,告诉它们包含根Terragrunt.hcl的配置:

# stage/mysql/terragrunt.hcl
include {
  path = find_in_parent_folders()
}

find_in_parent_folders()帮助程序将自动搜索目录树,找到根Terragrunt.hcl并从它继承remote_state配置。
现在,安装Terragrunt,并运行您所使用的所有Terraform命令,但是使用Terragrunt而不是Terraform作为命令名(例如,Terragrunt apply而不是Terraform apply)。要部署数据库模块,可以运行:

$ cd stage/mysql
$ terragrunt apply

Terragrunt将自动查找mysql模块的sterragrunt.hcl文件,使用根Terragrunt.hcl文件中的设置来配置后端,并通过path_relative_to_include()函数将键设置为stage/mysql/terraform.tfstate。如果在stage/fronten-app中运行terragrunt apply,它也会这样做,只是它会将键设置为stage/fronten-app/terraform.tfstate。
现在,您可以添加任意多个子模块,每个模块都带有一个带有include{…}块的TerrAgrunt.hcl,每个模块都将自动继承正确的后端配置!

【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。