ALTUSのインフラリソースをTerraformで管理する

はじめに

GMOグローバルサイン・ホールディングスの宮越です。パブリッククラウドサービス「ALTUS」の運用を担当しております。

ALTUSはCloudstackベースの国産パブリッククラウドで、6000件以上の導入実績と万全なカスタマーサポート体制を備えたクラウドサービスとなります。

サーバー運用初心者に優しい設計となっており、Web上のコンソール画面での直感的な操作でクラウドインフラの構築、運用、管理を行うことができます。

しかし、仮想サーバーの作成や設定変更などを頻繁に行うお客様にとっては、逐一画面上で操作するのは手間となってしまう側面もあります。また、お客様の中にはリソースを厳密にエクセルなどで管理されているところもあるかと思います。

そこで今回、大規模にサーバー運用をされている方々や運用効率化を検討されている方々向けに、ALTUSのリソースをTerraformで管理する方法を紹介したいと思います。

Terraformとは

TerraformはHashiCorp社が開発したオープンソースのIac(インフラストラクチャー・アズ・コード)ツールです。Iacとは言葉通り、インフラをコードで管理する考えとなります。サーバ、ネットワーク、ストレージなどのリソースをコードとして設定ファイルに記述することで、記述した通りの環境セットアップを自動で行うことが可能です。手動プロセスでの人為ミスを回避できたり、運用負担を減少できたりといった利点があります。

この仕組みのおかげで、設定ファイルの内容と実際のインフラ環境がピッタリ重なりあう状態をキープできるので、インフラリソースの状態をエクセルに書き込むといった管理の手間を減らせるのも強みです。

Terraformインストール方法(Windows)

WindowsのPCやサーバーでTerraformを使えるようになるまでの方法を紹介します。インストールと題していますが、公式サイトからバイナリをダウンロードして解凍するだけで使えるようになります。

  1. Terraformの公式サイトから使用しているWindowsのプロセッサに応じてバイナリをダウンロードします。

筆者のPCはx64 ベースのプロセッサだったので、AMD64のバージョンを選びました。

  1. zipファイルがダウンロードされます。解凍すると、「terraform.exe」というファイルが出力されます。

  2. terraform.exeを任意の作業フォルダに移動します。

  3. 環境変数を設定します。そうすることで、コマンドプロンプトからterraformコマンドを直接実行可能になります。

・[コントロールパネル]-[システムとセキュリティ]-[システムの詳細設定]を選択

・システム環境変数の「Path」を選択して「編集」をクリック

・「新規」をクリックして、terraform.exeがあるパス(例:C:\terraform)を追加

・OKを押して環境変数を保存

terraformコマンドが実行可能か確認します。

c:\>terraform --version
Terraform v1.7.4
on windows_amd64

以上を以てWindowsでterraformが使用可能になります。
LinuxやMacOS等の他OSも同じ方法でTerraformを導入可能ですので、是非お試しください。

以降もWindowsのPCからTerraformを実施していますので、その点ご留意ください。

プロバイダ 設定

冒頭で述べたようにALTUSはCloudstackベースのクラウドサービスです。
TerraformではCloudStack Provider(CloudStack環境を管理するためのプラグイン)が提供されているので、これを使用してALTUS環境に接続することができます。

任意のフォルダに新しく 「.tf ファイル」(Terraform設定ファイル)と「.tfvarsファイル」(変数定義ファイル)を作成します。

.tf ファイル

providers.tfというファイル名でCloudStack Providerを使用するための設定を記述します。
APIキー、シークレットキーもこのファイルに記述可能ですが、セキュリティ上の理由から固有の認証情報は.tfvarsファイルに記載して参照するようにします。

variable "api_key" {}
variable "secret_key" {}

terraform {
  required_providers {
    cloudstack = {
      source = "cloudstack/cloudstack"
      version = "0.4.0"
    }
  }
}

provider "cloudstack" {
  api_url    = "https://tky001b.pf.gmocloud.com/client/api"
  api_key    = "${var.api_key}"
  secret_key = "${var.secret_key}"
  http_get_only = true
}

providerで指定しているAPI URL(エンドポイント)、APIキー、シークレットキーは以下サイトの手順から確認することができます。

[ALTUS Basic API] APIキー/アクセスキーの取得

[ALTUS Isolate API] APIキー/アクセスキーの取得

.tfvarsファイル

terraform.tfvarsにAPIキー、シークレットキーの情報を記載します。

api_key = "YOUR_API_KEY"
secret_key = "YOUR_SECRET_KEY"

