Utilizing Terraform and Terraform Cloud Modules for Multi-Region AWS Deployment

The code for this example can be found on bespinian’s GitHub

Introduction

When you begin your journey with Terraform, it’s common practice to start small, focusing on creating and managing resources within a single AWS region.

This approach allows you to get an initial understanding of Terraform, it’s syntax, the plan => apply loop, state management, and in general grasp the fundamentals of infrastructure as code (IaC).

As the complexity and the requirements on your infrastructure grow, you will begin to notice that multi-region deployment in AWS is essential for various reasons.

These include improved application availability, reduced latency for global users, robust disaster recovery strategies, and many other use-cases.

However, replicating your infrastructure across multiple regions introduces extra complexity.

Without the right tools and practices, you might find yourself duplicating effort, managing extensive configurations, and navigating the challenges of keeping your infrastructure consistent across regions.

This is where Terraform, combined with strategic planning and organization, can significantly simplify the process.

In the following tutorial I would like to lead you through a possible way of setting up your configuration using Terraform Cloud workspaces, which can help you avoid the pitfalls of multi-region deployment, while reaping the benefits.

This is not the only way of doing it, but one that has worked very well for me and I hope will be interesting for anyone faced with this challenge.

Prerequisites

Creating Your Terraform Cloud Workspace

Creating a Terraform Cloud workspace is a step toward structuring and managing your infrastructure projects in a more organized, secure, and collaborative manner.

For our setup, we will create a new CLI-Driven Workspace:

cli-driven-workspace

AWS Generating Access Keys

If we want to connect our terraform cloud workspace with AWS we would need to create Access and Secret Keys for that follow the following steps:

1. IAM -> Users -> Create user

aws-create-user

2. Set permissions

aws-user-permissions

3. Create access and secret key

3.1 IAM -> Users -> select the terraform user

3.2 Under the Security credentials click on the Create access key

3.3 select the CLI option and Create access key

In the next chapter, we will add Access key and Secret access key into the terraform cloud workspace.

Integrating Terraform Cloud with AWS

In the terraform cloud newly created dev workspace add new Variables

access-key-workspace-variable.png

aws-variables.png

Deploy resource to single region with Terraform

We will start with deployment to single region, and then we will refactor our code to support multi region deployment.

terraform {
  cloud {
    organization = "terraform-cloud-mastering"

    workspaces {
      name = "dev"
    }
  }

  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "5.34.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}
tf init
Terraform Cloud has been successfully initialized!

Create our first resource

In this example we will create the SNS resource in the default us-east-1 region, the one which we have defined in the backend.tf

resource "aws_sns_topic" "sns_example" {
  name           = "demo_sns_topic"
  display_name   = "Demo SNS Topic"
}
Terraform will perform the following actions:

  # aws_sns_topic.sns_example will be created
  + resource "aws_sns_topic" "sns_example" {
      + arn                         = (known after apply)
      + beginning_archive_time      = (known after apply)
      + content_based_deduplication = false
      + display_name                = "Demo SNS Topic"
      + fifo_topic                  = false
      + id                          = (known after apply)
      + name                        = "demo_sns_topic"
      + name_prefix                 = (known after apply)
      + owner                       = (known after apply)
      + policy                      = (known after apply)
      + signature_version           = (known after apply)
      + tags_all                    = (known after apply)
      + tracing_config              = (known after apply)
    }

single-region-files.png

Module-Based Deployment: Expanding to Multi-Region Architecture

Let’s refactor our main.tf and create our first terraform module

variable "topic_name" {
  type = string
}

variable "topic_display_name" {
  type = string
}
resource "aws_sns_topic" "sns_example" {
  name           = var.topic_name
  display_name   = var.topic_display_name
}
terraform {
  required_providers {
    aws = {
      source = "hashicorp/aws"
      version = "5.34.0"
    }
  }
}

Refactoring the Root Project Directory

provider "aws" {
  region = "us-east-1"
  alias   = "us-east-1"
}

provider "aws" {
  region = "us-east-2"
  alias   = "us-east-2"
}
module "us-east-1" {
  source = "./modules/sns"
  providers = { aws = aws.us-east-1}

  topic_name = "demo-sns-us-east-1"
  topic_display_name = "Demos SNS"
}

module "us-east-2" {
  source = "./modules/sns"
  providers = { aws = aws.us-east-2}

  topic_name = "demo-sns-us-east-2"
  topic_display_name = "Demos SNS"
}

Multi-region folder structure multi-region-folder-structure

This approach will create an SNS topic in each region.

This is one strategy for implementing multi-region infrastructure deployment by utilizing multiple providers.

Keep an eye out for our upcoming blog posts, where we will explore how to achieve nearly identical outcomes by using multiple Terraform Cloud workspaces and will talk about when you might want to use the one approach or the other.