Skip to main content
Terraform Basics
CHAPTER 15

Terraform Security Best Practices

Updated: May 15, 2026
25 min read

# CHAPTER 15

Terraform Security Best Practices

1. Introduction

Infrastructure as Code (IaC) is incredibly powerful, but that power is a double-edged sword. If you write code to provision a highly secure data center, Terraform builds a secure data center. If you write code with a typo that exposes your database to the public internet, Terraform will execute that vulnerability with terrifying speed and mathematical precision. In this chapter, we will shift from functional provisioning to DevSecOps, focusing on secret management, state file vulnerabilities, and implementing automated security scanners directly into our CI/CD pipelines.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Identify the security risks inherent in the terraform.tfstate file.
  • Understand the danger of hardcoded secrets in HCL files.
  • Implement static code analysis (SAST) tools like Checkov or tfsec.
  • Utilize the sensitive = true parameter for variable masking.
  • Adopt the Principle of Least Privilege for CI/CD runners.

3. Beginner-Friendly Explanation

Imagine a master blueprint for a bank.
  • The Vulnerability: The blueprint shows exactly where the vault is, exactly where the security cameras have blind spots, and literally writes the vault combination in the margins.
  • State Security: You don't leave this blueprint sitting on a park bench (local state). You lock it in a secure, encrypted vault of its own (Remote S3 Backend).
  • Secret Management: You erase the vault combination from the margins (hardcoded secrets). Instead, the blueprint says: "Ask the bank manager for the code on opening day" (Dynamic Secrets / AWS Secrets Manager).
  • Security Scanning: Before you build the bank, you hire a security expert (Checkov) to review the blueprint. They say, "You forgot to put a lock on the back door. I am rejecting this blueprint."

4. The Vulnerability of Terraform State

As discussed in Chapter 5, Terraform records *everything* in plain text JSON within the terraform.tfstate file. If your HCL code creates a database password, that password is saved in plain text in the state file. Defenses:
  1. 1. Never commit .tfstate to Git. Add it to .gitignore immediately.
  1. 2. Encrypt Remote State: Your AWS S3 bucket must have Server-Side Encryption (SSE-S3 or KMS) enabled.
  1. 3. Restrict Access: Use strict AWS IAM policies so only the CI/CD pipeline and lead DevOps engineers can read the S3 bucket. Junior developers do not need access to the state file.

5. Handling Secrets in HCL

You must create a database. How do you pass the password to Terraform?

The Wrong Way (Hardcoded):

hcl
123
resource "aws_db_instance" "default" {
  password = "SuperSecretPassword123" # DO NOT DO THIS
}

The Better Way (Sensitive Variables): Pass the password securely from GitHub Secrets during the CI/CD run.

hcl
12345678
variable "db_password" {
  type      = string
  sensitive = true # Prevents Terraform from echoing the password to the terminal logs
}

resource "aws_db_instance" "default" {
  password = var.db_password
}

6. Mini Project: Automated Security Scanning (Checkov)

The absolute best time to catch a security flaw is *before* it is deployed. We can integrate a Static Application Security Testing (SAST) tool like Checkov into our CI/CD pipeline. Checkov reads your .tf files and checks them against hundreds of cloud security best practices.

Step-by-Step CI/CD Integration Concept:

yaml
1234567891011121314151617
name: Terraform Security Scan
on: [pull_request]

jobs:
  scan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      # We run Checkov BEFORE we even run terraform plan!
      - name: Run Checkov Security Scan
        uses: bridgecrewio/checkov-action@master
        with:
          directory: ./terraform-code/
          framework: terraform
          # If Checkov finds a violation, it throws an exit code of 1, 
          # instantly failing the workflow and blocking the PR!

*If a developer submits code that creates an S3 bucket without encryption, Checkov will catch it, fail the pipeline, and print a link to the exact line of code that caused the violation.*

7. Real-World Scenarios

A developer was tasked with setting up a temporary test server. They wrote a Terraform configuration that assigned a Security Group allowing SSH access (Port 22) from 0.0.0.0/0 (the entire internet). They submitted the Pull Request. Without automated scanning, a busy reviewer might have missed this single line of code and merged it. However, the company had integrated tfsec into their GitHub Actions pipeline. The pipeline instantly failed, stating: "CRITICAL: Security Group rule allows unrestricted SSH access." The developer was forced to fix the code to only allow their specific corporate IP address before the merge button was unlocked, preventing a massive security breach.

8. Best Practices

  • Least Privilege for Runners: The IAM Role assigned to your Jenkins or GitHub Actions runner (which executes terraform apply) is incredibly powerful. Do not give it AdministratorAccess. If an attacker hacks your GitHub account, they own your entire AWS organization. Restrict the runner's IAM policy so it can only create specific resources (e.g., EC2, S3, RDS) and deny it the ability to manipulate core IAM permissions unless absolutely necessary.

9. Security Recommendations

  • Dynamic Secrets (Vault): For maximum security, integrate Terraform with HashiCorp Vault or AWS Secrets Manager. Instead of passing passwords as variables, Terraform queries Vault via a data block, retrieves a temporary, dynamically generated password that expires in 1 hour, creates the database, and then the password vanishes. This is the ultimate Zero-Trust architecture.

10. Troubleshooting Tips

  • False Positives in Checkov: Sometimes a security scanner flags something you are doing intentionally (e.g., intentionally creating a public S3 bucket for website hosting). You can suppress specific Checkov warnings by adding a comment directly above the resource block: # checkov:skip=CKVAWS20: Intentionally public for static website.

11. Exercises

  1. 1. Explain why the sensitive = true argument in a variable block is not sufficient to protect a password from someone who has access to the remote S3 state backend.
  1. 2. What is the operational purpose of running a SAST tool like Checkov during the Pull Request phase?

12. FAQs

Q: Does Checkov scan the live cloud environment to see if it's secure? A: No. Checkov is a *static* analyzer. It only reads your local .tf text files. It does not need AWS credentials, and it does not talk to the cloud APIs. This makes it incredibly fast and safe to run on every commit.

13. Interview Questions

  • Q: A developer needs to provision a database requiring a master password. Detail the most secure architectural flow for providing this password to Terraform without exposing it in version control or CI/CD logs.
  • Q: Describe the security vulnerabilities inherent in the terraform.tfstate file. Outline a comprehensive strategy for mitigating these risks in an enterprise environment.

14. Summary

In Chapter 15, we confronted the immense responsibilities of defining infrastructure as code. We identified the terraform.tfstate file as a highly sensitive asset requiring encrypted, tightly controlled remote storage. We established strict protocols for handling sensitive inputs, utilizing the sensitive variable flag to sanitize our deployment logs. Most importantly, we shifted security to the left by integrating automated SAST tools like Checkov into our CI/CD pipelines, transforming our automation engine into a rigorous, proactive security enforcer that blocks vulnerabilities before they are ever provisioned.

15. Next Chapter Recommendation

Even with perfect code and security scans, things go wrong. A cloud provider might have an outage, or a dependency might fail. How do we figure out why Terraform crashed? Proceed to Chapter 16: Monitoring and Troubleshooting Terraform.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·