Hardening Terraform CI/CD — Building a Reliable Terraform Code

Calvine Otieno
6 min readJan 19, 2023

--

In my previous article I talked about improving your CI/CD pipeline for Helm Charts by doing security scanning with Trivy and GitHub Actions. In this article, I will taking a step further to about implementing some DevSecOps for Infrastructure as Code — Terraform.

With growing automation and CI/CD tools in the market popularity of Terraform, building a secure infrastructure has become a concern. With Terraform, performing static code analysis helps to build reliable code.

Static analysis is the ability to scan software code to search and highlight deviations from specified standards. Static analysis is one of the DevSecOps implementations.

DevSecOps

DevSecOps stands for development, security, and operations. It’s an approach to culture, automation, and platform design that integrates security as a shared responsibility throughout the entire IT lifecycle.

In general git workflow, once code is merged/committed to a repository, failures/defects/bugs are identified during stages like building the code, integration testing, unit testing, deployments and many others. Some of the defects or bugs are identified after product release. The cost of fixing defects increases as the code moves further away — towards the right. Identifying these defects as early as possible is the best way both for the business and for the developers.

Integrating some checks during the application development to ensure and prevent buggy code from being pushed to production can be achieved by for example using a pull-request-based workflow. You associated a pull-request policy with a code build and unit testing check to ensure the incoming changes do not break the build and cause the unit tests to fail. Static Analysis is a practical approach to identifying such code. A static analysis tool searches for anomalies in the code and determines the level of deviation to highlight depending on the static-analysis policies selected or configured for your infrastructure. The goal of static code analysis is to search for patterns that do not conform to the set standard of your infrastructure that can turn into defects later so that they can be addressed as early as possible.

In this article, we will go through how we can perform automated static analysis for Terraform code using Checkcov and GitHub Actions.

Static Analysis with Checkcov and GitHub Actions

What is Checkcov?

Per Bridgeview, Checkov is a static code analysis tool for scanning infrastructure as code (IaC) files for misconfigurations that may lead to security or compliance problems. Checkov includes more than 750 predefined policies to check for common misconfiguration issues.

Security becomes a more important part of the entire lifecycle of development and is also important from the start.

You can use Snyk to scan your application or IaC for vulnerabilities. GitHub’s dependabot is also a good one for scanning dependencies in your repositories. You can also use Checkcov to scan your infrastructure for code misconfigurations. All these tools, among many others, can be integrated into your CI/CD pipeline to help achieve a high level of security and shift the security left in your lifecycle. Shifting security to the right means that security is put into consideration from the start, from project design, CI/CD, build etc to ensure that security best practices are observed before the product is released.

Prerequisites

You need to have some basic knowledge of working with Terraform and GitHub Actions.

  • Terraform installed in your local machine
  • Checkcov is installed on your local machine.
  • A public GitHub Repository
  • And of course a code editor of your choice.

Analyze Terraform Directory

For this to work, you need to have some terraform files to analyze. For the purpose of this demo, I have created a repo. This repo will be used for scanning going forward.

To scan, you can run:

checkov -d <terraform root directory> - compact

In our case, this is the terraform folder:

checkcov scan

By default, the scan uses the default compliance policy set. You can find these here for Terraform. Checkcov gives you the ability to write your own custom policies. The most recommended way to write them is YAML. We will not be focusing on writing custom policies in this demo.

When you run checkcov with default settings, it will exit with error code 1 on failure. This will stop your workflow/pipeline. To avoid this you can use the -soft-fail switch. This will enable checkcov to list any misconfiguration, but will not stop your workflow. You can learn more about CLI switches here.

Analyse Terraform plan

Checkcov can also analyze a Terraform plan. The plan must be saved as json. I prefer this as a point of proof for any misconfiguration that maybe was not captured before the plan step.

terraform plan -out tfplan
terraform show -json tfplan > tfplan.json
checkov -f tfplan.json
Analyse Terraform plan

Please note that it’s only good to use this in a secure CI/CD pipeline as Checkcov recommends due to secrets.

Run in a Container

You can run checkcov from a container. It’s the best and most probably the recommended way one would run this in a production setting. The best part of it is you get the environment each time, and you don't need to bother installing all the dependencies in your workflow/pipeline.

docker run --tty --volume \
/path_to_your_awesome_project/:/tf \
--workdir /tf bridgecrew/checkov --directory /tf
Checkcov run in a docker

Run in Pre-Commit Stage

Checkcov is a plugin you can use with pre-commit hooks. You can use it in your pre-commit config file like this.

pre-commit hook for checkcov

Run in CI/CD workflow

One good thing with pre-commit hooks is to enforce adherence on the developer's computer, but pre-commit hooks can be silenced locally by a simple flag hence it’s good to run this in your workflow/pipeline to force adherence to company policy. You can’t turn this off in the repository where security measures are configured.

In addition to running checkcov in containers and via command as we did above, we can have a GitHub Workflow and soft fail for the pre-commit hook.

Checkcov run in GitHub Workflow

You can check the whole file here

With the increased use of infrastructure as code, it’s good to do a pre-check of your code with checkcov to add some security to the early stages of your IaC lifecycle. This can prevent misconfiguration, and make sure developers/contributors adhere to set standards and policies. Doing this help catch security risks in your code much earlier in the lifecycle and prevent any chance of them going into the live infrastructure.

This is all for now. I hope you have learnt something and enjoyed reading the article. Till next time.

Here is the repo for this article. Follow me on GitHub for more about DevOps and DevSecOps and GitOps.

Thanks for reading. Let’s connect on Twitter and LinkedIn 😁.

--

--