SecOps in IaC with Terraform — exploring Static Code analysis & Security scanner tools
HashiCorp Terraform supports various static code analysis tools which helps to detect vulnerabilities in your IaC platform. These code analysis & secops tools works in multicloud including Kubernetes yaml manifests. In this post, we’ll explore some of the reputed static code analysis & secops tools for Terraform. These tools not only helps to detect code level security policy violations but also helps integration with CI/CD pipelines like Azure DevOps, Jenkins, CircleCI, Aws Codebuild, Codedeploy, Codepipeline, TravisCI, Terraform CDK etc.
TFsec is an open-source static code analysis for Terraform written in Golang helps to identify potential security violation policies in static terraform configuration.
Installation:
Installation of tfsec is pretty simple, you can install it using “chocolatey” on Windows, “brew” on Mac.
Security Scanning of Terraform Configuration:
For this demo, I’ve used my GitHub repo “ awesome-terraform-azdata” containing the terraform configurations for Azure data analytics resources like Azure SQL db, SQL data warehouse, Azure Key vault, Azure Data factory, Azure Databricks, Stream analytics etc.
Scenario:
In this demo, I’ve executed the tfsec tool in the terraform code directory path of Azure Key vault with the following command:
tfsec .
here goes the terraform code snippet for the Azure Key vault resource main file “azkeyvault.tf” file.
#Retrieve Azure Key Vault tenant iddata "azurerm_client_config" "current" {}#Create Azure Resource Groupresource "azurerm_resource_group" "example" {name = "${var.Resource_group}"location = "${var.location}"tags = "${var.Resource_group_tags}"}#Create Azure Key Vault resourceresource "azurerm_key_vault" "example" {name = "${var.azkey_vault_name}"location = azurerm_resource_group.example.locationresource_group_name = azurerm_resource_group.example.nametenant_id = data.azurerm_client_config.current.tenant_idsoft_delete_retention_days = 7purge_protection_enabled = falsesku_name = "standard"access_policy {tenant_policy = data.azurerm_client_config.current.tenant_idobject_id = data.azurerm_client_config.current.object_idkey_permissions = ["Get"]secret_permissions = ["Get","Create"]storage_permissions = ["Get"]}}# Generate Random passwordresource "random_password" "password" {length = 16special = trueoverride_special = "_%@"}# Azure Key Vault Secret retrievalresource "azurerm_key_vault_secret" "example" {name = "${var.azurerm_key_vault_secret_name}"value = random_password.password.resultkey_vault_id = azurerm_key_vault.example.id}
on execution tfsec code scanning tool in the Terraform code of Azure Key vault, the following security vulnerabilities are detected.
- medium security issue like “azure_key_vault_secret.example” should have an expiration date set.
- critical vulnerability like “azure_key_vault.example” doesn’t specify a default network acl on default action
2. Checkov: Checkov is an open source static code analysis tool which not only works with Terraform static code, terraform plan but with Azure resource manager templates, Kubernetes yaml manifests, Aws cloudformation, Dockerfile, Serverless etc.
Installation:
Checkov can be installed with Pip3 using the simple command
pip3 install checkov
Scenario:
For running checkov, you may specify a Terraform code directory, or a static file, or even convert .tfplan to .json file & scan through checkov tool.
For the following terraform configurations of ADLS gen2 main.tf file, executed the commands to scan terraform code/plan using checkov.
provider "azurerm" {version = "~>2.0"features {}subscription_id = "var.subscription_id"client_id = "var.client_id"client_secret = "var.client_secret"tenant_id = "var.tenant_id"}resource "azurerm_resource_group" "examplerg" {name = "terraform_resources"location = "North Europe"}resource "azurerm_storage_account" "example" {name = "examplestoreani"resource_group_name = azurerm_resource_group.examplerg.namelocation = azurerm_resource_group.examplerg.locationaccount_tier = "Standard"account_replication_type = "LRS"}resource "azurerm_storage_container" "example" {name = "content"storage_account_name = azurerm_storage_account.example.namecontainer_access_type = "private"}resource "azurerm_storage_blob" "example" {name = "terraform.pdf"storage_account_name = azurerm_storage_account.example.namestorage_container_name = azurerm_storage_container.example.nametype = "Block"access_tier = "Hot"}resource "azurerm_data_lake_store" "example_store" {name = "consumptiondatalake"resource_group_name = azurerm_resource_group.examplerg.namelocation = azurerm_resource_group.examplerg.location}
3. Terrascan
Terrascan is an open source Terraform static code analysis tool which got 500+ security best practices & helps to run security vulnerability scanning of Terraform static code in Azure, Aws, GCP, Kubernetes json/yaml manifests, Helm v3, Kustomize, Dockerfiles etc.
Installation:
Terrascan can be installed as native executable on Linux (ubuntu/debian, rhel with curl github package) , using brew on Mac or simple tar extraction of Windows platform. Even a docker image for terrascan is also available.
Scenario:
in this demo, I’ve executed terrascan tool for scanning static terraform configuration file of Azure IoT hub.
First, the following “terrascan” command needs to executed post that “terrascan init” for initialization of policies & import of security policy from Github repo & “terrascan scan” command is required to be executed to start code scanning.
terrascan
terrascan init
terrascan scan
I’ve used the following “main.tf” configuration for the Azure IoT hub deployment.
resource "azurerm_resource_group" "example" {name = "${var.Resource_group}"location = "${var.location}"}resource "azurerm_storage_account" "example" {name = "${var.storage_account_name}"resource_group_name = "${var.Resource.group}"location = "${var.location}"account_tier = "Standard"account_replication_type = "LRS"}resource "azurerm_storage_container" "example" {name = "${var.storage_container_name}"storage_account_name = azurerm_storage_account.example.namecontainer_access_type = "${var.container_access_type}"}resource "azurerm_eventhub_namespace" "example" {name = "${var.azurerm_eventhub_ns_name}"resource_group_name = azurerm_resource_group.example.namelocation = azurerm_resource_group.example.locationsku = "{var.azurerm_eventhub_sku}"}resource "azurerm_eventhub" "example" {name = "{var.azurerm_eventhub_name}"resource_group_name = azurerm_resource_group.example.namepartition_count = 2message_retention = 1}resource "azurerm_eventhub_authorization_rule" "example" {resource_group_name = azurerm_resource_group.example.namenamespace_name = azurerm_eventhub_namespace.example.nameeventhub_name = azurerm_eventhub.example.namename = "${var.azurerm_eh_authorization_rulename}"send = true}resource "azurerm_iothub" "example" {name = "${var.azurerm_iothub_name}"resource_group_name = azurerm_resource_group.example.namelocation = azurerm_resource_group.locationsku {name = "S1"capacity = "1"}endpoint {batch_frequency_in_seconds = 60connection_string = azurerm_storage_account.example.primary_blob_connection_stringcontainer_name = azurerm_storage_container.example.nameencoding = "Avro"file_name_format = "{iothub}/{partition}_{YYYY}_{MM}_{DD}_{HH}_{mm}"max_chunk_size_in_bytes = 1name = "export"resource_group_name = azurerm_resource_group.example.nametype = "AzureIoTHub.StorageContainer"}endpoint {type = "AzureIotHub.EventHub"connection_string = azurerm_eventhub_authorization_rule.example.primary_blob_connection_stringname = "export2"}route {name = "export"source = "DeviceMessages"condition = "true"endpoint_names = ["export"]enabled = true}route {name = "export2"source = "DeviceMessages"condition = "true"endpoint_names = ["export2"]enabled = true}enrichment {endpoint_names = [ "tenant" ]key = "$twin.tags.Tenant"value = ["export", "export2"]}tags = {purpose = "dev"}}
On execution of terrascan scan on the IoT hub terraform code, got the following potential security violation risks with Low, Medium, High severity.
Terrascan can also be integrated with CI/CD pipelines to enforce security policies.
4. Snyk
Snyk is an open source vulnerability scanning tool which got support for Terraform on Azure, Aws, GCP, Kubernetes yaml/json manifest, dockerfile etc. Snyk also be integrated with CI/CD pipelines of CircleCI, Jenkins, Github actions etc.
Installation:
Snyk can be installed with npm packages, Windows scooop package manager, brew on Mac, on containers. The details of Snyk installation guide can be found here.
Snyk also provides a VS code vulnerability scanner, even it’s available for IntelliJ, Maven, Github, Eclipse, Azure pipelines task etc.
Scenario:
Snyk tools can tested with Snyk CLI commands like the following which can test for code quality as well as code security.
snyk auth
snyk test
snyk iac test "path of file/directory"
snyk monitor
For Terraform static code execution the following snyk commands can be executed.
terraform plan object.tfplan
terraform show --json object.tfplan > object.json
snyk iac test object.json
#Happy terraforming!