Terraformをクラウドゲートウェイサーバーホスティングで使ってみた

本コラムでは、Terraformの概要と、NTT東日本が提供するクラウドゲートウェイサーバーホスティング (以下「CGH」とします。)にてTerraformを用いてみた簡単な実施例を紹介します。

Terraformとは?

Terraformは、インフラを構成するクラウドのリソースをコードベースで安全かつ効率的に構築、変更、バージョン管理するためのコマンドラインツールです。
ここで、クラウドのリソースとは仮想化されたサーバーやネットワークなどを指します。
Terraformは、HashiCorp社よりオープンソース版とエンタープライズ版(有償版)が提供されており、Windows、Linux、Macなどに対応しています。

※オープンソース版のダウンロードページはこちらです。
https://www.terraform.io/downloads.html別ウィンドウで開きます

※エンタープライズ版(有償版)は以下の公式サイトをご確認下さい。
https://www.terraform.io/docs/enterprise/index.html別ウィンドウで開きます

本コラムでは、Windowsのオープンソース版バージョン「Terraform 0.12.8」を使用しています。お使いのバージョンによっては、本コラムとは異なる設定や動作となる場合がありますのでご注意下さい。

Terraform Custom Provider for Enterprise Cloud 2.0

Terraformは、Amazon Web Services、Microsoft Azure、Google Cloud Platformなど様々なクラウドプラットフォームに対応しています。 NTT東日本が提供するCGHでも、2019年4月24日より公開されている「Terraform Custom Provider for Enterprise Cloud 2.0」を利用することで、Terraformで管理することができるようになります。
Terraformでは管理できるクラウドなどのプラットフォームをプロバイダと呼びます。プロバイダには、Terraformにあらかじめビルトインされているプロバイダと、ビルトインされていないプロバイダがあります。ビルトインされていないプロバイダは、プロバイダなどが提供するカスタムプロバイダという「プラグイン」を導入することで管理することができます。
「Terraform Custom Provider for Enterprise Cloud 2.0」は、ここでいうカスタムプロバイダになります。

Infrastructure as code(コードとしてのインフラ)によるメリット

Terraformはコードベースでクラウドのリソースを扱うため、Infrastructure as codeに分類されます。
クラウドへ配置するリソースを宣言的に定義するための言語として、HashiCorp社が開発したJSON形式と互換性のあるHashiCorp Configuration Language(以下「HCL」とします。)を使用します。
Terraformを利用してコードベースでインフラを管理することで、

  • GUIを使用しないインフラの変更
  • 第三者によるコードの検証
  • GitHubなどのバージョン管理系クラウドサービスでの管理
  • 作成済みのコードの再利用

ができるようになり、

  • インフラ構築の自動化により、人的ミスの減少と作業時間の短縮が期待できる。
  • インフラの構成確認や変更履歴などの管理が容易となる。
  • インフラ構成の複製や変更が容易に行える。

というようなメリットを受けることができるようになります。

Terraformのコマンド

Terraformのコマンドでは、HCLで記述したコードを元にリソースの作成・削除・変更を行う以外にリソース同士の関連図の作成、変数の代入、コードのインデント自動調整などのさまざまな機能が提供されています。ここでは、主な一部機能のみの紹介となりますが、ここにない機能については、以下で確認することができます。
https://www.terraform.io/docs/commands/index.html別ウィンドウで開きます

terraform init

主に作業用ディレクトリを初期化するコマンドです。

terraform version

Terraformのバージョンを確認できます。

terraform plan

リソースの作成・削除・変更を事前に確認するコマンドです(これを「Dry-Run」といいます。)。Dry-Runを行うことで、定義したコードに間違いはないか、意図した内容となっているのかを確認することできます。
以下はキーペア作成を確認する“terraform plan”を実行した結果の一部抜粋です。

