Cloud Computing 12 min read

Mastering Multi-Cloud Terraform: Architecture, Modules, and Best Practices

This article explains why GrowingIO adopts Terraform for multi‑cloud resource management, introduces Terraform’s core concepts and architecture, details a practical project structure with modules, conditional logic, complex loops, global variables, and environment isolation, and shares insights on its advantages and limitations.

GrowingIO Tech Team
GrowingIO Tech Team
GrowingIO Tech Team
Mastering Multi-Cloud Terraform: Architecture, Modules, and Best Practices

Background

To meet GrowingIO customers' diverse needs, Terraform is used on public‑cloud infrastructure for resource management, offering multi‑cloud support, automated infrastructure orchestration, Infrastructure as Code, and a unified syntax for standardized management.

Multi‑cloud support via providers from major cloud vendors.

Automation and repeatable resource orchestration.

Infrastructure as Code for state tracking.

Unified syntax across services.

Terraform Introduction

Terraform is an open‑source IaC tool that provides a consistent CLI workflow to manage hundreds of cloud services. It uses declarative HCL configuration files and providers for each cloud platform (AWS, Azure, Google Cloud, DigitalOcean, Aliyun, Tencent Cloud, etc.).

Architecture

Terraform parses HCL DSL files, interacts with cloud provider APIs via the core engine, and applies the desired state. The diagram below illustrates this flow.

Project Practice

Project Design

Multiple homogeneous environments require consistent delivery.

Each environment hosts several projects with varying resource needs.

Projects need EC2, ELB, EBS, EMR, and other resources.

Project Implementation

Project Structure

# tree -L 3 .
├── README.MD
├── module
│   ├── app1
│   │   ├── config.tf
│   │   ├── locals.tf
│   │   ├── main.tf
│   │   ├── outputs.tf
│   │   └── variables.tf
│   ├── global
│   │   └── config.tf
└── dev
    ├── main.tf
    └── output.tf

The module directory groups resources by project name (e.g., app1). global holds shared parameters, and dev references modules for each environment.

Module Details config.tf: Provider and configuration parameters. locals.tf: Computed variables and complex expressions. main.tf: Resource and data declarations. outputs.tf: Exported values such as instance IPs. variables.tf: Input variables like instance count.

Module Packaging

Repeated atomic operations are encapsulated in modules, which are then invoked with appropriate arguments.

# dev/main.tf
module "app1" {
  source                     = "../module/app1"
  aws_ec2_create_number     = 3
  # other variables …
}

Conditional Logic in Modules

Terraform combines loops and conditionals for two main scenarios: validating variable forms and deciding whether to create a resource.

# module/app1/main.tf
resource "aws_instance" "aws-ec2-create" {
  count = var.aws_ec2_create_number
  tags = {
    Name = var.aws_ec2_create_number < 2 ? "${var.env}-${var.aws_ec2_name}" : "${var.env}-${var.aws_ec2_name}-${count.index + 1}"
  }
}

Dynamic blocks allow optional resources, e.g., creating an EBS volume only when its size is non‑zero.

# module/app1/main.tf
resource "aws_instance" "aws-ec2-create" {
  count = var.aws_ec2_create_number
  dynamic "ebs_block_device" {
    for_each = var.aws_ebs_block_device_volume_size != 0 ? [1] : []
    content {
      delete_on_termination = true
      device_name           = var.aws_ebs_block_device_name
      volume_size           = var.aws_ebs_block_device_volume_size
      volume_type           = var.aws_ebs_block_device_volume_type
    }
  }
}

When var.aws_ebs_block_device_volume_size is 0, the list is empty and the block is omitted.

Complex Loops

Terraform’s count and for_each support simple loops; for more complex scenarios, calculations are performed in locals and referenced later.

# module/app1/locals.tf
locals {
  times = ceil(var.aws_ec2_create_number / length(var.aws_subnet_id_list))
  subnet_list_combine = flatten([
    for p in range(local.times) : [
      for q in var.aws_subnet_id_list : [join(",", [q])]
    ]
  ])
}
# module/app1/main.tf
resource "aws_network_interface" "aws-network-interface" {
  count      = var.aws_ec2_create_number
  subnet_id  = local.subnet_list_combine[count.index]
}

Global Variables

Although Terraform discourages global variables, they can be encapsulated in a dedicated module for consistency across projects.

# module/global/config.tf
output "aws_profile_name" {
  value = "default"
}
# module/application/locals.tf
module "global" { source = "../global" }
locals { aws_profile_name = module.global.aws_profile_name }
# module/application/config.tf
provider "aws" {
  profile = var.aws_profile_name == "" ? local.aws_profile_name : var.aws_profile_name
}

Environment Isolation

Two isolation methods exist: workspaces and directory segregation. This project uses directory isolation for clarity.

# dev/main.tf
module "app1" { source = "../module/app1" aws_ec2_create_number = 3 }

# stage/main.tf
module "app1" { source = "../module/app1" aws_ec2_create_number = 3 }

Project Insights

Terraform simplifies basic resource orchestration with concise syntax, but provider inconsistencies across clouds increase multi‑cloud integration cost. Some Chinese cloud providers offer fewer resources, limiting certain scenarios. Advanced features may be lacking, requiring workarounds or additional modules, and occasional duplication of modules is necessary when providers differ.

Conclusion

This article introduced Terraform’s fundamentals, reasons for adoption, and a practical project layout with environment isolation, parameter passing, complex calculations, and global variables. While Terraform cannot cover every advanced use case, it provides a solid foundation for infrastructure as code.

References

Mikael Krief. Terraform Cookbook: Efficiently define, launch, and manage Infrastructure as Code across various cloud platforms. Packt Publishing 2020.

Scott Winkler. Terraform in Action. Manning 2021.

Yevgeniy Brikman. Terraform: Up & Running: Writing Infrastructure as Code. O'Reilly Media 2019.

https://www.terraform.io/docs/language/index.html

https://github.com/hashicorp/terraform/issues/5480

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

multi-cloudModulesTerraformInfrastructure as Code
GrowingIO Tech Team
Written by

GrowingIO Tech Team

The official technical account of GrowingIO, showcasing our tech innovations, experience summaries, and cutting‑edge black‑tech.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.