Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Tags
more
Archives
Today
Total
관리 메뉴

siklog

[NCP/Terraform] Terraform으로 구현하는 NCP 인프라 구성 Part2 본문

클라우드/NCP

[NCP/Terraform] Terraform으로 구현하는 NCP 인프라 구성 Part2

ms 2022. 10. 10. 02:06

저번 포스팅에서는 Terraform 으로 NCP 리소스를 어떻게 생성하는지 방법을 간단하게 알아봤었다.

이번 포스팅에서는 서버뿐만아닌 다른 NCP 리소스들까지 생성 및 연동해보고자 한다.

 

기본적인 리소스 생성 방법 가이드는 테라폼 레지스트리에서 제공하고 있으니 링크를 참고

테라폼 레지스트리 NCP Documentation : https://registry.terraform.io/providers/NaverCloudPlatform/ncloud/latest/docs

 

먼저, 테라폼 코드를 작성하기 전 각 모듈별로 파일의 구조를 잘 설정하는 것이 중요한데,
만약 프로젝트의 구분 없이 하나의 디렉터리 또는 tf 파일에 모든 코드를 같이 작성하거나 구성하였을 경우 알아 보기 힘들고 문제가 발생했을 때 수정하기가 굉장히 어려워질 수 있다.  (즉, 다시 만들어야 하는 불상사가 생길 수도 있다.)

때문에 처음부터 어떻게 구성을할지 나눌지 생각해 보는 것도 좋은 방법이 될 수 있다.
물론 여타 개발할 때와 마찬가지로 코드를 어떻게 사용할지 그리고 어떻게 나눌 것인지 등 이런 부분은 정답은 없으며, 다만 테라폼에서 권장하는 구조의 예시도 있으니 아래 구조도 참고 해보면 좋을 것 같다.

terraform 디렉터리 구조 권장 예시

minimal 예제
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
complete 예제
├── README.md
├── main.tf
├── variables.tf
├── outputs.tf
├── ...
├── modules/
│ ├── nestedA/
│ │ ├── README.md
│ │ ├── variables.tf
│ │ ├── main.tf
│ │ ├── outputs.tf
│ ├── nestedB/
│ ├── .../
├── examples/
│ ├── exampleA/
│ │ ├── main.tf
│ ├── exampleB/
│ ├── .../

여기에 추가로 커스텀하게 아래의 파일들을 붙히기도 합니다.
├── provider.tf
├── backend.tf

main.tf : 테라폼 CLI를 사용하여 apply 명령어를 사용하면 가장 먼저 main소스 코드를 동작시킵니다. 말 그대로 main
modules : 자바로 보면 하나의 클래스를 만드는 것과 비슷한 개념입니다. main에서 input 값을 지정하고 해당 모듈을 사용할 수 있습니다.
backend.tf : 테라폼은 형상관리를 위해 .tfstate 파일을 생성합니다. 이 파일을 backup하고 형상관리하기위한 설정을 정의합니다.
provider.tf : 리소스를 어디서 제공하는지, 버전은 어떤것인지 등을 설정합니다.
outputs.tf : 해당 파일에 설정을 통해서 소스코드에 대한 실행 결과를 출력할 수 있습니다.
variables.tf : 소스코드에 사용할 변수들을 정의 합니다.

 

그렇다면 이제 아래 구성도 대로 NCP 인프라 리소스를 생성해보는 과정을 terraform 코드로 차례대로 구성해 볼텐데,

그 전에 테라폼, 프로바이더 버전 및 액세스키 설정방법은 생략하였으니 설정방법을 모른다면 이전 포스팅을 참고하자. (Part1 내용을 참고)

https://minsigi.tistory.com/26

 

 

0. 변수 및 데이터

 

- variable.tf 파일로 자주 사용 또는 수정이 필요한 값들을 미리 지정해놓을 수 있다.

$ vi variable.tf