+ resource "ecl_compute_keypair_v2" "kp_1" {
      + fingerprint	= (known after apply)
      + id		= (known after apply)
      + name		= "keypair-1"
      + private_key	= (known after apply)
      + public_key	= (known after apply)
      + region	= (known after apply)
    }
Plan: 1 to add, 0 to change, 0 to destroy.

新しく作成されるリソース”ecl_compute_keypair_v2”に記号「+」が付与されています。
planの実行結果で、定義したリソースに対して付与される以下の記号によって、実際に行われる動作を事前に確認することができます。

「+」・・・新規にリソースを作成
「-」・・・既存リソースを削除
「~」・・・既存リソースの設定を変更
「-/+」・・既存リソースを削除し、新しいリソースを作成

最後の行には、作成(add)、変更(change)、削除(destroy)される予定のリソースの数が表示されます。

terraform apply

コードで定義したリソースの作成・削除・変更を行います。

terraform destroy

Terraformで作成したリソースを一括で削除するコマンドです。

terraform graph

リソース間の依存関係をdot言語で記述したテキストファイルへ出力するコマンドです。
出力したテキストファイルはGraphviz(http://www.graphviz.org/別ウィンドウで開きます)を利用し、画像ファイルへ変換します。

設定ファイルの構成

Terraformを利用するには、拡張子を“.tf”とするファイル(以下、「tfファイル」とします。)を作成します。
tfファイルには、インフラを構成するリソースを前述のHCLを用いて定義します。
ひとつのtfファイルに全てのリソースを定義することも、リソース毎に複数のファイルに分けることも可能です。

tfファイルでは、以下3つのセクションで構成されます。

  • providerセクション
  • resourceセクション
  • dataセクション
providerセクション

providerセクションでは、「プロバイダ」の認証情報を定義します。
CGHを利用するためには以下のように記述します。

provider "ecl" {
    auth_url		= "https://keystone-<リージョン>-ecl.api.ntt.com/v3/"
    user_name		= "<API鍵>"
    password		= "<API秘密鍵>"
    tenant_id		= "<テナントID>"
    user_domain_id	= "default"
    project_domain_id	= "default"
}

Terraformで管理するテナントの<リージョン>、<API鍵>、<API秘密鍵>、<テナントID>はCGHのポータル画面で確認します。
本コラムでは、割愛しますが、プロバイダを複数記述することで異なるクラウドのインフラを管理することも可能です。
※ここでは、認証情報を直接記述していますが、後ほど変数として記述する方法を説明します。

resourceセクション

resourceセクションではTerraformで管理するリソースを、リソース単位で以下のように定義します。

resource “リソースタイプ” “リソース名” {
属性名 = 属性の値
}

ボリュームをリソースとする例で各要素を説明します。

resource "ecl_compute_volume_v2" "volume_1" {
    name	= "volume-1"
    size	= “15”
}

ボリューム名を“volume-1”とする容量15GBのボリュームを作成するリソース定義の例です。

  • ボリュームを表すリソースタイプの“ecl_compute_volume_v2”は「Terraform Custom Provider for Enterprise Cloud 2.0」が定めた値を使用します。
  • リソース名には任意の値が記述可能ですが、同じリソースタイプ内では、ユニークとする必要があります。
  • “name”と“size”が属性名、“volume-1”と“15”がそれらに対応する属性の値になります。属性名は複数書くことが可能です。

※Terraform Custom Provider for Enterprise Cloud 2.0がサポートするリソースやリソース毎に指定可能な属性名、属性の値はGitHub上に公開されています。
https://github.com/nttcom/terraform-provider-ecl/tree/master/website/docs/r別ウィンドウで開きます

data セクション

dataセクションは、必須の定義ではありませんが、dataセクションを定義することでTerraformを用いずに、ポータルなどから作成したリソースの値を、resource セクションで定義したリソースへパラメータとして動的に渡すことができるようになります。
OSイメージなどクラウドが用意しているリソースもdataセクションで利用することができます。
※dataセクションで定義するこれらのリソースをTerraform管理外のリソースといいます。逆に、resourceセクションで定義するリソースは、Terraform管理のリソースといいます。
※Terraform管理のリソースの値であれば、dataセクションを利用しなくても動的に渡すことができます。詳しくは後ほど説明します。

dataセクションでは、以下のようにTerraform管理外のリソースを定義します。

data "リソースタイプ" "リソース名" {
  検索条件(リソース)
}

Terraform管理外のロジカルネットワークをデータソースとする例でdataセクションの各要素を説明します。

data “ecl_network_network_v2” “network” {
  name	= “test”
}

リソース名“test”のロジカルネットワークからIDなどの情報を取得するdataセクションの記述例です。

  • ロジカルネットワークを表すリソースタイプの“ecl_network_network_v2”は Terraform Custom Provider for Enterprise Cloud 2.0が定めた値を使用します。
  • リソース名には、任意の値が記述可能で、リソースから取得したIDなどの情報が格納されます。
  • 検索条件にはキーとなる属性名を左辺、その属性の値を右辺とし、“=”で結合して記述します。この例では、属性名を“name”、その値を“test”とする検索条件を記述しています。複数の検索条件を記述することも可能です。

※Terraform Custom Provider for Enterprise Cloud 2.0がサポートするデータソースやデータソース毎に使用可能な検索条件はGitHub上に公開されています。
https://github.com/nttcom/terraform-provider-ecl/tree/master/website/docs/d別ウィンドウで開きます

具体的な例として、ポータルを利用して作成した“test”という名前のロジカルネットワークのネットワークIDを参照し、そのロジカルネットワークの配下に作成するサブネット“subnet_1”の属性の値として渡す場合の記載例を説明します。

data “ecl_network_network_v2” “network” {
  name		= “test”
}

resource “ecl_network_subnet_v2” “subnet_1” {
name		= “subnet_1”
cidr		= “subnet_1”
network_id		= “${data.ecl_network_network_v2.network.id}”
}

ネットワークIDのデータソースを参照するには、“${data.リソースタイプ.リソース名.属性}”という形で記述します。
この例では、リソースタイプが“ecl_network_network_v2”、リソース名が“network”、属性が“id”となります。

他のリソースの情報を参照する方法

Terraform管理のリソースの値を参照する方法を紹介します。
dataセクションでは、ポータルから作成したTerraform管理外のリソースを参照していました。今回は、Terraformで作成したロジカルネットワークのIDを参照する例で説明します。

resource "ecl_network_network_v2" "network_1" {
  name		= "network_1"
  plane		= "data"
}

resource "ecl_network_subnet_v2" "subnet_1" {
  name		= "subnet_1"
  network_id	= "${ecl_network_network_v2.network_1.id}"
  no_gateway	= "true"
  enable_dhcp	= "false"
}

最初のresourceセクションの定義で“network_1”という名前のロジカルネットワークを作成し、次のresourceセクションの定義で“subnet_1”という名前のサブネットを作成します。
ここで“network_1”内に“subnet_1”を作成するために、“network_id”の属性の値に“network_1”のロジカルネットワークIDを参照させます。
Terraformで作成したリソースの情報を参照するには、“${リソースタイプ.リソース名.属性名}”と記述します。この例では、リソースタイプを“ecl_network_network_v2”、リソース名を“network_1”、属性を“id”としています。
※リソースの属性を参照する際に“${}”という記法を使いましたが、“${}”を利用するとこれ以外にも、変数を展開したり、組み込みの関数を呼び出したりすることができるようになります。

依存関係の付与

tfファイルで記述できるリソースの属性は、CGHのAPIやポータル画面からリソースを作成する際に指定できる全ての属性に対応していません。
例えば、CGHで仮想サーバーのインスタンスを作成する際には、あらかじめ作成した接続するロジカルネットワークを指定し、リソース間に依存関係を持たせますが、Terraformのこれまで紹介した記述法のみでは、これを実現することができません。
これを解決するため、“depends_on”というパラメータが用意されています。“depends_on”をresourceセクションに追加することでリソース間に依存関係を付与することができるようになります。

“depends_on”を利用し、仮想サーバーインスタンスにロジカルネットワークのサブネットの“id”との依存関係を付与する例が以下です。

resource "ecl_network_network_v2" "network_1" {
  name		= "network_1"
  plane		= "data"
}	
 resource "ecl_network_subnet_v2" "subnet_1" {
  name		= "subnet_1"
  network_id	= "${ecl_network_network_v2.network_1.id}"
  cidr		= "192.168.1.0/24"
  no_gateway	= "true"
  enable_dhcp	= "false"
  }
}

