Skip to content
hannctl
PDF

case-studies gcp-terraform DESIGN.md

GCP Terraform GKE platform Design and implementation

A module set that keeps capacity during GKE node pool upgrades with SURGE, and opens only what a VPN needs through a firewall baseline, all as code.

GKE node pool SURGE upgrademax_surge = 5 max_unavailable = 0New nodesOld nodesOld nodes leave one at a time · 0 unavailableSwapped to 5 new nodes · 0 nodes unavailableSoak 3600s applies only to BLUE_GREEN
The swap finishes. The 3600s soak value is read only under BLUE_GREEN.
Firewall evaluated in priority orderTwo rules from the c2sfirewall module, plus the GCP implied rules1000 · INGRESS allowVPN ranges to tcp 22, 3389, 637965534 · EGRESS denytcp and udp 0-65535 outbound denied65535 · GCP implied rulesInbound deny, outbound allowVPNallowServer outbounddenyDeny by default, open only what is needed with an earlier rule
An allow rule ahead of 65534 can still open a specific path.

Node pool SURGE settings

What this code does: Defines the game node pool to autoscale between 3 and 12 nodes and sets the upgrade strategy to SURGE. max_surge 5 brings five new nodes up first, and max_unavailable 0 means no existing node is taken away before its replacement is ready, so serving capacity does not drop during an upgrade. As the comment says, the soak time below is read only if the strategy is switched to BLUE_GREEN.

  node_pool = {
    game = {
      autoscaling_enable = true
      min_node_count     = 3
      max_node_count     = 12
      location_policy    = "BALANCED"
      node_count         = null
      pool_version       = "1.31"
      machine_type       = "e2-standard-4"
      tags               = ["gke-node"]

      # Five extra nodes come up first, and no node is taken away until its replacement is ready.
      strategy        = ["SURGE"]
      max_surge       = 5
      max_unavailable = 0

      # Soak time is read only when the strategy is switched to BLUE_GREEN.
      node_pool_soak_duration = "3600s"
    }
  }

A VPN-only firewall baseline

What this code does: Declares firewall rules as a map, and the c2s-inbound-vpn rule allows incoming (INGRESS) tcp traffic. The only sources are the VPN ranges passed in as a variable (vpn_source_ranges), only the management ports from another variable (management_ports) are opened, and priority 1000 makes it apply before the deny rules that follow. Because ranges and ports are variables, the same rule structure is reused across environments.

locals {
  firewall_rules = {
    c2s-inbound-vpn = {
      direction            = "INGRESS"
      action               = "allow"
      ranges               = var.vpn_source_ranges
      sources              = null
      targets              = null
      use_service_accounts = false
      enable_logging       = false
      priority             = "1000"
      rules = [
        {
          protocol = "tcp"
          ports    = var.management_ports
        }
      ]
    }
© 2026 Kim JunHyun · Built with Astro · The infrastructure behind this site is code too

↑↓ move · Enter open · Esc close

Choose a theme

Click a badge to switch to that theme on the same content. Dragging only swings it.

Back to the front page →