Terraformを活用したNAVERクラウドプラットフォームVPCインフラの構築

f:id:navercloud:20210223180106p:plain

皆さん、こんにちは。NAVERクラウドプラットフォームです。

本日は、インフラ自動化のためのIaC(Infrastructure as a Code)のオープンソースであるTerraformを活用して、VPC環境を構築する方法をご紹介します。

では、始めましょう!

VPCとは?

VPCを分かりやすく説明するために、以下のように仮定します。

  • N Companyという会社では、同じソリューションを3つのテナント(A、B、C)に提供します。
  • N Companyが管理する1つのアカウントで各テナント専用のインフラを作り、独立的にサービスを提供しています。

f:id:navercloud:20210224182206p:plain

既存のクラシック(CLASSIC)環境(VPCがない環境)だと、上図のようになります。

この環境では論理的にネットワーク環境を共有しているので、以下のような問題が生じます。

1つのアカウントでマルチテナントに対してサービスを提供する場合、各テナント間の通信が可能であるため、ACG(Access Control Group)などを通じてアクセス制御を別途設定しなければなりません。システムが複雑になると、このような設定はますます難しくなります。

各サーバのプライベートIPを直接設定することができないため、各テナントのネットワーク環境を同一に構築することはできません。

例) テナント別DBサーバのプライベートIP

  • Aテナント 10.53.1.56
  • Bテナント 10.46.12.41
  • Cテナント 10.61.51.23

上記のように同じ目的のサーバのプライベートIPがテナントごとに異なるため、テナントごとにIPアドレスを設定する必要があります。

また、サーバのプライベートIPは作成時にランダムで付与されるため、IP帯域を介したアクセス制御は難しいです。

 

では、VPCはどのようにして問題を解決してくれるのでしょうか。

NAVERクラウドプラットフォームのVPC(Virtual Private Cloud)は、パブリッククラウド上で提供される顧客専用のプライベートネットワークを意味します。

f:id:navercloud:20210224182312p:plain

N CompanyのVPC環境構築図

上記の環境でVPCを適用すると、以下のようになります。

N Companyから提供される各テナントのネットワークは、VPCを通じて完全に独立的に提供されます。すなわち、ACGを別途設定しなくても隔離されたネットワーク環境が作られます。

VPCごとに独立したIP帯がを提供されるため、サーバ作成時に希望するプライベートIPを設定できます。テナントごとに同じ設定値を利用することができ、サーバの作成前にどのようなプライベートIPを持つことになるか予測できます。

例) テナント別DBサーバのプライベートIP

  • Aテナント 10.0.1.7
  • Bテナント 10.0.1.7
  • Cテナント 10.0.1.7

Subnetを通じて希望するプライベートIP帯域を設定することができ、それによりIP帯域を用いたセキュリティ管理も効率的であることが分かります。

上記のようにVPCは隔離されたネットワークを提供することにより、管理やセキュリティ面で既存のCLASSIC環境より優れています。

VPCは他VPCネットワークと論理的に分離されており、既存の顧客データセンターネットワークと同様に実装できます。Subnet(Subnet)はVPCネットワーク空間を細分化して使用できる機能です。

VPCに関する詳しい説明は、ガイドをご参照ください。

VPCシナリオ

今回の投稿で、Terraformで構築するシナリオは以下のとおりです。

 シナリオ2. PublicPrivate Subnet

f:id:navercloud:20210224182526p:plain

  シナリオ2. PublicとPrivate Subnetの構成

上記シナリオでは、1つのVPC環境でKR-2 ZONEのPublic SubnetにFEサーバを置き、Private SubnetにWASのようなServerを1台ずつ作成します。

構造に関する理解を助けるため、構造について簡単に説明いたします。

1. VPC

ユーザー専用の仮想ネットワークで、すべてのリソースはVPC内で作成されます。例題の中のVPCは10.0.0.0/16のCIDRブロックを持ち、このVPC内では10.0.X.X形式のIPv4アドレスを65,536 (256²)個提供します。

Subnet

VPC内のアドレス範囲を指定できます。PrivateとPublicの2つのSubnetを提供します。Subnetが属するZoneを指定できます。KR Regionを基準に、KR-1またはKR-2に作成できます。高可用性のため、2つのZoneにそれぞれサービスを構築できます。

2. Public Subnet

