Infrastructure as code (IaC) is designed to provision cloud resources entirely through code and automation. IaC frameworks such as Terraform and CloudFormation make infrastructure management more repeatable, dependable, and scalable.
As we covered in our recent blog post, Terraform 101: Best practices for secure infrastructure as code, Terraform is one of the most popular frameworks that enables all the benefits of IaC, including security. In this post, weâre continuing our Terraform security journey to look at some advanced tips for using Terraform to reduce security and compliance errors, streamline deployments, and harden security.
Scan Terraform HCL as early as possible
Similar to how SAST and DAST tools inspect the different components of your application for known vulnerabilities in your software or in its dependencies, you can scan for misconfigurations in code. To check for issues, or misconfigurations, you simply scan Terraform code against policies that determine whether the infrastructure is considered secure and compliant. These policies help maintain security, comply with regulations, and enforce operational best practices. They can range from simple things, like ensuring an S3 bucket is encrypted, to more advanced checks, like enforcing multi-factor authentication for all users. Weâll explore how to write your own policies later on.
Bridgecrewâs Terraform policies range from simple public exposure of resources to more complex, graph-based policies. Here are some of our more popular policies:
- Use Read-Only filesystem for containers where possible
- Ensure AWS EC2 instances with public IP and associated with security groups do not have Internet access
- Ensure AWS Load Balancer is using TLS 1.2
- Ensure AWS access logging is enabled on S3 buckets
- Ensure Azure Storage Account default network access is set to Deny
Equally as important as the policies involved in scanning are the points in time that you run scans. Any scanning and policy enforcement is better than none, but to take your Terraform security to the next level, you should address security as early in the DevOps lifecycle as possibleâand make it as customized to your specific environment and needs.
Scan in pull/merge requests, CI/CD, and runtime
One place you can benefit from automated scans is in the pull/merge request stage. Every time you push a change to an infrastructure-as-code file, a tool like Bridgerew will automatically scan it and report failures as a GitHub comment. The comment will contain full details about the failure, such as policy name, severity, and a link to additional remediation options in the platform.
For example, letâs say you were to add an S3 bucket to a Terraform template. Bridgecrew can spot a misconfiguration and its severity, in this case, whether or not the S3 bucket has logging enabled. It will then provide comments where your code is to help you make the appropriate fixes.
In CI/CD, you can actually block builds that donât match your stated policies. For example, if your misconfiguration shows up as critical severity, you can automatically prevent it from being deployed or added to your repository.
Scanning in early development stages is especially important because itâs easier to make changes due to the complexities that are introduced in subsequent development stages. A developer given feedback in early stages will still have the code fresh in their minds, and so they are more likely to understand where and how to make changes.
One place to start is to implement security scanning in your integrated development environment (IDE), such as VS Code or IntelliJ. By utilizing our VS Code extension, you can place guardrails directly where developers are coding, improving the quality of code while saving time and resources spent identifying, detecting, and resolving issues further downstream. For example, if you were to scan an EC2, you might find flagged misconfigurations around data stored in an S3 bucket that must be securely encrypted at rest. The scan here would tell you where in the code to add encryption.
Another easy way to get fast, local feedback is running scans straight from your command line. Regardless of where youâre getting early feedback, being able to address issues before your Terraform code is integrated into a shared repository is crucial. That said, because of Terraformâs modular and dependency-driven nature, you canât always find all relevant misconfigurations with just the code.
Your IDE is one place to provide individual feedback, but itâs also important to scan Terraform HCL consistently within shared repositories. Whether thatâs in your VCS or build pipeline is up to you and your tools. A few IaC security tools including Bridgecrew have more advanced native integrations with VCSâ that allow you to configure how scan results appearâeither as checks or commentsâand even fix issues directly in pull requests. Bridgecrew also allows you to configure checks to block merging or just to be informational. For less severe misconfigurations, you can configure code comments to provide insight in the context of the code to implement the necessary fixes.
Pair GitOps with continuous integration and continuous deployment (CI/CD)
To up-level your Terraform security, adopting GitOps is key. This might seem like an obvious first step but itâs important to note that GitOps encompasses more than simply incorporating a version control system (VCS).
Simply put, GitOps is an operating model that applies version control, collaboration tools, and CI/CD used in application development to infrastructure automation. In the GitOps model, the open-source version control system Git is the single source of truth, making all changes visible and verifiable. GitOps and infrastructure as code go hand-in-hand. Although originally coined to describe Kubernetes orchestration, leveraging Terraform is, by default, leveraging GitOps.