Uncover hidden risks

Watch how the Wiz platform can expose unseen risks in your cloud environment without drowning your team in alerts.

Terraform Security Best Practices

Common security risks associated with Terraform and the 6 essential best practices for terraform security.

9 min read

Terraform is a key player in cloud infrastructure, simplifying the way developers set up and manage their cloud resources. This open-source tool is crucial in modern cloud-focused development settings because it acts as a bridge between complex cloud-service APIs and the user-friendly configurations developers prefer.

Terraform's ability to manage infrastructure as code (IaC) means that every aspect of the cloud environment is defined in code, which both facilitates automation and repeatability and also introduces a layer where security can be embedded directly into the infrastructure-provisioning process. Features such as environment variables, security group rules, and the use of Terraform modules contribute significantly to the secure, customizable nature of IaC.

This blog post explores Terraform security best practices by outlining potential risks and suggesting strategies to safeguard your infrastructure. Let’s dive in.

Understanding Terraform security

Infrastructure as code allows teams to manage their infrastructure through code-based definitions, which are versioned, reusable, and testable. Though this approach significantly improves the speed and reliability of infrastructure provisioning, it also introduces a new vector for security risks. Since infrastructure configuration is codified, inadequate security practices can lead to vulnerabilities embedded into your cloud environment's very foundation. That’s why implementing security best practices into your Terraform workflows is essential for maintaining a robust security posture in your cloud.

Common security risks associated with Terraform

Several security risks are inherent to managing infrastructure as code, and Terraform is no exception. Key areas of concern include

  • Sensitive data exposure: Terraform plans and state files can contain sensitive information. If not properly secured, this data can be exposed to unauthorized parties, potentially leading to security breaches.

  • Inadequate management of secrets: Hard coding secrets or inadequately managing them within Terraform scripts can lead to unauthorized access and compromise of sensitive systems.

  • Cloud misconfigurations and non-compliance: This category encompasses a range of issues, including improperly configured security groups, public-facing Kubernetes clusters with default settings, unencrypted storage buckets, and databases using default passwords. These misconfigurations and deviations from security policies can significantly increase the vulnerability of your infrastructure.

  • Infrastructure drift: Without proper state management, Terraform can lead to infrastructure drift, where the actual state of the cloud environment diverges from the intended state defined in the code, potentially opening up security gaps.

  • Supply chain vulnerabilities in modules and providers: Utilizing open-source Terraform modules and providers from unverified sources can introduce risks. These components could potentially contain malicious code or exhibit unwanted behaviors, which underscores the importance of thoroughly reviewing and securing the supply chain.

  • Elevated permission risks: When executed locally or via a runner, Terraform often requires high privileges to manage cloud resources effectively. If the runner or the local machine is compromised, attackers could potentially gain administrative access to cloud environments, leading to significant security breaches.

Luckily, you can address these risks with Terraform security best practices, which we will explore in the following section.

Terraform security best practices

Securing your Terraform-managed infrastructure involves multiple layers of protection, each vital to strengthening your security posture:

  1. Secure state management

  2. Least privilege access

  3. Secrets management

  4. IaC Scanning

  5. Compliance as code

  6. Encryption of sensitive data

Secure state management

Terraform state files are a blueprint of your cloud infrastructure, containing all the necessary information about the resources Terraform manages. These files can include sensitive data, making them a target for unauthorized access. Securing these files is essential to protecting your infrastructure. To protect yourself

  • Encrypt state files using backend configurations: One of the first steps in securing your Terraform state is to use backend configurations that support encryption. For instance, configuring Terraform to use an S3 backend with server-side encryption ensures that your state files are encrypted at rest, significantly reducing the risk of data exposure.

  • Restrict access to state files: Limit access to the Terraform state files strictly to the Terraform runner, adhering to the principle of least privilege. Additionally, restrict access to the storage bucket (such as an S3 bucket) by using IP whitelisting or security groups to ensure only authorized entities can access these sensitive files.

  • Avoid sensitive data in state files: While Terraform automatically detects and obfuscates certain sensitive data, it's best practice to avoid including plain-text sensitive information in your configurations. Use environment variables or integrate with a secrets management tool whenever possible.

  • Regularly back up state files: Implementing a robust backup and recovery strategy for your Terraform state files is crucial. Regular backups ensure you can recover from data loss or corruption incidents, while a well-defined recovery process minimizes downtime in such events.