例題では10.0.0.0/24のCIDRブロックを持ち、このサブネット内では10.0.0.X形式のIPv4アドレスを250個(Reserved IP address 6個は除く)作成できます。

Public Subnetの場合、基本的にInternet Gatewayとつながっているため、外部との通信が可能で、外部からもSubnetにアクセスできます。要塞ホストを置くのに適しています。

3. Private Subnet

例題では10.0.1.0/24のCIDRブロックを持ち、このサブネット内では10.0.1.X形式のIPv4アドレスを250個作成できます。基本的には外部ネットワークが遮断されていて、VPC内でのみ通信が可能です。しかし、NAT Gatewayを用いるとインターネットに接続できます。WASやDBといったサーバはここに置きます。

4. Internet Gateway

VPCを、外部とのインターネット通信ができるようにします。

(VPC作成時に基本提供されるため、Terraformでは当該リソースは扱いません。)

5. NAT Gateway

Private Subnetが外部との通信を行えるようにします。

(通常、OSのパッケージをアップグレードしたり、外部インターネットのAPIを呼び出すために接続します。)

Private Route Tableを介して接続されます。

6. Route Table

VPC作成時には、基本的にPublicとPrivateのルーティングテーブルが作成されます。ルーティングテーブルは、VPC内で他のインスタンスとの通信を可能にしてくれます。Publicは、Internet Gatewayとつながっていてインターネット通信を可能にし、PrivateはNAT Gatewayに接続してインターネット通信を可能にします。

7. Network ACL

セキュリティのためにACGまたはNetwork ACLを使用しますが、ACGはサーバのInbound/Outboundトラフィックを制御し、Network ACLはサブネットのInbound/Outboundトラフィックを制御できます。基本的には0.0.0.0/0ソースに対してallowされているため、セキュリティのためにACLルールの設定が必要です。

この例題で作成されるリソースは以下のとおりです。 

VPC 1個

  • Subnet 2個 (Public、Private)
  • NAT Gateway 1個
  • Network ACL 2個
  • Server 2個 (Frontend、Backend)
  • Public IP 1個

* Terraformのインストール

Terraformはこちらからダウンロードできます。

$ unzip terraform_0.14.2_linux_amd64.zip && mv terraform /usr/bin

$ terraform version # 설치 확인

Terraform v0.14.2

例題コードの構造

例題では、以下のようなファイル構造を持ちます。

$ cd terraform/tf-vpc-scenario2
$ tree
.
├── main.tf # VPCリソースを定義します。
├── security.tf # Network ACLルールを指定します。
├── versions.tf # Terraformに関連するバージョンを指定します。
└── variables.tf # variable変数を定義します。

 

当該例題コードはこちらで確認できます。

# versions.tf
terraform {
required_providers {
ncloud = {
source = "navercloudplatform/ncloud"
}
}
required_version = ">= 0.13"
}
versions.tfでは、NAVERクラウドプラットフォームProviderのバージョンを設定します。本例題ではProviderバージョンv2.0.3以降の基準で作成されました。この例題ではTerraform 0.13バージョン以降を推奨します。

variables.tf

# variables.tf
variable name_scn02 {
default = "tf-scn02"
}
variable client_ip {
default = "YOUR_CLIENT_IP" // To access ssh
}
variable access_key {
default = "YOUR_ACCESS_KEY"
}
variable secret_key {
default = "YOUR_SECRET_KEY"
}

 

このファイルではTerraformコード内でよく使われる値を変数として設定します。

リソース名を簡単に設定するため、name_scn02を設定します。この値は好きなように変更してもかまいません。

SSH接続時に、Network ACL設定のためのclient_ipを入力します。

ポータルで認証キー情報をaccess_keyとsecret_keyに入力します。

(この値はポータルにログインして、マイペ > 認証キ管理より確認できます。)

main.tf

このファイルにはproviderの設定とVPCを含むほとんどのインフラコードが含まれています。

# main.tf
provider "ncloud" {
support_vpc = true
region = "KR"
access_key = var.access_key
secret_key = var.secret_key
}

 

まずはncloud providerの設定を行います。ここではsupport_vpcをtrueに設定して、VPC環境を使用します。(重要)

1. VPC (ncloud_vpc)

f:id:navercloud:20210224193825p:plain

VPC (Virtual Private Network)の作成

始めに、ncloud_vpcリソースを用いてVPCを定義します。当該リソースに関するガイドはこちらで確認できます。

