A single terraform apply can provision an entire data centre — and a single misconfigured resource can expose that data centre to the internet. In 2025, 68% of cloud security incidents traced back to misconfigured Infrastructure as Code (IaC) templates that were deployed without security review. If your Terraform or CloudFormation code isn't scanned before deployment, you're not shipping infrastructure — you're shipping risk.
Infrastructure as Code has transformed how teams provision cloud resources. Instead of clicking through web consoles, engineers define their entire infrastructure in version-controlled configuration files. But this shift also means that every security mistake is automated, repeatable, and scalable — a single open security group in a Terraform module deploys that vulnerability to every environment.
This article covers the 10 most critical IaC security mistakes, how to scan for them using tools like Checkov, tfsec, cfn-nag, and AWS CloudFormation Guard, and a practical checklist you can integrate into your CI/CD pipeline today.
Why IaC Security Matters
Traditional infrastructure security relied on manual reviews and post-deployment audits. IaC changes this paradigm entirely: security must be checked before the resource exists. Once a Terraform apply or CloudFormation stack update completes, a misconfigured security group is already accepting traffic from the internet.
According to the AWS Well-Architected Framework, IaC security scanning should be embedded as a quality gate in the CI/CD pipeline — failing the build when critical misconfigurations are detected.
10 Critical IaC Security Mistakes
1. Hardcoded Secrets in Configuration Files
The most common and most dangerous IaC mistake. Database passwords, API keys, and access tokens embedded directly in Terraform or CloudFormation files are visible to anyone with repository access.
The fix: Use a secrets manager. Terraform supports data.aws_secretsmanager_secret and CloudFormation supports dynamic references to AWS Secrets Manager.
2. Overly Permissive IAM Roles and Policies
Wildcard IAM policies (Action: "*", Resource: "*") violate the principle of least privilege and are a leading cause of privilege escalation in cloud breaches.
3. Open Security Groups (0.0.0.0/0)
Allowing traffic from any IP address on SSH (port 22), RDP (port 3389), or database ports is the most common IaC misconfiguration.
4. Unencrypted Data at Rest
EBS volumes, RDS instances, and S3 buckets without encryption violate PCI DSS, HIPAA, and SOC 2.
5. Public S3 Buckets
S3 buckets with public read or write access cause thousands of data breaches.
6-10: More Critical Mistakes
Missing encryption in transit, unrestricted egress rules, deploying in default VPCs, ignoring deprecated resource types, and no policy enforcement.
Complete IaC Security Checklist
- Scan all Terraform files with Checkov or tfsec on every PR
- Scan all CloudFormation templates with cfn-nag or AWS Guard
- Fail the CI/CD pipeline on HIGH and CRITICAL findings
- Block public S3 access at the organisation level
- Require encryption at rest on all storage resources
- Enforce least-privilege IAM — no wildcard actions
- Restrict security group ingress — never use 0.0.0.0/0
- Use secrets managers — never hardcode passwords
- Enable IMDSv2 on all EC2 instances
Frequently Asked Questions
What is the best IaC security scanning tool?
There is no single best tool. Checkov has the widest coverage, tfsec offers the best developer experience, and cfn-nag is purpose-built for CloudFormation.
How do I integrate IaC scanning into CI/CD?
Most tools provide GitHub Actions, GitLab CI, and Jenkins plugins. A typical setup runs Checkov on every PR push and blocks merges on critical findings.
Does ShieldOps support Terraform and CloudFormation scanning?
Yes — ShieldOps provides unified IaC security scanning that checks Terraform, CloudFormation, and Kubernetes manifests against 1,000+ built-in policies.
👉 Read the full article on ShieldOps: https://shieldops-ai.dev/blog/infrastructure-as-code-security-scanning-terraform-and-cloudformation
Originally published on ShieldOps Blog.











