Enforcing Policies in Terraform Deployments with Sentinel

Introduction

Terraform is a powerful infrastructure as code (IaC) tool that allows you to define and provision infrastructure using a declarative configuration language. While Terraform provides a robust framework for managing infrastructure, it’s equally important to enforce policies to ensure compliance, security, and governance.

In this blog post, we will explore how to integrate Terraform with HashiCorp Sentinel, a policy as code framework. We’ll create a simple Terraform configuration for deploying a Google Cloud Platform (GCP) Compute Engine instance and use Sentinel to enforce a policy that checks the allowed machine types.

Prerequisites

  1. Terraform Installation:
    Ensure Terraform is installed on your machine. You can download the latest version from Terraform Downloads and follow the installation instructions for your operating system.
  2. GCP Service Account:
    Create a GCP service account and download the JSON key file. Set the path to the key file in the Terraform configuration.

Sentinel Installation

Linux

curl -o sentinel.zip -LJO https://releases.hashicorp.com/sentinel/0.20.1/sentinel_0.20.1_linux_amd64.zip
unzip sentinel.zip
sudo mv sentinel /usr/local/bin/
rm sentinel.zip

macOS

brew tap hashicorp/tap
brew install hashicorp/tap/sentinel

Windows

Download the Sentinel ZIP archive from Sentinel Releases and extract the executable (sentinel.exe) to a directory in your system’s PATH.

Terraform Configuration (main.tf)

Create a file named main.tf with the following content:

# main.tf

provider "google" {
  credentials = file("path/to/your/gcp/keyfile.json")
  project     = "your-gcp-project-id"
  region      = "us-central1"
}

resource "google_compute_instance" "example_instance" {
  name         = "example-instance"
  machine_type = "n1-standard-1"
  zone         = "us-central1-a"

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-10"
    }
  }
}

Replace "path/to/your/gcp/keyfile.json" and "your-gcp-project-id" with the actual path to your GCP service account key file and your GCP project ID.

Sentinel Policy (gcp_machine_type_policy.sentinel)

Create a Sentinel policy file named gcp_machine_type_policy.sentinel:

# gcp_machine_type_policy.sentinel

import "tfplan"

allowed_machine_types = [
  "n1-standard-1",
  "n1-standard-2",
  "n1-standard-4",
]

main = rule {
  all tfplan.resources as _, instances {
    all instances as _, r {
      r.attr("provider") == "google" and r.attr("type") == "google_compute_instance" and r.attr("values")["machine_type"] not in allowed_machine_types
    }
  }
}

This policy checks that the machine type specified in the Terraform plan is within the allowed list.

Apply the Configuration with Sentinel

Run the following commands to apply the Terraform configuration with Sentinel policy enforcement:

# Initialize Terraform
terraform init

# Create a Terraform plan
terraform plan -out=terraform.tfplan

# Apply the Sentinel policy during the Terraform apply
sentinel apply -context=. -config=gcp_machine_type_policy.sentinel -input=terraform.tfplan

The sentinel apply command checks the Terraform plan against the specified policy before applying the changes. If the policy is violated, the apply process will be blocked.

Conclusion

Integrating Terraform with Sentinel provides a powerful mechanism for enforcing policies and ensuring compliance within your infrastructure deployments. This example demonstrates a basic policy, and you can extend and customize Sentinel policies based on your specific requirements.

For more information on Terraform and Sentinel, refer to the official documentation:

Happy Terraforming!