variable client_ip {
  default = "1.242.31.207" // To access ssh
}
variable access_key {
  default = "*****"
}
variable secret_key {
  default = "*****
}
variable "vpc_cidr" {
        default = "10.0.0.0/16"
}
variable "availability_zone" {
        default = ["KR-1", "KR-2"]
}
variable "pub_server_lists" {
  type        = list(any)
  description = "module 2 server name list"
  default     = ["web1", "web2"]
}

variable "pri_ip" {

  type = list

  default = ["10.0.0.26" , "10.0.1.26"]

}

 

- 이미 ncp내 생성 되어 있는 리소스의 대한 정보를 데이터로 추출 후 참조하여 사용할 수 있다.

- 데이터 값은 output을 통해 출력하여 확인해볼 수도 있다.

$ vi data.tf

data "ncloud_server_image" "image" {
  filter {
    name = "product_name"
    values = ["CentOS 7.8 (64-bit)"]
  }
}
data "ncloud_server_image" "db_image" {
  filter {
    name = "product_name"
    values = ["mysql(8.0)-centos-7.8-64"]
  }
}

 

 

1. VPC 생성

 

resource "ncloud_vpc" "terraform-test-vpc" {

  name            = var.vpc-name

  ipv4_cidr_block = "10.0.0.0/16"

}

> 각 문법과 속성에 관한 설명은 생략 공식문서 참고
> cidr_block = "${var.vpc_cidr}" 변수참조는 variable.tf 참조

 

 

2. Subnet 생성

 

- 퍼블릭, 프라이빗 서브넷을 생성하였고 ncp의 경우 LB 전용 서브넷을 따로 생성해줘야 하기때문에 LB 전용서브넷까지 같이 생성

$  vi subnet.tf

# Public Subnet
resource "ncloud_subnet" "public_subnet" {
  count          = 2
  vpc_no         = ncloud_vpc.terraform-test-vpc.vpc_no
  subnet         = "${cidrsubnet(var.vpc_cidr, 8, count.index)}" // "10.0.0.0/24"
  zone           = "${element(var.availability_zone, count.index)}"
  network_acl_no = ncloud_network_acl.public_nacl.id
  subnet_type    = "PUBLIC" // PUBLIC(Public)
}
# Private Subnet
resource "ncloud_subnet" "private_subnet" {
  count          = 3
  vpc_no         = ncloud_vpc.terraform-test-vpc.vpc_no
  subnet         = "${cidrsubnet(var.vpc_cidr, 8, count.index+2)}" // "10.0.1.0/24"
  zone           = "${element(var.availability_zone, count.index)}"
  network_acl_no = ncloud_network_acl.private_nacl.id
  subnet_type    = "PRIVATE" // PRIVATE(Private)
}
# Public LB Subnet
resource "ncloud_subnet" "pub_lb_subnet" {
  vpc_no         = ncloud_vpc.terraform-test-vpc.id

  subnet         = "10.0.10.0/24"
  zone           = "KR-2"
  network_acl_no = ncloud_network_acl.public_nacl.id
  subnet_type    = "PRIVATE" // PUBLIC(Public) | PRIVATE(Private)
  // below fields is optional
  name           = "pub-lb-subnet-01"
  usage_type     = "LOADB"    // GEN(General) | LOADB(For load balancer)
}
# Private LB Subnet
resource "ncloud_subnet" "pri_lb_subnet" {
  vpc_no         = ncloud_vpc.terraform-test-vpc.id
  subnet         = "10.0.11.0/24"
  zone           = "KR-2"
  network_acl_no = ncloud_network_acl.private_nacl.id
  subnet_type    = "PRIVATE" // PUBLIC(Public) | PRIVATE(Private)
  // below fields is optional
  name           = "pri-lb-subnet-01"
  usage_type     = "LOADB"    // GEN(General) | LOADB(For load balancer)
}

