Fix Terraform Error: CloudWatch Log Group Already Exists
Fix terraform CloudWatch Log Group ResourceAlreadyExistsException. Import orphaned log groups, prevent Lambda auto-creation
DevOps
Fix 'inconsistent plan' errors where Terraform shows changes on every plan even after applying. Handle perpetual diffs, API normalization, and computed values.
terraform plan shows changes every time even though you just applied. This is a perpetual diff — usually caused by the cloud API normalizing values (JSON reordering, default values) or computed attributes that change server-side. Fix with jsonencode(), ignore_changes, or provider upgrade.
# You just ran terraform apply, but terraform plan shows:
~ resource "aws_iam_role" "main" {
~ assume_role_policy = jsonencode(
~ {
~ Statement = [
~ {
# Whitespace/ordering differences
}
]
}
)
}AWS returns JSON with different key ordering or whitespace than what you sent.
The API adds fields you didn't specify, and Terraform sees them as changes.
Values like arn, last_modified, or version change server-side.
The provider doesn't properly handle read-back normalization.
# ❌ Raw JSON — key order may differ from API response
resource "aws_iam_role" "main" {
assume_role_policy = <<-EOF
{
"Version": "2012-10-17",
"Statement": [{"Effect": "Allow", ...}]
}
EOF
}
# ✅ jsonencode — canonical ordering
resource "aws_iam_role" "main" {
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Effect = "Allow"
Action = "sts:AssumeRole"
Principal = { Service = "ec2.amazonaws.com" }
}]
})
}data "aws_iam_policy_document" "assume_role" {
statement {
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role" "main" {
assume_role_policy = data.aws_iam_policy_document.assume_role.json
}resource "aws_security_group" "web" {
name = "web-sg"
lifecycle {
ignore_changes = [
ingress, # API may reorder rules
tags_all, # Provider auto-adds default tags
]
}
}terraform init -upgrade
terraform plan # Check if the perpetual diff is fixed| Resource | Field | Cause | Fix |
|---|---|---|---|
aws_iam_role | assume_role_policy | JSON reorder | jsonencode() or aws_iam_policy_document |
aws_security_group | ingress/egress | Rule reorder | ignore_changes or separate aws_security_group_rule |
aws_lambda_function | last_modified | Computed | ignore_changes |
aws_s3_bucket | Various | Provider v4 migration | Upgrade to v5+ |
azurerm_* | tags | Default tags | ignore_changes = [tags] |
jsonencode() or data sourceignore_changesPerpetual diffs are annoying but fixable. Use jsonencode() for IAM policies, aws_iam_policy_document data sources, ignore_changes for computed fields, and keep providers updated. Read the plan output carefully to identify which field is cycling.
Fix terraform CloudWatch Log Group ResourceAlreadyExistsException. Import orphaned log groups, prevent Lambda auto-creation
Fix terraform import errors when a resource already exists in state. Covers state rm, state show, reimport workflow, import blocks
Fix terraform too many command line arguments errors. Correct -var syntax, quote values with spaces, and learn proper Terraform CLI argument format for plan
Fix terraform invalid escape sequence errors. Double backslashes for Windows paths, use heredocs for regex, and learn all valid HCL escape sequences.