data "ecl_imagestorages_image_v2" "image_1" {
    most_recent	= true
    name		= "Ubuntu-14.04.1_64_virtual-server_02"
}

resource "ecl_compute_instance_v2" "instance_1" {
  name		= "instance_1"
  image_id		= "${data.ecl_imagestorages_image_v2.image_1.id}"
  flavor_id		= "1CPU-2GB"
  
  network {
    uuid		= "${ecl_network_network_v2.network_1.id}"
  }
  depends_on	= ["ecl_network_subnet_v2.subnet_1"] 
}

仮想サーバーインスタンスを定義するresourceセクションに
“depends_on = [“ecl_network_subnet_v2.subnet_1”]”
を記述することでサブネットとの依存関係を付与しています。

設定ファイルのインデント自動調整

コードレビュー時にインデントがずれているという指摘があると思います。
“terraform fmt”によりtfファイルのインデントの自動調整ができます。

上のようにインデントがずれた状態のtfファイルへ“terraform fmt”を実施し、インデントが揃えることができました。

変数の定義(宣言)・代入・利用

tfファイルをGitHubなどで管理する場合、認証情報を直接書き込んだままgit pushしてしまうと、認証情報を公開してしまい情報漏えいの原因となってしまいます。
このようなことを避けるために、変数を利用して認証情報を渡す方法を紹介します。

