Managing Your Infrastructure With Terraform Modules

A How to Guide from 66degrees

Managing your cloud infrastructure can be a tedious task. Though Infrastructure as Code (IaC) tools help streamline its management, an IaC repository can quickly become convoluted. This is especially true when working with multiple applications that each have multiple environments with a need for their own infrastructure. Terraform is an open-source IaC tool dev-ops teams can employ with Google Cloud to deploy and manage infrastructure. This quick how-to will showcase a strategy that can be utilized with Terraform.

Gif image of Google logo for Terraform article written by Google partner, 66degrees.

Picture this:

You have two distinct applications, each with four different environments (Dev, QA, Staging, Production) where each environment is deployed to its dedicated infrastructure. The “definition” of this infrastructure (i.e. the IaC) is contained within an “IaC code” repository and consists of ten plus modules and one hundred-plus files, each configuring a distinct set of resource(s). The “implementation” (i.e. assigning names to infrastructure components and the actual deployment) for this infrastructure exists in each application’s repository for each of its required environments. Separating the definition from the implementation allows us to treat the “IaC code” repository as a module containing submodules. If the IaC was not modularized each environment would require copying/pasting at least one hundred files.

This scenario presents an opportunity to showcase the benefit of modularizing your Terraform code. We can package cloud resources into a module reducing the amount of code required to create multiple instances of the resource in question. Let us isolate one such resource using the multiple application, multiple environment example above. Below, you will find code to create a Cloud Armor policy that has been packaged into a module. Then this module is called to create multiple Cloud Armor policies in different projects/environments.

Managing Infrastructure with Terraform

Directory Structure

				
					|root
|-modules
|--cloud-armor
|---cloudarmor-implement.tf
|---variables.tf
|infrastructure
|-cloudarmor-setup.tf

				
			
Module Implementation Files

variables.tf

				
					variable "project_id" {
  type        = string
  description = "The project ID"
  
}

variable "policy_name" {
  type        = string
  description = "The cloud-armor policy name"
  default     = "cloud-armor-policy"
}
				
			

cloudarmor-implement.tf​

				
					resource "google_compute_security_policy" "cloud_armor_policy" {
  project     = var.project_id
  name        = var.policy_name
  description = "WAF Policy"


  rule {
    action   = "deny(403)"
    priority = "1000"
    preview  = true
    match {
      expr {
        expression = <<EOT
        evaluatePreconfiguredExpr('sqli-stable')
        EOT
      }
    }
    description = "SQL injection protection"
  }

  rule {
    action   = "deny(403)"
    priority = "1001"
    preview  = true
    match {
      expr {
        expression = <<EOT
        evaluatePreconfiguredExpr('xss-stable')
        EOT
      }
    }
    description = "XSS protection"
  }

  rule {
    action   = "allow"
    priority = "2147483647"
    match {
      versioned_expr = "SRC_IPS_V1"
      config {
        src_ip_ranges = ["*"]
      }
    }
    description = "default rule"
  }

}
				
			

Resource Setup

cloudarmor-setup.tf

				
					module "project1-cloudarmor-policy" {
  source     = "root/modules/cloud-armor"
  project_id = "projectID#1"
  policy_name = "project1-cloudarmor-policy-name"
}

module "project2-cloudarmor-policy-name" {
  source     = "root/modules/cloud-armor"
  project_id = "projectID#2"
  policy_name = "project2-cloudarmor-policy-name"
}
				
			

Redundant code adds an unnecessary and avoidable layer of complexity when it comes to scaling and managing a codebase, especially regarding infrastructure code when working with multiple applications with similar architecture requirements across multiple environments.

This concept of modularizing Terraform code can be used to package multiple resources into one module to represent all the cloud resources you need to deploy your “application infrastructure stack”. Such a module would contain all the necessary cloud resources required for an application’s deployment. As seen in the example above we set up the module in a manner so the only input required to create the resource was a “name” and a “project_id”; the module did the rest.

When Does Modularizing IaC Code Come in Handy

  • When you know there will be a need to create multiple instances of a specific resource.

IaC, Terraform, and Customization

Terraform is a software tool created by Hashicorp to create infrastructure resources reliably and consistently spanning multiple cloud platforms. Tools like Terraform allow you to use code to manage and maintain resources while adding simplicity and speed to your infrastructure; perfect for enterprise-level infrastructure support and provisioning Google Cloud resources with declarative configuration files. Terraform is strictly an IaC language. Without such a tool creating and maintaining your cloud infrastructure on GCP would require using the UI which can be tedious and does not scale well.

Terraform’s registry provides pre-configured modules available for deploying resources to Google Cloud Platform along with other providers. Learn more about Terraform for Google Cloud by watching the video below. When you’re finished, reach out to us at 66degrees to find out what other pain points we can relieve. Our Google-certified experts are more than capable of navigating you through GCP. Let’s get you there!

Author Box

Share this article