Terraformプロジェクト 初期セットアップ

terraform initコマンドを実行してTerraformの初期セットアップを行います。
これにより、providers.tfで指定したプロバイダ(CloudStack Provider)のダウンロード・インストールがなされ、ALTUS環境との通信が可能になります。

C:\tf_project> terraform init

Initializing the backend...

Initializing provider plugins...
- Finding cloudstack/cloudstack versions matching "0.4.0"...
- Installing cloudstack/cloudstack v0.4.0...
- Installed cloudstack/cloudstack v0.4.0 (self-signed, key ID AEA5313845ADC482)

<<<中略>>>
Terraform has been successfully initialized!

terraform initはプロジェクトが新規である場合や、.tfファイルに変更を加えた後(特にプロバイダー関連の変更)などに必要な作業となります。Terraformでの作業を開始する際の最初のステップです。

これでTerraformでALTUSのリソースを管理する環境が整いました。次項以降では、リソースの作成、変更、追加、削除の操作についてそれぞれ基本的な実用例を紹介していきます。

ALTUS Terraform操作 実用例

リソース作成

.tfファイルでcloudstack_instanceを定義することで仮想サーバー(VM)を作成することができます。

ALTUSでは、BasicとIsolateの二つのシリーズを提供しており、シリーズによってVMを作成するパラメータが異なるため、それぞれ実例を紹介する形を取ります。

BasicシリーズとIsolateシリーズの違いと共通点

定義ファイル作成

Basicシリーズ用 定義ファイル

以下の内容でbasic-terraform.tf ファイルを作成します。※ファイル名は任意

resource "cloudstack_instance" "vm01" {
  name             = "tf-vm01"
  display_name     = "tf-vm01"
  zone             = "Basic_tky003"
  service_offering = "m1.small"
  security_group_names = ["Normal"]
  template         = "AlmaLinux 9.3 20240207"
  expunge          = true
}
Isolateシリーズ用 定義ファイル

以下の内容でisolate-terraform.tf ファイルを作成します。Basicとの違いは、security_groupの代わりにnetworkを指定しています。

resource "cloudstack_instance" "vm01" {
  name             = "tf-vm01"
  display_name     = "tf-vm01"
  zone             = "Isolate_tky001"
  service_offering = "SV2(1 vCPU / 2GB RAM)"
  network_id = "35d2acc8-654f-403d-840d-dd48de0f0dd8"
  template         = "AlmaLinux 9.3 20240207"
  expunge          = true
}
パラメータ説明

・name: 仮想サーバー名(必須)
・display_name: 仮想サーバー表示名(任意)
・zone: 仮想サーバー作成先のゾーン名またはID(必須)
・service_offering:サービスオファリング(CPU/メモリのサイズ)名またはID(必須)
・security_group_names:セキュリティーグループ(ファイアーウォール)名。リスト形式で記載します。(任意)
・template:OSテンプレート名またはID(必須)
・expunge: インスタンスが破棄されたときに抹消されるかどうかを決定するフラグ(任意、default:false)

terraform plan

実際の作成を実行する前に、teraform planコマンドでTerraformによるインフラストラクチャーの変更計画を表示させ、表示内容が意図した結果であるかを確認(レビュー)します。もし記述に問題があればエラーを出してくれます。

PS C:\tf> terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # cloudstack_instance.vm01 will be created
  + resource "cloudstack_instance" "vm01" {
      + display_name         = "tf-vm01"
      + expunge              = true
      + group                = (known after apply)
      + id                   = (known after apply)
      + ip_address           = (known after apply)
      + name                 = "tf-vm01"
      + network_id           = (known after apply)
      + project              = (known after apply)
      + root_disk_size       = (known after apply)
      + security_group_names = [
          + "Normal",
        ]
      + service_offering     = "m1.small"
      + start_vm             = true
      + tags                 = (known after apply)
      + template             = "AlmaLinux 9.3 20240207"
      + zone                 = "Basic_tky003"
    }

VMの作成計画が表示されました。左にある+ はリソースが新規に作成されることを示しています。

terraform apply

planで問題ないことが確認できたら、terraform applyコマンドで適用を実行します。

PS C:\tf> terraform apply
<<<中略>>>
cloudstack_instance.vm01: Still creating... [1m30s elapsed]
cloudstack_instance.vm01: Creation complete after 1m33s [id=517bf3ef-adfa-4bf9-8506-eb5e298e86d0]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

定義ファイルの記述通りに仮想サーバーが自動で構築されました。

terraform show