変数の定義(宣言)

“variable.tf”というファイルに以下を記述し、空の変数を宣言します。

variable "api_key" {}
variable "api_secret_key" {}
variable "tenant_id {}
variable "region" {
  default = https://keystone-jp1-ecl.api.ntt.com/v3/
}

“api_key”、“api_secret_key”、“tenant_id”は、“{}”(空のブロック)で定義します。
“region”のようにデフォルトで値を設定することも可能です。今回はjp1リージョンのテナントで作業しているため“jp1”と記述しています。別リージョンの場合は
“https://keystone-<リージョン>-ecl.api.ntt.com/v3/”
と<リージョン>の箇所を置き換えて下さい。

providerセクションでの変数の参照

tfファイルのproviderセクションで、“variable.tf”に定義した変数を参照するために、以下のように“${var.変数名}”という形式で“variable.tf”に定義した変数名を指定します。

provider "ecl" {
    auth_url		= "${var.region}"
    user_name		= "${var.api_key}"
    password		= "${var.api_secret_key}"
    tenant_id		= "${var.tenant_id}"
    user_domain_id		= "default"
    project_domain_id	= "default"
}
変数への値の代入方法

定義した変数に値を代入するには、以下3通りの方法があります。

Terraformコマンドのパラメータで値を代入

Terraform実行時のパラメータで“terraform <plan/apply/..> -var <変数名>=<値>”と指定し、変数に値を代入します。

Terraform plan –var api_key=<api鍵> -var api_secret_key=<api秘密鍵> -var tenant_id=<テナントID>
ファイルで値を代入

以下を記述した“terraform.tfvars”あるいは、“*.auto.tfvars”ファイルを作成します。Terraform実行時にこれらのファイルが読み込まれ、変数に値を代入します。

api_key		= “<API鍵>”
api_secret_key	= “<API秘密鍵>”
tenant_id		= “<テナントID>”
環境変数で値を代入

