Contents

Part 4: Scanning Terraform Code with Checkov

🛠️ Why Infrastructure Code Needs Scanning

We’ve secured:

  • ✅ Our libraries with Snyk (SCA)

  • ✅ Our application code with SonarQube (SAST)

But what about the Terraform code we use to provision our cloud resources?

If we accidentally expose a public IP, open all ports, or skip encryption, it can create massive security holes — before our app is even live.

That’s why we scan our infrastructure as code (IaC).

🔍 What Is Checkov?

Checkov is an open-source tool from Bridgecrew that scans Terraform (and other IaC formats) for security and compliance risks.

It checks for things like:

  • Publicly accessible resources

  • Missing encryption on storage

  • Overly permissive IAM roles

  • Open security groups or NSGs

  • Hardcoded secrets or access keys

Think of it like Snyk — but for your Terraform instead of your Java code.

⚡ Getting Started with Checkov

To test it locally:

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML bashCopyEditpip install checkov checkov -d ./terraform

That’s it. It will scan all .tf files in the ./terraform directory and give you a nice CLI report.

✅ Integrate Checkov into Azure DevOps Pipeline

Let’s add Checkov as a separate stage in your Azure Pipeline.

Step 1: Make Sure Python is Available

Use a VM image with Python pre-installed:

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML yamlCopyEditpool: vmImage: 'ubuntu-latest'

Step 2: Add the Checkov Stage to Your YAML

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML yamlCopyEdit- stage: IaCScan displayName: 'Scan Terraform with Checkov' dependsOn: SAST jobs: - job: checkov displayName: 'Run Checkov Scan' pool: vmImage: 'ubuntu-latest' steps: - checkout: self - script: | pip install checkov checkov -d terraform/ --quiet --soft-fail displayName: 'Checkov Terraform Scan'

What That Does

  • Installs Checkov

  • Scans all .tf files in the terraform/ folder

  • The –soft-fail flag means: don’t fail the pipeline yet — just report findings

Once your team is comfortable, you can remove –soft-fail to enforce blocking.

✅ What Will It Catch?

Let’s say you have a VNet with a public IP:

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML hclCopyEditresource "azurerm_public_ip" "example" { allocation_method = "Static" sku = "Standard" }

Checkov will warn you:“Public IPs should be avoided unless absolutely necessary”

Or maybe an NSG allows all traffic:

Plain textANTLR4BashCC#CSSCoffeeScriptCMakeDartDjangoDockerEJSErlangGitGoGraphQLGroovyHTMLJavaJavaScriptJSONJSXKotlinLaTeXLessLuaMakefileMarkdownMATLABMarkupObjective-CPerlPHPPowerShell.propertiesProtocol BuffersPythonRRubySass (Sass)Sass (Scss)SchemeSQLShellSwiftSVGTSXTypeScriptWebAssemblyYAMLXML hclCopyEditaccess = "Allow" destination_port_range = "*" source_address_prefix = "*"

Checkov will catch that too. It uses hundreds of built-in policies (based on CIS Benchmarks, AWS/Azure/GCP security best practices, etc.)

🔐 Why This Is Essential

Even the most secure app can be exposed if:

  • A storage account is open to the internet

  • A Function app has no authentication

  • A key vault is public

  • You hardcode secrets in Terraform

Checkov helps you catch all of that before terraform apply.

✅ Bonus: Use terraform validate too

Before scanning, you can also validate the syntax:

- script: |
    terraform init
    terraform validate
  displayName: 'Terraform Syntax Check'

This ensures your Terraform is even parseable before Checkov analyzes it.

⏭️ What’s Next?

We’ve now secured:

  • ✅ Dependencies (Snyk)

  • ✅ App code (SonarQube)

  • ✅ Infrastructure code (Checkov)

Next up?We apply that infrastructure using Terraform and deploy our app — the next stage in bringing our secure Java app to life.

👉 Continue to Part 5 – Deploying Infrastructure with Terraform in Azure Pipelines