Running terraform validate catches configuration errors before you plan or apply, but the error messages can be cryptic. Here's how to interpret and fix common validation errors.
Understanding Validation Errors
Terraform validate checks your configuration for syntax errors, invalid references, and schema violations. Unlike plan, it doesn't require access to cloud providers.
A typical error looks like:
``
Error: Missing required argument
on main.tf line 12, in resource "aws_instance" "example":
12: resource "aws_instance" "example" {
The argument "ami" is required, but no definition was found.
Common Cause 1: Missing Required Arguments
Resources require specific arguments to be set. When you forget one, validation fails.
Error Example:
``
Error: Missing required argument
on main.tf line 5, in resource "aws_s3_bucket" "logs":
5: resource "aws_s3_bucket" "logs" {
"bucket": one of bucket,bucket_prefix must be specified
Solution:
Check the provider documentation for required fields:
``bash
terraform providers schema -show-address | grep -A 50 "aws_s3_bucket"
Add the missing argument:
``hcl
resource "aws_s3_bucket" "logs" {
bucket = "my-application-logs-bucket" # Required
}
Or use a prefix for auto-generated names:
``hcl
resource "aws_s3_bucket" "logs" {
bucket_prefix = "app-logs-"
}
Common Cause 2: Invalid Attribute Names
Typos in attribute names or using outdated field names cause validation errors.
Error Example:
``
Error: Unsupported argument
on main.tf line 8, in resource "aws_instance" "web":
8: source_dest_check = false
An argument named "source_dest_check" is not expected here.
Did you mean "source_dest_check_enabled"?
Solution:
Terraform often suggests the correct name. Use the suggestion: ```hcl resource "aws_instance" "web" { # Wrong # source_dest_check = false
# Correct source_dest_check_enabled = false } ```
For AWS provider v4+, some attributes moved to separate resources: ```hcl # Old (now invalid in some contexts) resource "aws_s3_bucket" "example" { bucket = "my-bucket" acl = "private" # Deprecated }
# New approach resource "aws_s3_bucket" "example" { bucket = "my-bucket" }
resource "aws_s3_bucket_acl" "example" { bucket = aws_s3_bucket.example.id acl = "private" } ```
Common Cause 3: Invalid Variable References
Referencing variables that don't exist or using wrong syntax causes failures.
Error Example:
``
Error: Reference to undeclared input variable
on variables.tf line 15:
15: default = var.enviroment # Typo: should be "environment"
An input variable with the name "enviroment" has not been declared.
Solution:
Verify your variable declarations:
``bash
# List all declared variables
grep -r "variable \"" *.tf
Fix the typo: ```hcl variable "environment" { type = string default = "dev" }
resource "aws_instance" "web" { # Wrong # tags = { Name = var.enviroment }
# Correct tags = { Name = var.environment } } ```
Common Cause 4: Type Mismatch Errors
When expected types don't match provided values.
Error Example:
``
Error: Incorrect attribute value type
on main.tf line 20:
20: ingress = [80, 443]
Inappropriate value for attribute "ingress": list of number required.
Solution:
Check the expected type and fix accordingly: ```hcl # Wrong - plain numbers ingress = [80, 443]
# Correct - object structure expected by aws_security_group ingress = [ { from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] }, { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } ] ```
Common Cause 5: Invalid Resource References
Referencing resources that don't exist or using wrong attribute names.
Error Example:
``
Error: Unsupported attribute
on outputs.tf line 5:
5: value = aws_instance.web.ip_address
This object has no argument, nested block, or exported attribute named
"ip_address". Did you mean "private_ip"?
Solution:
Check available attributes for the resource:
``bash
terraform console
> aws_instance.web
Use the correct attribute: ```hcl output "instance_ip" { # Wrong # value = aws_instance.web.ip_address
# Correct value = aws_instance.web.public_ip # or for private IP # value = aws_instance.web.private_ip } ```
Common Cause 6: Cycle Detection
Circular dependencies between resources or modules.
Error Example:
``
Error: Cycle: module.vpc.aws_subnet.public,
module.vpc.aws_route_table_association.public[0]
Solution:
Break the cycle by restructuring your configuration: ```hcl # Problem: Route table depends on subnet, subnet depends on route table
# Solution: Create route table first, then subnets, then associations resource "aws_route_table" "public" { vpc_id = aws_vpc.main.id # routes defined here }
resource "aws_subnet" "public" { vpc_id = aws_vpc.main.id availability_zone = "us-east-1a" cidr_block = "10.0.1.0/24" }
resource "aws_route_table_association" "public" { subnet_id = aws_subnet.public.id route_table_id = aws_route_table.public.id } ```
Verification Steps
After fixing errors, validate again:
``bash
terraform validate
# Should show: Success! The configuration is valid.
For detailed output:
``bash
terraform validate -json | jq '.diagnostics[]'
Prevention Tips
- 1.Run validate early and often during development
- 2.Use a Terraform linter like tflint for additional checks:
- 3.```bash
- 4.tflint
- 5.
` - 6.Enable validation in your IDE with the Terraform extension
- 7.Use pre-commit hooks to validate before committing:
- 8.```yaml
- 9.# .pre-commit-config.yaml
- 10.repos:
- 11.- repo: https://github.com/antonbabenko/pre-commit-terraform
- 12.hooks:
- 13.- id: terraform_validate
- 14.
` - 15.Keep provider versions up to date to get the latest schema validations