TF_VAR_<変数名>=<変数の値>で環境変数を設定します。Terraform実行時に環境変数が読み込まれ、変数に値を代入します。

set TF_VAR_api_key	=<API鍵>
set TF_VAR_api_secret_key	=<API秘密鍵>
set TF_VAR_tenant_id	=<テナントID>

インストール

TerraformはWindows、Linux、Macなどに対応していますが、CGHのプラグインは64bitのみに対応しています。今回は、Windows(64bit)でインストールの説明を行います。

Terraformおよびプラグインのインストール

① 公式サイトからTerraform 本体をダウンロードします。
※ダウンロードはこちらから
https://www.terraform.io/downloads.html別ウィンドウで開きます

② ダウンロードしたzipファイルを展開し、“terraform.exe”を任意のフォルダに配置します。
※今回は、以下フォルダに配置しています。
C:\User\<ユーザー名>\Desktop\terraform

③ フォルダへのパスを通します。
set PATH=%PATH%;C:\Users\<ユーザー名>\Desktop\terraform

④ 続いてGitHubからCGHのプラグイン「Terraform Custom Provider for Enterprise Cloud 2.0」をダウンロードします。
※ダウンロードはこちらから。
https://github.com/nttcom/terraform-provider-ecl/tree/master/website/docs/d別ウィンドウで開きます

⑤ ダウンロードしたzipファイルを展開し、“terraform-provider-ecl.exe”を“terraform.exe”と同じフォルダに配置します。

⑥ 確認のためにコマンド“terraform”と“terraform version”を実行し、以下のように表示されればインストールは完了です。

C:\Users\~\Desktop\terraform\work>terraform
Usage: terraform [-version] [-help] <command> [args]
	
The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.
	
Common commands:
    apply	       Builds or changes infrastructure
    console	       Interactive console for Terraform interpolations
    destroy 	       Destroy Terraform-managed infrastructure
    env	       Workspace management
    fmt	       Rewrites config files to canonical format
    get	       Download and install modules for the configuration
    graph	       Create a visual graph of Terraform resources
    import	       Import existing infrastructure into Terraform
    init	       Initialize a Terraform working directory
    output	       Read an output from a state file
    plan	       Generate and show an execution plan
    providers	       Prints a tree of the providers used in the configuration
    refresh	       Update local state file against real resources
    show	       Inspect Terraform state or plan
    taint	       Manually mark a resource for recreation
    untaint	       Manually unmark a resource as tainted
    validate	       Validates the Terraform files
    version	       Prints the Terraform version
    workspace	       Workspace management

All other commands:
    0.12upgrade	Rewrites pre-0.12 module source code for v0.12
    debug		Debug output management (experimental)
    force-unlock 	Manually unlock the terraform state
    push		Obsolete command for Terraform Enterprise legacy (v1)
    state 		Advanced state management

C:\Users\~\Desktop\terraform\work>
C:\Users\~\Desktop\terraform\work>terraform version
Terraform v0.12.8

Your version of Terraform is out of date! The latest version
is 0.12.9. You can update by downloading from
www.terraform.io/downloads.html

CGHでの実施例

これまでの紹介した内容を踏まえ、TerraformでCGHのテナント上に仮想サーバーとロジカルネットワークをひとつ作成し、ロジカルネットワークのサブネットに仮想サーバーを接続した例を紹介します。

作業は以下の順で行っています。

  • 作業フォルダの作成
  • 認証情報の定義
  • tfファイルの作成
  • Terraformの実行
  • リソース一式の削除
作業フォルダの作成

Terraformを配置したフォルダの配下に作業フォルダ“work”を作成します。この作業フォルダにこれから作成するリソースを定義したtfファイルや認証情報を定義したファイルを配置します。Terraformもこのフォルダで実行します。

認証情報の定義

同じフォルダに認証情報を定義したvariable.tfとterraform.tfvarsを作成します。

・variable.tfの設定内容

