---
title: "terraformで作るHTTP(S) 負荷分散 | grasys blog"
url: "https://blog.grasys.io/post/okawa/tf-httplb/"
description: "はじめまして、昨年8月よりgrasysにJoinしました大川と申します。 以後お見知り置きを。 構成要素が多く地味に作るのが面倒なHTTP(S) 負荷分散について、シンプルな構成をterraformで作る方法をドキュメントを追 いつつゆるく解説させていただきます。 1. GCPを触ったことがある 2. terrafo…"
---

# terraformで作るHTTP(S) 負荷分散

-   ![](/_astro/noicon.CTHOhNiB_1HMs6A.webp)[okawa](/authors/okawa/)
-   公開日：2018年8月15日
-   カテゴリー：[Tech](/categories/tech/)
-   タグ：[#httplb](/tags/httplb/)[#Terraform](/tags/terraform/)

![terraformで作るHTTP(S) 負荷分散](/_astro/og-image.DDSiu2Ny_XHpDd.webp)

はじめまして、昨年8月よりgrasysにJoinしました大川と申します。  
以後お見知り置きを。

構成要素が多く地味に作るのが面倒なHTTP(S) 負荷分散について、シンプルな構成をterraformで作る方法をドキュメントを追>いつつゆるく解説させていただきます。

1.  GCPを触ったことがある
2.  terraformを触ったことがある
3.  httplb作るのメンドい

といった方にとって有用な情報となれば幸いです。

## 前提知識

### GCP HTTP(S) 負荷分散

Google社が提供するロードバランサーです。  
[https://cloud.google.com/compute/docs/load-balancing/http/?hl=ja](https://cloud.google.com/compute/docs/load-balancing/http/?hl=ja)

> Google Cloud (GCP) Platform（GCP）の HTTP(S) 負荷分散は、インスタンスの HTTP(S) リクエストに対してグローバルな負荷分散を提供します。あるセットのインスタンスに一部の URL をルーティングし、別のインスタンスには別の URL をルーティングする URL ルールを設定できます。

–公式ドキュメントより

HTTPS(S)ロードバランサは下記のように複数のコンポーネントから構成されています。 今回はコンポーネントごとにバックエンドよりフロントに向けて作っていきます。

Cross-region load balancing diagram

### terraform

hashicorp社が公開しているオーケストレーションツールです。

[https://www.terraform.io/](https://www.terraform.io/)

クラウドや仮想基盤、CDNなど多岐にわたる項目をコードベースで管理することができ、冪等性を担保することが出来ます。 GCPやAWSをはじめとするメジャーなCloud Providerに対応しています。

## 作ってみる

それでは、実際にHTTP(S) 負荷分散を作ってみます。  
まずはバックエンドサービスの配下から作り始めます。

-   バックエンド サービス  
    [https://cloud.google.com/compute/docs/load-balancing/http/backend-service?authuser=19&hl=ja](https://cloud.google.com/compute/docs/load-balancing/http/backend-service?authuser=19&hl=ja)

> HTTP(S) 負荷分散バックエンド サービスはバックエンドを管理するための集中管理サービスであり、ユーザー リクエストを処理するインスタンスを管理します。負荷分散サービスは、バックエンド サービスにリクエストがルーティングされるように設定します。

### 1\. Backendの作成

ドキュメントより、概要図右端にあるインスタンスグループから作成します。

> 各バックエンドは、1 つのインスタンス グループと、追加の提供容量メタデータから構成されます。

![HTTP負荷分散を構成するバックエンドサービスとインスタンスグループの関係図](/_astro/02-11-2-6c1e472d.bOqOR27O_Z1SCWLr.webp)

#### 1.1. Instance Groupに所属するインスタンスの作成

インスタンスグループに所属するインスタンスを作成します。  
今回はhttpでアクセスするwebサーバを作成します。  
※サーバ内容については割愛します。

[https://www.terraform.io/docs/providers/google/r/compute\_instance.html](https://www.terraform.io/docs/providers/google/r/compute_instance.html)

Plain textcontent\_copy

```
resource "google_compute_instance" "webserver" {
  name         = "webserver"
  machine_type = "n1-standard-1"
  zone         = "asia-northeast1-a"

  tags = ["web"]

  boot_disk {
    initialize_params {
      image = "centos-7-v20180815"
      size = "10"
      type = "pd-standard"
    }
  }

  network_interface {
    network = "default"

    access_config {
      // Ephemeral IP
    }
  }

  metadata {
    foo = "server-web"
  }

  service_account {
    scopes = ["userinfo-email", "compute-ro", "storage-ro"]
  }
}
```

#### 1.2. Instance Groupの作成

次に、1.1で作成したInstanceが所属するInstance Groupを作成します。

![Instance Groupの作成の画面](/_astro/03-12-2-6eb2a2ce.D4soUwWg_odSDG.webp)

#### code

[https://www.terraform.io/docs/providers/google/r/compute\_instance\_group.html](https://www.terraform.io/docs/providers/google/r/compute_instance_group.html)

Plain textcontent\_copy

```
resource "google_compute_instance_group" "webserver" {
  name        = "webserver"
  description = "webserver instance group"
  
  instances = [
    "${google_compute_instance.webserver.self_link}",
  ]

  named_port {
    name = "http"
    port = "80"
  }

  zone        = "asia-northeast1-a"
}
```

### 2\. Backend serviceの作成

次に、Backendを管理するBackend serviceを作成します。

> バックエンド サービスによって、受信トラフィックが 1 つ以上の関連バックエンドに振り向けられます。

#### 2.1. health check

Backend service作成時に要求されるhealth checkを先に作成します。

ここではSSLはLBで終端し、webserverへはhttpでアクセスするため http\_health\_checkを指定します。  
health checkとして一定間隔でアクセスするため、比較的軽いページを選択するか、status check専用のページを作ると良いでしょう。

![health checkの画面](/_astro/04-13-2-369be6e4.D0PF74w2_ZqPMGp.webp)

##### document

[https://cloud.google.com/compute/docs/load-balancing/health-checks?hl=ja](https://cloud.google.com/compute/docs/load-balancing/health-checks?hl=ja)

> 各バックエンド サービスは、使用可能なインスタンスに対して実行されるヘルスチェックも指定します。

##### code

[https://www.terraform.io/docs/providers/google/r/compute\_http\_health\_check.html](https://www.terraform.io/docs/providers/google/r/compute_http_health_check.html)

Plain textcontent\_copy

```
resource "google_compute_http_health_check" "webserver" {
  name         = "webserver-health-check"
  request_path = "/health_check"

  timeout_sec         = 5
  check_interval_sec  = 5
  healthy_threshold   = 2
  unhealthy_threshold = 2
}
```

#### 2.2. Backend service

Backend,health-checkの作成が終わりましたので、backend serviceを作成します。  
`backend``health_checks`の項目にはそれぞれ先に作成したリソースのself\_linkを設定します。

![Backend serviceの画面](/_astro/05-14-2-f203e018.PYjgKpGr_McpQw.webp)

##### code

[https://www.terraform.io/docs/providers/google/r/compute\_backend\_service.html](https://www.terraform.io/docs/providers/google/r/compute_backend_service.html)

Plain textcontent\_copy

```
resource "google_compute_backend_service" "webserver-backend" {
  name        = "webserver-backend"
  description = "webserver-backend"
  port_name   = "http"
  protocol    = "HTTP"
  timeout_sec = 10
  enable_cdn  = false

  backend {
    group = "${google_compute_instance_group.webserver.self_link}"
  }

  health_checks = ["${google_compute_http_health_check.webserver.self_link}"]
}
```

#### 2.3 Backend用firewall rule

backendとhealth\_checksを設定しただけの状態ではまだfirewall ruleが存在しないため、health-checkが全てInstanceに届かず失敗する状態です。  
そこで、health-check用のIPアドレスを許可するfirewall ruleを作成します。

##### document

[https://cloud.google.com/compute/docs/load-balancing/health-checks?hl=ja#health\_check\_source\_ips\_and\_firewall\_rules](https://cloud.google.com/compute/docs/load-balancing/health-checks?hl=ja#health_check_source_ips_and_firewall_rules)

> HTTP(S)、SSL プロキシ、TCP プロキシまたは内部負荷分散でヘルスチェックを使用した場合、ヘルスチェック プローブを範囲 130.211.0.0/22 と 35.191.0.0/16 のアドレスから受信します。これらの接続を、負荷分散されるすべてのインスタンスに許可するファイアウォール ルールを作成する必要があります。

##### code

[https://www.terraform.io/docs/providers/google/r/compute\_firewall.html](https://www.terraform.io/docs/providers/google/r/compute_firewall.html)

Plain textcontent\_copy

```
resource "google_compute_firewall" "webserver" {
  name        = "backend-http-server"
  network     = "default"

  allow {
    protocol = "tcp"
    ports    = [
      "80",   # http
    ]
  }

  source_ranges = [
    "130.211.0.0/22",  # Google LB
    "35.191.0.0/16",   # Google LB
  ]

  target_tags   = [
    "web",
  ]
}
```

ここまでで、Backend serviceの作成が完了しました。  
ようやく半分です。

### 3\. Url Map

URL マップを作成します。

URLベースでバックエンドサービスを指定できる機能で、アクセス頻度や負荷の高い処理は別ディレクトリに切り出しバックエンドサーバを分けて負荷の影響を昨日単位にとどめるといった運用も可能です。  
最低でも一つ path\_rule が必要なため、ここでは `/` に対するルールを作成します。

![HTTP負荷分散におけるURLマップの役割を示す構成図](/_astro/06-15-2-9413ea1e.BEI8s03b_ZqhkN5.webp)

##### document

[https://cloud.google.com/compute/docs/load-balancing/http/url-map?authuser=19&hl=ja](https://cloud.google.com/compute/docs/load-balancing/http/url-map?authuser=19&hl=ja)

> Compute Engine の HTTP（S）負荷分散を使用すると、受信 URL に基づいてトラフィックを異なるインスタンスに転送できます。たとえば、[http://www.example.com/audio](http://www.example.com/audio) へのリクエストは音声ファイル配信用に設定されているインスタンスを含むバックエンド サービスに送信し、[http://www.example.com/video](http://www.example.com/video) へのリクエストは動画ファイル配信用に設定されているインスタンスを含む別のバックエンド サービスに送信することができます。

##### code

[https://www.terraform.io/docs/providers/google/r/compute\_url\_map.html](https://www.terraform.io/docs/providers/google/r/compute_url_map.html)

Plain textcontent\_copy

```
resource "google_compute_url_map" "website" {
  name        = "website"
  description = "a description"

  default_service = "${google_compute_backend_service.webserver-backend.self_link}"

  host_rule {
    hosts        = ["example.grasys.io"]
    path_matcher = "allpaths"
  }

  path_matcher {
    name            = "allpaths"
    default_service = "${google_compute_backend_service.webserver-backend.self_link}"

    path_rule {
      paths   = ["/"]
      service = "${google_compute_backend_service.webserver-backend.self_link}"
    }
  }
}
```

### 4\. Target Proxy

プロトコルとURLマップを指定します。

![HTTP負荷分散におけるターゲットプロキシの役割を示す構成図](/_astro/07-16-2-dcb06903.C0StIoPZ_ZW0M30.webp)

#### document

[https://cloud.google.com/compute/docs/load-balancing/http/target-proxies?authuser=19&hl=ja](https://cloud.google.com/compute/docs/load-balancing/http/target-proxies?authuser=19&hl=ja)

> ターゲット プロキシはグローバル転送ルールによって参照されます。HTTP(S) 負荷分散の場合、プロキシは着信リクエストを URL マップにルーティングします。SSL プロキシと TCP プロキシの負荷分散の場合、ターゲット プロキシは着信リクエストを直接バックエンド サービスにルーティングします。

#### 4.1. SSL certificate

ここではhttpsのルールを作成するため、SSL証明書を登録します。  
証明書は中間証明書を連結して登録します。  
nginxを運用されている方にはおなじみかと思います。

##### document

[https://cloud.google.com/compute/docs/load-balancing/http/ssl-certificates?authuser=19&hl=ja](https://cloud.google.com/compute/docs/load-balancing/http/ssl-certificates?authuser=19&hl=ja)

> HTTPS または SSL 負荷分散を使用するには、ロードバランサのターゲット プロキシで使用できる SSL 証明書を少なくとも 1 つ作成する必要があります。最大 10 個の SSL 証明書を使用してターゲット プロキシを設定できます。SSL 証明書ごとに、まず SSL 証明書リソースを作成します。SSL 証明書リソースには証明書情報が含まれています。

##### code

[https://www.terraform.io/docs/providers/google/r/compute\_ssl\_certificate.html](https://www.terraform.io/docs/providers/google/r/compute_ssl_certificate.html)

Plain textcontent\_copy

```
resource "google_compute_ssl_certificate" "website-20180815" {
  name        = "website-20180815"
  description = "a description"
  private_key = "${file("path/to/private.key")}"
  certificate = "${file("path/to/certificate.crt")}"
}
```

#### 4.2. target https proxy

先立って作成したurl\_mapとssl\_certificateを設定します。

##### code

[https://www.terraform.io/docs/providers/google/r/compute\_target\_https\_proxy.html](https://www.terraform.io/docs/providers/google/r/compute_target_https_proxy.html)

Plain textcontent\_copy

```
resource "google_compute_target_https_proxy" "website" {
  name             = "website"
  description      = "a description"
  url_map          = "${google_compute_url_map.website.self_link}"
  ssl_certificates = ["${google_compute_ssl_certificate.website-20180815.self_link}"]
}
```

### 5\. Global Forwarding Rule

最後にグローバル転送ルールを設定します。

![HTTP負荷分散におけるグローバル転送ルールの役割を示す構成図](/_astro/08-17-2-fa7d201a.RWbTT4WZ_Z1dbAPm.webp)

#### 5.1. global address

HTTP(S) 負荷分散が受け付けるIPアドレスを設定します。  
静的外部IPアドレスのうち、グローバル静的外部IPアドレスが必要になります。

##### document

[https://cloud.google.com/compute/docs/ip-addresses/#reservedaddress](https://cloud.google.com/compute/docs/ip-addresses/#reservedaddress)

> グローバル静的外部 IP アドレスは、グローバル負荷分散に使用されるグローバル転送ルールでのみ使用できます。グローバル IP アドレスをリージョン IP アドレスまたはゾーンリソースに割り当てることはできません。

##### code

[https://www.terraform.io/docs/providers/google/d/datasource\_compute\_global\_address.html](https://www.terraform.io/docs/providers/google/d/datasource_compute_global_address.html)

Plain textcontent\_copy

```
resource "google_compute_global_address" "website" {
  name = "website"
}
```

#### 5.2. global\_forwarding\_rule

作成されたグローバル静的IPアドレスとURLマップを設定します。  
これによりInternetから受け付けるIPアドレスとその後の経路の紐付けを行えます。

##### document

[https://cloud.google.com/compute/docs/load-balancing/http/global-forwarding-rules?authuser=19&hl=ja](https://cloud.google.com/compute/docs/load-balancing/http/global-forwarding-rules?authuser=19&hl=ja)

> _グローバル転送ルールは、自分のサイトの DNS レコードで使用できる単一のグローバル IPv4 または IPv6 アドレスを提供します。特定のプロキシについて複数の転送ルールを使用することができるため、IPv4 トラフィック用に 1 つ、IPv6 トラフィック用に 1 つのルールを設定することができます。_

##### code

[https://www.terraform.io/docs/providers/google/r/compute\_global\_forwarding\_rule.html](https://www.terraform.io/docs/providers/google/r/compute_global_forwarding_rule.html)

Plain textcontent\_copy

```
resource "google_compute_global_forwarding_rule" "website" {
  name         = "website"
  depends_on   = [
    "google_compute_target_https_proxy.website",
    "google_compute_global_address.website"
  ]
  target       = "${google_compute_target_https_proxy.website.self_link}"
  ip_protocol  = "TCP"
  port_range   = "443"
  ip_address   = "${google_compute_global_address.website.address}"
}
```

## まとめ

だいぶ駆け足となってしまいましたが、以上でHTTP(S)負荷分散を作成できたかと思います。

こうして紐解いてみると案外多数の要素で構成されていることがわかるかと思います。 機能をひとつひとつ読み解くことで理解の一助になりますと幸いです。

## この記事を書いた人

[![](/_astro/noicon.CTHOhNiB_Z24aAgM.webp)](/authors/okawa/)

### [okawa](/authors/okawa/)

okawaのプロフィールと執筆記事をご覧いただけます。

[プロフィールと記事一覧](/authors/okawa/)