0
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?

Terraformで構築するOCIのAPI Gatewayとロードバランサ連携

Last updated at Posted at 2025-04-06

1. はじめに

Oracle Cloud Infrastructure(OCI)のAPI Gatewayを利用することで、ロードバランサ(Load Balancer)を通してコンピュートインスタンス(Compute Instance)のWebサーバ(Apache)を返す環境を作成したので、その内容について以下を中心に記載しています。

  • API Gatewayやロードバランサ、コンピュートインスタンスの役割と連携
  • Terraformを使用したインフラ構築コード

2. 全体アーキテクチャ

2.1 各サービスの役割

API Gateway: 外部からのHTTPリクエストを受け取り、適切なバックエンド(この場合はLoad Balancer)に転送します。
Load Balancer: API Gatewayからのリクエストを受け、指定されたバックエンド(Computeインスタンス)に負荷分散します。
Compute Instance: HelloWorldページを提供するシンプルなWebサーバ(Apache)として動作します。

2.2 アーキテクチャ図

以下の構成でリクエストが処理されます。
003.png

3. Terraformコード

Terraformを使用して、以下のリソースを構築します。

  • VCNとサブネット
  • Computeインスタンス
  • Load Balancer
  • API Gateway

3.1 VCNとサブネット

ネットワークの基盤となるVCN(仮想クラウドネットワーク)と、その内部に作成するサブネットを定義します。

resource "oci_core_vcn" "my_vcn" {
  compartment_id = var.compartment_ocid
  cidr_block     = "10.0.0.0/16"
  display_name   = "my_vcn"
  dns_label      = "myvcn"
}

resource "oci_core_subnet" "my_subnet" {
  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.my_vcn.id
  cidr_block     = "10.0.1.0/24"
  display_name   = "my_subnet"
  prohibit_public_ip_on_vnic = false
  route_table_id = oci_core_route_table.my_route_table.id
  dns_label      = "pub1"
}

resource "oci_core_network_security_group" "my_nsg" {
  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.my_vcn.id
  display_name   = "my_nsg"
}

resource "oci_core_network_security_group_security_rule" "my_nsg_rule" {
  network_security_group_id = oci_core_network_security_group.my_nsg.id
  direction = "INGRESS"
  protocol  = "6"
  source    = "0.0.0.0/0"

  tcp_options {
    destination_port_range {
      min = 80
      max = 80
    }
  }
}

resource "oci_core_network_security_group_security_rule" "my_nsg_https_rule" {
  network_security_group_id = oci_core_network_security_group.my_nsg.id
  direction = "INGRESS"
  protocol  = "6"
  source    = "0.0.0.0/0"

  tcp_options {
    destination_port_range {
      min = 443
      max = 443
    }
  }
}

resource "oci_core_internet_gateway" "my_igw" {
  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.my_vcn.id
  display_name   = "my_internet_gateway"
  enabled        = true
}

resource "oci_core_route_table" "my_route_table" {
  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.my_vcn.id

  route_rules {
    destination = "0.0.0.0/0"
    network_entity_id = oci_core_internet_gateway.my_igw.id
  }
}

3.2 Load Balancer

ロードバランサは本体の作成に以下の設定を含んで作成しています。

バックエンドセット: Computeインスタンスを登録。
ヘルスチェック: HTTPプロトコルでバックエンドの正常性を監視。

resource "oci_load_balancer_load_balancer" "my_lb" {
  compartment_id = var.compartment_ocid
  display_name   = "my_lb"
  shape          = "100Mbps"
  subnet_ids     = [oci_core_subnet.my_subnet.id]
  network_security_group_ids = [oci_core_network_security_group.my_nsg.id] 
}

resource "oci_load_balancer_backend_set" "my_backend_set" {
  load_balancer_id = oci_load_balancer_load_balancer.my_lb.id
  name             = "my_backend_set"
  policy           = "ROUND_ROBIN"

  health_checker {
    protocol = "HTTP"
    url_path = "/"
    port     = 80
  }
}

resource "oci_load_balancer_backend" "my_backend" {
  load_balancer_id   = oci_load_balancer_load_balancer.my_lb.id
  backendset_name    = oci_load_balancer_backend_set.my_backend_set.name
  ip_address         = oci_core_instance.my_instance.private_ip
  port               = 80
}

resource "oci_load_balancer_listener" "my_listener" {
  load_balancer_id = oci_load_balancer_load_balancer.my_lb.id
  name             = "my_listener"
  protocol         = "HTTP"
  port             = 80
  default_backend_set_name = oci_load_balancer_backend_set.my_backend_set.name
}

3.3API Gatewayとデプロイメント

API Gatewayの作成と、その上で動作するデプロイメント(APIのルーティングとバックエンドの設定)の定義について作成しています。

※デプロイメントの役割
デプロイメントは、API Gatewayに設定される「ルートマップ」として機能します。具体的には以下を定義します:

リクエストのルーティング: 特定のパス(例: /helloworld)やHTTPメソッド(GET, POSTなど)に基づいてリクエストをどのバックエンドに転送するかを指定します。
バックエンドの接続情報: リクエストを処理するバックエンド(ここではロードバランサ)のURLを指定します。
これにより、API Gatewayが適切なバックエンドリソースにリクエストをルーティングし、クライアントに応答を返す仕組みを構築できます。

resource "oci_apigateway_gateway" "my_api_gateway" {
  compartment_id = var.compartment_ocid
  display_name   = "my_api_gateway"
  endpoint_type  = "PUBLIC"
  subnet_id      = oci_core_subnet.my_subnet.id
  network_security_group_ids = [oci_core_network_security_group.my_nsg.id] 
}