# Network ACL
resource "ncloud_network_acl" "public_nacl" {
  vpc_no = ncloud_vpc.terraform-test-vpc.id
  name   = "${var.vpc-name}-public"
}
resource "ncloud_network_acl" "private_nacl" {
  vpc_no = ncloud_vpc.terraform-test-vpc.id
  name   = "${var.vpc-name}-private"
}

 

 

3. 서버 생성

 

# Server
# WEB1 WEB2 server
resource "ncloud_server" "public_server" {
  count = length(var.pub_server_lists)
  subnet_no                 = "${ncloud_subnet.public_subnet[count.index].id}"
  name                      = "terraform-${element(var.pub_server_lists,count.index)}-public"
  server_image_product_code = data.ncloud_server_image.image.id
  login_key_name            = ncloud_login_key.loginkey.key_name
  server_product_code       = "SVR.VSVR.STAND.C002.M008.NET.SSD.B050.G002"
  network_interface   {
    network_interface_no = ncloud_network_interface.pub_server_nic[count.index].id
    order = 0
  }
}

# WAS1 WAS2 server
resource "ncloud_server" "private_server" {
  count = length(var.pub_server_lists)
  subnet_no                 = "${ncloud_subnet.private_subnet[count.index].id}"
  name                      = "terraform-${element(var.pri_server_lists,count.index)}-private"
  server_image_product_code = data.ncloud_server_image.image.id
  login_key_name            = ncloud_login_key.loginkey.key_name
  server_product_code       = "SVR.VSVR.STAND.C002.M008.NET.SSD.B050.G002"
  network_interface   {
    network_interface_no = ncloud_network_interface.pri_server_nic[count.index].id
    order = 0
  }
}

# DB server
resource "ncloud_server" "private_db_server" {
  subnet_no                 = "${ncloud_subnet.private_subnet[2].id}"
  name                      = "${var.vpc-name}-db-private"
  server_image_product_code = data.ncloud_server_image.db_image.id
  login_key_name            = ncloud_login_key.loginkey.key_name
  server_product_code       = "SVR.VSVR.STAND.C002.M008.NET.SSD.B050.G002"
  network_interface   {
    network_interface_no = ncloud_network_interface.pri_db_server_nic.id
    order = 0
  }
}

 

 

4. ACG 및 NIC 생성

 

- NCP에서는 테라폼으로 생성된 서버 리소스에대한 기본 ACG 룰 설정이 불가능 하다.

- 때문에 별도로 룰 설정을한 ACG에 NIC을 생성하여 연결하는 방식으로 사용해야 한다.

- 테스트로 만든 리소스이기에 ip_block을 0.0.0.0/0로 하였으나, ip 범위는 용도나 보안에 맞게 수정해서 적용하도록 하자.

 

# acg
resource "ncloud_access_control_group" "terraform-acg" {
  name        = "terraform-acg"
  vpc_no      = ncloud_vpc.terraform-test-vpc.id
}
resource "ncloud_access_control_group" "terraform-db-acg" {
  name        = "terraform-db-acg"
  vpc_no      = ncloud_vpc.terraform-test-vpc.id
}

 

# acg rule

resource "ncloud_access_control_group_rule" "terraform-acg-rule" {

  access_control_group_no = ncloud_access_control_group.terraform-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"

  }

  inbound {

    protocol    = "ICMP"

    ip_block    = "0.0.0.0/0"

    description = "accept ping"

  }

  outbound {

    protocol    = "TCP"

    ip_block    = "0.0.0.0/0"

    port_range  = "1-65535"

    description = "accept 1-65535 port"

  }

}

 

resource "ncloud_access_control_group_rule" "terraform-db-acg-rule" {

  access_control_group_no = ncloud_access_control_group.terraform-db-acg.id

 

  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"

  }

}

 

