[Terraform - NaverCloud vm생성] part 1

Terraform 이란,
테라폼(Terraform)은 Hashicorp에서 오픈소스로 개발 중인 클라우드 인프라스트럭처 자동화를 지향하는 코드로서의 Infrastructure as Code, IaC 도구입니다.
AWS, Azure, GCP 등 여러 cloud 플랫폼에서 사용이 가능하며, 국내 플랫폼중에서는 네이버 클라우드 플랫폼이 유일하게 등록되어 있습니다.

 

Terraform 기본 개념
resource : 실제로 생성할 인프라 자원을 의미
provider : 리소스들이 배포될 환경을 정의한 것으로 ncp, aws, gcp 등
output : 인프라를 프로비저닝 한 후에 생성된 자원을 output 부분으로 뽑을 수 있습니다. Output으로 추출한 부분은 이후에 remote state에서 활용 가능
backend : 백엔드는 Terraform의 상태 snapshot이 저장 되는 위치를 정의합니다. 백엔드는 주로 Terraform이 상태를 저장하는 위치를 결정 
module : Module은 함께 사용되는 여러 리소스의 컨테이너입니다. Module을 사용하면 변수만 바꿔서 동일한 리소스를 손쉽게 생성할 수 있다는 장점이 있습니다.
remote state : remote state를 사용하면 VPC, IAM 등과 같은 공용 서비스를 다른 서비스에서 참조할 수 있습니다. tfstate파일(최신 테라폼 상태정보)이 저장되어 있는 backend 정보를 명시하면, terraform이 해당 backend에서 output 정보들을 가져옵니다.

 

 

일반적으로 local에서 visual studio code와 같은 프로그램 이용해서 하지만, 이번 테스트는 NCP에서 일반 linux서버 하나 생성하여 거기서 테스트 진행하였습니다.

VPC 환경에 WEB 서버, WAS 서버, DB 서버 용으로 총 3대 VM 생성 예정.

 

■ 사전 준비
NCP 계정 및 access key/secret key 필요
아래 사진과 같이 ncp 홈페이지 -> 마이페이지 -> 인증키 관리에서 확인 가능

 

■ 테스트 환경
Hostname
IP
OS
Terraform
terraform
192.168.100.43
CentOS 7.3
v0.14.8

 

■ Terraform 설치
terraform은 Linux에 설치할 때 binary 설치를 지원하여 편리하게 설치 및 삭제가 가능합니다.
[root@terraform ~]# wget https://releases.hashicorp.com/terraform/0.14.8/terraform_0.14.8_linux_amd64.zip
--2022-06-16 15:13:44--  https://releases.hashicorp.com/terraform/0.14.8/terraform_0.14.8_linux_amd64.zip
Resolving releases.hashicorp.com (releases.hashicorp.com)... 146.75.50.49
Connecting to releases.hashicorp.com (releases.hashicorp.com)|146.75.50.49|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 33785240 (32M) [application/zip]
Saving to: ‘terraform_0.14.8_linux_amd64.zip’

100%[===================================================>] 33,785,240  --.-K/s   in 0.08s   

2022-06-16 15:13:44 (408 MB/s) - ‘terraform_0.14.8_linux_amd64.zip’ saved [33785240/33785240]


[root@terraform ~]# unzip terraform_0.14.8_linux_amd64.zip
Archive:  terraform_0.14.8_linux_amd64.zip
  inflating: terraform  


## 경로 이동
[root@terraform ~]# mv terraform /usr/bin/


[root@terraform ~]# terraform version
Terraform v0.14.8

 

 

■ 총 3개의 terraform 파일 생성
main.tf / variables.tf / version.tf
## main.tf
[root@terraform ~]# vi main.tf
provider "ncloud" {
  support_vpc = true
  access_key = var.access_key
  secret_key = var.secret_key
  region     = var.region
}


resource "ncloud_login_key" "key" {
  key_name = var.login_key_name
}


data "ncloud_root_password" "web_pwd" {
  count                     = "1"
  server_instance_no        = ncloud_server.server_web[count.index].id
  private_key               = ncloud_login_key.key.private_key
}


data "ncloud_root_password" "was_pwd" {
  count                     = "1"
  server_instance_no        = ncloud_server.server_was[count.index].id
  private_key               = ncloud_login_key.key.private_key
}


data "ncloud_root_password" "db_pwd" {
  count                     = "1"
  server_instance_no        = ncloud_server.server_db[count.index].id
  private_key               = ncloud_login_key.key.private_key
}


