GitLab CI/CD中Terraform分层架构Plan/Apply阶段失败求助
解决Terraform分层架构下GitLab CI的依赖部署问题
问题背景
当前采用Terraform分层架构,目录结构如下:
. ├── README.md ├── application-layer │ ├── datasources.tf │ ├── ec2.tf │ ├── providers.tf │ ├── terraform.tfvars │ └── variables.tf └── network-layer ├── gateways.tf ├── outputs.tf ├── providers.tf ├── routes.tf ├── securitygroups.tf ├── subnet.tf ├── terraform.tfvars ├── variables.tf └── vpc.tf
application-layer需要拉取network-layer的Terraform状态,才能让EC2实例引用network-layer中的安全组,因此必须先完成network-layer的部署,才能执行application-layer的plan/app操作。但当前GitLab CI配置中,network和application的plan/app任务处于同一阶段并行执行,导致application-layer的plan阶段失败。
尝试为plan-app添加needs: ["apply-network"]时,出现错误:
plan-app 任务:依赖的 apply-network 未在当前或之前的阶段中定义
错误原因
原CI配置的阶段顺序为format -> validate -> plan -> apply,其中apply-network属于apply阶段,而plan-app属于plan阶段。GitLab CI的needs规则要求:依赖的任务必须处于当前阶段或更早的阶段,但apply阶段在plan阶段之后,因此plan阶段的任务无法依赖apply阶段的任务,导致报错。
修正后的GitLab CI配置
调整阶段顺序,确保network-layer的部署完全完成后,再启动application-layer的相关任务。同时优化before_script避免重复代码:
stages: - network-format - network-validate - network-plan - network-apply - app-format - app-validate - app-plan - app-apply image: name: hashicorp/terraform:light entrypoint: - '/usr/bin/env' - 'PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin' # 全局环境变量与基础配置 before_script: - terraform --version - export AWS_ACCESS_KEY=${AWS_ACCESS_KEY_ID} - export AWS_SECRET_ACCESS_KEY=${AWS_SECRET_ACCESS_KEY} # Network Layer 任务 fmt-network: stage: network-format script: - cd network-layer - terraform init - terraform fmt allow_failure: false validate-network: stage: network-validate script: - cd network-layer - terraform init - terraform validate needs: ["fmt-network"] plan-network: stage: network-plan script: - cd network-layer - terraform init - terraform plan needs: ["validate-network"] apply-network: stage: network-apply script: - cd network-layer - terraform init - terraform apply --auto-approve needs: ["plan-network"] only: - main # 仅在主分支执行apply,可按需调整分支规则 # Application Layer 任务 fmt-app: stage: app-format script: - cd application-layer - terraform init - terraform fmt allow_failure: false needs: ["apply-network"] validate-app: stage: app-validate script: - cd application-layer - terraform init - terraform validate needs: ["fmt-app"] plan-app: stage: app-plan script: - cd application-layer - terraform init - terraform plan needs: ["validate-app"] apply-app: stage: app-apply script: - cd application-layer - terraform init - terraform apply --auto-approve needs: ["plan-app"] only: - main # 仅在主分支执行apply,可按需调整分支规则
关键说明
- 阶段顺序调整:将network和application的任务拆分为独立阶段,确保network的
apply完成后才启动application的任何任务,满足依赖关系。 needs优化:每个任务仅依赖前序必要任务,避免全阶段等待,提升Pipeline执行效率。- 全局配置简化:将重复的版本检查、环境变量配置移到全局,仅在任务内部执行目录切换和
terraform init,减少冗余代码。 - 分支安全控制:为
apply任务添加only: main,避免非主分支意外执行资源创建操作,可根据团队流程调整分支规则。
内容的提问来源于stack exchange,提问作者annonymous-robot
相关产品推荐
相关产品推荐

