Terraform で GCE + LB を構築、 Apache へアクセス

概要

やりたいこと

LB + GCE の環境を Terraform で構築する。

前回は GCE のみを構築した。

GCP LB

基本的には以下に従ってやっていく。

Terraform

Terraform テンプレートは GCP コンソールに沿った形で分割している。

GCE

Apache が起動している GCE VM インスタンスを作成する。

GCE 用の静的 IP を予約する。指定しない場合でも Ephemeral IP (動的 IP )が自動で割り当てられるが、LB のために静的にしておく。

ネットワークタグに http-server を指定しない説もあるが、指定しないと動かなかった。

vi gce.tf
resource "google_compute_address" "instance-address" {
  name = "instance-address"
}

resource "google_compute_instance" "default" {
  name         = "test"
  machine_type = "e2-medium"
  zone         = "asia-northeast2-a"

  tags = ["http-server","allow-health-check"]
  #tags = ["allow-health-check"]

  boot_disk {
    initialize_params {
      image = "debian-cloud/debian-9"
    }
  }

  network_interface {
    network = "default"

    access_config {
      nat_ip = google_compute_address.instance-address.address
    }
  }

  metadata = {
    foo = "bar"
  }

  metadata_startup_script =  <<EOF
sudo apt -y install apache2 && echo 'Hello Apache!' | sudo tee /var/www/html/index.html
EOF
}

# インスタンスに紐づいたIPアドレスの出力
output "instance-ipaddress" {
  value = google_compute_address.instance-address.address
}

デプロイ。

terraform apply

CLI コンソールに IP が出力されるので、この IP へアクセスし Apache ページ(Hello Apache!)が表示されれば OK。

LB 設定前の準備

インスタンスグループを作成

lb-backend-example という名前の非マネージドインスタンスグループを作成する。
Port 名のマッピングもここで指定する。

GCE 用の Terrafrom テンプレート に追記する。

vi gce.tf
resource "google_compute_instance_group" "instance-group" {
  name        = "lb-backend-example"

  instances = [
    google_compute_instance.default.self_link,
  ]

  // Port名のマッピング
  named_port {
    name = "http"
    port = "80"
  }

  zone = "asia-northeast2-a"
}

デプロイ。

terraform apply

インスタンスグループが作成される。

Port 名のマッピングもできている。

ファイアウォールルールの構築

fw-allow-health-check という名前のファイアウォールルールを作成する。
ヘルスチェック用のアクセス許可を行う。

GCE と LB とは別の Terraform テンプレートに作成する。

vi network.tf
# ネットワーク設定の情報取得
data "google_compute_network" "default" {
  name = "default"
}

# ヘルスチェック用ファイアウォール設定
resource "google_compute_firewall" "firewall" {
  name    = "fw-allow-health-check"
  network = data.google_compute_network.default.name

  target_tags = ["allow-health-check"]
  source_ranges = ["130.211.0.0/22", "35.191.0.0/16"]
  direction = "INGRESS" # 上り(受信)

  allow {
    protocol = "tcp"
    ports    = ["80"]
  }
}

デプロイ。

terraform apply

ファイアウォールルールが作成される。

外部 IP アドレスの予約

アクセス用の IP を lb-ipv4-1 という名前で予約する。

Network のテンプレートに追記する。

vi network.tf
resource "google_compute_global_address" "lb-address" {
  name = "lb-ipv4-1"
  ip_version = "IPV4"
  address_type = "EXTERNAL"
}

output "lb-ipaddress" {
  value = google_compute_global_address.lb-address.address
}

デプロイ。

terraform apply

VPC ネットワーク → 外部 IP アドレスより、以下のように予約できていること。

LB

web-map-http という LB を作成する。

以下 3 つを行う

バックエンドの作成

web-backend-service という名前でバックエンドサービスを、http-basic-check という名前でヘルスチェックを作成する。

LB 用の Terraform テンプレートを新規に作成。

vi lb.tf
resource "google_compute_backend_service" "backend-service" {
  name        = "web-backend-service"
  port_name   = "http"
  protocol    = "HTTP"
  timeout_sec = 3000

  backend {
    group = google_compute_instance_group.instance-group.self_link
  }

  health_checks = [google_compute_health_check.health-check.self_link]
}

resource "google_compute_health_check" "health-check" {
  name = "http-basic-check"

  timeout_sec        = 1
  check_interval_sec = 1

  tcp_health_check {
    port = "80"
  }
}

ホストとパスのルール

ここで LB の名前を指定する (web-map-http)。

今回は特にパスに対するルールを指定しないためシンプル。

vi lb.tf
resource "google_compute_url_map" "url-map" {
  name        = "web-map-http"
  default_service = google_compute_backend_service.backend-service.self_link
}

フロントエンドの設定

web-frontend-service という名前でフロントエンドサービスを、target-proxy という名前で作成する。

vi lb.tf
resource "google_compute_global_forwarding_rule" "global-forwarding-rule-http" {
  name       = "global-forwarding-rule-http"
  target     = google_compute_target_http_proxy.target-http-proxy.self_link
  port_range = "80"
  ip_address = google_compute_global_address.lb-address.address
}

resource "google_compute_target_http_proxy" "target-http-proxy" {
  name             = "target-http-proxy"
  url_map          = google_compute_url_map.url-map.self_link
}

最後にまとめてデプロイ。

terraform apply

ネットワークサービス → 負荷分散 にて作成した LB が確認できる。

割り当てられた外部 IP から HTTP アクセスし、 Apache Hello! と出れば OK。

最後に忘れずに消しておくこと。

terraform destroy

エラー

GCE のネットワークタグに http-server を指定しないと 404 エラー

以下が解決できていない。。

  • GCE のネットワークタグに http-server を指定しないで LB の GIP にアクセスすると 404 エラーとなる
  • GCE の静的 IP へ直接アクセスできてしまう

公式では以下のように「HTTP トラフィックを許可する」選択しなくても良い(= http-server を指定しなくていい)となっているのに。。

注: 外部 HTTP(S) ロードバランサはプロキシであるため、[ファイアウォール] で [HTTP トラフィックを許可する] を選択する必要はありません。ファイアウォール ルールの構成では、このロードバランサに必要な唯一のファイアウォール ルールを作成します。

ヘルスチェックのファイアウォール ルール

未解決。一旦 http-server を指定することにした。

参考

シンプルな外部 HTTP ロードバランサの設定

terraform を使って GCP にロードバランサを設置してみた ~その①~

【GCP】 Cloud Load Balancing + Compute Engine で冗長構成の Web サーバーを構築

GCP, Terraform

Posted by さいき