본문으로 건너뛰기

테라폼

terraform으로 vm + 보안 그룹 + 퍼블릭 ip를 자동 생성합니다.
모든 단계는 macOS의 VSCode + 터미널만으로 진행합니다. 콘솔 수동 클릭 없이 인프라를 코드로 구성하는 흐름에 초점을 둡니다.

기본 정보
  • 예상 소요 시간: 20~30분
  • 권장 환경: macOS (터미널, VSCode)
  • 사전 준비
    • terraform cli 설치 (brew install hashicorp/tap/terraform)
    • kakaoCloud IAM 액세스 키 (Access Key / Secret Key)
    • 프로젝트에 사용 중인 VPC/서브넷/이미지/키 페어 확인

시나리오 소개

이 가이드는 가장 작은 단위의 IaC 실습을 목표로 합니다.

  • 보안 그룹 tf-vm-sg: 내 퍼블릭 ip에서만 22/tcp 허용
  • vm tf-demo-vm: 지정 서브넷에 ubuntu 20.04로 생성
  • 퍼블릭 ip tf-demo-vm-pip: vm에 연결(associate)
  • 출력 값: vm 퍼블릭 ip, ssh 접속 예시 명령

tip: 실습 완료 후 반드시 destroy 해서 퍼블릭 ip 과금을 방지하세요.


준비하기

  1. HashiCorp 공식 tap을 추가합니다.
brew tap hashicorp/tap
  1. Terraform을 설치합니다.
brew install hashicorp/tap/terraform
  1. 설치 후 버전을 확인합니다.
terraform -version

추가 명령어 (중급자용)

# 최신 버전으로 업그레이드
brew upgrade hashicorp/tap/terraform

# 특정 버전으로 설치
brew install hashicorp/tap/terraform@1.6.2

# 버전 전환 (예: tfenv 대신 brew 링크 변경)
brew unlink hashicorp/tap/terraform
brew link --overwrite hashicorp/tap/terraform@1.6.2

2. kakaoCloud 자격 증명 설정

환경 변수로 설정하면 provider가 자동 인식합니다.

export KAKAOCLOUD_ACCESS_KEY=${ACCESS_KEY}
export KAKAOCLOUD_SECRET_KEY=${SECRET_KEY}
export KAKAOCLOUD_REGION=${REGION}
환경 변수설명
ACCESS_KEY🖌;IAM 액세스 키
SECRET_KEY🖌;IAM 시크릿 키
REGION🖌kr-central-2;리전
export KAKAOCLOUD_ACCESS_KEY=1f090495a7b4447c9506be46c5515d10
export KAKAOCLOUD_SECRET_KEY=8aab712d14c44225a9f8cd66281b9598946903bd63718acd02c84f99ed32114c664144
export KAKAOCLOUD_REGION=kr-central-2
환경 변수설명

프로젝트 생성하기

작업 폴더를 만들고 main.tf 하나로 구성합니다.

mkdir kakaocloud-tf-vm && cd kakaocloud-tf-vm
환경변수설명

terraform 코드 작성하기 (단일 파일)

아래 전체 내용을 그대로 main.tf로 저장하세요. (한 파일로 끝냅니다)

############################################################
# kakaoCloud: VM + Security Group + Public IP (single file)
# - terraform >= 1.6.0
# - provider: kakaoenterprise/kakaocloud (env-based auth)
############################################################

terraform {
required_version = ">= 1.6.0"
required_providers {
kakaocloud = {
source = "kakaoenterprise/kakaocloud"
version = ">= 0.1.0"
}
}
}

# 환경 변수(KAKAOCLOUD_*) 자동 인식
provider "kakaocloud" {}

############################################################
# 입력 변수
############################################################
variable "vpc_id" {
type = string
description = "기존 VPC ID"
}

variable "subnet_id" {
type = string
description = "서브넷 ID (vm이 생성될 서브넷)"
}

variable "image_id" {
type = string
description = "Ubuntu 20.04 이미지 ID"
}

variable "flavor_name" {
type = string
default = "m2a.large"
description = "인스턴스 타입 이름"
}

variable "keypair_name" {
type = string
description = "기존 키 페어 이름 (pem 생성된 키)"
}

variable "my_public_ip" {
type = string
description = "ssh 허용할 내 퍼블릭 ip/cidr (예: 203.0.113.10/32)"
}

locals {
tags = {
project = "kakaocloud-terraform-hands-on"
}
}

############################################################
# 보안 그룹: 22/tcp만 내 ip 허용
############################################################
# 주의: provider 버전에 따라 리소스/필드명이 다를 수 있습니다.
# 본 예시는 kakaocloud_security_group 형식을 사용합니다.
resource "kakaocloud_security_group" "vm_sg" {
name = "tf-vm-sg"
description = "terraform demo security group"
vpc_id = var.vpc_id

ingress {
protocol = "tcp"
port_range = "22"
cidr_blocks = [var.my_public_ip]
description = "allow ssh from my ip"
}

egress {
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}

tags = local.tags
}

