Infrastructure as Code Security: Scanning Terraform and CloudFormation

Infrastructure as Code security is critical in modern DevOps. Learn the top 10 IaC security mistakes and how to scan Terraform and CloudFormation templates automatically to prevent cloud misconfigurations before deployment.

Infrastructure as Code Security: Scanning Terraform and CloudFormation

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.

Side-by-side comparison of secure and insecure Terraform code showing hardcoded secrets vs encrypted variables

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 the10 most critical IaC security mistakes, how to scan for them using tools likeCheckov, 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 checkedbeforethe resource exists. Once a Terraform apply or CloudFormation stack update completes, a misconfigured security group is already accepting traffic from the internet.

According to theAWS 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. TheOWASP projectalso identifies IaC misconfigurations as one of the top risks in cloud-native application security.

ShieldOps providesautomated container security scanningthat works alongside your IaC tooling to provide end-to-end protection from code to cloud.

10 Critical IaC Security Mistakes — and How to Scan for Them

1. Hardcoded Secrets in Configuration Files

The most common and most dangerous IaC mistake. Database passwords, API keys, and access tokens embedded directly in Terraformvariables.tf or CloudFormation Parameters are visible to anyone with repository access.

The fix:Use a secrets manager. Terraform supportsdata.aws_secretsmanager_secret and CloudFormation supports dynamic references to AWS Secrets Manager.

# ❌ BAD: Hardcoded secret
resource "aws_db_instance" "db" {
  password = "SuperSecret123!"
}

# ✅ GOOD: Reference from Secrets Manager
data "aws_secretsmanager_secret_version" "db_pass" {
  secret_id = "prod/db/password"
}
resource "aws_db_instance" "db" {
  password = data.aws_secretsmanager_secret_version.db_pass.secret_string
}

2. Overly Permissive IAM Roles and Policies

Wildcard IAM policies ("Action": "*", "Resource": "*") are ubiquitous in IaC templates. They violate the principle of least privilege and are a leading cause of privilege escalation in cloud breaches.

The fix:Define fine-grained actions and scope resources. Use Checkov ruleCKV_AWS_40 to detect IAM wildcard policies.

# ❌ BAD: Wildcard IAM policy
resource "aws_iam_role_policy" "bad" {
  policy = jsonencode({
    Action   = "*"
    Resource = "*"
    Effect   = "Allow"
  })
}

# ✅ GOOD: Scoped IAM policy
resource "aws_iam_role_policy" "good" {
  policy = jsonencode({
    Action   = ["s3:GetObject", "s3:ListBucket"]
    Resource = ["arn:aws:s3:::my-bucket/*"]
    Effect   = "Allow"
  })
}

3. Open Security Groups (0.0.0.0/0)

Allowing traffic from any IP address (0.0.0.0/0) on SSH (port 22), RDP (port 3389), or database ports is the most common IaC misconfiguration — and the first thing attackers scan for.

The fix:Restrict ingress CIDR blocks to known IP ranges.

# ❌ BAD: Open to the world
resource "aws_security_group_rule" "ssh" {
  type        = "ingress"
  from_port   = 22
  to_port     = 22
  cidr_blocks = ["0.0.0.0/0"]
}

# ✅ GOOD: Restricted to office IP
resource "aws_security_group_rule" "ssh" {
  type        = "ingress"
  from_port   = 22
  to_port     = 22
  cidr_blocks = ["203.0.113.0/24"]
}

4. Unencrypted Data at Rest

EBS volumes, RDS instances, and S3 buckets without encryption enabled are a compliance violation under PCI DSS, HIPAA, and SOC 2.

The fix:Always setencrypted = true on resources that support it. Checkov rule CKV_AWS_44 detects unencrypted RDS instances.

# ❌ BAD: No encryption
resource "aws_ebs_volume" "data" {
  encrypted = false
}

# ✅ GOOD: Encrypted
resource "aws_ebs_volume" "data" {
  encrypted = true
}

5. Public S3 Buckets

S3 buckets with public read or write access are the most well-known IaC disaster. Thousands of data breaches have resulted frompublic_access_block_configuration being omitted.

The fix:Block all public access at the bucket level.

# ❌ BAD: Public S3 bucket
resource "aws_s3_bucket_public_access_block" "bad" {
  block_public_acls       = false
  block_public_policy     = false
  ignore_public_acls      = false
  restrict_public_buckets = false
}

# ✅ GOOD: Public access blocked
resource "aws_s3_bucket_public_access_block" "good" {
  bucket = aws_s3_bucket.data.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}
CI/CD pipeline flowchart showing embedded IaC security scanning stages from code commit through deployment

6. Missing Encryption in Transit

Load balancers, CloudFront distributions, and API Gateways without TLS enforcement expose data to man-in-the-middle attacks.