variable		"api_key" {}
variable		"api_secret_key" {}
variable		"tenant_id” {}
variable		"region" {
default	= https://keystone-jp1-ecl.api.ntt.com/v3/
}

・terraform.tfvarsの設定内容

api_key		= “<API鍵>”
api_secret_key	= “<API秘密鍵>”
tenant_id	= “<テナントID>”
tfファイルの作成

ロジカルネットワーク、サブネット、仮想サーバーの3つのリソースを作成するtfファイルを作成します。providerセクション内の認証情報を変数化し、dataセクションを使用して仮想サーバーのOSイメージにUbuntuを指定し、“depends_on”を利用してネットワークとの関連付けも行っています。

provider "ecl" {
    auth_url		= "${var.region}"
    user_name		= "${var.api_key}"
    password		= "${var.api_secret_key}"
    tenant_id		= "${var.tenant_id}"
    user_domain_id	= "default"
    project_domain_id	= "default"
}	

data "ecl_imagestorages_image_v2" "image_1" {
    most_recent	= true
    name	= "Ubuntu-14.04.1_64_virtual-server_02"
}

resource "ecl_network_network_v2" "network_1" {
  name		= "network_1"
  plane		= "data"
}

resource "ecl_network_subnet_v2" "subnet_1" {
  name = "subnet_1"
  network_id	= "${ecl_network_network_v2.network_1.id}"
  cidr		= "192.168.1.0/24"
  no_gateway	= "true"
  enable_dhcp	= "false"
}

resource "ecl_compute_instance_v2" "instance_1" {
  name		= "instance_1"
  image_id	= "${data.ecl_imagestorages_image_v2.image_1.id}"
  flavor_id	= "1CPU-2GB"
  network {
    uuid	= "${ecl_network_network_v2.network_1.id}"
  }
   depends_on	= ["ecl_network_subnet_v2.subnet_1"]
}
Terraformの実行

用意ができましたので、Terraformを利用してリソースの作成を行っていきます。

まず、“terraform init”で初期化を行います。

C:\Users\~\Desktop\terraform\work>terraform init

Initializing the backend...

Initializing provider plugins...
		
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.

C:\Users\~\Desktop\terraform\work>

次に、“terraform graph”でリソースの依存関係図を作成し、確認してみます。

C:\Users\~\Desktop\terraform\work>terraform graph > input.dot

出力結果をGraphvizを使用してpng形式の画像ファイルに変換します。

C:\Users\~\Desktop\terraform\work>dot -Tpng input.dot > output.png

※事前に公式サイトからGraphvizのzipファイルをダウンロードし、任意のフォルダに展開します。展開したフォルダ名をgraphvizに変更させ、PATHを通します。

set PATH=%PATH%;C:\Users\<ユーザー名>\Desktop\graphviz\bin

図を開くと以下のようなリソース同士の依存関係が確認できます。

実際にリソースの作成を行う前に“terraform plan”を実行し、期待通りにロジカルネットワーク、サブネット、インスタンスが作成されることを確認します。