上図のように、VPC作成時には基本的にInternet Gateway、Route Table、Network ACL、ACG(Access Control Group)が作成されます。

# main.tf
# VPC
resource "ncloud_vpc" "vpc_scn_02" {
name = var.name_scn02
ipv4_cidr_block = "10.0.0.0/16"
}

 

ipv4_cidr_blockは10.0.0.0/16に設定します。10.0.X.Xのような形式のIPv4アドレスを65536個(256 x 256)持てることを意味します。VPCの名前はvariable.tfにあるname_scn02をヒントにして「tf-scn02」と作成される予定です。

2.Subnet & Network ACL (ncloud_subnetncloud_network_acl)

f:id:navercloud:20210224193913p:plain

Private SubnetとPublic Subnetの作成


図のようにPrivate SubnetとPublic Subnet、それからNetwork ACLを定義します。

Public Subnetは基本的に提供されるInternet Gatewayを通じて外部との通信を行うため、Frontend(要塞ホスト)サーバを置いてサービスを提供します。
Private SubnetはVPC内でのみ通信が可能で、BackendサーバのWASやDBサーバなどを置いてサービスを提供します。

# main.tf
# Public Subnet
resource "ncloud_subnet" "subnet_scn_02_public" {
name = "${var.name_scn02}-public"
vpc_no = ncloud_vpc.vpc_scn_02.vpc_no
subnet = cidrsubnet(ncloud_vpc.vpc_scn_02.ipv4_cidr_block, 8, 0) // "10.0.0.0/24"
zone = "KR-2"
network_acl_no = ncloud_network_acl.network_acl_02_public.id
subnet_type = "PUBLIC" // PUBLIC(Public)
}
# Private Subnet
resource "ncloud_subnet" "subnet_scn_02_private" {
name = "${var.name_scn02}-private"
vpc_no = ncloud_vpc.vpc_scn_02.vpc_no
subnet = cidrsubnet(ncloud_vpc.vpc_scn_02.ipv4_cidr_block, 8, 1) // "10.0.1.0/24"
zone = "KR-2"
network_acl_no = ncloud_network_acl.network_acl_02_private.id
subnet_type = "PRIVATE" // PRIVATE(Private)
}
# Network ACL
resource "ncloud_network_acl" "network_acl_02_public" {
vpc_no = ncloud_vpc.vpc_scn_02.id
name = "${var.name_scn02}-public"
}
resource "ncloud_network_acl" "network_acl_02_private" {
vpc_no = ncloud_vpc.vpc_scn_02.id
name = "${var.name_scn02}-private"
}

 

SubnetはVPCの中に作られるため、vpc_noを指定する必要があります。

上で設定したVPC ncloud_vpc.vpc_scn_02.vpc_noに設定します。ZONEはKR-2と定義します。

Terraformでは、cidrsubnet(10.0.0.0/16, 8, 1)のような関数を用いてCIDRブロックを計算できます。

詳しい内容はcidrsubnet Functionをご参照ください。

 

Subnet作成時にはNetwork ACLが必要になるので、network_acl_noを指定します。

VPC作成時に基本提供されるNetwork ACLに設定することもできますが、PrivateとPublicのACL設定を別々にするために、それぞれ作りました。

セキュリティのためのACLルール設定は、7. Network ACLで説明します。 

3. Server (ncloud_server)

VPC環境でサーバを作成できるSubnetが完成しました。では、ここからはServerの作成方法に進みます。

f:id:navercloud:20210224194213p:plain

