siklog
[NCP/Terraform] Terraform으로 구현하는 NCP 인프라 구성 Part2 본문
저번 포스팅에서는 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
}
'클라우드 > NCP' 카테고리의 다른 글
[NCP/Terraform] Terraform으로 구현하는 NCP 인프라 구성 Part1 (1) | 2022.09.12 |
---|---|
[NCP/Load Balancer] LB 내 바인딩된 Target VM에서 동일 LB로 재호출하는 경우 (0) | 2022.08.31 |
[NCP/Security] ACG, NACL 설정 간 유의할 사항 (0) | 2022.08.16 |
[Server/FTP] FTP Active, PassiveMode 차이점 (0) | 2022.06.19 |
[NCP/Containers] NKS 생성 및 접근 방법 (0) | 2022.05.17 |