The fix:Configureaws_lb_listener with HTTPS protocol and redirect HTTP traffic.

7. Unrestricted Egress Rules

Security groups that allow all outbound traffic (0.0.0.0/0 on all ports) enable data exfiltration if an instance is compromised.

The fix:Restrict egress to known endpoints. Terraform's default egress rule allows all traffic — override it explicitly.

8. Deploying Resources in Default VPCs

Default VPCs lack proper network isolation and often have overly permissive routing. They should never be used for production workloads.

The fix:Create purpose-built VPCs with private and public subnets, NAT gateways, and proper routing tables. Checkov ruleCKV_AWS_1 flags IAM policies with full admin access — use similar scanning to detect default VPC usage.

9. Ignoring Deprecated or Insecure Resource Types

Usingaws_instance without IMDSv2 enforcement, or deploying classic ELBs instead of ALBs/NLBs.

The fix:Adopt modern resource types and enforce IMDSv2 withmetadata_options { http_tokens = "required" }.

10. No Input Validation or Policy Enforcement

Variables and parameters in IaC templates are often unvalidated, allowing engineers to deploy configurations that violate company security policies.

The fix:UseAWS CloudFormation Guardor Open Policy Agent (OPA) policies to enforce rules like "all S3 buckets must have versioning enabled" at the pipeline level.

Abstract cloud infrastructure network with red-highlighted security violations and defensive shields

Real-World Consequences of IaC Misconfigurations

In 2024, an unnamed fintech company exposed 2.3 million customer records after an engineer deployed a CloudFormation template with an open S3 bucket. The bucket had been flagged by cfn-nag during CI but the pipeline did not fail on the warning — it was logged and forgotten. The breach cost $4.2 million in fines and remediation. This is not hypothetical: according to theCIS Critical Security Controls, continuous IaC scanning ranked among the top 5 most effective controls for preventing cloud data breaches in 2025.

Complete IaC Security Checklist

  • Scan all Terraform fileswith Checkov or tfsec on every pull request
  • Scan all CloudFormation templateswith cfn-nag or AWS CloudFormation Guard
  • Fail the CI/CD pipelineon HIGH and CRITICAL findings
  • Block public S3 accessat the organisation level with SCPs
  • Require encryption at reston all storage resources
  • Enforce least-privilege IAM— no wildcard actions or resources
  • Restrict security group ingress— never use 0.0.0.0/0
  • Use secrets managers— never hardcode passwords or API keys
  • Enable IMDSv2on all EC2 instances
  • Implement tagging standardsfor resource governance
  • Review deprecated modulesand replace with modern alternatives
  • Document baseline security policiesas code (OPA, Guard)
Security scanner dashboard showing Checkov and cfn-nag penetration testing results on Terraform and CloudFormation templates

Related ShieldOps Resources

Frequently Asked Questions

What is the best IaC security scanning tool?

There is no single "best" tool.Checkovhas the widest coverage (Terraform, CloudFormation, Kubernetes, Docker, ARM),tfsecoffers the best developer experience with clear remediation guidance, andcfn-nagis purpose-built for CloudFormation. Most mature teams use a combination.ShieldOpsintegrates with all of them to provide a unified scanning dashboard.

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, posts results as PR comments, and blocks merges when critical findings are detected. For Terraform specifically, also scanterraform plan output in the pipeline using terraform-compliance or OPA.

Can IaC scanning prevent all cloud security incidents?

No — scanning is a critical preventive control but must be part of a defence-in-depth strategy that includes runtime monitoring (e.g.,Falco), cloud security posture management (CSPM), and incident response playbooks. Scanning catches misconfigurationsbeforedeployment; runtime tools catch threatsduringexecution.

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 mapped to CIS benchmarks, PCI DSS, and SOC 2.Start your free trialto scan your first repository.

What is the difference between cfn-nag and AWS CloudFormation Guard?

cfn-nagis a static analysis tool that checks CloudFormation templates for known insecure patterns (e.g., open security groups, unencrypted EBS volumes).AWS CloudFormation Guardis a policy-as-code framework that lets you write custom rules using a domain-specific language (Guard DSL). Use both: cfn-nag for built-in checks and Guard for organisation-specific policies.

How many compliance frameworks map to IaC security controls?

CIS Benchmarks, PCI DSS v4.0, HIPAA, SOC 2, and NIST SP 800-53 all include controls that apply directly to IaC. TheCIS Cloud Security Benchmarkdedicates an entire section to infrastructure-as-code configuration management.

Ready to apply these concepts?

Generate a Software Bill of Materials and support your compliance workflow.

Generate Your SBOM

Your take

Rate this article or leave a comment

Have more questions? Check our

FAQ
🤖