applyコマンドの処理が完了したら、terraform showコマンドで作成された仮想サーバーの情報を見ることができます。

planで(known after apply)と表示されていたパラメータの値も参照できるようになっています。

C:\tf> terraform show
# cloudstack_instance.vm01:
resource "cloudstack_instance" "vm01" {
    display_name         = "tf-vm01"
    expunge              = true
    id                   = "517bf3ef-adfa-4bf9-8506-eb5e298e86d0"
    ip_address           = "172.31.231.103"
    name                 = "tf-vm01"
    network_id           = "8e555c76-8da9-45ee-9352-e6314ed6c890"
    root_disk_size       = 20
    security_group_names = [
        "Normal",
    ]
    service_offering     = "m1.small"
    start_vm             = true
    tags                 = {}
    template             = "AlmaLinux 9.3 20240207"
    zone                 = "Basic_tky003"
}

リソース変更(service_offering)

Terraformでは設定ファイルを書き換えることで、実際のリソースに変更を反映させることができます。

ここでは、service_offering(CPU/メモリのサイズ)を変更してみます。

定義ファイル修正

basic-terraform.tf のservice_offering をm1.small から m1.large に変更します。

resource "cloudstack_instance" "vm01" {
  name             = "tf-vm01"
  display_name     = "tf-vm01"
  zone             = "Basic_tky003"
  service_offering = "m1.large"
  security_group_names = ["Normal"]
  template         = "AlmaLinux 9.3 20240207"
  expunge          = true
}

terraform plan

planを実行すると次のように変更内容が表示されます。

  # cloudstack_instance.vm01 will be updated in-place
  ~ resource "cloudstack_instance" "vm01" {
        id                   = "517bf3ef-adfa-4bf9-8506-eb5e298e86d0"
        name                 = "tf-vm01"
      ~ service_offering     = "m1.small" -> "m1.large"
        tags                 = {}
        # (9 unchanged attributes hidden)
    }

Plan: 0 to add, 1 to change, 0 to destroy.

~マークはリソースに変更が加えられることを示します。

terraform apply / show

terraform applyで変更を反映させ、terraform show コマンドでservice_offering(CPU/メモリのサイズ)が変更されていることが確認できます。

C:\tf> terraform apply
<<<中略>>>
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.

C:\tf> terraform show
# cloudstack_instance.vm01:
resource "cloudstack_instance" "vm01" {
    display_name         = "tf-vm01"
    expunge              = true
    id                   = "517bf3ef-adfa-4bf9-8506-eb5e298e86d0"
    ip_address           = "172.31.231.103"
    name                 = "tf-vm01"
    network_id           = "8e555c76-8da9-45ee-9352-e6314ed6c890"
    root_disk_size       = 20
    security_group_names = [
        "Normal",
    ]
    service_offering     = "m1.large"
    start_vm             = true
    tags                 = {}
    template             = "AlmaLinux 9.3 20240207"
    zone                 = "Basic_tky003"
}

注意点

service_offeringの変更は仮想サーバーの電源を停止しなければできない処理となります。apply実行時に特に警告などはなかったですが、変更の反映中にバックグラウンドで仮想サーバーの停止も行われていました。

変更内容によっては、サーバー停止が発生するので、その点は考慮の上実行する必要があります。

リソース変更(template)

templateの値を変更する事例も紹介します。

定義ファイル修正

basic-terraform.tf のtemplate をAlmaLinux 9.3 20240207 から AlmaLinux 8.9 20240207 に変更します。

resource "cloudstack_instance" "vm01" {
  name             = "tf-vm01"
  display_name     = "tf-vm01"
  zone             = "Basic_tky003"
  service_offering = "m1.large"
  security_group_names = ["Normal"]
  template         = "AlmaLinux 8.9 20240207"
  expunge          = true
}

terraform plan

planを実行すると次のように変更内容が表示されます。

  # cloudstack_instance.vm01 must be replaced
-/+ resource "cloudstack_instance" "vm01" {
      + group                = (known after apply)
      ~ id                   = "517bf3ef-adfa-4bf9-8506-eb5e298e86d0" -> (known after apply)
      ~ ip_address           = "172.31.231.103" -> (known after apply)
        name                 = "tf-vm01"
      ~ network_id           = "8e555c76-8da9-45ee-9352-e6314ed6c890" -> (known after apply)
      + project              = (known after apply)
      ~ root_disk_size       = 20 -> (known after apply)
      ~ tags                 = {} -> (known after apply)
      ~ template             = "AlmaLinux 9.3 20240207" -> "AlmaLinux 8.9 20240207" # forces replacement
        # (6 unchanged attributes hidden)
    }

