6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Google Cloud の API GatewayをTerraformで扱う際に注意すること

Posted at

はじめに

Google Cloudを用いたプロジェクトでAPI Gatewayを用いてバックエンドのCloud Runとやり取りをする構成を作成しました。その際に、API GatewayをTerraformで設計しました。
ここでは、TerraformでAPI Gatewayを扱う際の注意事項について記事にします。

API Gatewayの構成要素

Google CloudのAPI Gatewayは以下のような構成で作られています。

  • API:API全体を管理するための論理的な「コンテナ(入れ物)」です。APIの名前などの管理情報を保持し、後述するAPI ConfigとGatewayは、このAPIリソースの中に作成されます
  • API Config: APIの具体的な振る舞いを定義する「設計図」にあたる設定情報です。Swagger 2.0形式をサポートしており、YAML形式で表現され、APIのパス、バックエンドへのルーティングルールなどを記述します
  • Gateway (ゲートウェイ):API Configをデプロイして作成される、リクエストを処理する「実体」です。このGatewayに固有のURL(エンドポイント)が割り当てられ、紐づけられたAPI Configの定義に従って、外部からのリクエストを受け付けます

Terraformで記述されるAPI Gatewayの構成要素を視覚的に表現すると以下のようになります。
「API Config」にはAPIの振る舞いを定義したYAMLファイルが含まれており、Configをもとに「Gateway」が作られます。
これらのリソースを「API Gateway」としてまとめて機能するというイメージです
api.png

Terraformでの記述

API GatewayをTerraformで作成するには以下のように記述します。
「google_api_gateway_api」、「google_api_gateway_api_config」、「google_api_gateway_gateway」という3つのリソースが主になっていることがわかります。

また、API Gatewayに対してAPI Keyで認証を行うために「google_apikeys_key」リソースを作成しています。

# Terraform の main.tf
resource "google_api_gateway_api" "api_gw" {
  provider     = google-beta
  project      = test_project
  api_id       = "api-gw-test"
  display_name = "api-gw-test"
}

resource "google_api_gateway_api_config" "api_gw" {
  provider             = google-beta
  project              = test_project
  api                  = google_api_gateway_api.api_gw.api_id
  api_config_id_prefix = "config-api-gw-test"

  gateway_config {
    backend_config {
      google_service_account = <your_service_account_email>
    }
  }
  openapi_documents {
    document {
      path = "spec.yaml"
      contents = base64encode(<api定義のYAMLファイルパス>)
    }
  }
  lifecycle {
    create_before_destroy = true
  }
}

resource "google_api_gateway_gateway" "api_gw" {
  provider     = google-beta
  project      = test_project
  api_config   = google_api_gateway_api_config.api_gw.id
  gateway_id   = "gateway-test"
  display_name = "gateway-test"
  region       = asia-northeast1
}

resource "google_apikeys_key" "api_key" {
  project      = test_project
  name         = "api-key-auth-compute-crun-test"
  display_name = "api-key-auth-compute-crun-test"

  restrictions {
    api_targets {
      service = google_api_gateway_api.api_gw.managed_service
      methods = ["*"]
    }
  }
}

resource "google_project_service" "enable_api_gateway" {
  project = test_project
  service = google_api_gateway_api.api_gw.managed_service

  disable_dependent_services = true

  depends_on = [google_api_gateway_api.api_gw]
}

# api.yaml
swagger: '2.0'
info:
  title: Hello API
  description: Hello World API with API Key and Google Backend
  version: 1.0.0
schemes:
  - https
produces:
  - application/json

x-google-backend:
  address: https://your-backend-url.example.com

security:
  - api_key: []

securityDefinitions:
  api_key:
    type: "apiKey"
    name: "x-api-key"
    in: "header"

paths:
  /hello:
    get:
      summary: Returns a hello message
      operationId: getHello
      responses:
        200:
          description: Successful response
          schema:
            type: object
            properties:
              message:
                type: string
                example: "Hello, world!"
      x-google-backend:
        address: https://your-backend-url.example.com/hello

このようなファイルを準備した状態でTerraformを実行するとAPI Gatewayが作成できます。

API Gatewayの更新について

開発の中でapi.yamlのファイルを更新したい(api定義を更新したい)場合、yamlファイルを更新後に再度terraform applyを実行する必要があります。
この際、「google_api_gateway_api_config」は更新できず、「409 Conflict Error」になります。

API Gatewayの「構成」は基本的に不変であり、変更可能なものは「ラベルと表示名を更新する場合のみ」です。

対策

更新の失敗を回避するには、下記のようにTerraformを更新します。
以下のような点に差異があります。

  • ランダムIDを生成するリソースの追加
  • google_api_gateway_api_configの名前にランダムな文字列を付けるようにする
    具体的には下の2点が変更されています。
resource "random_id" "api_gw_prefix" {
  byte_length = 2
}
api_config_id_prefix = "config-api-gw-test-${random_id.api_gw_prefix.hex}"

変更結果を適用したTerraformは以下になります。

# Terraform の main.tf
resource "random_id" "api_gw_prefix" {
  byte_length = 2
}

resource "google_api_gateway_api" "api_gw" {
  provider     = google-beta
  project      = test_project
  api_id       = "api-gw-test"
  display_name = "api-gw-test"
}

resource "google_api_gateway_api_config" "api_gw" {
  provider             = google-beta
  project              = test_project
  api                  = google_api_gateway_api.api_gw.api_id
  api_config_id_prefix = "config-api-gw-test-${random_id.api_gw_prefix.hex}"

  gateway_config {
    backend_config {
      google_service_account = <your_service_account_email>
    }
  }
  openapi_documents {
    document {
      path = "spec.yaml"
      contents = base64encode(<api定義のYAMLファイルパス>)
    }
  }
  lifecycle {
    create_before_destroy = true
  }
}

resource "google_api_gateway_gateway" "api_gw" {
  provider     = google-beta
  project      = test_project
  api_config   = google_api_gateway_api_config.api_gw.id
  gateway_id   = "gateway-test"
  display_name = "gateway-test"
  region       = asia-northeast1
}


resource "google_apikeys_key" "api_key" {
  project      = test_project
  name         = "api-key-auth-compute-crun-test"
  display_name = "api-key-auth-compute-crun-test"

  restrictions {
    api_targets {
      service = google_api_gateway_api.api_gw.managed_service
      methods = ["*"]
    }
  }
}

resource "google_project_service" "enable_api_gateway" {
  project = test_project
  service = google_api_gateway_api.api_gw.managed_service

  disable_dependent_services = true

  depends_on = [google_api_gateway_api.api_gw]
}

この変更を行うことによって、Conflictを回避しapi gatewayの更新が可能になります。create_before_destroy = trueとしているため、新しいリソースを作成したのち古いリソースは削除されるという動作をします。

終わりに

Terraformで構成管理をしていると開発環境を作ったあと、ステージング環境や本番/商用環境用のディレクトリを作成してそれぞれの環境に展開される事があると思いますが、リソース間の依存などで1回の実行で環境を作り切るのが難しい場面に遭遇しました。よりよいTerraformの構成管理を学んだ際にはまた共有したいと思います。

Appendix

Google CloudのAPI Gatewayは2025年7月1日時点で、Swagger 2.0形式で記述されたAPIのみのサポートです。
OpenAPI 3.0ではないことに注意が必要です。
また、機能の制限についても確認しておく必要があります。

Google Cloudでは、Apigeeというエンタープライズ規模で利用可能なフルマネージドなAPI基盤のサービスも用意されています。
ご自身のユースケースに合わせてApigeeも選択肢になります!

参考資料

6
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?