如何仅对变更后的Terraform父模块执行plan操作?
仅对变更的Terraform父模块执行Plan的实现方法
针对你描述的场景,有几种实用的实现方式,可根据项目实际情况选择:
方法一:Git Diff + Shell脚本(本地/通用场景)
利用Git的变更检测能力,结合Shell脚本自动筛选需要执行Plan的父模块目录,适合本地开发或简单CI流程。
示例脚本
#!/bin/bash # 获取变更文件列表(此处对比当前提交与上一次提交,可按需调整为对比工作区与暂存区等) CHANGED_FILES=$(git diff --name-only HEAD HEAD~1) # 定义子模块与父模块的映射关系 declare -A MODULE_PARENT_MAP=( ["module_1"]="parent_modules/parent_1" ["module_2"]="parent_modules/parent_2" ["module_3"]="parent_modules/parent_3" ) # 存储需要执行Plan的父模块目录(去重) PLAN_DIRS=() # 遍历变更文件,匹配对应的父模块 for FILE in $CHANGED_FILES; do # 处理父模块目录内的文件变更 if [[ $FILE == parent_modules/* ]]; then PARENT_DIR=$(dirname "$FILE") PLAN_DIRS+=("$PARENT_DIR") # 处理子模块文件变更,映射到对应的父模块 elif [[ $FILE == modules/* ]]; then MODULE_NAME=$(basename $(dirname "$FILE")) PARENT_DIR=${MODULE_PARENT_MAP[$MODULE_NAME]} [[ -n $PARENT_DIR ]] && PLAN_DIRS+=("$PARENT_DIR") fi done # 去重并执行Plan UNIQUE_PLAN_DIRS=($(echo "${PLAN_DIRS[@]}" | tr ' ' '\n' | sort -u | tr '\n' ' ')) for DIR in "${UNIQUE_PLAN_DIRS[@]}"; do echo "=== 执行Terraform Plan:$DIR ===" cd "$DIR" || exit 1 terraform init -upgrade=false # 按需跳过或调整init参数 terraform plan cd - > /dev/null done
说明
- 脚本自动识别两类变更:父模块目录内的文件(如
main.tf、*.auto.tfvars)、对应子模块的文件变更 - 可根据需求修改Git Diff的对比逻辑(比如
git diff --name-only对比工作区与暂存区)
方法二:Terragrunt依赖检测(适合Terragrunt管理的项目)
如果项目已使用Terragrunt,可利用其依赖追踪能力,自动检测模块变更并仅执行受影响的父模块Plan。
配置示例
在每个父模块目录下创建terragrunt.hcl,配置依赖关联:
terraform { source = "../../modules/module_3" # 关联对应的子模块路径 } # 配置子模块依赖 dependency "module_3" { config_path = "../../modules/module_3" } # 输入变量(替代原auto.tfvars的内容) inputs = { # 填入原module_3.auto.tfvars中的变量键值对 }
执行命令
terragrunt run-all plan --terragrunt-include-external-dependencies
Terragrunt会自动检测依赖的子模块是否变更,仅对受影响的父模块执行Plan。
方法三:CI/CD工具的路径触发(适合团队协作场景)
在GitHub Actions、GitLab CI等工具中,可通过文件路径过滤规则,仅当指定目录变更时触发对应父模块的Plan任务。
GitHub Actions示例
name: Terraform Plan on Change on: [push, pull_request] jobs: plan-parent-1: runs-on: ubuntu-latest # 仅当parent_1或对应的子模块有变更时触发 if: contains(github.event.paths, 'parent_modules/parent_1/') || contains(github.event.paths, 'modules/module_1/') steps: - uses: actions/checkout@v4 - uses: hashicorp/setup-terraform@v3 - name: Run Terraform Plan working-directory: ./parent_modules/parent_1 run: | terraform init terraform plan # parent_2、parent_3的配置逻辑相同,复制上述job修改路径即可
内容的提问来源于stack exchange,提问作者Andromeda
相关产品推荐
相关产品推荐