Plan: 1 to add, 0 to change, 1 to destroy.

service_offeringを変更したときと異なり、既存の仮想サーバーが削除され再作成される内容が表示されました。仮想サーバーのテンプレートを変えるということは、中のOSを別物にすることと同じなので、サーバーを一度抹消し、再作成する動きになってしまいます。

terraform apply / show

terraform applyで変更を反映させると、仮想サーバーに対してDestroyとCreateの処理が流れます。showで確認すると、idやtemplateが変わり、別のリソースとして作り直されたことが見て取れます。

C:\tf> terraform apply
<<<中略>>>
cloudstack_instance.vm01: Destroying... [id=517bf3ef-adfa-4bf9-8506-eb5e298e86d0]
<<<中略>>>
cloudstack_instance.vm01: Creating...

C:\tf> terraform show
# cloudstack_instance.vm01:
resource "cloudstack_instance" "vm01" {
    display_name         = "tf-vm01"
    expunge              = true
    id                   = "ac087d1a-3047-424f-ae00-3b72b95b8254"
    ip_address           = "172.31.231.103"
    name                 = "tf-vm01"
    network_id           = "8e555c76-8da9-45ee-9352-e6314ed6c890"
    root_disk_size       = 20
    security_group_names = [
        "Normal",
    ]
    service_offering     = "m1.large"
    start_vm             = true
    tags                 = {}
    template             = "AlmaLinux 8.9 20240207"
    zone                 = "Basic_tky003"
}

リソース追加

仮想サーバーに一つデータディスクを追加してみます。

定義ファイル修正

basic-terraform.tf にデータディスクの定義を追記します。
tf-datadisk01 という名前で10Gのデータディスクを作成し、先ほど作成した仮想マシンへアタッチします。

resource "cloudstack_disk" "datadisk01" {
  name             = "tf-datadisk01"
  disk_offering    = "51b2caac-cfda-44e2-8212-ff424ab112a7"
  size             = 10
  attach           = true
  virtual_machine_id  = "ac087d1a-3047-424f-ae00-3b72b95b8254"
  zone             = "${cloudstack_instance.vm01.zone}"
}

各パラメータの参照方法は次の通りです。

virtual_machine_id

terraform showコマンドで参照可能です。