C:\Users\~\Desktop\terraform\work >terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.ecl_imagestorages_image_v2.image_1: Refreshing state...

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # ecl_compute_instance_v2.instance_1 will be created
  + resource "ecl_compute_instance_v2" "instance_1" {
      + access_ip_v4	= (known after apply)
      + all_metadata	= (known after apply)
      + availability_zone	= (known after apply)
      + flavor_id	= "1CPU-2GB"
      + flavor_name	= (known after apply)
      + id		= (known after apply)
      + image_id	= "ad936ae4-2983-4f23-9187-e47e82cb2725"
      + image_name	= (known after apply)
      + name		= "instance_1"
      + power_state	= "active"
      + region		= (known after apply)
      + stop_before_destroy = false

      + network {
          + access_network = false
          + fixed_ip_v4	= (known after apply)
          + mac		= (known after apply)
          + name	= (known after apply)
          + port		= (known after apply)
          + uuid	= (known after apply)
        }
    }

  # ecl_network_network_v2.network_1 will be created
  + resource "ecl_network_network_v2" "network_1" {
      + admin_state_up	= (known after apply)
      + id		= (known after apply)
      + name		= "network_1"
      + plane		= "data"
      + region		= (known after apply)
      + shared		= (known after apply)
      + status		= (known after apply)
      + subnets		= (known after apply)
      + tenant_id	= (known after apply)
    }

  # ecl_network_subnet_v2.subnet_1 will be created
  + resource "ecl_network_subnet_v2" "subnet_1" {
      + cidr		= "192.168.1.0/24"
      + dns_nameservers	= (known after apply)
      + enable_dhcp	= false
      + gateway_ip	= (known after apply)
      + id		= (known after apply)
      + ip_version	= 4
      + ipv6_address_mode = (known after apply)
      + ipv6_ra_mode	= (known after apply)
      + name		= "subnet_1"
      + network_id	= (known after apply)
      + no_gateway	= true
      + region		= (known after apply)
      + status		= (known after apply)
      + tenant_id	= (known after apply)

      + allocation_pools {
          + end		= (known after apply)
          + start	= (known after apply)
        }
    }

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

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

問題なく3つのリソースが作成されることが確認できたので、“terraform apply”を実行し、実際にリソースを作成します。
“terraform plan”と同じ内容が出力されたあとに、実施を確認する以下のメッセージが出力されますので、”Enter a value: “に“yes”と入力します。

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.
		
  Enter a value: 
C:\Users\~\Desktop\terraform\work >terraform apply
		~
(前半はplanと同様の出力が行われますので省略します。)
		~
Plan: 3 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

ecl_network_network_v2.network_1: Creating...
ecl_network_network_v2.network_1: Creation complete after 9s [id=2957a8da-e4c5-45ac-ba7c-d5635a7f3094]
ecl_network_subnet_v2.subnet_1: Creating...
ecl_network_subnet_v2.subnet_1: Creation complete after 6s [id=29f79bf0-8789-4154-bf34-9c6ed7deff12]
ecl_compute_instance_v2.instance_1: Creating...
ecl_compute_instance_v2.instance_1: Still creating... [10s elapsed]
ecl_compute_instance_v2.instance_1: Creation complete after 13s [id=a0dd90b0-bb7f-4301-a354-00327e9c5da8]

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

“Apply complete!”が出力されたので、無事完了です。ポータルでもロジカルネットワークにつながった状態で仮想サーバーが作成できたことが確認できました。

リソースの一式削除

最後に作成したリソースを削除します。実施の前に“terraform plan –destroy”で、作成したロジカルネットワーク、サブネット、インスタンスが削除されることを確認します。

C:\Users\~\Desktop\terraform\work>terraform plan -destroy
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

data.ecl_imagestorages_image_v2.image_1: Refreshing state...
ecl_network_network_v2.network_1: Refreshing state... [id=8b8a1eec-d583-4790-a2dc-b21278dd836a]
ecl_network_subnet_v2.subnet_1: Refreshing state... [id=bb17604b-8aaa-4430-9a99-4041a060c729]
ecl_compute_instance_v2.instance_1: Refreshing state... [id=d8e6b509-556c-4305-b6fe-b5948aadac40]

