Skip to content

Infrastructure: the shared model

Cloud Delivery Lab runs the same application on two independent implementations: Amazon EKS with RDS, and Google Kubernetes Engine with Cloud SQL. GitLab coordinates changes; the cloud providers run the workloads. Portability comes from sharing the workflow and application manifests, with provider-specific infrastructure and exposure adaptations.

This documentation describes public terraform-modules commit ae1502b0, reviewed on 26 October 2026. Listed values are the versioned defaults, not readings of currently running resources or private GitLab variables.

Terraform configuration; OpenTofu execution

All eight directories use .tf files, terraform blocks, Terraform ecosystem providers and an HTTP backend. The pipeline runs tofu using registry.gitlab.com/components/opentofu/gitlab-opentofu:4.7.0-opentofu1.12.1-alpine. The precise description is therefore infrastructure written in Terraform HCL and executed in CI with OpenTofu. The thesis already states this in §7.2.7, printed page 45 (PDF page 51).

Using a component's container image does not imply including its templates: this repository defines its own jobs and invokes tofu directly. Features of the official component that are not invoked or configured here should not be assumed to be active.

Eight roots, four responsibilities

Each provider and layer combination is a separate root configuration with its own backend and state.

Layer AWS GCP Responsibility
network VPC, subnets, NAT and routes through the VPC module VPC, two subnets, secondary ranges, Router, NAT and firewall Base connectivity
kubernetes EKS, node group, IRSA and EBS CSI GKE, node pool, node identity and CSI/Workload Identity capabilities Control plane and compute
database RDS MySQL and security groups Cloud SQL MySQL and Private Service Access Persistence outside Kubernetes
platform Namespaces, DB secret, Agent and AWS Load Balancer Controller Namespaces, DB secret, Agent and optional service account Cluster preparation for deployment

These are not eight modules published to a registry. They are eight executable roots in a repository named terraform-modules; AWS additionally consumes public third-party modules. No module publishing job is present.

The pipeline order is network → kubernetes → database → platform. Destruction follows the reverse order. The actual dependencies explain the separate states:

flowchart TD
    N["network"] --> K["kubernetes"]
    N --> D["database"]
    K -->|"AWS security group"| D
    N --> P["platform"]
    K -->|"Endpoint, CA and identity"| P
    D -->|"MySQL connection"| P

The platform layer needs an existing, reachable Kubernetes API before planning and applying its Kubernetes and Helm resources. Separating it also allows platform resources to be removed before deleting the cluster. This agrees with the explanation in the thesis, §7.2.7, printed pages 44–45 (PDF 50–51).

What the implementations share

  • An app application namespace and a rest secret containing MySQL connection settings.
  • A Helm-installed GitLab agent connecting the cluster to GitLab.
  • Remote state in the infrastructure project, with HTTP locking.
  • The CLOUD_PROVIDER=aws|gcp selector, PIPELINE_ACTION=create|destroy action and ENVIRONMENT identifier.
  • Saved plans applied through manual approval for each layer.
  • Private nodes and outbound Internet access for images, services and the agent connection.

Operational differences

Area AWS default GCP default
Region eu-west-1 europe-west1
Network Three private and three public subnets One private subnet and one reserved public subnet; pod and service ranges
Egress One shared NAT Gateway Regional Cloud NAT for the private subnet
Kubernetes EKS, configured version 1.31 Regional GKE, REGULAR channel, no fixed minimum version
Nodes t3.small, desired 1, limits 1–3 e2-small, node locations in two zones; per-zone counts
Database RDS MySQL 8.0, db.t4g.micro, single AZ Cloud SQL MYSQL_8_0, db-f1-micro, ZONAL
Provisioner access to Kubernetes aws eks get-token Google provider OAuth token
Application exposure ALB controller and AWS Ingress manifest No GKE Ingress variant in the reviewed repositories

The infrastructure does not configure cross-cloud database replication, global load balancing, multi-cloud failover or private connectivity between AWS and GCP. Each provider has a separate database. Deploying the same image to both does not synchronize application data.

Environments: state separation is not resource isolation

ENVIRONMENT changes state prefixes and CI resource_group values. Cloud names remain gitlab-terraform-eks or gitlab-terraform-gke by default; tags retain dev. A second ENVIRONMENT value can create a separate state that tries to manage names already in use. Before running dev, pre and pro simultaneously, define accounts/projects, names, networks and environment-specific variables. See state and variables.

Boundaries and external steps

The repository creates resources inside existing cloud accounts and a GCP project. It does not declare billing, CI provisioning identities, GCP API activation, initial GitLab agent registration, or the certificate and DNS used by the AWS Ingress. The source alone also does not establish that a recent run succeeded.

Continue with AWS, GCP, the pipeline, agent access and resource teardown. The getting-started guide brings the cross-repository steps together.

Declared versions and reproducibility

Dependency Snapshot constraint Used by
HCL-compatible engine required_version >= 1.6.0; CI runs OpenTofu 1.12.1 All eight roots
AWS provider >= 5.95.0, < 6.0.0 Four AWS roots
Google provider >= 7.0.0, < 8.0.0 Four GCP roots
Kubernetes provider >= 2.25.0, < 3.0.0 Both platforms
Helm provider >= 2.12.0, < 3.0.0 Both platforms
TLS / time / cloudinit >= 3.0.0 / >= 0.9.0 / >= 2.0.0 EKS root
AWS VPC module ~> 5.0 AWS network
AWS EKS module ~> 20.0 AWS Kubernetes
AWS IAM submodules 5.39.0 EBS and ALB IRSA
Agent and ALB charts No release version pinned Platform

Constraints are not the versions actually resolved during a run. The snapshot contains no .terraform.lock.hcl, so Git alone cannot reconstruct that exact selection. To improve reproducibility, record and review per-root locks and pin chart versions; retest updates. Constraints come from AWS network, EKS, AWS platform and GCP platform.

Sources