The following code snippet demonstrates how to set up an S3 backend for Terraform with encryption enabled, keeping your state files securely stored:

terraform {
  backend "s3" {
    bucket         = "my-terraform-state"
    key            = "global/s3/terraform.tfstate"
    region         = "us-east-1"
    encrypt        = true
    dynamodb_table = "my-lock-table"
  }
}

Least privilege access

The principle of least privilege is a security concept that dictates that a user, program, or process should have only the minimum privileges necessary to perform its task. Applying this principle to Terraform helps minimize the potential impact of a security breach by restricting access to what is strictly necessary. Here are some key tips:

  • Implement role-based access control (RBAC): Role-based access control (RBAC) is a method of restricting system access to authorized users. In the context of Terraform, implementing RBAC involves defining roles with specific permissions and assigning these roles to users or automated processes that interact with your Terraform configurations.

  • Use Terraform workspaces for environment segregation: Terraform workspaces enable the use of distinct state files for various environments—like development, staging, or production—under a single configuration. Separation ensures that actions in one environment do not accidentally impact another, upholding the principle of least privilege and limiting the blast radius in the case of a misconfiguration.

  • Limit resource permissions in Terraform modules: When defining Terraform modules, explicitly specify the minimum necessary permissions for the resources within those modules. This best practice helps prevent over-provisioning permissions, reducing the risk of unauthorized access or actions.

The following code snippet creates an IAM role with limited permissions, demonstrating how to implement the principle of least privilege in Terraform through RBAC:

resource "aws_iam_role" "example_role" {
  name = "example_role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      },
    ]
  })
}

Secrets management

Managing secrets—such as API keys, passwords, and certificates—within Terraform poses significant challenges. While it’s a common practice, hard coding secrets into Terraform configurations or state files is risky because it exposes sensitive information to anyone accessing these files. The key to effective secrets management in Terraform is ensuring that secrets are securely stored, accessed, and managed throughout the life cycle of your infrastructure. To make the most of secrets management

  • Avoid hard-coded secrets: Never hard-code sensitive information in your Terraform configurations. Instead, inject secrets at runtime using environment variables, input variables, or secrets management tools.

  • Integrate Terraform with secrets management tools: Integrating Terraform with a secrets management tool like Vault can significantly enhance your security posture. Vault provides a secure place to store and manage strict access to tokens, passwords, certificates, API keys, and other secrets. By integrating Terraform with Vault, you can dynamically generate secrets, reducing the risks associated with static, long-lived secrets.

The following example demonstrates how to retrieve a secret from Vault and use it in a Terraform configuration, ensuring the secret remains secure and hidden within both the configuration and state file:

data "vault_generic_secret" "example" {
  path = "secret/data/my_secrets"
}

resource "aws_db_instance" "example" {
  engine               = "mysql"
  username             = "user"
  password             = data.vault_generic_secret.example.data["password"]
 ...
}

Infrastructure as code (IaC) scanning

IaC scanning involves automatically reviewing your Terraform configurations for potential security issues, misconfigurations, and compliance violations. Comprehensive scanning is a crucial means of identifying and mitigating security risks early in development, well before the infrastructure is deployed. Here are some actionable steps:

  • Use tools for scanning Terraform code: Several security scanner tools, including Checkov and Terrascan, are available to scan Terraform code. These tools analyze Terraform configurations against predefined rules to identify potential security issues and best-practice violations.

  • Set up automated scanning in CI/CD pipelines: Integrating IaC scanning into your CI/CD pipelines ensures that every change to your Terraform configurations is automatically checked for potential issues. This setup allows you to catch and fix security issues early, significantly reducing the risk of deploying vulnerable infrastructure.

Figure 1: Terrascan output (Source: GitHub)

Compliance as code