resource "cloudstack_instance" "vm01" {
    display_name         = "tf-vm01"
    expunge              = true
    id                   = "ac087d1a-3047-424f-ae00-3b72b95b8254"
zone

ゾーンは${cloudstack_instance.vm01.zone}という形で変数定義して参照します。

disk_offering

ALTUSの仕様で、disk_offering(ディスクのプリセット構成)はIDでの指定に限られます。提供しているdisk_offeringはStandard Disk 1GB~2000GBのみなので、そのIDを調べる必要があります。

少し裏技な感じですが、次の方法でIDを参照可能です。

  • ALTUSのポータルサイトにログイン
  • ポータルサイトから該当のシリーズ(Basic/Isolate)のWebコンソールに接続
  • Webコンソールへの接続に用いたWebブラウザで新しいタブを追加し、以下のURLにアクセス
  • idタグの値が指定するIDとなります。
<Basic>
https://tky001b.pf.gmocloud.com/client/api?command=listDiskOfferings&name=Standard%20Disk%201GB%7E2000GB

<Isolate>
https://tky001i.pf.gmocloud.com/client/api?command=listDiskOfferings&name=Standard%20Disk%201GB%7E2000GB

terraform plan

planを実行すると次のようにデータディスクが作成される内容が表示されます。

  # cloudstack_disk.datadisk01 will be created
  + resource "cloudstack_disk" "datadisk01" {
      + attach             = true
      + device_id          = (known after apply)
      + disk_offering      = "51b2caac-cfda-44e2-8212-ff424ab112a7"
      + id                 = (known after apply)
      + name               = "tf-datadisk01"
      + project            = (known after apply)
      + shrink_ok          = false
      + size               = 10
      + tags               = (known after apply)
      + virtual_machine_id = "ac087d1a-3047-424f-ae00-3b72b95b8254"
      + zone               = "Basic_tky003"
    }

Plan: 1 to add, 0 to change, 0 to destroy.

terraform apply / show

terraform apply, terraform show を実行すると実際にデータディスクが作成され仮想サーバーにアタッチされたことが確認できます。

C:\tf> terraform apply
C:\tf> terraform show
# cloudstack_disk.datadisk01:
resource "cloudstack_disk" "datadisk01" {
    attach             = true
    device_id          = 1
    disk_offering      = "51b2caac-cfda-44e2-8212-ff424ab112a7"
    id                 = "28531041-899b-444a-8a8b-5abe19b1f6e7"
    name               = "tf-datadisk01"
    shrink_ok          = false
    size               = 10
    tags               = {}
    virtual_machine_id = "ac087d1a-3047-424f-ae00-3b72b95b8254"
    zone               = "Basic_tky003"
}

# cloudstack_instance.vm01:
resource "cloudstack_instance" "vm01" {
    display_name         = "tf-vm01"
    expunge              = true
    id                   = "ac087d1a-3047-424f-ae00-3b72b95b8254"
    ip_address           = "172.31.231.103"
    name                 = "tf-vm01"
    network_id           = "8e555c76-8da9-45ee-9352-e6314ed6c890"
    root_disk_size       = 20
    security_group_names = [
        "Normal",
    ]
    service_offering     = "m1.large"
    start_vm             = true
    tags                 = {}
    template             = "AlmaLinux 8.9 20240207"
    zone                 = "Basic_tky003"
}

リソース削除

設定ファイルからリソースの記述消して、terraform applyを実行することでリソースを削除することができます。

定義ファイル修正

今回はデータディスクを削除してみます。
basic-terraform.tfのデータディスクの部分をコメントアウト(/*~*/)します。

resource "cloudstack_instance" "vm01" {
  name             = "tf-vm01"
  display_name     = "tf-vm01"
  zone             = "Basic_tky003"
  service_offering = "m1.large"
  security_group_names = ["Normal"]
  template         = "AlmaLinux 9.3 20240207"
  expunge          = true
}

/*
resource "cloudstack_disk" "datadisk01" {
  name             = "tf-datadisk01"
  disk_offering    = "51b2caac-cfda-44e2-8212-ff424ab112a7"
  size             = 10
  attach           = true
  virtual_machine_id  = "a6ebb351-4f86-4d60-9e21-4c3f1d61baaf"
  zone             = "${cloudstack_instance.vm01.zone}"
}
*/

terraform plan / apply

planで確認すると次の結果が表示されます。- はリソースが削除されること示すマークです。

  # cloudstack_disk.datadisk01 will be destroyed
  # (because cloudstack_disk.datadisk01 is not in configuration)
  - resource "cloudstack_disk" "datadisk01" {
      - attach             = true -> null
      - device_id          = 1 -> null
      - disk_offering      = "51b2caac-cfda-44e2-8212-ff424ab112a7" -> null
      - id                 = "28531041-899b-444a-8a8b-5abe19b1f6e7" -> null
      - name               = "tf-datadisk01" -> null
      - shrink_ok          = false -> null
      - size               = 10 -> null
      - tags               = {} -> null
      - virtual_machine_id = "a6ebb351-4f86-4d60-9e21-4c3f1d61baaf" -> null
      - zone               = "Basic_tky003" -> null
    }

Plan: 0 to add, 0 to change, 1 to destroy.

terraform applyを実行して削除を行います。
もしデータディスクをもう一度作り直したいという場合はコメントアウトを外して再度applyすれば、すぐに復元できます。

さいごに

この記事では、ALTUSのリソースをTerraformで管理する方法を紹介しました。Terraformを使うことで、仮想サーバーの作成・変更・追加・削除などの運用作業を効率化し、エラーを防ぐことができます。

もし興味を持って、より活用したいということがあれば、以下のTerraformの公式ドキュメントを参考にし、楽しみながらサーバー運用を行って頂ければ嬉しいです。

Terraform公式ドキュメント

筆者がTerraformを使ってみて一番に思ったのは、使い方がすごくシンプルだということです。もちろん最初の学習コストは少しありますが、一度定義ファイルを整えてしまえば、あとは「plan」「apply」「show」コマンドだけで操作ができて、とても楽でした。たくさんWebで操作して管理している方には本当にオススメです。

ALTUSを利用されている方々の中には厳密に手順を管理してサーバー運用を行っている方もいらっしゃると思います。Web UIでの作業ですと、視覚的に分かりやすい反面、手順書として書き起こす際に説明の表現に困ることが、私の経験ではありました。

一方、Terraformならばコード/コマンドベースの運用になるので、手順書への書き起こしや資料として整理しやすい利点があります。また、定義ファイルがそのまま設計書としての役割も果たせるので、資料作成の工数を削減することもできます。

ALTUSの運用を効率化したい方や、IaCの導入を考えている方は、ぜひTerraformを活用してみてください。