Terraform でGKEクラスタを準備する

Terraformを使ってGKEクラスタを作るのに下のような定義をする。 VPCネイティブにするためには ip_allocation_policy を設定する必要がある。

GUIならVPCネイティブでもネットワークアドレスを自動確保できるけど terraform だとアドレス範囲かネットワーク名を明記しないとならない。 おそらく google_compute_network でネットワークを定義すればアドレス範囲の自動確保を実現できる。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
resource "google_container_cluster" "main" {
  count = length(var.specs)
  name     = "${var.name_prefix}-${count.index}"
  location = var.specs[count.index].location

  remove_default_node_pool = true
  initial_node_count       = 1

  min_master_version = var.min_master_version
  # node_version       = var.min_master_version

  ip_allocation_policy {
    # TODO make it adjustable
    cluster_ipv4_cidr_block  = cidrsubnet(var.ipv4_cidr_block, 3, 2*(count.index + var.ipv4_cidr_block_offset) + 0)
    services_ipv4_cidr_block = cidrsubnet(var.ipv4_cidr_block, 3, 2*(count.index + var.ipv4_cidr_block_offset) + 1)
  }

  addons_config {
    network_policy_config {
      disabled = true
    }
    horizontal_pod_autoscaling {
      disabled = false
    }
    http_load_balancing {
      disabled = false
    }
  }
}


locals {
  pool_specs = flatten([
    for spec in var.specs :
    [ for pool in spec.pools : {
      location: spec.location,
      cluster_name: "${var.name_prefix}-${index(var.specs, spec)}",
      id: index(spec.pools, pool),
      machine_type: pool.machine_type,
      node_count: pool.size,
    } ]
  ])
}

resource "google_container_node_pool" "primary_nodes" {
  count = length(local.pool_specs)
  depends_on = [google_container_cluster.main]

  name     = "${local.pool_specs[count.index].cluster_name}-base-pool-${local.pool_specs[count.index].id}"
  location = local.pool_specs[count.index].location

  cluster    = local.pool_specs[count.index].cluster_name
  node_count = local.pool_specs[count.index].node_count

  management {
    auto_upgrade = false
    auto_repair = true
  }

  node_config {
    oauth_scopes = [
      "https://www.googleapis.com/auth/devstorage.read_only",
      "https://www.googleapis.com/auth/logging.write",
      "https://www.googleapis.com/auth/monitoring",
      "https://www.googleapis.com/auth/service.management.readonly",
      "https://www.googleapis.com/auth/servicecontrol",
      "https://www.googleapis.com/auth/trace.append",
    ]

    machine_type = local.pool_specs[count.index].machine_type

    metadata = {
      disable-legacy-endpoints = "true"
    }
  }
}

モジュールの引数は下な感じ。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
variable "project" {}

variable "default_region" {
  default = "asia-northeast1"
}

variable "name_prefix" {}

variable "specs" {
  type = list(object({
    location = string
    pools = list(object({
      machine_type = string
      size = number
    }))
  }))
  default = [
    {
      location: "asia-northeast1-a"
      pools: [
        {
          machine_type: "n1-highcpu-4",
          size: 1,
        }
      ]
    }
  ]
  validation {
    condition = length(setsubtract([ for spec in var.specs : length(spec.pools) ], [0])) == length(toset([ for spec in var.specs : length(spec.pools) ]))

    error_message = "Pool size must be lager than 1."
  }
}

variable "min_master_version" {
  default = "1.15.11-gke.3"
}


variable "ipv4_cidr_block" {
  default = "192.168.0.0/16"
}

variable "ipv4_cidr_block_offset" {
  type = number
  default = 0
}

試してないけど google_compute_network を使えば自動でネットワークアドレスを割り当てられるはず!!

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
resource "google_compute_network" "service-net" {
  count = length(var.locations)
  name                    = "${var.name_prefix}-${count.index}-service-${count.index}"
  auto_create_subnetworks = true
}
resource "google_compute_network" "pod-net" {
  count = length(var.locations)
  name                    = "${var.name_prefix}-${count.index}-pod-${count.index}"
  auto_create_subnetworks = true
}

一応、書いておくとプロバイダ定義はモジュールごとに置いている。

1
2
3
4
5
6
7
8
9
provider "google" {
  project = var.project
  region  = var.default_region
}

provider "google-beta" {
  project = var.project
  region  = var.default_region
}
comments powered by Disqus