테라폼
terraform으로 vm + 보안 그룹 + 퍼블릭 ip를 자동 생성합니다.
모든 단계는 macOS의 VSCode + 터미널만으로 진행합니다. 콘솔 수동 클릭 없이 인프라를 코드로 구성하는 흐름에 초점을 둡니다.
기본 정보
- 예상 소요 시간: 20~30분
- 권장 환경: macOS (터미널, VSCode)
- 사전 준비
- terraform cli 설치 (
brew install hashicorp/tap/terraform
) - kakaoCloud IAM 액세스 키 (Access Key / Secret Key)
- 프로젝트에 사용 중인 VPC/서브넷/이미지/키 페어 확인
- terraform cli 설치 (
시나리오 소개
이 가이드는 가장 작은 단위의 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 과금을 방지하세요.
준비하기
- HashiCorp 공식 tap을 추가합니다.
brew tap hashicorp/tap
- Terraform을 설치합니다.
brew install hashicorp/tap/terraform
- 설치 후 버전을 확인합니다.
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
인 경우가 많습니다. 배포 이미지 가이드를 확인하세요.
- ubuntu 계열:
-
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로 확장해 보세요.