------------------------------------------------------------------------

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # ecl_compute_instance_v2.instance_1 will be destroyed
  - resource "ecl_compute_instance_v2" "instance_1" {
      - access_ip_v4 	= "192.168.1.2" -> null
      - all_metadata 	= {} -> null
      - availability_zone	= "zone1-groupa" -> null
      - flavor_id 	= "1CPU-2GB" -> null
      - flavor_name 	= "1CPU-2GB" -> null
      - id 		= "d8e6b509-556c-4305-b6fe-b5948aadac40" -> null
      - image_id 	= "ad936ae4-2983-4f23-9187-e47e82cb2725" -> null
      - image_name 	= "Ubuntu-14.04.1_64_virtual-server_02" -> null
      - name		= "instance_1" -> null
      - power_state 	= "active" -> null
      - stop_before_destroy = false -> null

      - network {
          - access_network = false -> null
          - fixed_ip_v4	= "192.168.1.2" -> null
          - mac		= "fa:16:3e:10:fc:f7" -> null
          - name	= "network_1" -> null
          - uuid		= "8b8a1eec-d583-4790-a2dc-b21278dd836a" -> null
        }
    }

  # ecl_network_network_v2.network_1 will be destroyed
  - resource "ecl_network_network_v2" "network_1" {
      - admin_state_up	= true -> null
      - id		= "8b8a1eec-d583-4790-a2dc-b21278dd836a" -> null
      - name		= "network_1" -> null
      - plane		= "data" -> null
      - shared		= false -> null
      - status		= "ACTIVE" -> null
      - subnets		= [
          - "bb17604b-8aaa-4430-9a99-4041a060c729",
        		] -> null
      - tags		= {} -> null
      - tenant_id	= "XXXX" -> null
    }

  # ecl_network_subnet_v2.subnet_1 will be destroyed
  - resource "ecl_network_subnet_v2" "subnet_1" {
      - cidr		= "192.168.1.0/24" -> null
      - dns_nameservers	= [] -> null
      - enable_dhcp	= false -> null
      - id		= "bb17604b-8aaa-4430-9a99-4041a060c729" -> null
      - ip_version	= 4 -> null
      - name		= "subnet_1" -> null
      - network_id	= "8b8a1eec-d583-4790-a2dc-b21278dd836a" -> null
      - no_gateway	= true -> null
      - ntp_servers	= [] -> null
      - status		= "ACTIVE" -> null
      - tags		= {} -> null
      - tenant_id	= "XXXX" -> null

      - allocation_pools {
          - end	= "192.168.1.254" -> null
          - start	= "192.168.1.2" -> null
        }
    }

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

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

期待通りにリソースが削除されることが確認できましたので、“terraform destroy”でリソースを削除します。
※applyと同じように実施確認のメッセージが出力されますので、“yes”と入力します。

C:\Users\nwse2\Desktop\terraform\work>terraform destroy
~
(前半はplanと同様の出力が行われますので省略します。)
		~
Plan: 0 to add, 0 to change, 3 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

ecl_compute_instance_v2.instance_1: Destroying... [id=d8e6b509-556c-4305-b6fe-b5948aadac40]
ecl_compute_instance_v2.instance_1: Still destroying... [id=d8e6b509-556c-4305-b6fe-b5948aadac40, 10s elapsed]
ecl_compute_instance_v2.instance_1: Destruction complete after 12s
ecl_network_subnet_v2.subnet_1: Destroying... [id=bb17604b-8aaa-4430-9a99-4041a060c729]
ecl_network_subnet_v2.subnet_1: Still destroying... [id=bb17604b-8aaa-4430-9a99-4041a060c729, 10s elapsed]
ecl_network_subnet_v2.subnet_1: Still destroying... [id=bb17604b-8aaa-4430-9a99-4041a060c729, 20s elapsed]
ecl_network_subnet_v2.subnet_1: Still destroying... [id=bb17604b-8aaa-4430-9a99-4041a060c729, 30s elapsed]
ecl_network_subnet_v2.subnet_1: Destruction complete after 36s
ecl_network_network_v2.network_1: Destroying... [id=8b8a1eec-d583-4790-a2dc-b21278dd836a]
ecl_network_network_v2.network_1: Destruction complete after 5s

Destroy complete! Resources: 3 destroyed.

“Destroy complete!”で無事完了です。ポータルからもリソースが削除できたことが確認できました。

簡単でしたが以上となります。

関連サービス:

Amazon Web Services(AWS)、Microsoft Azureの
導入支援サービスのご相談、お問い合わせをお待ちしております。

ページ上部へ戻る