TerraformでフレキシブルサーバリソースAPIを利用する

フレキシブルサーバリソースをAPIで操作するために、VMware Cloud Director Terraform Providerを利用できます。
VMware Cloud Director Terraform Providerにより、フレキシブルサーバリソースに構築するインフラをソースコードとして管理できます。
詳しくは、以下のページをご覧ください。

https://www.vmware.com/products/cloud-director/terraform-provider.html

ここでは、VMware Cloud Director Terraform Providerを利用してAPIでフレキシブルサーバリソースを操作する方法を説明します。

なお、お使いの端末にTerraformが導入済みである前提で説明します。Terraformについては、公式ページ(https://www.terraform.io/)をご覧ください。

【注意】

1.認証のための設定ファイルを作成します。

フレキシブルサーバリソースAPIを利用するためには、フレキシブルサーバリソース画面の「API情報」タブに書かれた情報と、事前に作成したAPIトークンが必要です。

【参考】

基本となる設定ファイルの例を以下に示します。

auth_sample.tf
terraform {
  required_providers {
    vcd = {
      source = "vmware/vcd" // VMware Cloud Director APIを利用するための設定
    }
  }
}

provider "vcd" {
  auth_type = "api_token" // 認証方式(固定値)
  api_token = "XXXXXXXX" // 事前に作成したAPIトークン
  org = "svrssa-XXXXXXXX" // 組織名。「API情報」タブに記載
  vdc = "svrssa-XXXXXXXX" // 組織VDC名。「API情報」タブに記載
  url = "https://vcd14.gen2.p2.iijgio.jp/api" // APIエンドポイント。「API情報」タブに記載
  max_retry_timeout = 3 // リトライ回数
}

2.認証のための設定ファイルをもとに、初期化を行います。

Terraformの初期化を行うために、任意の空ディレクトリに上記のファイルを置いた状態で以下のコマンドを実行します(コマンド実行後の出力は異なる場合があります)。

初期化
% terraform init

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of vmware/vcd from the dependency lock file
- Using previously-installed vmware/vcd vX.X.X

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.

エラーが出力されることなくコマンドが終了したらTerraformを使う準備は完了です。

3.インフラ環境構築のための設定ファイルを作成します。

先述のファイルと同じディレクトリに次のようなファイルを追加します。記載方法については、以下をご覧ください。

https://registry.terraform.io/providers/vmware/vcd/latest/docs

ここでは、標準ライブラリで提供されているCentOS 8 Streamを利用して、vAppと仮想マシンを作成する例を示します。

vapp_sample.tf
// 標準ライブラリ
data "vcd_catalog" "std_lib" {
  org  = "os-library" // 組織名(固定値)
  name = "標準ライブラリ"  // カタログ名(固定値)
}

// OSテンプレート
// CentOS8の場合
data "vcd_catalog_vapp_template" "centos8s" {
  catalog_id = data.vcd_catalog.std_lib.id // vcd_catalogのIDを参照
  name = "CentOS 8 Stream (1.3)" // 実在のOSテンプレートの名前
}

// vAppの定義
resource "vcd_vapp" "tfmvappex" {
  name = "tfmvappex" // vApp: 名前
  description = "Terraform Example" // vApp: 説明
  power_on = false // 電源の状態
}

// vAppに属する仮想マシンの定義
resource "vcd_vapp_vm" "tfmvappvmex" {
  vapp_name = vcd_vapp.tfmvappex.name // vcd_vappの名前を参照
  name = "tfmvappvmex" // 仮想マシン名
  vapp_template_id = data.vcd_catalog_vapp_template.centos8s.id  // vcd_catalog_vapp_templateのIDを参照
  cpus = 2 // 仮想CPUの数
  cpu_cores = 1 // ソケットあたりのコア数
  memory = 2048 // メモリのサイズ(MB)
  power_on = false // 電源の状態
  accept_all_eulas = true // EULAに同意する
  computer_name = "tfmvappvmex01" // コンピュータ名
  storage_profile = "basic" // 利用するストレージのプロファイル名、"basic"か"standard"を指定
}

カタログ名に応じて、OSライブラリ及びOSテンプレートはそれぞれ下記のように設定します。

カタログ名サンプルコード
標準ライブラリ
// OSライブラリ
data "vcd_catalog" "std_lib" {
  org  = "os-library" // 組織名(固定値)
  name = "標準ライブラリ" // カタログ名(固定値)
}

// OSテンプレートの例
data "vcd_catalog_vapp_template" "centos8s" {
  catalog_id = data.vcd_catalog.std_lib.id // vcd_catalogのIDを参照
  name = "CentOS 8 Stream (1.3)" // 実在のOSテンプレートの名前
}
OSライセンス:Windows
// OSライブラリ
data "vcd_catalog" "win_lib" {
  org  = "os-library" // 組織名(固定値)
  name = "OSライセンス:Windows" // カタログ名(固定値)
}

// OSテンプレートの例
data "vcd_catalog_vapp_template" "win2022" {
  catalog_id = data.vcd_catalog.win_lib.id // vcd_catalogのIDを参照
  name = "Windows Server 2022 (1.2)" // 実在のOSテンプレートの名前
}
OSライセンス:Red Hat Enterprise Linux
// OSライブラリ
data "vcd_catalog" "rhel_lib" {
  org  = "os-library" // 組織名(固定値)
  name = "OSライセンス:Red Hat Enterprise Linux" // カタログ名(固定値)
}

// OSテンプレートの例
data "vcd_catalog_vapp_template" "rhel91" {
  catalog_id = data.vcd_catalog.rhel_lib.id // vcd_catalogのIDを参照
  name = "Red Hat Enterprise Linux 9.1 (1.0)" // 実在のOSテンプレートの名前
}
プライベートOSライブラリ
// OSライブラリ
data "vcd_catalog" "prv_lib" {
  org  = "svrssa-XXXXXXXX" // 組織名。「API情報」タブに記載
  name = "プライベートOSライブラリ" // カタログ名(固定値)
}

// OSテンプレートの例
data "vcd_catalog_vapp_template" "xxxx" {
  catalog_id = data.vcd_catalog.prv_lib.id // vcd_catalogのIDを参照
  name = "XXXXXX" // 実在のOSテンプレートの名前
}

4.設定内容を確認します。

設定したvAppと仮想マシンの内容を確認するには、以下のコマンドを実行します。

確認
% terraform plan   
data.vcd_catalog.std_lib: Reading...
data.vcd_catalog.std_lib: Read complete after 1s [id=urn:vcloud:########]
data.vcd_catalog_vapp_template.centos8s: Reading...
data.vcd_catalog_vapp_template.centos8s: Read complete after 1s [id=urn:vcloud:vapptemplate:########]

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:

  # vcd_vapp.tfmvappex will be created
  + resource "vcd_vapp" "tfmvappex" {
      + description = "Terraform Example"
      + href        = (known after apply)
      + id          = (known after apply)
      + metadata    = (known after apply)
      + name        = "tfmvappex"
      + power_on    = false
      + status      = (known after apply)
      + status_text = (known after apply)

      + lease {
          + runtime_lease_in_sec = (known after apply)
          + storage_lease_in_sec = (known after apply)
        }

      + metadata_entry {
          + is_system   = (known after apply)
          + key         = (known after apply)
          + type        = (known after apply)
          + user_access = (known after apply)
          + value       = (known after apply)
        }
    }

  # vcd_vapp_vm.tfmvappvmex will be created
  + resource "vcd_vapp_vm" "tfmvappvmex" {
      + accept_all_eulas               = true
      + computer_name                  = "tfmvappvmex01"
      + cpu_cores                      = 1
      + cpu_hot_add_enabled            = false
      + cpu_limit                      = (known after apply)
      + cpu_priority                   = (known after apply)
      + cpu_reservation                = (known after apply)
      + cpu_shares                     = (known after apply)
      + cpus                           = 2
      + description                    = (known after apply)
      + expose_hardware_virtualization = false
      + hardware_version               = (known after apply)
      + href                           = (known after apply)
      + id                             = (known after apply)
      + internal_disk                  = (known after apply)
      + memory                         = 2048
      + memory_hot_add_enabled         = false
      + memory_limit                   = (known after apply)
      + memory_priority                = (known after apply)
      + memory_reservation             = (known after apply)
      + memory_shares                  = (known after apply)
      + metadata                       = (known after apply)
      + name                           = "tfmvappvmex"
      + os_type                        = (known after apply)
      + placement_policy_id            = (known after apply)
      + power_on                       = false
      + prevent_update_power_off       = false
      + sizing_policy_id               = (known after apply)
      + status                         = (known after apply)
      + status_text                    = (known after apply)
      + storage_profile                = "basic"
      + vapp_name                      = "tfmvappex"
      + vapp_template_id               = "urn:vcloud:vapptemplate:########"
      + vm_type                        = (known after apply)

      + customization {
          + admin_password                      = (sensitive value)
          + allow_local_admin_password          = (known after apply)
          + auto_generate_password              = (known after apply)
          + change_sid                          = (known after apply)
          + enabled                             = (known after apply)
          + force                               = (known after apply)
          + initscript                          = (known after apply)
          + join_domain                         = (known after apply)
          + join_domain_account_ou              = (known after apply)
          + join_domain_name                    = (known after apply)
          + join_domain_password                = (sensitive value)
          + join_domain_user                    = (known after apply)
          + join_org_domain                     = (known after apply)
          + must_change_password_on_first_login = (known after apply)
          + number_of_auto_logons               = (known after apply)
        }

      + metadata_entry {
          + is_system   = (known after apply)
          + key         = (known after apply)
          + type        = (known after apply)
          + user_access = (known after apply)
          + value       = (known after apply)
        }
    }

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

───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

5.設定内容をフレキシブルサーバリソースに適用します。

設定内容に問題が無ければ、次のコマンドを実行します。

実行
% terraform apply
data.vcd_catalog.std_lib: Reading...
data.vcd_catalog.std_lib: Read complete after 0s [id=urn:vcloud:catalog:########]
data.vcd_catalog_vapp_template.centos8s: Reading...
data.vcd_catalog_vapp_template.centos8s: Read complete after 1s [id=urn:vcloud:vapptemplate:########]

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:

  # vcd_vapp.tfmvappex will be created
  + resource "vcd_vapp" "tfmvappex" {
      + description = "Terraform Example"
      + href        = (known after apply)
      + id          = (known after apply)
      + metadata    = (known after apply)
      + name        = "tfmvappex"
      + power_on    = false
      + status      = (known after apply)
      + status_text = (known after apply)

      + lease {
          + runtime_lease_in_sec = (known after apply)
          + storage_lease_in_sec = (known after apply)
        }

      + metadata_entry {
          + is_system   = (known after apply)
          + key         = (known after apply)
          + type        = (known after apply)
          + user_access = (known after apply)
          + value       = (known after apply)
        }
    }

  # vcd_vapp_vm.tfmvappvmex will be created
  + resource "vcd_vapp_vm" "tfmvappvmex" {
      + accept_all_eulas               = true
      + computer_name                  = "tfmvappvmex01"
      + cpu_cores                      = 1
      + cpu_hot_add_enabled            = false
      + cpu_limit                      = (known after apply)
      + cpu_priority                   = (known after apply)
      + cpu_reservation                = (known after apply)
      + cpu_shares                     = (known after apply)
      + cpus                           = 2
      + description                    = (known after apply)
      + expose_hardware_virtualization = false
      + hardware_version               = (known after apply)
      + href                           = (known after apply)
      + id                             = (known after apply)
      + internal_disk                  = (known after apply)
      + memory                         = 2048
      + memory_hot_add_enabled         = false
      + memory_limit                   = (known after apply)
      + memory_priority                = (known after apply)
      + memory_reservation             = (known after apply)
      + memory_shares                  = (known after apply)
      + metadata                       = (known after apply)
      + name                           = "tfmvappvmex"
      + os_type                        = (known after apply)
      + placement_policy_id            = (known after apply)
      + power_on                       = false
      + prevent_update_power_off       = false
      + sizing_policy_id               = (known after apply)
      + status                         = (known after apply)
      + status_text                    = (known after apply)
      + storage_profile                = "basic"
      + vapp_name                      = "tfmvappex"
      + vapp_template_id               = "urn:vcloud:vapptemplate:########"
      + vm_type                        = (known after apply)

      + customization {
          + admin_password                      = (sensitive value)
          + allow_local_admin_password          = (known after apply)
          + auto_generate_password              = (known after apply)
          + change_sid                          = (known after apply)
          + enabled                             = (known after apply)
          + force                               = (known after apply)
          + initscript                          = (known after apply)
          + join_domain                         = (known after apply)
          + join_domain_account_ou              = (known after apply)
          + join_domain_name                    = (known after apply)
          + join_domain_password                = (sensitive value)
          + join_domain_user                    = (known after apply)
          + join_org_domain                     = (known after apply)
          + must_change_password_on_first_login = (known after apply)
          + number_of_auto_logons               = (known after apply)
        }

      + metadata_entry {
          + is_system   = (known after apply)
          + key         = (known after apply)
          + type        = (known after apply)
          + user_access = (known after apply)
          + value       = (known after apply)
        }
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: 

"yes"と入力して「Enter」を押します。

実行結果
Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

vcd_vapp.tfmvappex: Creating...
vcd_vapp.tfmvappex: Creation complete after 5s [id=urn:vcloud:vapp:########]
vcd_vapp_vm.tfmvappvmex: Creating...
vcd_vapp_vm.tfmvappvmex: Still creating... [10s elapsed]
vcd_vapp_vm.tfmvappvmex: Still creating... [20s elapsed]
vcd_vapp_vm.tfmvappvmex: Still creating... [30s elapsed]
vcd_vapp_vm.tfmvappvmex: Still creating... [40s elapsed]
vcd_vapp_vm.tfmvappvmex: Still creating... [50s elapsed]
vcd_vapp_vm.tfmvappvmex: Creation complete after 53s [id=urn:vcloud:vm:########]

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

フレキシブルサーバリソースに設定が適用され、vAppと仮想マシンが作成されます。