# Terraform Plan Failed in CI
Introduction
This article covers troubleshooting steps and solutions for Terraform Plan Failed in CI. The error typically occurs in production environments and can cause service disruptions if not addressed promptly.
Symptoms
Common error messages include:
Error: Error refreshing state: state lock errorError: Failed to get existing workspaces: AccessDeniedError: Provider produced inconsistent result after applyCommon Causes
- Configuration misconfiguration
- Missing or incorrect credentials
- Network connectivity issues
- Version compatibility problems
- Resource exhaustion or limits
- Permission or access denied
Step-by-Step Fix
Common Error Patterns
Terraform plan failures typically show:
Error: Error refreshing state: state lock errorError: Failed to get existing workspaces: AccessDeniedError: Provider produced inconsistent result after applyError: required_providers block must be specifiedError: Error running plan: 1 error(s) occurredRoot Causes and Solutions
1. State Lock Conflict
State is locked by another Terraform operation.
Solution:
Check for lock:
terraform force-unlock LOCK_IDFor S3 backend with DynamoDB lock table:
```bash # Check DynamoDB lock aws dynamodb scan --table-name terraform-locks
# Delete lock manually (use with caution) aws dynamodb delete-item \ --table-name terraform-locks \ --key '{"LockID":{"S":"terraform-state-lock"}}' ```
In CI, use retry mechanism:
# GitHub Actions with retry
- name: Terraform Plan
uses: nick-fields/retry@v2
with:
timeout_minutes: 10
max_attempts: 3
command: terraform plan -out=tfplan2. Backend Authentication Failure
Cannot access state backend storage.
Solution:
For S3 backend:
```yaml # GitHub Actions - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 with: role-to-assume: arn:aws:iam::123456789012:role/terraform-role aws-region: us-east-1
- name: Terraform Init
- run: terraform init
`
For Terraform Cloud:
- name: Terraform Init
env:
TF_TOKEN_app_terraform_io: ${{ secrets.TFC_TOKEN }}
run: terraform initFor GCS backend:
```yaml - name: Authenticate to Google Cloud uses: google-github-actions/auth@v2 with: credentials_json: ${{ secrets.GCP_CREDENTIALS }}
- name: Terraform Init
- run: terraform init
`
3. Provider Configuration Errors
Provider not properly configured.
Solution:
Use required_providers block:
```hcl terraform { required_version = ">= 1.0"
required_providers { aws = { source = "hashicorp/aws" version = "~> 5.0" } google = { source = "hashicorp/google" version = "~> 4.0" } } }
provider "aws" { region = var.aws_region } ```
For multiple provider configurations:
```hcl provider "aws" { alias = "east" region = "us-east-1" }
provider "aws" { alias = "west" region = "us-west-2" }
resource "aws_s3_bucket" "east_bucket" { provider = aws.east bucket = "east-bucket" } ```
4. Missing Variables
Required variables not provided.
Solution:
Pass variables via CLI:
terraform plan \
-var="aws_region=us-east-1" \
-var="environment=production" \
-var-file="production.tfvars"Or use environment variables:
export TF_VAR_aws_region="us-east-1"
export TF_VAR_environment="production"
terraform planIn CI:
- name: Terraform Plan
env:
TF_VAR_aws_region: us-east-1
TF_VAR_environment: production
run: |
terraform plan \
-var-file="environments/${{ github.ref_name }}.tfvars" \
-out=tfplan5. Invalid Configuration Syntax
HCL syntax errors in configuration.
Solution:
Validate configuration:
terraform fmt -check
terraform validateIn CI pipeline:
```yaml - name: Terraform Format Check run: terraform fmt -check -recursive
- name: Terraform Validate
- run: terraform validate
`
Use terraform-validator:
- name: Check Terraform
uses: tf-actions/tf-validate@v1
with:
path: terraform/6. State Drift
Actual infrastructure differs from Terraform state.
Solution:
Refresh state before plan:
terraform refresh
terraform planOr use -refresh-only:
terraform plan -refresh-onlyDetect drift:
# Show state vs actual
terraform plan -detailed-exitcode
# Exit code:
# 0 = no changes
# 1 = error
# 2 = changes presentImport existing resources:
terraform import aws_s3_bucket.mybucket mybucket-name7. Module Download Failures
Cannot download modules from registry.
Solution:
Use module caching:
terraform init -get=false
terraform init -plugin-dir=/pluginsFor private modules:
module "private_module" {
source = "app.terraform.io/organization/module/aws"
version = "1.0.0"
}Configure Terraform Cloud token:
- name: Terraform Init
env:
TF_TOKEN_app_terraform_io: ${{ secrets.TFC_TOKEN }}
run: terraform init8. Workspace/Environment Issues
Wrong workspace selected.
Solution:
Create and select workspace:
terraform workspace new production
terraform workspace select production
terraform planIn CI:
- name: Terraform Workspace
run: |
terraform workspace select ${{ github.ref_name }} || \
terraform workspace new ${{ github.ref_name }}Use workspace-specific state:
terraform {
backend "s3" {
bucket = "terraform-state"
key = "terraform.tfstate"
dynamodb_table = "terraform-locks"
region = "us-east-1"
workspace_key_prefix = "environments"
}
}CI Pipeline Configuration
GitHub Actions Full Workflow
```yaml name: Terraform
on: push: branches: [main] pull_request: branches: [main]
jobs: terraform: runs-on: ubuntu-latest permissions: id-token: write contents: read steps: - name: Checkout uses: actions/checkout@v4
- name: Setup Terraform
- uses: hashicorp/setup-terraform@v3
- with:
- terraform_version: 1.5.0
- name: Configure AWS credentials
- uses: aws-actions/configure-aws-credentials@v4
- with:
- role-to-assume: arn:aws:iam::123456789012:role/terraform-role
- aws-region: us-east-1
- name: Terraform Format
- run: terraform fmt -check
- name: Terraform Init
- run: terraform init
- name: Terraform Validate
- run: terraform validate
- name: Terraform Plan
- run: terraform plan -out=tfplan
- name: Terraform Apply
- if: github.ref == 'refs/heads/main' && github.event_name == 'push'
- run: terraform apply -auto-approve tfplan
`
GitLab CI Configuration
```yaml stages: - validate - plan - apply
variables: TF_IN_AUTOMATION: "true" TF_ROOT: "terraform"
validate: stage: validate image: hashicorp/terraform:1.5 script: - terraform fmt -check - terraform init - terraform validate
plan: stage: plan image: hashicorp/terraform:1.5 script: - terraform init - terraform plan -out=tfplan artifacts: paths: - tfplan
apply: stage: apply image: hashicorp/terraform:1.5 script: - terraform init - terraform apply -auto-approve tfplan rules: - if: $CI_COMMIT_BRANCH == "main" dependencies: - plan ```
Debugging Commands
```bash # Verbose plan output terraform plan -out=tfplan -verbose
# Show plan details terraform show tfplan
# Debug mode TF_LOG=DEBUG terraform plan
# Trace mode TF_LOG=TRACE terraform plan 2>&1 | tee terraform-debug.log
# Check state terraform state list terraform state show aws_s3_bucket.main
# State manipulation terraform state mv aws_s3_bucket.old aws_s3_bucket.new terraform state rm aws_s3_bucket.unmanaged ```
Verification
| Error | Solution |
|---|---|
| State lock | terraform force-unlock |
| Auth failed | Configure provider credentials |
| Missing vars | Pass -var or TF_VAR_* |
| Syntax error | Run terraform fmt and validate |
| Module fail | Use token for private modules |
| Drift | Run terraform refresh |
Prevention
- 1.Use
terraform fmtandvalidatein CI - 2.Configure proper state locking
- 3.Use OIDC authentication for cloud providers
- 4.Run plan on every PR before apply
- 5.Store plan artifacts for audit
- 6.Use sentinel/policy-as-code for governance
Related Articles
- [AWS CloudFormation Stack Failed](#)
- [Kubernetes Deployment Failed in CI](#)
- [AWS IAM Permission Denied](#)
Related Articles
- [Technical troubleshooting: Fix Cicd Artifact Upload Failed Storage Issue in C](cicd-artifact-upload-failed-storage)
- [Technical troubleshooting: Fix Cicd Code Quality Gate Failed Sonarqube Issue ](cicd-code-quality-gate-failed-sonarqube)
- [Technical troubleshooting: Fix Cicd Deployment Failed Health Check Issue in C](cicd-deployment-failed-health-check)
- [Technical troubleshooting: Fix Cicd Github Actions Workflow Queue Timeout in ](cicd-github-actions-workflow-queue-timeout)
- [Technical troubleshooting: Fix Cicd Gitlab Runner Stuck Pending Issue in CI/C](cicd-gitlab-runner-stuck-pending)
<script type="application/ld+json"> { "@context": "https://schema.org", "@type": "TechArticle", "headline": "Terraform Plan Failed in CI", "description": "Resolve Terraform plan failures in CI. Covers state management, authentication, provider configuration, and validation errors.", "url": "https://www.fixwikihub.com/fix-cicd-terraform-plan-failed", "publisher": { "@type": "Organization", "name": "FixWikiHub", "url": "https://www.fixwikihub.com" }, "author": { "@type": "Person", "name": "FixWikiHub Editorial Team" }, "datePublished": "2025-11-20T09:52:15.346Z", "dateModified": "2025-11-20T09:52:15.346Z" } </script>