※ 本記事は、Martin Bachによる”Using Terraform to create Container Instances in Oracle Cloud Infrastructure“を翻訳したものです。

2023年2月21日


Oracle Cloud Infrastructure(OCI)Container Instanceは、サーバーを管理せずに迅速かつ簡単にコンテナを実行できるサーバーレス・コンピュート・サービスです。Container Instanceは、仮想マシンと同じ分離を提供するコンテナ・ワークロード用に最適化されたサーバーレス・コンピュートでコンテナを実行します。

Container Instanceは、通常Kubernetesクラスタを使用することで得られる追加のメリットを必要とせずにコンテナを実行する場合に最適です。OCI Container Instanceの概要については、ドキュメントおよび「First Principles: Inside OCI Container Instances」というYouTubeビデオを参照してください。

次の例は、TerraformでContainer Instanceを作成する方法を示しています。コードを単一のTerraformファイルに自己完結させるため、実際のワークロードは、デフォルトのディレクトリおよびファイル構造を使用してベスト・プラクティスに従う必要があります。この例は、MacOSでOCIプロバイダ 4.107.0を使用してTerraform 1.3.7を使用してテストされました。

概要

この例のTerraformコードは、単一のパブリック・サブネットを持つ小さなVirtual Cloud Network(VCN)を作成し、HTTP:2.4コンテナへのアクセスをデフォルト・ページ以外に何も提供しません。これは、記事の長さを合理的に短くしながら、基本的な概念をカバーするのに十分です。追加のブログ投稿では、プライベート・コンテナ・レジストリからイメージをプルする方法、リソースの使用制限、およびボリュームの使用について説明します。

Network Diagram

これらのリソースの作成にコストがかかる場合があります。

Terraform用のOCIプロバイダの構成

最初のステップは、OCI APIへの接続を構成することです。これは、OCI用のTerraform Providerによって行われます。Terraformを使用するには、必要なAPIキーとOracle Cloud IDs(OCID)が使用可能であることを確認する必要があります。詳細は、OCI Provider for Terraformのドキュメントを参照してください。この例では、API-key認証を使用します。コードを再利用できるようにするために、プロバイダ構成は環境変数によって提供されます。次の変数の最初の6つは一目瞭然ですが、7番目はそうではありません。

Terraformコードは、ホームIPアドレスのx.x.x.x/32 などのサブネット範囲を”home IP CIDR”として受け入れます。このアドレス範囲は、HTTPdコンテナのポート80へのアクセスを許可されます。コンテナを世界中に開くため、ここで0.0.0.0/0を使用しないでください。

# ------------------------------------------------------------------------------------------------ variables

variable "tenancy_ocid" {}
variable "user_ocid" {}
variable "key_fingerprint" {}
variable "private_key_path" {}
variable "oci_region" {}
variable "compartment_ocid" {}
variable "home_address_cidr" {}

# ------------------------------------------------------------------------------------------------ provider

provider "oci" {

  tenancy_ocid     = var.tenancy_ocid
  user_ocid        = var.user_ocid
  private_key_path = var.private_key_path
  fingerprint      = var.key_fingerprint
  region           = var.oci_region
}

terraform {

  required_providers {
    oci = {
      source  = "oracle/oci"
      version = ">= 4.107.0"
    }
  }
}

OCIプロバイダに必要な詳細を渡す(この例ではAPIキー認証を使用)以外に、プロバイダのソースがoracle/ociに変更され、以前に使用されたhashicorp/ociの場所が変わります。詳細は、ドキュメントのレジストリおよびネームスペースの変更を参照してください。

Virtual Cloudネットワークの構成

Virtual Cloud Network(VCN)なしでクラウド・リソースを作成することはできません。この例では、最低限実行可能なVCNが作成され、パブリック・サブネットに存在するContainer Instanceが制限内で外部と通信できるようになります。パブリック・サブネットに関連付けられたセキュリティ・リストでは、コンテナ・レジストリからイメージをプルするための送信HTTPSアクセスのみが許可されます。var.home_address_cidrに一致するポート80でインバウンド・トラフィックが許可されます。

# ------------------------------------------------------------------------------------------------ network

#
# the VCN resource
#

