What is Terraform IaC? Infrastructure as Code (IaC) is the DevOps practice to manage and provision infrastructure through code instead of through manual processes. With IaC, your infrastructure specifications are written in config files which makes it easier to edit and distribute. It also ensures that you provision the same environment every time. That also helps in avoiding undocumented, ad-hoc configuration changes.
Terraform from HashiCorp is the most popular Infrastructure as Code (IaC) tool in the market. The tool supports the majority of, if not all cloud providers (AWS, Azure, GCP, OCI …etc), on-prem resources and many other products from different vendors.
With terraform you define your resources in configuration files which you can then apply against your provider to provision your infrastructure.
Terraform stores the state of your infrastructure in a state file. Thas state is used by Terraform to map real world resources to your configuration, keep track of metadata, and to improve performance for large infrastructures.
Some system admins would have many documents on how to provision resources and spreadsheets to keep record of changes. With Terraform, you can keep your configuration for building various types of resources versioned in source control, reuse it and build a CI/CD around that. When applying your configuration, the state of the provisioned infrastructure is kept so any future changes are visible by comparing existing and new states.
plan: Creates an execution plan of the infrastructure to create, update or destroy based on existing infrastructure and the code. That gives visibility of what changes are going to happen to your infrastructure.
init: Initialise the environment which then downloads all external modules and providers used by your code from Terraform Registry
How to use Terraform
Terraform is a single binary you can download from Download Terraform.
Once you have your code ready, terraform workflow start by:
apply: Apply the desired changes to infrastructure resources upon review of the actions to be taken and approval.
destroy: Optional step to destroy the whole of your infrastructure defined in the code
Terraform configuration is a complete documentation of your infrastructure written in terraform language that details how to build the desired infrastructure. That configuration can be split into multiple files and directories. When terraform runs, it reads all of them and provision infrastructure in logical order, so dependencies are created before dependents.
Terraform configuration contains different elements of terraform like:
Resources are the most important element in the Terraform language. Each resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records.
Providers are the plugins Terraform relies on to interact with cloud providers, SaaS providers, and other APIs. Terraform configurations must declare which providers they require so that Terraform can install and use them. Additionally, some providers require configuration (like endpoint URLs or cloud regions) before they can be used.
Data sources: Allow Terraform to use information defined outside of Terraform, defined by another separate Terraform configuration, or modified by functions.
Modules are containers for multiple resources that are used together. A module consists of a collection of .tf and/or .tf.json files kept together in a directory. Modules also include input/output variables which can be taken from other modules or emitted to others. Modules are the main way to package and reuse resource configurations with Terraform.
Modules are collections of related resources that can be packaged and reused between multiple structures of terraform code.
For example, A module which would setup few AWS EC2 instances under an Autoscaling group running behind a Load Balancer fronted by a Route53 address. That module can then be used for as many projects need similar setup and each will only need to provide desired values for the variables while code is all in the module. Any future changes will be applied to the module and all other projects will inherit that automatically.
A module structure can look like the following code snippet where all code is defined under “module” folder while the upper level “main.tf” is just calling the module and passing the required values (e.g., instance type, ami id, security groups …etc). The module can be stored in central location (e.g., S3, git repository, Artifactory, web server …etc) and pulled at the time the module is initialised.
There are different types of variables in Terraform:
- Input Variables, which are used to provide input to terraform modules when they are used
- Output Values, which are used to return value within the module (e.g., providing security group id created earlier to new resource)
- Local Values, used for assigning short name to an expression.
In Terraform Code – Best Practices article, we explained a few best practices to help make your code readable, repeatable and easily maintainable.
Following best practices for terraform is important to start from the beginning of building the code for your infrastructure. As a project grows, code grows and needs to be maintainable and manageable.
Another important part you need to consider to get your infrastructure into best shape is to ensure compliance of your code with industry standard frameworks. oak9 provides a way to analyse the code and apply security dynamically as application’s needs evolve.
You may also consider checking your own compliance rules (e.g., certain tags applied, security groups …etc) by defining compliance rules in the scanning config.
Most cloud providers have a shared responsibility model around security (e.g., AWS Shared Responsibility Model). Cloud providers look after security of underlying infrastructure. Clients are responsible for security of their own provisioned infrastructure on the cloud.
As it’s important to follow best practices when writing Terraform code, it’s also important to security scan your code frequently for loopholes to keep your infrastructure safe and secure.
As an example, a client might provision a stack of resources for running an application but fails to setup proper security groups and firewalls to protect them from the outside world. That leaves the infrastructure very vulnerable to attacks like hacking into compute instances or getting unauthenticated access to APIs. That won’t only damage infrastructure but also damage reputation and can possibly put the company under legal liability.
Terraform is a powerful tool for managing your infrastructure. As your infrastructure grows and Terraform configurations multiply, it’s important to secure that infrastructure from development to production. Learn these best practices to get the most out of Terraform.
oak9’s Security as Code platform intelligently analyzes and remediates security and compliance design gaps as your Terraform and application context change, automatically. If you need to know where any potential security gaps are, take the free Terraform Security Test.