data "ncloud_vpc" "selected" {
  id = "16825"
}


resource "ncloud_network_acl" "web_acl" {
   vpc_no         = data.ncloud_vpc.selected.id
   name           = "web-acl"
   description    = "for test"
}


resource "ncloud_network_acl" "was_acl" {
   vpc_no         = data.ncloud_vpc.selected.id
   name           = "was-acl"
   description    = "for test"
}


resource "ncloud_network_acl" "db_acl" {
   vpc_no         = data.ncloud_vpc.selected.id
   name           = "db-acl"
   description    = "for test"
}


resource "ncloud_subnet" "web_subnet" {
  vpc_no         = data.ncloud_vpc.selected.id
  subnet         = var.subnets[0]
  zone           = var.zones
  network_acl_no = ncloud_network_acl.web_acl.id
  subnet_type    = var.subnet_types[0]
  name           = var.subnet_names[0]
  usage_type     = var.subnet_usage[0]
}


resource "ncloud_subnet" "was_subnet" {
  vpc_no         = data.ncloud_vpc.selected.id
  subnet         = var.subnets[1]
  zone           = var.zones
  network_acl_no = ncloud_network_acl.was_acl.id
  subnet_type    = var.subnet_types[1]
  name           = var.subnet_names[1]
  usage_type     = var.subnet_usage[1]
}


resource "ncloud_subnet" "db_subnet" {
  vpc_no         = data.ncloud_vpc.selected.id
  subnet         = var.subnets[2]
  zone           = var.zones
  network_acl_no = ncloud_network_acl.db_acl.id
  subnet_type    = var.subnet_types[2]
  name           = var.subnet_names[2]
  usage_type     = var.subnet_usage[2]
}


resource "ncloud_access_control_group" "web_acg" {
  name        = "web-acg"
  description = "description"
  vpc_no      = data.ncloud_vpc.selected.id
}


resource "ncloud_access_control_group_rule" "web_acg-rule" {
  access_control_group_no = ncloud_access_control_group.web_acg.id
  inbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "22"
    description = "accept 22 port"
  }


  inbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "80"
    description = "accept 80 port"
  }


  inbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "443"
    description = "accept 443 port"
  }


  outbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "1-65535"
    description = "accept 1-65535 port"
  }
}


resource "ncloud_access_control_group" "was_acg" {
  name        = "was-acg"
  description = "description"
  vpc_no      = data.ncloud_vpc.selected.id
}


resource "ncloud_access_control_group_rule" "was_acg-rule" {
  access_control_group_no = ncloud_access_control_group.was_acg.id
  inbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "22"
    description = "accept 22 port"
  }


  inbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "80"
    description = "accept 80 port"
  }


  inbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "8080"
    description = "accept 8080 port"
  }


  outbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "1-65535"
    description = "accept 1-65535 port"
  }
}


resource "ncloud_access_control_group" "db_acg" {
  name        = "db-acg"
  description = "description"
  vpc_no      = data.ncloud_vpc.selected.id
}


resource "ncloud_access_control_group_rule" "db_acg-rule" {
  access_control_group_no = ncloud_access_control_group.db_acg.id
  inbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "22"
    description = "accept 22 port"
  }


  inbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "8080"
    description = "accept 8080 port"
  }


  inbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "3306"
    description = "accept 3306 port"
  }


  outbound {
    protocol    = "TCP"
    ip_block    = "0.0.0.0/0"
    port_range  = "1-65535"
    description = "accept 1-65535 port"
  }
}



resource "ncloud_network_interface" "nic_web" {
  count = "1"
  name                  = "terra-web-nic-${count.index+1}"
  subnet_no             = ncloud_subnet.web_subnet.id
  private_ip            = var.web[count.index]
  access_control_groups = [ncloud_access_control_group.web_acg.id]
}


resource "ncloud_server" "server_web" {
  count                       = "1"
  subnet_no                   = ncloud_subnet.web_subnet.id
  name                        = "ncloud-terraform-web-vm-${count.index+1}"
  server_image_product_code   = var.server_image_product_code
  server_product_code         = var.server_product_code
  description                 = "terraform-vm-${count.index+1} is best tip!!"
  login_key_name              = ncloud_login_key.key.key_name
  network_interface   {
    network_interface_no = ncloud_network_interface.nic_web[count.index].id
    order = 0
  }
}