resource "oci_core_vcn" "demo_vcn" {

  compartment_id = var.compartment_ocid
  cidr_block     = "10.0.0.0/16"
  display_name   = "demo-vcn"
  dns_label      = "demo"
  freeform_tags = {
    "project-name" = "blogpost"
  }
}

#
# The default security list grants access to the container instance
# and allows pulling images from container registries via HTTPS
#

resource "oci_core_security_list" "public_sn_sl" {

  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.demo_vcn.id
  display_name   = "demo-vcn - security list for the public subnet"
  ingress_security_rules {

    protocol    = 6
    source_type = "CIDR_BLOCK"
    source      = var.home_address_cidr
    description = "access to container instance port 80 from home"
    tcp_options {

      min = 80
      max = 80
    }
  }

  egress_security_rules {

    protocol         = 6
    destination_type = "CIDR_BLOCK"
    destination      = "0.0.0.0/0"
    description      = "access to container registries via HTTPS"
    tcp_options {
      min = 443
      max = 443
    }
  }

  freeform_tags = {
    "project-name" = "blogpost"
  }

}

#
# A subnet for the Container Instance referencing the previously created security list
#

resource "oci_core_subnet" "demo_subnet" {

  cidr_block     = "10.0.0.0/24"
  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.demo_vcn.id
  display_name   = "demo vcn - container instance (public) subnet"
  dns_label      = "containers"
  security_list_ids = [
    oci_core_security_list.public_sn_sl.id
  ]
  route_table_id = oci_core_route_table.demo_igw_rt.id
  freeform_tags = {
    "project-name" = "blogpost"
  }
}

#
# Internet Gateway & Route Table
#

resource "oci_core_internet_gateway" "demo_igw" {

  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.demo_vcn.id
  display_name   = "demo-vcn - Internet gateway"
  enabled        = true
}

resource "oci_core_route_table" "demo_igw_rt" {

  compartment_id = var.compartment_ocid
  vcn_id         = oci_core_vcn.demo_vcn.id
  display_name   = "demo vcn - Internet gateway route table"
  route_rules {

    network_entity_id = oci_core_internet_gateway.demo_igw.id
    destination       = "0.0.0.0/0"
  }

  freeform_tags = {
    "project-name" = "blogpost"
  }
}

Container Instanceの作成

VCNを配置して、Container Instanceを作成します。最初のステップは、ローカル・アベイラビリティ・ドメイン(AD)の名前を取得することです。これを使用すると、OCI Container Instanceを作成できます。繰り返しになりますが、これは最小限の実行可能な例です。さらにブログ投稿では、プライベート・レジストリからイメージをプルする方法、リソース使用率を制限する方法、ボリュームを使用する方法、および高度なトピックの多くが説明されています

# ------------------------------------------------------------------------------------------------ container instance

data "oci_identity_availability_domains" "local_ads" {

  compartment_id = var.compartment_ocid
}

resource "oci_container_instances_container_instance" "demo_container_instance" {

  # create the container instance in AD1
  availability_domain      = data.oci_identity_availability_domains.local_ads.availability_domains.0.name
  compartment_id           = var.compartment_ocid
  freeform_tags            = { "project-name" = "blogpost" }
  display_name             = "demo container instance"
  container_restart_policy = "ALWAYS"
  shape                    = "CI.Standard.E4.Flex"
  shape_config {

    memory_in_gbs = 4
    ocpus         = 1
  }

  vnics {

    subnet_id             = oci_core_subnet.demo_subnet.id
    display_name          = "demo-container-instance"
    is_public_ip_assigned = true
    nsg_ids               = []
  }

  containers {

    image_url    = "httpd:2.4"
    display_name = "demo apache http server container"
  }
}

OCI Container Instanceは、1 Oracle CPU(OCPU)と4GBメモリーのみを使用して、E4 Flexシェイプを使用して最初のADに作成されます。VNICブロック内では、Container InstanceにパブリックIPアドレスが割り当てられます。使用するコンテナ・イメージはcontainers {} blockで定義されています。デフォルト設定のパブリックHTTPd(別名 Apache Web サーバー)は、パブリックDockerレジストリから参照されます。

まとめ

OCI Container Instanceは非常に迅速に開始でき、完全なKubernetesインストールが必要ないシナリオでも簡単に使用できます。コンテナを実行するだけで済む場合は、Container Instanceが適切なソリューションになる可能性があります。