With the growing complexity of infrastructure deployments, security vulnerabilities can unavoidably creep into your Terraform configurations. In this blog post, we will explore how tfsec
can help us identify and address security issues in Terraform code through a practical example.
What is tfsec?
Tfsec is an open-source static analysis tool developed specifically for Terraform. Its main objective is to scan your Terraform code and identify potential security risks and misconfigurations in your codebase. By running tfsec
against your Terraform files, you can proactively detect vulnerabilities, ensuring that your infrastructure is built on a solid foundation of security best practices.
Example Scenario: Creating an AWS S3 Bucket
Let's consider a simple example of creating an AWS S3 bucket using Terraform. Below is the Terraform configuration for our S3 bucket:
provider "aws" {
region = "us-west-2"
}
resource "aws_s3_bucket" "example_bucket" {
bucket = "example-bucket"
acl = "private"
tags = {
Name = "Example Bucket"
Environment = "Production"
}
}
In this example, we are creating an S3 bucket named example-bucket
in the us-west-2
AWS region. The bucket is set to private access, additionally, we've added some tags to the bucket.
Running tfsec
Before running tfsec, ensure you have Terraform and tfsec installed on your machine. Once everything is set up, open your terminal and navigate to the directory containing the Terraform configuration.
Now, run the following command to analyze the Terraform file with tfsec:
tfsec example_bucket.tf
Tfsec will analyze the configuration and provide a report on potential security issues. In our example, tfsec would give us an output similar to the following:
WARNING: S3 bucket has an ACL defined which allows public read access.
File: example_bucket.tf:6
WARNING: S3 bucket has no server-side encryption defined.
File: example_bucket.tf:6
Interpreting the tfsec Results
From the tfsec output, we can see that it has identified two security issues in our Terraform configuration:
Public Read Access: The S3 bucket is configured with an "acl" attribute set to "private," but tfsec is warning us that the configuration still allows public read access.
Lack of Server-Side Encryption: The S3 bucket does not have server-side encryption (SSE) enabled, which poses a potential security risk for sensitive data stored in the bucket.
Addressing the findings
Now that we have identified the issues, let's take steps to address them:
- Resolving Public Read Access:
To restrict public access, we need to update the S3 bucket's configuration to deny public read access explicitly. We can achieve this by adding a "block_public_acls" attribute to the resource block.
Please note that the AWS Terraform Provider version used for the examples below is not the latest. Syntax varies in the latest version, especially, for the S3 resources.
The updated Terraform configuration will look like this:
resource "aws_s3_bucket" "example_bucket" {
bucket = "example-bucket"
acl = "private"
block_public_acls = true
tags = {
Name = "Example Bucket"
Environment = "Production"
}
}
- Implementing Server-Side Encryption:
To enable server-side encryption, we can set the "server_side_encryption_configuration" attribute within the "aws_s3_bucket" resource block. The updated Terraform configuration will look like this:
resource "aws_s3_bucket" "example_bucket" {
bucket = "example-bucket"
acl = "private"
block_public_acls = true
server_side_encryption_configuration {
rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}
tags = {
Name = "Example Bucket"
Environment = "Production"
}
}
Just a reminder again that the AWS Terraform Provider version used for the example above is not the latest. Please refer to the provider documentation for the latest updates.
With these changes, we have addressed the security issues identified by tfsec in our Terraform configuration.
Tfsec with Pre-commit Hooks and CI
Integrating tfsec into pre-commit hooks and Continuous Integration (CI) pipelines ensures that security checks are performed automatically at different stages of the development process. Let's go through the steps to integrate tfsec in both scenarios.
Integrating tfsec in Pre-Commit Hooks:
Pre-commit hooks are scripts that run before each commit is made in your version control system. By adding tfsec as a pre-commit hook, you can prevent developers from committing Terraform code that violates security best practices.
Step 1: Install tfsec and Pre-commit
Ensure that tfsec and pre-commit are installed on your local machine. You can install pre-commit using a package manager like pip (for Python projects) or your OS's package manager.
Step 2: Create the Pre-commit Configuration File
In your Terraform project's root directory, create a file named .pre-commit-config.yaml
. This file will define the pre-commit hooks and the tools to use for validation.
repos:
- repo: https://github.com/liamg/tfsec
rev: <tfsec_version> # Replace <tfsec_version> with the desired version or use "master" for the latest.
hooks:
- id: tfsec
name: tfsec
stages: [commit]
types: [terraform]
Step 3: Install Pre-commit Hooks
After creating the .pre-commit-config.yaml
file, run the following command to install the pre-commit hooks:
pre-commit install
Now, every time you attempt to make a commit, pre-commit will automatically execute tfsec on your Terraform files, preventing commits with security issues.
- Integrating tfsec in Continuous Integration (CI) Pipelines:
Incorporating tfsec into your CI pipeline allows you to perform security checks on your Terraform code whenever changes are pushed to the repository. We'll use an example with GitLab CI, but the steps can be adapted for other CI/CD systems.
Step 1: Create .gitlab-ci.yml
In your project's root directory, create a .gitlab-ci.yml
file if it doesn't already exist. This file defines the pipeline stages and jobs to be executed in CI.
stages:
- test
tfsec_scan:
stage: test
image: liamg/tfsec:latest # Use the tfsec Docker image
script:
- tfsec # Run tfsec against Terraform files
Step 2: Push and Trigger CI Pipeline
Commit and push the .gitlab-ci.yml
file to your GitLab repository. This will trigger the CI pipeline, and tfsec will be executed to scan your Terraform code for security issues.
You can adapt this example to other CI/CD systems like Jenkins, Travis CI, CircleCI, or GitHub Actions by configuring the CI pipeline to run tfsec using their specific syntax.
Now, every time you attempt to make a commit, pre-commit will automatically execute tfsec on your Terraform files, preventing commits with security issues.
Wrapping Up
Tfsec is an invaluable tool for enhancing the security of your Terraform infrastructure. In our example, we saw how using a simple tool we were able to successfully to detect public read access and the absence of server-side encryption in our S3 bucket configuration before they became significant risks, allowing us to take appropriate corrective measures.
By integrating tfsec in both pre-commit hooks and CI pipelines, you ensure that Terraform code is continuously checked for security issues throughout the development process. Pre-commit hooks prevent insecure code from being committed, while CI pipelines catch security problems early, before changes are merged into the main branch.
By adopting these practices, you can enhance the security of your Terraform infrastructure and prevent security vulnerabilities from slipping into your production environments. Happy Terraforming!
If you liked what you read, do consider sharing the article with a friend and connect with me on Twitter - @afraz_momin. Also, subscribe to my newsletter and stay up-to-date with my latest blog posts.