Terraform and CloudFormation are two popular infrastructure as code (IaC) frameworks, and there are functional pros and cons to each. For example, Terraform is more helpful for multi-cloud and has a bigger open source community, while CloudFormation is a framework that provides first-class support for AWS services.
Both Terraform and CloudFormation are CLI tools. From a security point of view, they represent client applications that manage infrastructure programmatically on behalf of a user or a service. Therefore, they entail operational risks like:
- Risk of misconfigurations: Terraform and CloudFormation do not always protect against drift, so there’s a risk of misconfiguration. For example, you could inadvertently expose internal resources like private S3 buckets if you have incorrectly overprivileged EC2 instances. This can be identified and prevented early in the process with a tool like Checkov, as we will explore later in this article.
- Risk of invalid access controls: Who obtains the permission to apply infrastructure changes, and when? With CloudFormation, you can forward API calls made in AWS in CloudTrail using relevant service roles with specific access credentials. With Terraform, you also need to create service accounts and IAMs with the right permissions, as well as enable the log forwarding feature in the enterprise edition. You can enable debug logging locally, but it should be used sparingly and only for troubleshooting sessions.
- Risk of configuration drift: When leveraging IaC to provision infrastructure, there is a risk of changes being made out-of-band causing configuration drift. Whether changes get made directly in your cloud console by mistake or a temporary change gets canonized, drift undermines the value of IaC, rendering files that correspond with now out-of-sync resources useless.
In this extended article, we’ll take a closer look at unique security considerations between Terraform and CloudFormation.
Terraform Security Considerations
Terraform offers multi-cloud features and friendly extensibility using a CLI binary tool that reads HCL configuration files. Terraform uses this configuration to apply basic sanity tests and to create a plan for the infrastructure changes it intends to modify as well as maintain state using a local “tfstate” file that can be shared using remote state.
Using Terraform providers, third-parties such as cloud providers can extend Terraform Core to manage a broad range of resources, including IaaS, PaaS, SaaS, and hardware services. Most of the major public cloud providers are maintained by Hashicorp, and the rest are maintained by open-source contributors.
From a security point of view, security and engineering teams working with Terraform files must take several things into account, including:
- Selecting a provider: When selecting a provider, you should always choose one that is official and verified over an unknown provider that you take from a random repo. The provider plugin interfaces with real APIs and must conform to security best practices for handling sensitive information and secrets. If you choose one that doesn’t, you risk exposing secrets, provisioning the wrong components, or decreasing the availability of the service.
- Selecting relevant modules: When selecting a module, which represents a reusable piece of code, you want to perform a thorough audit of the configuration parameters and the intended behavior. Our own research showed that out of thousands of Terraform modules, nearly half of them contained misconfigurations and a lot to be desired about their compliance. Security misconfigurations can be extremely risky in certain scenarios and comprise item A05 on the OWASP Top 10 list.
- Protecting remote tfstate files: State files, such as tfstate, include the last known configuration of the actual running infrastructure resource. When using remote state files, you should treat them as secrets; therefore, you should enforce proper security controls like encryption at rest and maintain separate service accounts for authentication.
- Storing secrets within a tfstate file: It is also generally not advisable to store secrets within configuration and state files. Terraform allows you, for example, to include AWS provider credentials in your Terraform files which may accidentally be committed in a version control system. You might need to fetch secrets from a secure vault or KMS using a secrets data provider when possible. Ideally, you should keep secrets out of your Terraform files and occasionally scan your files for secrets and keys just in case. With CloudFormation, you are somewhat protected as there is only the AWS provider, but you may still have secrets in other parts of the config.
- Enforcing security policies before executing plans: Security and engineering teams need a way to enforce security checks before and after they enact their Terraform plans so that there are no unexpected events. Terraform is unique in that checks can be added for both the configuration files and the plan outputs that have a more holistic view of the entire environment.
- Configuration Defaults: Terraform Templates allow for default values. As a security best practice, you should define secure fallback values that are ideally consistent across different modules. If you provide insecure values, then it can lead to data exposures and leakages.
Now that you are familiar with the security considerations that you should take into account when using Terraform, let’s take a look at security considerations when using CloudFormation.
CloudFormation Security Considerations
CloudFormation is similar to Terraform, but it’s dedicated to AWS infrastructure automation. With CloudFormation, you write template files in JSON or YAML, along with key-values to describe AWS resources. You can save those templates locally or in an S3 bucket and instruct the tool to utilize them as blueprints to provision AWS infrastructure components.
There are several things to consider when it comes to CloudFormation security, including:
- Creating IAM service roles for CFN workloads: Prior to defining CloudFormation templates, you should create an IAM service role that is associated with your CloudFormation stack and then perform a security audit to determine if it adheres to the principle of least privilege. This role needs to be limited to the minimum permissions required to perform its task and to have no unused permissions in place.
- Enforcing stack security policies: Security administrators can include policies like a DeletionPolicy to help prevent the accidental deletion of resources or an UpdateReplacePolicy to guard against replacement/update operations. Both are very useful for protecting resources, such as databases, so it’s important that they are set correctly and early. The main benefit here compared to Terraform is that CF allows for the rollback of the infrastructure to its previous working state in case a predefined alarm is triggered.
- Logging CloudFormation events with CloudTrail and sending events with SMS: For better visibility and accountability of IaC operations, you want to capture events in CloudTrail and set up AWS SNS to trigger notifications when certain events occur (like successful or failed deployments). It is critical to safeguard against catastrophic events and make sure that all relevant teams get notified from multiple communications channels if possible.
- Understand how AWS really helps if you want to fix deployment failures: CloudFormation is tied to AWS infrastructure, and its definitions map directly to describing AWS resources. If you don’t understand how a resource or property works and behaves, you need to consult with the documentation. Sometimes you may find that it’s missing all the newest AWS features or part of the documentation, so you have to document it out yourself. Additionally, because CFN manages the state internally, you may find that recovering from a broken state is harder than Terraform, and you will have to perform manual steps. Those steps usually take more time to perform. And if you don’t have a reference guide, it’s easier to make mistakes, leading to security incidents by misconfiguration.
Terraform and CloudFormation best practices
So whether you’re reaping the benefits of Terraform’s vast open-source community or CloudFormation’s first-class support for AWS, teams should adhere to these universal IaC best practices:
- Identify misconfigurations early: The risk of misconfigurations may be heightened with the use of IaC—especially with the use of complex dependencies (whether with Terraform modules and CloudFormation substacks). The use of open-source IaC templates also increases the likelihood of misconfiguration as security is typically second to functionality. Without the right proactive security tools in place, those misconfigurations can pose a serious risk. The benefit of IaC, however, is that it makes it easier than ever to identify and actually prevent misconfigurations from making their way into your running environment. Policy-as-code tools like Checkov and Bridgecrew provide Terraform and CloudFormation scanning directly within development tools and workflows—from your IDE and terminal to your commits and CI pipelines.
- Mitigate the risk of misconfiguration: In the inevitable event of a misconfiguration, it’s important to have a proper backup plan and to minimize the potential attack surface. You want to ensure business continuity and compliance by providing consistent backups and log monitoring in place. Utilizing encryption both for data at rest and in transit improves confidentiality, and it’s relatively simple to configure using IaC. Similarly, following the principle of least privilege for your IAM permissions and roles minimizes the risk profile up to the security of the infrastructure deployed by the IaC files. Luckily, policy-as-code tools like the aforementioned can help identify these gaps and overly permissive permissions and roles. There are also framework-specific tools like IAM Policy Validator for CloudFormation and AirIAM help analyze and right-size IAM configurations.
- Avoid configuration drift: Configuration drift is possible (and often inevitable) with both Terraform and CloudFormation, and they each manage state and drift slightly differently. Regardless of how you’re detecting drift, a complete IaC security strategy should include end-to-end visibility and enforcement of policies across code and cloud. This requires not only the right tooling but the right education and support for your security and development teams. Investing in good code review tools and taking the time to learn from configuration drift and misconfigurations is key to a secure IaC strategy.
Neither Terraform nor CloudFormation is more or less secure than the other. Although they each have pros and cons when it comes to both function and security—it’s how you approach IaC security holistically that can have the biggest impact.