Compliance as code means codifying security policies and standards to enforce compliance across your infrastructure automatically. Leveraging compliance as code allows you to integrate compliance checks into your development and deployment processes, giving you peace of mind that your Terraform-managed infrastructure adheres to required security policies and regulations. It’s best practice to

  • Use tools for enforcing compliance: HashiCorp's Sentinel and Open Policy Agent (OPA) are two prominent tools that enable compliance as code. Integrated with Terraform Cloud and Terraform Enterprise, Sentinel allows you to define policy as code, enforcing rules that your Terraform configurations must adhere to before deployment. OPA, a more general policy engine, can be used with Terraform and other tools to enforce policies across your cloud environments.

  • Regularly update policies to reflect changing regulations: Security policies and regulations are not static—they change over time. Regularly reviewing and updating your compliance policies keeps your infrastructure compliant with the latest security standards and regulations. The first step is staying informed about changes in the regulatory landscape; then you can adjust your policies accordingly.

The following Sentinel policy ensures that all AWS S3 buckets defined in Terraform configurations have encryption enabled, demonstrating how compliance policies can be codified and automatically enforced:

import "tfplan"

main = rule {
  all tfplan.resources.aws_s3_bucket as _, buckets {
    all buckets as _, bucket {
      bucket.applied.encryption.enabled is true
    }
  }
}

Encryption of sensitive data

Encrypting sensitive data within your Terraform configurations protects that data from unauthorized access. Encryption is critical when dealing with secrets, credentials, and any data that, if exposed, could compromise the security of your infrastructure. Remember to

  • Use data encryption methods: Key management services (KMS) and Pretty Good Privacy (PGP) are two methods commonly used for encrypting sensitive data in Terraform configurations. Key management services provided by cloud providers, such as AWS KMS, Azure Key Vault, or Google Cloud KMS, allow you to encrypt data using managed keys. PGP, on the other hand, offers a way to encrypt data using a public key, ensuring that only the holder of the corresponding private key can decrypt it.

  • Manage encryption keys securely: Managing encryption keys securely is just as crucial as the act of encrypting data itself. Store keys securely, tightly control access to them, and put key rotation policies in place to mitigate the risk of key compromise.

However, it's important to note that encrypting data using methods like AWS KMS still involves some risks. Encrypted data, such as the plaintext parameter in the aws_kms_ciphertext resource, can appear in logs and will be stored in the Terraform state file. This visibility potentially exposes sensitive data. For complete protection of sensitive information in state files, it’s a good idea to use Terraform Cloud or Enterprise, which provide enhanced state file encryption and management features. Below is an example of encrypting a block of sensitive data using AWS KMS, though it is critical to understand its limitations:

resource "aws_kms_ciphertext" "example" {
  key_id = aws_kms_key.example.id
  plaintext = "SensitiveData"
}

Embrace advanced security and efficiency with Terraform and Wiz

As we’ve seen, securing Terraform-managed cloud infrastructure can be complex. However, integrating advanced tools like Wiz with Terraform opens new avenues for enhancing security and operational efficiency.

Wiz's announcement of GitOps workflows and our new Terraform provider marks a significant advancement in policy management. This integration enables customers to manage policies as code, streamlining the enforcement of security policies throughout infrastructure managed by Terraform. By leveraging Wiz's capabilities within Terraform workflows, teams can achieve holistic cloud governance, keeping their infrastructure compliant with security policies and also optimizing for performance and cost. With security baked right into the infrastructure management process, you don’t have to worry about the risk of deploying vulnerable or non-compliant resources. 

Want to explore the possibilities of enhanced policy management with GitOps and Terraform and discover how Wiz can transform your Terraform run tasks? Schedule a demo with Wiz today!

Continue reading

Credential Stuffing Explained

Wiz Experts Team

Credential stuffing is a type of cyberattack where automated tools are used to repeatedly inject stolen username/password combinations into various services to gain access to legitimate users’ accounts in addition to those that were originally breached.

Container Orchestration

Container orchestration involves organizing groups of containers that make up an application, managing their deployment, scaling, networking, and their availability to ensure they're running optimally.

Native Azure Security Tools

Wiz Experts Team

This blog explores the significance of security in Azure environments and provides an overview of native as well as third-party security tools available to improve an organization’s Azure security stance.