The Complete Responsive CMS Blog created by Francesco Malagrino

The Multi-Cloud Reality: Architecting Kubernetes Baselines Across AWS, Azure, and GCP with Terraform

Category: Software Architecture & Written by Francesco Malagrino On July-15-2026 14:20:41


Introduction


Vendor lock-in is a legitimate concern for modern enterprises, but adopting multiple cloud providers without a consistent operating model can create an even larger problem: operational fragmentation.


AWS, Azure, and Google Cloud expose different networking models, identity mechanisms, managed services, and Kubernetes integrations. Without a shared Infrastructure as Code strategy, teams often duplicate work, apply inconsistent security controls, and maintain separate deployment processes for each provider.


This reference architecture demonstrates how Terraform can establish a consistent, production-oriented Kubernetes baseline across Amazon EKS, Azure AKS, and Google GKE while preserving the native capabilities of each cloud platform.


The Architectural Challenge


Managed Kubernetes services may expose a similar Kubernetes API, but the infrastructure surrounding them is fundamentally different.


AWS uses VPCs, IAM and IAM Roles for Service Accounts. Azure relies on virtual networks, Network Security Groups and managed identities. Google Cloud combines VPC networking with IAM, Workload Identity and regional cloud services.


Attempting to hide every difference behind a generic abstraction usually produces a lowest-common-denominator platform. The objective of this architecture is therefore not to make every cloud identical. It is to standardize the deployment lifecycle, security baseline and repository structure while allowing each provider to retain its native strengths.


A Consistent Multi-Cloud Foundation


The repository separates AWS, Azure, and GCP into independent Terraform root configurations. Each provider has its own variables, outputs and module composition, while reusable modules organize shared infrastructure concerns such as networking, compute, storage and monitoring.


This structure avoids a single monolithic configuration and limits the blast radius of infrastructure changes. An update to the AWS environment can be planned and deployed independently from Azure or GCP without coupling all three providers to the same Terraform state.


Development, staging and production environments are also represented through provider-specific tfvars files and dedicated backend configurations. This allows the same infrastructure code to support different availability, retention, redundancy and cost requirements across environments.


Remote State and Keyless Authentication


Terraform state is isolated by provider and environment:



  • Amazon S3 with DynamoDB locking for AWS

  • Azure Blob Storage for Azure

  • Google Cloud Storage for GCP


The GitHub Actions pipeline uses cloud-native federation instead of storing long-lived cloud access keys.


AWS authentication uses GitHub OIDC to assume an IAM role. Azure uses federated identity through azure/login, while GCP uses Workload Identity Federation.


Removing static credentials from CI/CD reduces credential exposure, simplifies rotation and supports the security and audit controls commonly required in regulated enterprise environments.


Provider-Native Kubernetes Identity


The architecture establishes a common identity principle across all three platforms: workloads should receive narrowly scoped cloud permissions without embedding credentials inside containers or Kubernetes Secrets.


On AWS, EKS workloads can use IAM Roles for Service Accounts through the cluster’s OIDC provider. AKS uses Azure managed identities, while GKE integrates with Google Workload Identity.


The implementations differ, but the security objective remains consistent: applications authenticate through short-lived, workload-bound identities rather than shared static credentials.


Networking and Environment Isolation


Each cloud deployment provisions its own virtual network, subnets and provider-native security controls.


The AWS implementation includes a VPC, public and private subnets, route tables, Internet Gateway, NAT Gateway and security groups. Azure uses a VNet, delegated subnets and Network Security Groups. GCP provisions a custom VPC, subnets, Cloud Router and Cloud NAT.


The architecture provides a consistent networking baseline while respecting the native networking model of each provider. Production environments can use stronger availability and redundancy settings, while development environments can use lower-cost configurations.


Automated Validation and Security Analysis


The GitHub Actions workflow validates all three cloud implementations through a matrix-based pipeline.


Every change runs:



  • Terraform formatting checks

  • Terraform initialization and validation

  • TFLint

  • tfsec

  • Checkov


Pull requests can therefore expose formatting errors, invalid Terraform configurations and potential infrastructure security issues before changes are applied.


The workflow supports development, staging and production environments and allows deployments to target AWS, Azure, GCP or all three providers.


Kubernetes Hardening After Provisioning


Provisioning a managed Kubernetes cluster is only the first layer of the platform.


The repository includes portable post-deployment hardening resources that can be applied across EKS, AKS and GKE. These include:



  • Namespaces configured with Pod Security Admission labels

  • Default-deny NetworkPolicies

  • Explicit DNS and internal-network egress policies

  • Kyverno policies that reject privileged containers

  • Policies requiring workloads to run as non-root


This hardening stage is optional in the deployment workflow and can be enabled after Terraform provisions the target cluster.


Private Kubernetes API endpoints require a runner with connectivity to the target VPC or VNet. In those environments, a self-hosted GitHub Actions runner should execute the post-deployment configuration.


Limitations and Trade-offs


Multi-Cloud Does Not Mean Cloud-Agnostic


The architecture creates a consistent operational baseline, but it does not pretend that AWS, Azure and GCP are interchangeable.


Identity, networking, storage, monitoring and database services remain provider-specific. Applications must still be designed carefully if they are expected to move between clouds.


The repository improves portability by standardizing infrastructure structure and deployment practices, not by hiding every provider difference.


Egress Costs and Data Gravity


Moving large volumes of data between cloud providers introduces network charges, latency and additional operational complexity.


For this reason, the architecture is better suited to independent cloud deployments, disaster-recovery strategies and application portability than to continuous active-active database replication across providers.


Data gravity remains one of the most important constraints in any realistic multi-cloud design.


Kubernetes and Provider Version Drift


EKS, AKS and GKE do not release Kubernetes versions or deprecate platform features on identical schedules.


Terraform providers, modules, Kubernetes versions and cluster add-ons must therefore be version-pinned and upgraded deliberately. A manifest or configuration that works correctly on one provider may require adjustments on another.


Multi-cloud consistency requires continuous testing rather than assuming that identical Kubernetes APIs guarantee identical behaviour.


Operational Complexity


Supporting three cloud providers increases the number of services, permissions, failure modes and upgrade paths that platform teams must understand.


Multi-cloud should therefore solve a defined business requirement—such as regulatory separation, resilience, acquisition integration or provider diversification—not simply be adopted because the technology makes it possible.


What the Repository Demonstrates


The repository provides a practical reference implementation containing:



  • Independent Terraform configurations for AWS, Azure and GCP

  • Amazon EKS, Azure AKS and Google GKE deployments

  • Reusable networking, compute, storage and monitoring modules

  • Environment-specific development, staging and production variables

  • Isolated remote-state configurations

  • Keyless CI/CD authentication

  • Automated Terraform validation and security scanning

  • Optional post-deployment Kubernetes hardening


The result is not a fictional abstraction that makes every cloud look the same. It is a structured approach for managing three different cloud platforms through a consistent engineering and delivery model.


Conclusion


A successful multi-cloud strategy is not defined by how many cloud providers an organisation uses. It is defined by whether those environments can be governed, secured and operated consistently.


Terraform provides the common delivery language, while provider-specific modules preserve access to native cloud capabilities. Isolated state, federated identities, automated validation and portable Kubernetes security controls create a foundation that platform teams can understand and extend.


This approach reduces operational differences between providers and makes future workload migration more manageable—without ignoring the technical and financial trade-offs that multi-cloud architecture introduces.


Explore the Code


Explore the Terraform configurations, reusable modules, CI/CD workflow and Kubernetes hardening resources in my public repository: Vegetam/terraform-multicloud



Share


Comments

Share your thoughts about this post