# Azure IaC Testing: Terraform Compliance

# What is Terraform Compliance

Terraform Compliance is an Open Source security tool used to enforce compliance controls on IaC, specifically Terraform. It is written in easy-to-read language and stored in files that act as policies.

# How does it work

The tool runs against your Terraform Plan, evaluating against the policies you create. During the run, it identifies violations and outputs the results for remediation. Organisations can put these policies in a central location and have all IaC conform to best practices and standards.

# When should you run Terraform Compliance

There are two stages of a Software Delivery Life Cycle (SDLC) this tool can be introduced. As far left as you can go, I recommend using pre-commit to trigger on push of commits. [Follow my article on pre-commit](https://jamescook.dev/pre-commit-for-terraform) for how to implement, but once configured, you can add the following to the pre-commit config file:

```yaml
repos:
  - repo: https://github.com/terraform-compliance/cli
    rev: v2.4.0  # Use the latest version or specify a specific version
    hooks:
      - id: terraform-compliance
        args: ["--planfile", ".terraform-compliance/terraform.tfplan", "--features", "examples/features/", "--path", "path/to/your/terraform/files"]
        name: terraform-compliance
        stages: [commit]
        types: [terraform]
```

Replace the arguments with what relates to your environment and files. For example, the path would be where you are storing these compliance files.

The second stage to run this is during the CI when a PR is raised. This prevents code from merging that does not adhere to your policies. Update the pipelines you have to install Terraform Compliance and then execute the CLI against the Terraform Plan file.

# Installing Terraform Compliance Locally

For the Pre-Commit to work locally, or if you want to run the CLI manually, you need to install Terraform Compliance.

There are two options to install locally; first is PIP:

```bash
pip install terraform-compliance
```

Or if you have docker installed, you can pull the image:

```bash
docker pull eerkunt/terraform-compliance
```

# Example Policies

## Key Vault example

```yaml
Feature: Azure Key Vault - General

    related resources: azurerm_key_vault

    Scenario: Ensure Key Vault is located in UK South
            Given I have azurerm_key_vault defined
            Then it must have location
            And its value must be uksouth
    
    Scenario: Ensure Key Vault soft delete is set to 7 days
            Given I have azurerm_key_vault defined
            Then it must have soft_delete_retention_days
            And its value must be 7

    Scenario: Ensure Key Vault is Purge Protected
            Given I have azurerm_key_vault defined
            Then it must have purge_protection_enabled
            And its value must be true

    Scenario: Ensure Key Vault is RBAC enabled
            Given I have azurerm_key_vault defined
            Then it must have enable_rbac_authorization
            And its value must be true
```

## App Service Plan example

```yaml
Feature: Azure Service Plan - General

    related resources: azurerm_service_plan

    Scenario: Ensure Service Plan is located in UK South
            Given I have azurerm_service_plan defined
            Then it must have location
            And its value must be uksouth

    Scenario: Ensure Service Plan is set to WS1 SKU
            Given I have azurerm_service_plan defined
            Then it must have sku_name
            And its value must be WS1
```

## Storage Account example

```yaml
Feature: Azure Storage Account - General

    related resources: azurerm_storage_account

    Scenario: Ensure Storage Account is located in UK South
            Given I have azurerm_storage_account defined
            Then it must have location
            And its value must be uksouth
            
    Scenario: Ensure Storage Account is encrypted with TLS 1.2
            Given I have azurerm_storage_account defined
            Then it must have min_tls_version
            And its value must be tls1_2

    Scenario: Ensure that 'Secure transfer required' is set to 'Enabled'
            Given I have azurerm_storage_account defined
            Then it must have enable_https_traffic_only
            And its value must be true
```

%%[buymeacoffe-butyellow]
