terraformiaccloud-security

Terraform Security Mistakes That Get Companies Breached

YoCyber Team · June 28, 2026 · 3 min read
Share:

Infrastructure-as-code gets sold as a security win — and it can be, because it makes infrastructure reviewable and repeatable. But it cuts both ways: a bad security pattern in a Terraform module doesn't just create one insecure resource, it creates every insecure resource that module gets used for, forever, until someone catches it. Here are the patterns that keep showing up when that goes wrong.

1. 0.0.0.0/0 in a security group, "just for now"

This is the single most common finding in real cloud security audits, and it almost always starts as a temporary debugging convenience that nobody removed.

# Don't do this
ingress {
  from_port   = 22
  to_port     = 22
  protocol    = "tcp"
  cidr_blocks = ["0.0.0.0/0"]  # "I'll fix this later"
}

"Later" doesn't happen, because the resource works fine from the developer's point of view — it's a monitoring/scanning problem, not a "my code doesn't run" problem, so it never surfaces in normal testing. Scope ingress rules to actual known ranges (your VPN CIDR, a bastion host, a specific peer VPC) and treat any 0.0.0.0/0 ingress rule as something that requires explicit sign-off, enforced by policy, not convention.

2. State files with secrets in them, stored insecurely

Terraform state files contain the full resource attributes — including, frequently, plaintext secrets: database passwords generated by a random_password resource, API keys passed as variables, connection strings. If that state file lives in an S3 bucket without encryption and strict access controls, or worse, gets committed to git "temporarily," every secret Terraform has ever touched is exposed.

Use a remote backend with encryption at rest and tightly scoped IAM access, and never, ever commit terraform.tfstate to version control — add it to .gitignore on day one of every project, not after the first incident.

3. Overly broad IAM policies because scoping them is annoying

Action: "*" and Resource: "*" show up constantly in Terraform-managed IAM policies, because writing a correctly scoped policy takes real thought and a wildcard always "just works." The problem is that a wildcard policy attached to, say, a CI/CD role means anything that compromises that role — a leaked token, a supply-chain compromise in a dependency — now has full account access instead of the narrow set of permissions the job actually needed.

# Don't do this
resource "aws_iam_policy" "ci_deploy" {
  policy = jsonencode({
    Statement = [{
      Effect   = "Allow"
      Action   = "*"
      Resource = "*"
    }]
  })
}

Scope every policy to the specific actions and resources the role needs. Yes, this means more Terraform code and more iteration when something breaks because a permission was missing. That friction is the point — it's cheaper than the alternative.

4. No policy-as-code gate before apply

Code review catches what a human reviewer happens to notice. It does not reliably catch "this subnet is now publicly routable" in a 200-line diff. Tools like OPA, Checkov, or tfsec run automated policy checks against your Terraform plan before apply — catching public S3 buckets, unencrypted volumes, and overly permissive security groups as a hard CI failure, not a hopeful code-review comment.

5. Treating modules as trusted without reading them

Public Terraform Registry modules are convenient, but pulling in a community module means running whatever that module's author decided to provision — including default security groups, default IAM policies, and default settings you never explicitly reviewed. Pin module versions, and actually read what a module provisions before using it in anything that touches production, especially around networking and IAM.

The common thread

None of these are exotic. They're all "convenient default that nobody circled back to fix" — which is exactly why policy-as-code gates matter more than good intentions. If you want to build a real CI pipeline with these gates enforced automatically, that's covered hands-on in our CI/CD pipeline security hardening guide and in depth in our DevSecOps Masterclass.

Share:

Discussion