# NIC
resource "ncloud_network_interface" "pub_server_nic" {
  count = length(var.pub_server_lists)
  name = "${var.vpc-name}-${element(var.pub_server_lists,count.index)}-nic"
  subnet_no = ncloud_subnet.public_subnet[count.index].id
  access_control_groups = [ncloud_access_control_group.terraform-acg.id]
  private_ip = var.pri_ip[count.index]
}
resource "ncloud_network_interface" "pri_server_nic" {
  count = length(var.pri_server_lists)
  name = "${var.vpc-name}-${element(var.pri_server_lists,count.index+2)}-nic"
  subnet_no = ncloud_subnet.private_subnet[count.index].id
  access_control_groups = [ncloud_access_control_group.terraform-acg.id]
}

resource "ncloud_network_interface" "pri_db_server_nic" {

  name = "${var.vpc-name}-db-nic"

  subnet_no = ncloud_subnet.private_subnet[2].id

  access_control_groups = [ncloud_access_control_group.terraform-db-acg.id]

}

resource "ncloud_network_interface" "pri_db_server_nic" {

  name = "${var.vpc-name}-db-nic"

  subnet_no = ncloud_subnet.private_subnet[2].id

  access_control_groups = [ncloud_access_control_group.terraform-db-acg.id]

}

 

 

5. LB 생성

 

# LB Targetgroup
resource "ncloud_lb_target_group" "pub_lb_tg" {
  name = "pub-lb-tg"
  vpc_no   = ncloud_vpc.terraform-test-vpc.vpc_no
  protocol = "HTTP"
  target_type = "VSVR"
  port        = 80
  description = "for test"
  health_check {
    protocol = "HTTP"
    http_method = "GET"
    port           = 80
    url_path       = "/"
    cycle          = 30
    up_threshold   = 2
    down_threshold = 2
  }
  algorithm_type = "RR"
}

resource "ncloud_lb_target_group" "pri_lb_tg" {

  name = "pri-lb-tg"

  vpc_no   = ncloud_vpc.terraform-test-vpc.vpc_no

  protocol = "HTTP"

  target_type = "VSVR"

  port        = 80

  description = "for test"

  health_check {

    protocol = "HTTP"

    http_method = "GET"

    port           = 80

    url_path       = "/"

    cycle          = 30

    up_threshold   = 2

    down_threshold = 2

  }

  algorithm_type = "RR"

}

 

# LB targetgorup attachment

resource "ncloud_lb_target_group_attachment" "pub_lb_tg_att" {

  count = length(var.pub_server_lists)

  target_group_no = ncloud_lb_target_group.pub_lb_tg.id

  target_no_list = ["${ncloud_server.public_server[count.index].id}"]

}

resource "ncloud_lb_target_group_attachment" "pri_lb_tg_att" {

  count = length(var.pri_server_lists)

  target_group_no = ncloud_lb_target_group.pri_lb_tg.id

  target_no_list = ["${ncloud_server.private_server[count.index].id}"]

}

 

# LB

resource "ncloud_lb" "pub_alb" {

  name  = "pub-alb"

  network_type = "PUBLIC"

  type = "APPLICATION"

  subnet_no_list = [ncloud_subnet.pub_lb_subnet.id]

}

resource "ncloud_lb" "pri_alb" {

  name  = "pri-alb"

  network_type = "PRIVATE"

  type = "APPLICATION"

  subnet_no_list = [ncloud_subnet.pri_lb_subnet.id]

}

 

# LB Listener

resource "ncloud_lb_listener" "pub_alb_listener" {

  load_balancer_no = ncloud_lb.pub_alb.id

  protocol = "HTTP"

  port = 80

  target_group_no = ncloud_lb_target_group.pub_lb_tg.id

}

resource "ncloud_lb_listener" "pri_alb_listener" {

  load_balancer_no = ncloud_lb.pri_alb.id

  protocol = "HTTP"

  port = 80

  target_group_no = ncloud_lb_target_group.pri_lb_tg.id

}

Comments