如何通过Terragrunt实现不同环境之间的状态共享
Terragrunt多环境配置及GitLab CI变量同步实现方案
1. 跨环境共用Remote State Bucket配置
要实现根账户通用S3 bucket作为所有环境的remote_state存储,无需在子环境强制全量覆盖配置,按以下规则配置即可:
- 在根目录terragrunt.hcl中定义全局remote_state规则,使用动态参数自动区分不同环境的state存储路径:
remote_state { backend = "s3" config = { bucket = "替换为你的根账户通用tfstate bucket名称" region = "替换为bucket所在区域" key = "${path_relative_to_include()}/terraform.tfstate" dynamodb_table = "替换为你的state锁表名称" encrypt = true } generate = { path = "backend.tf" if_exists = "overwrite" } }
- 上述配置中
key参数通过path_relative_to_include()自动匹配子环境的目录层级生成唯一state路径,无需子环境单独配置。如果确实需要为个别环境覆盖特定backend参数,仅需在子环境terragrunt.hcl中重新定义remote_state.config下的对应字段即可,Terragrunt会自动合并全局与子环境的配置。
2. ECR等资源输出同步到GitLab CI/CD变量
你可以通过Terraform的GitLab provider直接读取各环境的state输出,批量创建CI变量,无需手动配置:
- 第一步:在你的通用业务module中定义需要导出的输出变量,示例如下:
output "ecr_repository_url" { type = string description = "业务应用ECR仓库访问地址" value = aws_ecr_repository.app.repository_url }
- 第二步:新增独立的Terraform配置(可以单独放在
gitlab-ci-vars目录下配置对应的terragrunt.hcl),通过terraform_remote_state数据源读取各环境state输出,批量创建GitLab CI变量:
# 读取staging环境state输出 data "terraform_remote_state" "staging" { backend = "s3" config = { bucket = "替换为你的通用tfstate bucket名称" key = "staging/terraform.tfstate" region = "替换为bucket所在区域" } } # 读取production环境state输出 data "terraform_remote_state" "production" { backend = "s3" config = { bucket = "替换为你的通用tfstate bucket名称" key = "production/terraform.tfstate" region = "替换为bucket所在区域" } } # 配置GitLab provider provider "gitlab" { token = var.gitlab_admin_token # 建议通过环境变量GITLAB_TOKEN传入,禁止硬编码提交到代码库 } # 创建staging环境对应CI变量 resource "gitlab_project_variable" "staging_ecr_url" { project = "替换为你的GitLab项目ID/路径" key = "STAGING_ECR_REPO_URL" value = data.terraform_remote_state.staging.outputs.ecr_repository_url protected = true masked = true environment_scope = "staging/*" } # 创建production环境对应CI变量 resource "gitlab_project_variable" "prod_ecr_url" { project = "替换为你的GitLab项目ID/路径" key = "PROD_ECR_REPO_URL" value = data.terraform_remote_state.production.outputs.ecr_repository_url protected = true masked = true environment_scope = "production/*" }
注意:执行该配置的身份需要提前开通S3 state bucket的读权限,以及GitLab项目的管理员权限,GitLab令牌建议通过环境变量或云厂商密钥管理服务注入。
内容的提问来源于stack exchange,提问作者jasiek
相关产品推荐
相关产品推荐

