-
[Terraform] VM(Virtual Machine) 100개 한번에 만들기 (2/3)오픈소스 2024. 5. 1. 00:00
개요
1편 포스팅에 이어서 계속해서 이어가 보자. 2편에서는 실제로 사용했던 코드를 보며 각 항목이 무엇을 의미하며 어떤 식으로 동작하는지 살펴보도록 하자. 코드를 다루는 사람이라면 알겠지만 정답은 없으니 필요한 부분은 추출하여 사용하면 되겠으며, 코드가 워낙 길어서 주요 부분들로 나누어서 설명하도록 하겠다.
(수행 간 오류가 발생하면 처음부터 수정해야 할 수 있으니, 주요 부분들을 작성하여 #terraform plan을 수행하면 정상 여부를 체크하면서 수행하는 것이 정신건강에 좋다. )
main.tf 계정 정보 선언
Terraform ↔ VMware 구성에서 vCenter의 계정 정보는 가장 중요한 역할이다. 해당 계정 정보를 바탕으로 vCenter에 접속하여 생성/관리/삭제 등의 작업을 수행하기 때문이며, #terraform plan을 수행한 정보 불러오기/사전 테스트 역시도 정상 접속이 선행되어야만 한다.
terraform { required_providers { vsphere = { source = "hashicorp/vsphere" version = "2.5.0" } } } provider "vsphere" { user = "admin@vmware" password = "admin123" vsphere_server = "admin.comm" allow_unverified_ssl = true }
1편에서 수행한 Provider 버전에 맞게 선언하여 주고 vCenter에 접속하기 위한 정보들을 순차적으로 선언해주면 된다. 크게 어려운 부분은 없으니 오타/띄어쓰기 등에 주의하며 다음으로 넘어가면 된다.
다중 Client 세부 사양 정보 작성
제목에서 언급한 바와 같이 포스팅 최종 목표는 100개의 서버를 한번에 생성하는 것이다. Template 기반으로 수행하기에 대부분의 정보는 같지만 Hostname/IP 등의 변수는 수동으로 선언을 해줘야만 한다. 코드 후반부에 Count라는 값이 등장하는데 Dictionary 형태로 값이 들어가기에 콤마(,)와 큰따옴표(") 값에 주의해야 한다. 그리고 당연한 애기겠지만 hostname/ip_aaddress/cpu_core/MEM_Byte 변수가 동일하게 100개여야 하며 하나라도 빠지거나 하면 매우 곤란할 수 있으니 주의 바란다.
variable "hostname" { description = "The hostname for the vm" type = list(string) default = ["SVR1","SVR2","SVR3"] } variable "ip_address" { description = "The IP Address for the vm" type = list(string) default = ["192.168.0.10","192.168.0.20","192.168.0.30"] } variable "cpu_core" { description = "Cpu Core" type = list(string) default = ["4","4","4"] } variable "MEM_MByte" { description = "Cpu Core" type = list(string) default = ["16384","16384","16384" }
VMware 구성 요소 선언
이번 단계에서는 Guest VM이 사용하는 ESX Host/Datastore/Network 등의 VM 요소들을 선언해주어야 한다. Terraform 에서는 이를 data라는 요소에 담아서 사용하는 트리구조에 방식을 취하기 때문이다. 예를 들면 아래와 같다.
datacenter_id = data.vsphere_datastore.datastore.id
더보기data 구성 요소 중에서 vpshere_datastore라는 항목을 찾고, 하위에서 다시 datastore라는 값을 찾고 해당 값의 ID 정보를 추출하여 datacetner_id 라는 변수 안에 담는다.
위 내용을 바탕으로 Guest VM을 생성하는데 필요한 구성 요소들을 순차적으로 생성해보자.
data "vsphere_datacenter" "dc" { name = "Datacenter" } data "vsphere_network" "net" { name = "192.168.0.X" datacenter_id = data.vsphere_datacenter.dc.id } data"vsphere_host" "host" { name = "VM_Host1.admin.com" datacenter_id = data.vsphere_datacenter.dc.id } data "vsphere_datastore" "datastore" { name = "Datastore1" datacenter_id = data.vsphere_datacenter.dc.id } data "vsphere_virtual_machine" "template" { name = "Template_LINUX" datacenter_id = data.vsphere_datacenter.dc.id }
Guest VM 서버 생성하는 부분
가장 중요한 부분이다. 위에서 선언한 변수와 정보들을 바탕으로 실제 Guest VM을 생성하는 것이며 필자는 Clone이라는 기능을 사용하기 위하여 작업 전에 복제를 위한 Template 용도의 서버를 만들어두어 사용하였으며, 코드가 길기 때문에 주요 항목들에 대하여 주석으로 설명을 남긴다.
resource "vsphere_virtual_machine" "vm" { // Terraform Resource 구문의 시작 count = 100 // 복제해야 하는 횟수(=생성 VM 수량) // 각 VM이 가지는 기본 정보 name = "${var.hostname[count.index]}" resource_pool_id = "${data.vsphere_host.host.resource_pool_id}" datastore_id = data.vsphere_datastore.datastore.id // 위에서 선언했던 각 VM 변수 값 num_cpus = "${var.cpu_core[count.index]}" memory = "${var.MEM_MByte[count.index]}" guest_id = data.vsphere_virtual_machine.template.guest_id scsi_type = data.vsphere_virtual_machine.template.scsi_type firmware = "efi" // Guest VM 부팅 Mode 선언 network_interface { // 각 VM이 사용할 VM Network (="192.168.0.X") network_id = data.vsphere_network.net.id } // Template의 Disk 정보를 그대로 복사하지 않기에 Disk 단위로 선언 필요 disk { label = "disk0" size = "${data.vsphere_virtual_machine.template.disks.0.size}" eagerly_scrub = "${data.vsphere_virtual_machine.template.disks.0.eagerly_scrub}" thin_provisioned = "true" // Thin Provising 기능 사용 여부 unit_number = 0 } disk { label = "disk1" size = "${data.vsphere_virtual_machine.template.disks.1.size}" eagerly_scrub = "${data.vsphere_virtual_machine.template.disks.1.eagerly_scrub}" thin_provisioned = "true" // Thin Provising 기능 사용 여부 unit_number = 1 } disk { label = "disk2" size = "${data.vsphere_virtual_machine.template.disks.2.size}" eagerly_scrub = "${data.vsphere_virtual_machine.template.disks.2.eagerly_scrub}" thin_provisioned = "true" // Thin Provising 기능 사용 여부 unit_number = 2 } // Guest VM CDROM 정보 선언 cdrom { datastore_id = "${data.vsphere_datastore.datastore.id}" path = "LINUX.iso" }
1편에서 언급했던 것처럼 코드는 Terraform/Provider 등 버전 차이로 인하여 달라질 수 있음에 주의하도록 하자. 그리고 다시 한번 강조하지만 주요 구문 작성을 완료하면 #terraform plan을 수행하여 코드에 이상한 점은 없는지 주기적으로 확인하는 것이 좋으며, 간혹 오타나 문제가 없어 보이는데도 문제가 발생하는 경우가 있을 수 있다. 필자도 겪었던 내용인데 원인을 찾지 못하여 초기 구성 파일을 모두 삭제하고 다시 실행해 보니 정상 수행되었다.
초기 구성 파일 삭제 (.terraform.lock.hcl / *.tfstate) → #terraform init 수행 → #terraform plan
마무리
사용할 때마다 느끼지만 IaC 관련 오픈소스는 분명히 공식적으로 지원된다고 하지만 막상 해보면 안되거나 다른 결괏값이 도출되는 경우가 있는 듯하다. 그래도 감수할 만한 가치가 있으니까 하긴 하지만 주기적으로 저장/검증하여 문제 해결 시간을 최대한 줄이도록 하자. 3편에서는 Cloud-init 기능을 통하여 Hostname/IP 까지 자동으로 부여하는 내용을 다룰 예정이다.
궁금하신 내용은 댓글로 남겨주시고, 많은 블로그 방문은 저에게 큰 힘이 됩니다. ・ᴥ・
'오픈소스' 카테고리의 다른 글
[Terraform] VM(Virtual Machine) 100개 한번에 만들기 (1/3) (0) 2024.02.17 [Terraform] 코드 기반으로 서버 만드는 오픈소스 (1) 2024.01.13 [Ansible] 신규 Client 서비스 활성화 (WINDOW/LINUX) (0) 2022.09.27 [Docker] 파이썬(Python3.8) 개발 환경 구축하기 (0) 2022.08.29 [Ansible] WinSVR 업데이트 Playbook 고도화 (V3) (0) 2022.08.04