Advanced Troubleshooting
Introduction
Terraform is powerful but can sometimes exhibit unexpected behavior. This chapter covers the most common problems and their solutions.
1. State problems
Stuck State Lock
Symptom:
Error: Error acquiring the state lock
Lock Info:
ID: 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Path: s3://bucket/terraform.tfstate
Operation: OperationTypeApply
Created: 2024-01-15 10:30:00
Solutions:
# 1. Vérifier si un autre process tourne
ps aux | grep terraform
# 2. Vérifier dans DynamoDB (AWS)
aws dynamodb get-item \
--table-name terraform-locks \
--key '{"LockID": {"S": "s3://bucket/terraform.tfstate"}}'
# 3. Force unlock (DANGEREUX - s'assurer qu'aucun process n'est actif)
terraform force-unlock 12345678-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# 4. Supprimer manuellement dans DynamoDB (dernier recours)
aws dynamodb delete-item \
--table-name terraform-locks \
--key '{"LockID": {"S": "s3://bucket/terraform.tfstate"}}'
Corrupted State
Symptom:
Error: Failed to load state: state snapshot was created by Terraform v1.5.0
Solutions:
# 1. Télécharger le state
aws s3 cp s3://bucket/terraform.tfstate ./terraform.tfstate.backup
# 2. Vérifier le JSON
jq '.' terraform.tfstate.backup
# 3. Récupérer une version précédente (S3 versioning)
aws s3api list-object-versions \
--bucket bucket \
--prefix terraform.tfstate
aws s3api get-object \
--bucket bucket \
--key terraform.tfstate \
--version-id "PREVIOUS_VERSION_ID" \
./terraform.tfstate.restored
# 4. Restaurer le state
terraform state push terraform.tfstate.restored
State Drift
Symptom: Resources modified manually, state out of sync
# Détecter le drift
terraform plan -detailed-exitcode
# Exit code 2 = changes detected
# Rafraîchir le state depuis l'infrastructure réelle
terraform refresh
# Ou avec apply
terraform apply -refresh-only
# Importer une ressource manquante
terraform import aws_instance.example i-1234567890abcdef0
# Supprimer une ressource du state (sans la détruire)
terraform state rm aws_instance.orphan
2. Provider problems
Incompatible version
Symptom:
Error: Unsupported Terraform Core version
This configuration does not support Terraform version 1.6.0.
Solution:
# Fixer les versions dans versions.tf
terraform {
required_version = ">= 1.5.0, < 2.0.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0" # >= 5.0.0, < 6.0.0
}
}
}
# Mettre à jour les providers
terraform init -upgrade
# Utiliser tfenv pour gérer les versions
tfenv install 1.6.0
tfenv use 1.6.0
Provider Timeout
Symptom: Error: Timeout while waiting for state...
Solutions:
# Augmenter les timeouts
resource "aws_db_instance" "main" {
# ...
timeouts {
create = "60m"
update = "60m"
delete = "60m"
}
}
# Pour EKS (particulièrement long)
resource "aws_eks_cluster" "main" {
# ...
timeouts {
create = "45m"
update = "60m"
delete = "30m"
}
}
Expired credentials
Symptom:
Error: error configuring Terraform AWS Provider:
ExpiredToken: The security token included in the request is expired
Solutions:
# 1. Rafraîchir les credentials
aws sts get-caller-identity
# 2. Avec SSO
aws sso login --profile myprofile
# 3. Avec assume role
aws sts assume-role \
--role-arn arn:aws:iam::123456789012:role/MyRole \
--role-session-name mysession
# 4. Variables d'environnement
export AWS_ACCESS_KEY_ID="..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_SESSION_TOKEN="..." # Si STS
3. Dependency problems
Dependency cycle
Symptom:
Error: Cycle: aws_security_group.a, aws_security_group.b
Solution:
# MAUVAIS - Crée un cycle
resource "aws_security_group" "a" {
ingress {
security_groups = [aws_security_group.b.id]
}
}
resource "aws_security_group" "b" {
ingress {
security_groups = [aws_security_group.a.id]
}
}
# CORRECT - Utiliser des règles séparées
resource "aws_security_group" "a" {
name = "sg-a"
}
resource "aws_security_group" "b" {
name = "sg-b"
}
resource "aws_security_group_rule" "a_from_b" {
type = "ingress"
security_group_id = aws_security_group.a.id
source_security_group_id = aws_security_group.b.id
from_port = 443
to_port = 443
protocol = "tcp"
}
resource "aws_security_group_rule" "b_from_a" {
type = "ingress"
security_group_id = aws_security_group.b.id
source_security_group_id = aws_security_group.a.id
from_port = 443
to_port = 443
protocol = "tcp"
}