############################################################
# VM 생성
############################################################
resource "kakaocloud_instance" "vm" {
name = "tf-demo-vm"
image_id = var.image_id
flavor_name = var.flavor_name
subnet_id = var.subnet_id
keypair_name = var.keypair_name
security_groups = [kakaocloud_security_group.vm_sg.id]

# cloud-init이 필요하면 user_data를 추가하세요.
# user_data = base64encode(file("${path.module}/cloudinit.yaml"))

tags = local.tags
}

############################################################
# 퍼블릭 IP 연결 (vm 1대에 associate)
############################################################
resource "kakaocloud_public_ip" "vm_pip" {
name = "tf-demo-vm-pip"
instance_id = kakaocloud_instance.vm.id
tags = local.tags
}

############################################################
# 출력
############################################################
output "vm_public_ip" {
value = kakaocloud_public_ip.vm_pip.address
description = "vm 퍼블릭 ip"
}

output "ssh_command" {
value = "ssh -i ./YOUR_KEY.pem ubuntu@${kakaocloud_public_ip.vm_pip.address}"
description = "접속 명령 예시(이미지에 따라 계정명이 ubuntu가 아닐 수 있음)"
}

tip: image_id, vpc_id, subnet_id, keypair_name은 콘솔에서 복사해 넣으면 가장 빠릅니다.

원한다면 값을 별도 파일로 넘기기 위해 terraform.tfvars를 사용해도 좋습니다.

# terraform.tfvars (선택)
vpc_id = "VPC-XXXXXXXX"
subnet_id = "SUBNET-YYYYYYYY"
image_id = "IMAGE-ZZZZZZZZ" # ubuntu 20.04
keypair_name = "my-keypair"
my_public_ip = "203.0.113.10/32"

실행하기

1) 초기화 · 검증 · 계획

terraform init
terraform fmt -recursive
terraform validate

terraform plan \
-var 'vpc_id=VPC-XXXXXXXX' \
-var 'subnet_id=SUBNET-YYYYYYYY' \
-var 'image_id=IMAGE-ZZZZZZZZ' \
-var 'keypair_name=my-keypair' \
-var 'my_public_ip=203.0.113.10/32'
환경변수설명

2) 적용

terraform apply -auto-approve \
-var 'vpc_id=VPC-XXXXXXXX' \
-var 'subnet_id=SUBNET-YYYYYYYY' \
-var 'image_id=IMAGE-ZZZZZZZZ' \
-var 'keypair_name=my-keypair' \
-var 'my_public_ip=203.0.113.10/32'
환경변수설명

3) 결과 확인 · 접속

terraform output
terraform output -raw vm_public_ip

# 이미지에 따라 기본 계정이 ubuntu / centos 등 상이할 수 있음
ssh -i ./YOUR_KEY.pem ubuntu@$(terraform output -raw vm_public_ip)
환경변수설명

문제 해결하기

  • ssh가 안 돼요 (timeout).

    • my_public_ip 값이 현재 ip와 다른지 확인합니다. (LTE, 재부팅 등으로 IP가 바뀔 수 있음)
    • 로컬 방화벽(회사 보안 프로그램 등) 차단 여부를 확인합니다.
    • 키 파일 권한 오류면 chmod 400 YOUR_KEY.pem 후 재시도합니다.
  • 이미지 디폴트 계정을 모르겠어요.

    • ubuntu 계열: ubuntu, debian 계열: debian, centos 계열: centos 인 경우가 많습니다. 배포 이미지 가이드를 확인하세요.
  • provider 리소스/필드명이 달라요.

    • kakaocloud_* 네이밍을 기본으로 했습니다. 사용하는 provider 버전의 문서/스키마에 맞게 이름을 조정하세요.

정리하기

실습 리소스를 제거해 비용을 방지합니다.

terraform destroy -auto-approve \
-var 'vpc_id=VPC-XXXXXXXX' \
-var 'subnet_id=SUBNET-YYYYYYYY' \
-var 'image_id=IMAGE-ZZZZZZZZ' \
-var 'keypair_name=my-keypair' \
-var 'my_public_ip=203.0.113.10/32'
환경변수설명

다음 단계

  • 보안 그룹에 80/tcp를 열고 간단한 http 서버(nginx)를 올려 웹 응답을 확인해 보세요.
  • count를 사용해 다수의 vm을 한 번에 배포하고 출력값을 리스트로 받아보세요.
  • 본 실습을 기반으로 web lb + app lb를 추가하고, MemStore/MySQL 같은 관리형 서비스와 연동해 3-tier로 확장해 보세요.