resource "ncloud_network_interface" "nic_was" {
  count = "1"
  name                  = "terra-was-nic-${count.index+1}"
  subnet_no             = ncloud_subnet.was_subnet.id
  private_ip            = var.was[count.index]
  access_control_groups = [ncloud_access_control_group.was_acg.id]
}


resource "ncloud_server" "server_was" {
  count                       = "1"
  subnet_no                   = ncloud_subnet.was_subnet.id
  name                        = "ncloud-terraform-was-vm-${count.index+1}"
  server_image_product_code   = var.server_image_product_code
  server_product_code         = var.server_product_code
  description                 = "terraform-vm-${count.index+1} is best tip!!"
  login_key_name              = ncloud_login_key.key.key_name
  network_interface   {
    network_interface_no = ncloud_network_interface.nic_was[count.index].id
    order = 0
  }
}


resource "ncloud_network_interface" "nic_db" {
  count = "1"
  name                  = "terra-db-nic-${count.index+1}"
  subnet_no             = ncloud_subnet.db_subnet.id
  private_ip            = var.db[count.index]
  access_control_groups = [ncloud_access_control_group.db_acg.id]
}


resource "ncloud_server" "server_db" {
  count                       = "1"
  subnet_no                   = ncloud_subnet.db_subnet.id
  name                        = "ncloud-terraform-db-vm-${count.index+1}"
  server_image_product_code   = var.server_image_product_code
  server_product_code         = var.server_product_code
  description                 = "terraform-vm-${count.index+1} is best tip!!"
  login_key_name              = ncloud_login_key.key.key_name
  network_interface   {
    network_interface_no = ncloud_network_interface.nic_db[count.index].id
    order = 0
  }
}


resource "ncloud_public_ip" "pi" {
  count = "1"
  server_instance_no = ncloud_server.server_web[count.index].id
  description        = "terra-IP"
}

 

 

## variables.tf

[root@terraform ~]# vi variables.tf

variable "access_key" { # export TF_VAR_access_key=...
  default = ""
}


variable "secret_key" { # export TF_VAR_secret_key=...
  default = ""
}


variable "region" {
  default = "KR"
}


variable "zones" {
  default =  "KR-2"
}


# centos- 7.3-64
variable "server_image_product_code" {
  default = "SW.VSVR.OS.LNX64.CNTOS.0703.B050"
}


# HDD : CPU 2 ,Memory 4GB , Disk 50GB
variable "server_product_code" {
  default = "SVR.VSVR.HICPU.C002.M004.NET.HDD.B050.G002"
}


variable "login_key_name" {
  default = "jeonghyun"
}


variable "subnets" {
  type = list
  default = ["10.0.20.0/24" , "10.0.30.0/24" , "10.0.40.0/24"]
}


variable "subnet_types" {
  type = list
  default = ["PUBLIC" , "PRIVATE" , "PRIVATE"]
}


variable "subnet_names" {
  type = list
  default = ["terraform-web" , "terraform-was" , "terraform-db"]
}


variable "subnet_usage" {
  type = list
  default = ["GEN" , "GEN" , "GEN"]
}


variable "web" {
  type = list
  default = ["10.0.20.100" , "10.0.20.101"]
}


variable "was" {
  type = list
  default = ["10.0.30.100" , "10.0.30.101"]
}


variable "db" {
  type = list
  default = ["10.0.40.100" , "10.0.40.101"]
}


variable "block_storage_no" {
  default = "11150638"
}
 
 
## versions.tf
[root@terraform ~]# vi versions.tf

terraform {
  required_version = ">= 0.13"
  required_providers {
    ncloud = {
      source = "terraform-providers/ncloud"
    }
    null = {
      source = "hashicorp/null"
    }
    random = {
      source = "hashicorp/random"
    }
  }
}

 

■ NCP 계정
access key / secret key 환경 변수 등록
[root@terraform ~]# export TF_VAR_access_key=<access key 입력>
[root@terraform ~]# export TF_VAR_secret_key=<secret key 입력>

 

 

이번 글에선 teraform설치 및 파일 구성까지 진행하였습니다. 다음 part2에서 실행하여 서버 생성하도록 하겠습니다.

 

 

참고 

https://not-to-be-reset.tistory.com/369

 

[Terraform] NCP - Terraform으로 서버 생성하기

NCP를 사용하는 이유 AWS는 프리티어 기간이 끝났다. => 유료다 NCP는 아직 프리티어 기간이다 => 무료다 NCP의 경우 무료 VM을 한개만 사용이 가능합니다. 즉 아래의 실습을 하기 위해서는 유료 요금

not-to-be-reset.tistory.com