resource "oci_apigateway_deployment" "my_api_deployment" {
  compartment_id = var.compartment_ocid
  display_name   = "my_api_deployment"
  gateway_id     = oci_apigateway_gateway.my_api_gateway.id
  path_prefix    = "/helloworld"

  specification {
    routes {
      path = "/"
      methods = ["GET"]
      backend {
        type = "HTTP_BACKEND"
        url  = "http://${oci_load_balancer_load_balancer.my_lb.ip_address_details[0].ip_address}/"
      }
    }
  }
}

path_prefixを"/helloworld/"のように最後に/を入れたら以下のエラーが出ました。最後に/はいれたら内容です。

Error: 400-InvalidParameter, Invalid pathPrefix: must not end with '/'
Suggestion: Please update the parameter(s) in the Terraform config as per error message Invalid pathPrefix: must not end with '/'

3.4 Computeインスタンス

以下の設定でComputeインスタンスを作成します。

Apacheを自動インストール: user_data を使い、インスタンス起動時にApacheをインストールしてHelloWorldページを設定します。
firewalldを無効化: Oracle Linuxでデフォルト有効になっているfirewalldを停止しています。

resource "oci_core_instance" "my_instance" {
  compartment_id       = var.compartment_ocid
  availability_domain  = "Vior:AP-TOKYO-1-AD-1"
  shape                = "VM.Standard.A1.Flex"
  display_name         = "my_compute_instance"

  create_vnic_details {
    subnet_id = oci_core_subnet.my_subnet.id
    assign_public_ip  = false
    nsg_ids   = [oci_core_network_security_group.my_nsg.id] 
  }

  source_details {
    source_type = "image"
    source_id   = "ocid1.image.oc1.ap-tokyo-1.aaaaaaaa5bee4ivdv6ymoykdziexp3hvaapltwqhiklcbszv3bno4gbyncpq"
  }

  shape_config {
    ocpus         = 4
    memory_in_gbs = 8
  }

  metadata = {
    ssh_authorized_keys = var.ssh_public_key
    user_data = base64encode(<<-EOF
      #!/bin/bash
      sudo yum install -y httpd
      echo '<html><body><h1>helloworld</h1></body></html>' > /var/www/html/index.html
      sudo systemctl start httpd
      sudo systemctl enable httpd
      sudo systemctl stop firewalld  # firewalldを停止
      sudo systemctl disable firewalld  # firewalldを無効化(自動起動をオフ)
      EOF
    )
  }
}

3.5 variables

Terraformでは、変数を利用することでコードの再利用性できます(今回は変数を1回しか利用してないので変数化しなくてもよかったのですが使ってみたいので)。

変数の説明
ssh_public_key: コンピュートインスタンスへのSSH接続に使用する公開鍵を指定します。
もしこちらを参考にするようなことがあれば、xxxxの箇所を実際に使用する公開鍵に置き換えてください。
compartment_ocid: リソースが作成されるOCIのコンパートメントを指定します。

variable "ssh_public_key" {
  description = "Public SSH key to be used for the compute instance."
  type        = string
  default     = "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvWlbXXXXXXXXXXXXXX"  # デフォルトのSSH公開鍵
}

variable "compartment_ocid" {
  default = "ocid1.compartment.oc1..aaaaaaaazlydmn3is6vsmgllckofon62npunr5shgemek35zdnai36fpa2ga"
}

3.6 provider.tf

OCIプロバイダを設定しています。

provider "oci" {
}

4. 動作確認

APIエンドポイントの確認: Terraformが出力するAPIエンドポイントを使ってブラウザからアクセスし、HelloWorldページが正しく表示されることを確認します。
004.png

LoadBalancerのIP確認: ロードバランサーのIPアドレスを使って、直接アクセスした際の応答も確認します。
005.png

5. 作成されたリソースの確認

Terraformで作成したリソースがOCIコンソール上に正しく表示されているかを確認します。画面で設定値は確認できるもので、ポイントとなる箇所については文章補足しています。

5.1 API Gateway

API Gatewayの設定確認
API Gateway > APIゲートウェイ > ゲートウェイ > ゲートウェイの詳細 でゲートウェイのエンドポイントや紐付けられたデプロイメントを確認します。
0052.png

デプロイメントの詳細
OCIコンソール > API Gateway > APIゲートウェイ > ゲートウェイ > ゲートウェイの詳細 > デプロイメントの詳細でデプロイメントのルーティング設定やバックエンド情報が正しいことを確認します。ここに表示されているホスト名がhttpアクセスするAPI情報です
006.png

5.2 LB

LBとヘルスチェック
OCIコンソール > ネットワーキング > ロード・バランサ > ロード・バランサ詳細 でヘルスチェックがOKとなっていることを確認します。
007.png

バックエンドセット
OCIコンソール > ロード・バランサ詳細 > バックエンド・セット でComputeインスタンスがバックエンドとして登録され、正常に動作していることを確認します。
008.png

5.3 Compputeインスタンス

IPアドレス確認
OCIコンソール > コンピュート > インスタンス > インスタンスの詳細 でインスタンスのプライベートIPがロードバランサに登録されたIPと一致していることを確認します。
009.png

6. 参考資料

Terraform公式ドキュメント
TerraformでOCIリソースを構築する際の詳細な設定や例は以下の公式ドキュメントを参照してみてください。

0
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
0
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?