各SubnetにServerを作成する
# main.tf
# Login Key
resource "ncloud_login_key" "key_scn_02" {
key_name = var.name_scn02 }
# Server
# for Front-end (bastion) server
resource "ncloud_server" "server_scn_02_public" {
subnet_no = ncloud_subnet.subnet_scn_02_public.id
name = "${var.name_scn02}-public"
server_image_product_code = "SW.VSVR.OS.LNX64.CNTOS.0703.B050"
login_key_name = ncloud_login_key.key_scn_02.key_name
//server_product_code = "SVR.VSVR.STAND.C002.M008.NET.SSD.B050.G002" }
# for Back-end (WAS) server
resource "ncloud_server" "server_scn_02_private" {
subnet_no = ncloud_subnet.subnet_scn_02_private.id
name = "${var.name_scn02}-private"
server_image_product_code = "SW.VSVR.OS.LNX64.CNTOS.0703.B050"
login_key_name = ncloud_login_key.key_scn_02.key_name
//server_product_code = "SVR.VSVR.STAND.C002.M008.NET.SSD.B050.G002"
} 

 

VPC ServerはSubnetを指定する必要があります。例題では、それぞれPublicとPrivate Subnetを参照しました。

server_image_product_codeを通じてサーバ画像を設定することもできますが、例題ではCentOS 7.3に指定しました。

サーバ画像コードをインポートする方法は、タソス:ncloud_server_imagesをご参照ください。

 

server_product_code設定でサーバのスペックを指定することができます。入力しないと、最も低いスペックに設定されます。

そのコードはタソス:ncloud_server_productsをご参照ください。

resource "ncloud_public_ip" "public_ip_scn_02" {

server_instance_no = ncloud_server.server_scn_02_public.id

description = "for ${var.name_scn02}"

}

外部からこちらのFrontendサーバにアクセスできるようにし、管理者もSSHにアクセスできるように、グローバルIP(Public IP)を上記のように設定してサーバとつなぎます。

4. NAT Gateway (ncloud_nat_gateway)

ここまででサービスのための全体図がある程度完成しました。

ところが、Private Subnetにあるサーバで外部のパッケージをダウンロードしたいのに、インターネットがつながりません。どうすればいいでしょうか。

 NAT Gatewayを通じてPrivate Subnetから外部のインターネットに接続できます。

f:id:navercloud:20210224194423p:plain

NAT Gatewayの作成
# main.tf
# NAT Gateway
resource "ncloud_nat_gateway" "nat_gateway_scn_02" {
vpc_no = ncloud_vpc.vpc_scn_02.id
zone = "KR-2"
name = var.name_scn02
} 

NAT GatewayをKR-2 ZONEに作成します。

5. Routeの設定 (ncloud_route)

しかし、NAT Gatewayを追加するだけでは外部との通信ができません。

問題は、Private Subnetで外部通信(0.0.0.0/0)がNAT Gatewayまで行けるように道を作らなければならないことです。

これは以下のようにRoute設定を通じて行います。

f:id:navercloud:20210224194541p:plain

Route 設定

ncloud_route_tableリソースを通じてRoute Tableを作成できます。

VPCで基本として作成されたRoute Tableを使用する予定です。

基本的にRoute TableはPublic用とPrivate用にそれぞれ1つずつ作成されますが、NAT GatewayをつけるためにPrivate Route Tableを参照します。

# main.tf
# Route
resource "ncloud_route" "route_scn_02_nat" {
 route_table_no       = ncloud_vpc.vpc_scn_02.default_private_route_table_no
 destination_cidr_block  = "0.0.0.0/0"
 target_type         = "NATGW" // NATGW (NAT Gateway) | VPCPEERING (VPC Peering) | VGW (Virtual Private Gateway).
 target_name         = ncloud_nat_gateway.nat_gateway_scn_02.name
 target_no         = ncloud_nat_gateway.nat_gateway_scn_02.id
}

 

destination_cidr_blockを0.0.0.0/0に指定し、このアドレスに向かうリクエストをNAT Gatewayに向かわせます。

target_typeとtarget_noは、上で定義したNAT Gatewayを参照します。

6. SSH接続とコマンドの実行

TerraformではNull Resourceを通じたSSH接続が可能で、remote-exec Provisionerを通じてls -alといったコマンドを実行できます。

以下のコードは、Network ACLルールがうまく適用されたかどうかをls -alコマンドを実行して出力します。

# main.tf
data "ncloud_root_password" "scn_02_root_password" {
 server_instance_no = ncloud_server.server_scn_02_public.id
 private_key = ncloud_login_key.key_scn_02.private_key
}
resource "null_resource" "ls-al" {
 connection {
   type = "ssh"
   host = ncloud_public_ip.public_ip_scn_02.public_ip
   user = "root"
   port = "22"
   password = data.ncloud_root_password.scn_02_root_password.root_password
 }
   provisioner "remote-exec" { // コマンド実行
    inline = [
     "ls -al",
    ]
 }
 depends_on = [
  ncloud_public_ip.public_ip_scn_02,
  ncloud_server.server_scn_02_public
 ]
}

 

ここまでコードを作成したら、サービスのためのインフラ準備全般ができたと言えますが、

セキュリティのため、さらに行うことが残っています。

security.tf

Subnet & Network ACLでNetwork ACLを作成しましたが、基本Network ACLルールはすべてのIPとportに対してallowされている状態です。すなわち、外部からSSHやサービスにアクセスしてハッキングするリスクがあるという意味です。

以下の例題では、セキュリティのためのACLルールを設定してみましょう。

 

7. Network ACL (ncloud_network_acl_rule)

NAVERクラウドプラットフォームは、VPCのセキュリティ強化に使用できるACGとNetwork ACLの2つの機能を提供します。

詳しい内容は、説明書 > NETWORKING > VPC > セキュリティをご参照ください。

まずはPublic SubnetとつながるACLルールを設定しましょう。

▶ Public Subnet:Inbound

f:id:navercloud:20210224204758p:plain

▶ Public Subnet:Outbound

f:id:navercloud:20210224204840p:plain

# security.tf
# Network ACL Rule
locals {
 public_subnet_inbound = [
   [1, "TCP", "0.0.0.0/0", "80", "ALLOW"],
   [2, "TCP", "0.0.0.0/0", "443", "ALLOW"],
   [3, "TCP", "${var.client_ip}/32", "22", "ALLOW"],
   [4, "TCP", "${var.client_ip}/32", "3389", "ALLOW"],
   [5, "TCP", "0.0.0.0/0", "32768-65535", "ALLOW"],
   [197, "TCP", "0.0.0.0/0", "1-65535", "DROP"],
   [198, "UDP", "0.0.0.0/0", "1-65535", "DROP"],
   [199, "ICMP", "0.0.0.0/0", null, "DROP"],
 ]
public_subnet_outbound = [
   [1, "TCP", "0.0.0.0/0", "80", "ALLOW"],
   [2, "TCP", "0.0.0.0/0", "443", "ALLOW"],
   [3, "TCP", "0.0.0.0/0", "9001-65535", "ALLOW"],
   [4, "TCP", "${ncloud_server.server_scn_02_private.network_interface[0].private_ip}/32", "8080", "ALLOW"], // Allow 8080 port to private server
   [197, "TCP", "0.0.0.0/0", "1-65535", "DROP"],
   [198, "UDP", "0.0.0.0/0", "1-65535", "DROP"],
   [199, "ICMP", "0.0.0.0/0", null, "DROP"]
 ]
}
resource "ncloud_network_acl_rule" "network_acl_02_rule_public" {
 network_acl_no = ncloud_network_acl.network_acl_02_public.id
 dynamic "inbound" {
  for_each = local.public_subnet_inbound
  content {
    priority = inbound.value[0]
    protocol = inbound.value[1]
    ip_block = inbound.value[2]
    port_range = inbound.value[3]
   rule_action = inbound.value[4]
  }
 }
dynamic "outbound" {
  for_each = local.public_subnet_outbound
  content {
    priority = outbound.value[0]
    protocol = outbound.value[1]
    ip_block = outbound.value[2]
    port_range = outbound.value[3]
    rule_action = outbound.value[4]
   }
  }
}

 

次は、PrivateのSubnetのACLルールを以下のように設定します。 

▶ Private Subnet:Inbound

f:id:navercloud:20210224204858p:plain

▶ Private Subnet:Outbound

f:id:navercloud:20210224204919p:plain

# security.tf
locals {
 private_subnet_inbound = [
   [1, "TCP", "${ncloud_server.server_scn_02_public.network_interface[0].private_ip}/32", "8080", "ALLOW"], // Allow 8080 port from public server
   [2, "TCP", "0.0.0.0/0", "32768-65535", "ALLOW"],
   [197, "TCP", "0.0.0.0/0", "1-65535", "DROP"],
   [198, "UDP", "0.0.0.0/0", "1-65535", "DROP"],
   [199, "ICMP", "0.0.0.0/0", null, "DROP"],
 ]
private_subnet_outbound = [
   [1, "TCP", "${ncloud_server.server_scn_02_public.network_interface[0].private_ip}/32", "32768-65535", "ALLOW"], // Allow 32768-65535 port to public server
   [197, "TCP", "0.0.0.0/0", "1-65535", "DROP"],
   [198, "UDP", "0.0.0.0/0", "1-65535", "DROP"],
   [199, "ICMP", "0.0.0.0/0", null, "DROP"]
 ]
}
resource "ncloud_network_acl_rule" "network_acl_02_private" {
 network_acl_no = ncloud_network_acl.network_acl_02_private.id
dynamic "inbound" {
  for_each = local.private_subnet_inbound
  content {
    priority = inbound.value[0]
     protocol = inbound.value[1]
     ip_block = inbound.value[2]
    port_range = inbound.value[3]
    rule_action = inbound.value[4]
 }
}
dynamic "outbound" {
  for_each = local.private_subnet_outbound
  content {
    priority = outbound.value[0]
    protocol = outbound.value[1]
    ip_block = outbound.value[2]
    port_range = outbound.value[3]
    rule_action = outbound.value[4]
  }
 }
}

上記コードでは、約24個のルールをハードコーディングするとソースコードが長くなってしまうため、localsdynamicのBlockを用いてルールを作成します。

これでTerraformコードの作成が終わりました。では実際にインフラを作成してみましょう。

リソース作成計画 (terraform plan)

$ cd terraform/tf-vpc-scenario2
$ 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.
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
 + create
<= read (data resources)
Terraform will perform the following actions:
# data.ncloud_root_password.scn_02_root_password will be read during apply
 # (config refers to values not yet known)
 <= data "ncloud_root_password" "scn_02_root_password" {
    + id = (known after apply)
    + private_key = (sensitive value)
    + root_password = (sensitive value)
    + server_instance_no = (known after apply)
  }
# ncloud_login_key.key_scn_02 will be created
 + resource "ncloud_login_key" "key_scn_02" {
    + fingerprint = (known after apply)
    + id = (known after apply)
    + key_name = "tf-scn02"
    + private_key = (sensitive value)
 }
# ncloud_nat_gateway.nat_gateway_scn_02 will be created
 + resource "ncloud_nat_gateway" "nat_gateway_scn_02" {
    + description = (known after apply)
    + id = (known after apply)
    + name = "tf-scn02"
    + nat_gateway_no = (known after apply)
    + public_ip = (known after apply)
    + vpc_no = (known after apply) + zone = "KR-2" } ... 中略
Plan: 14 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.

 

コードが無事作成されれば、上記のようにPlan: 14 to add, 0 to change, 0 to destroy.と表示され、実際の適用時に14のリソースが作成されることになります。では、以下のterraform applyを通じてリソースを作成してみましょう。

リソースの適用 (terraform apply)

以下のようにterraform applyのコマンドを実行してPlanをもう一度確認し、yesを入力してリソースを作成します。 

$ terraform apply
 
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
 + create
 <= read (data resources)
Terraform will perform the following actions:
# ncloud_login_key.key_scn_02 will be created
 + resource "ncloud_login_key" "key_scn_02" {
    + fingerprint = (known after apply)
    + id = (known after apply)
    + key_name = "tf-scn02"
    + private_key = (sensitive value)
 }
# ncloud_nat_gateway.nat_gateway_scn_02 will be created
 + resource "ncloud_nat_gateway" "nat_gateway_scn_02" {
    + description = (known after apply)
    + id = (known after apply) + name = "tf-scn02"
    + nat_gateway_no = (known after apply)
    + public_ip = (known after apply)  
    + vpc_no = (known after apply) + zone = "KR-2" } ...中略
Plan: 13 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
ncloud_login_key.key_scn_02: Creating...
ncloud_vpc.vpc_scn_02: Creating...
ncloud_login_key.key_scn_02: Creation complete after 1s [id=tf-scn02]
ncloud_vpc.vpc_scn_02: Still creating... [10s elapsed]
ncloud_vpc.vpc_scn_02: Creation complete after 13s [id=2988]
ncloud_network_acl.network_acl_02_public: Creating...
ncloud_nat_gateway.nat_gateway_scn_02: Creating...
ncloud_network_acl.network_acl_02_private: Creating...
ncloud_network_acl.network_acl_02_private: Creation complete after 3s [id=4250]
ncloud_subnet.subnet_scn_02_private: Creating...
ncloud_network_acl.network_acl_02_public: Creation complete after 3s [id=4249]
ncloud_subnet.subnet_scn_02_public: Creating...
ncloud_nat_gateway.nat_gateway_scn_02: Still creating... [10s elapsed]
ncloud_nat_gateway.nat_gateway_scn_02: Creation complete after 13s [id=5648219]
ncloud_route.route_scn_02_nat: Creating...
ncloud_subnet.subnet_scn_02_private: Still creating... [10s elapsed]
ncloud_subnet.subnet_scn_02_public: Still creating... [10s elapsed]
ncloud_subnet.subnet_scn_02_private: Still creating... [20s elapsed]
ncloud_subnet.subnet_scn_02_public: Still creating... [20s elapsed]
ncloud_subnet.subnet_scn_02_private: Creation complete after 22s [id=5506]
ncloud_server.server_scn_02_private: Creating...
ncloud_subnet.subnet_scn_02_public: Creation complete after 22s [id=5507]
ncloud_server.server_scn_02_public: Creating...
ncloud_server.server_scn_02_private: Still creating... [10s elapsed]
ncloud_server.server_scn_02_public: Still creating... [10s elapsed]
...中略
ncloud_server.server_scn_02_public: Creation complete after 2m48s [id=5648223]
data.ncloud_root_password.scn_02_root_password: Reading...
ncloud_public_ip.public_ip_scn_02: Creating...
ncloud_network_acl_rule.network_acl_02_private: Creating...
data.ncloud_root_password.scn_02_root_password: Read complete after 0s [id=5648223]
ncloud_public_ip.public_ip_scn_02: Creation complete after 3s [id=5648227]
null_resource.ls-al: Creating...
null_resource.ls-al: Provisioning with 'remote-exec'...
null_resource.ls-al (remote-exec): Connecting to remote host via SSH...
null_resource.ls-al (remote-exec): Host: 110.165.17.xx
null_resource.ls-al (remote-exec): User: root null_resource.ls-al (remote-exec): Password: true
null_resource.ls-al (remote-exec): Private key: false null_resource.ls-al (remote-exec): Certificate: false
null_resource.ls-al (remote-exec): SSH Agent: false null_resource.ls-al (remote-exec): Checking Host Key: false
null_resource.ls-al (remote-exec): Connected!
null_resource.ls-al (remote-exec): total 24
null_resource.ls-al (remote-exec): dr-xr-x---. 4 root root 138 May 26 2020 .
null_resource.ls-al (remote-exec): dr-xr-xr-x. 18 root root 257 May 26 2020 ..
null_resource.ls-al (remote-exec): -rw-------. 1 root root 1441 May 26 2020 .bash_history
null_resource.ls-al (remote-exec): -rw-r--r--. 1 root root 18 Dec 29 2013 .bash_logout
null_resource.ls-al (remote-exec): -rw-r--r--. 1 root root 176 Dec 29 2013 .bash_profile
null_resource.ls-al (remote-exec): -rw-r--r--. 1 root root 176 Dec 29 2013 .bashrc
null_resource.ls-al (remote-exec): drwx------. 3 root root 17 May 26 2020 .cache
null_resource.ls-al (remote-exec): -rw-r--r--. 1 root root 100 Dec 29 2013 .cshrc
null_resource.ls-al (remote-exec): drwxr-----. 3 root root 19 May 26 2020 .pki
null_resource.ls-al (remote-exec): -rw-r--r--. 1 root root 129 Dec 29 2013 .tcshrc
null_resource.ls-al: Creation complete after 1s [id=8315713944255249232]
ncloud_network_acl_rule.network_acl_02_private: Still creating... [10s elapsed]
ncloud_network_acl_rule.network_acl_02_private: Still creating... [20s elapsed]
ncloud_network_acl_rule.network_acl_02_private: Creation complete after 25s [id=4250]
Apply complete! Resources: 14 added, 0 changed, 0 destroyed.
上のように最後にApply complete!が表示されれば、すべてのリソースの作成は完了します。

それからnull_resourceからSSHにアクセスしてみれば、ls -alもうまく実行されたことを確認できます。

 

では、リソースのうちサーバがうまく作成されたかどうかをコンソールで確認してみましょう。

f:id:navercloud:20210224192200p:plain

上のようにサーバ2台が正しく作成されたことが確認できます。

その他のリソースは、Terraformガイドを参考にして追加することができます。 

f:id:navercloud:20210108155858p:plain
今回の記事では、Terraformを用いてVPC環境でServerを作成し、サービスを提供する方法を説明いたしました。

VPCのような複雑な環境でTerraformを活用すれば、大規模なインフラ環境をより一層効率的に管理できます。

(* 全体のソースコードは、こちらをご参照ください。)

 

お役に立ちましたでしょうか? 次回の投稿でも有益な情報を提供いたします。

引き続きよろしくお願いします。

 

f:id:navercloud:20201209180753p:plain