Terraform 개요
Terraform이란?
Terraform은 HashiCorp에서 개발한 오픈소스 Infrastructure as Code (IaC) 도구로, 클라우드 인프라를 선언적으로 정의하고 관리할 수 있게 해주는 도구입니다. 멀티 클라우드를 지원하며, 인프라의 생성, 수정, 삭제를 자동화합니다.
Terraform의 특징
1. 선언적 구성 (Declarative Configuration)
- 원하는 상태를 선언
- Terraform이 자동으로 계획 및 실행
- 명령형 스크립트 불필요
2. 멱등성 (Idempotency)
- 여러 번 실행해도 동일한 결과
- 현재 상태와 비교하여 필요한 변경만 수행
- 안전한 반복 실행
3. 멀티 클라우드 지원
- AWS, Azure, GCP 등 주요 클라우드 지원
- 온프레미스 인프라도 지원
- 하나의 도구로 통합 관리
4. 상태 관리 (State Management)
- 인프라 상태 추적
- 변경사항 추적
- 협업 지원
5. 계획 및 적용 (Plan & Apply)
- 실행 전 변경사항 미리보기
- 안전한 검토 후 적용
- 롤백 지원
6. 모듈화
- 재사용 가능한 모듈
- 코드 재사용성 향상
- 표준화된 인프라
Terraform 아키텍처
1. Terraform Core
- 구성 파일 파싱
- 실행 계획 생성
- 리소스 그래프 생성
- 프로바이더 호출
2. Providers (프로바이더)
- 클라우드 플랫폼과의 인터페이스
- AWS, Azure, GCP 등
- 커뮤니티 프로바이더
3. State (상태)
- 현재 인프라 상태 저장
- 변경사항 추적
- 리소스 매핑
4. Configuration Files (구성 파일)
.tf파일- HCL (HashiCorp Configuration Language)
- 선언적 구성
Terraform 핵심 개념
1. Provider (프로바이더)
클라우드 플랫폼과의 연결을 담당
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "ap-northeast-2"
}2. Resource (리소스)
인프라 구성 요소를 정의
resource "aws_instance" "web" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
}
}3. Data Source (데이터 소스)
기존 리소스 정보 조회
data "aws_ami" "latest_amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
}4. Variable (변수)
재사용 가능한 값 정의
variable "instance_type" {
description = "EC2 인스턴스 타입"
type = string
default = "t2.micro"
}
variable "environment" {
description = "환경 이름"
type = string
validation {
condition = contains(["dev", "staging", "prod"], var.environment)
error_message = "환경은 dev, staging, prod 중 하나여야 합니다."
}
}5. Output (출력)
리소스 정보 출력
output "instance_id" {
description = "EC2 인스턴스 ID"
value = aws_instance.web.id
}
output "instance_public_ip" {
description = "EC2 인스턴스 공용 IP"
value = aws_instance.web.public_ip
}6. Module (모듈)
재사용 가능한 구성 단위
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
environment = var.environment
}Terraform 설치
Linux/macOS
# Homebrew (macOS)
brew install terraform
# 직접 다운로드
wget https://releases.hashicorp.com/terraform/1.6.0/terraform_1.6.0_linux_amd64.zip
unzip terraform_1.6.0_linux_amd64.zip
sudo mv terraform /usr/local/bin/Windows
# Chocolatey
choco install terraform
# 직접 다운로드 후 PATH에 추가설치 확인
terraform versionTerraform 기본 명령어
초기화
# Terraform 초기화
terraform init
# 특정 백엔드 사용
terraform init -backend-config="bucket=my-terraform-state"
# 모듈 업데이트
terraform init -upgrade계획 및 적용
# 실행 계획 생성
terraform plan
# 계획을 파일로 저장
terraform plan -out=tfplan
# 계획 적용
terraform apply
# 저장된 계획 적용
terraform apply tfplan
# 자동 승인 (주의)
terraform apply -auto-approve상태 관리
# 상태 확인
terraform show
# 상태 목록
terraform state list
# 특정 리소스 상태 확인
terraform state show aws_instance.web
# 상태 새로고침
terraform refresh
# 상태 가져오기
terraform import aws_instance.web i-1234567890abcdef0리소스 관리
# 리소스 삭제
terraform destroy
# 특정 리소스만 삭제
terraform destroy -target=aws_instance.web
# 자동 승인
terraform destroy -auto-approve기타 명령어
# 포맷팅
terraform fmt
# 검증
terraform validate
# 그래프 생성
terraform graph | dot -Tsvg > graph.svg
# 출력 확인
terraform output
terraform output instance_idTerraform 구성 파일 예시
기본 구성
# main.tf
terraform {
required_version = ">= 1.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
backend "s3" {
bucket = "my-terraform-state"
key = "terraform.tfstate"
region = "ap-northeast-2"
}
}
provider "aws" {
region = var.aws_region
}
resource "aws_vpc" "main" {
cidr_block = var.vpc_cidr
enable_dns_hostnames = true
enable_dns_support = true
tags = {
Name = "${var.environment}-vpc"
}
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = var.public_subnet_cidr
availability_zone = var.availability_zone
map_public_ip_on_launch = true
tags = {
Name = "${var.environment}-public-subnet"
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.latest_amazon_linux.id
instance_type = var.instance_type
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web.id]
user_data = <<-EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
EOF
tags = {
Name = "${var.environment}-web-server"
}
}변수 파일
# variables.tf
variable "aws_region" {
description = "AWS 리전"
type = string
default = "ap-northeast-2"
}
variable "environment" {
description = "환경 이름"
type = string
}
variable "vpc_cidr" {
description = "VPC CIDR 블록"
type = string
default = "10.0.0.0/16"
}
variable "public_subnet_cidr" {
description = "퍼블릭 서브넷 CIDR"
type = string
default = "10.0.1.0/24"
}
variable "instance_type" {
description = "EC2 인스턴스 타입"
type = string
default = "t2.micro"
}
variable "availability_zone" {
description = "가용 영역"
type = string
default = "ap-northeast-2a"
}변수 값 파일
# terraform.tfvars
environment = "dev"
aws_region = "ap-northeast-2"
vpc_cidr = "10.0.0.0/16"
public_subnet_cidr = "10.0.1.0/24"
instance_type = "t2.micro"출력 파일
# outputs.tf
output "vpc_id" {
description = "VPC ID"
value = aws_vpc.main.id
}
output "subnet_id" {
description = "퍼블릭 서브넷 ID"
value = aws_subnet.public.id
}
output "instance_id" {
description = "EC2 인스턴스 ID"
value = aws_instance.web.id
}
output "instance_public_ip" {
description = "EC2 인스턴스 공용 IP"
value = aws_instance.web.public_ip
}데이터 소스
# data.tf
data "aws_ami" "latest_amazon_linux" {
most_recent = true
owners = ["amazon"]
filter {
name = "name"
values = ["amzn2-ami-hvm-*-x86_64-gp2"]
}
filter {
name = "virtualization-type"
values = ["hvm"]
}
}Terraform 모듈
모듈 구조
modules/
vpc/
main.tf
variables.tf
outputs.tf
README.md
모듈 사용
module "vpc" {
source = "./modules/vpc"
vpc_cidr = "10.0.0.0/16"
environment = var.environment
public_subnets = ["10.0.1.0/24", "10.0.2.0/24"]
}모듈 생성
# modules/vpc/main.tf
resource "aws_vpc" "this" {
cidr_block = var.vpc_cidr
tags = {
Name = "${var.environment}-vpc"
}
}
# modules/vpc/variables.tf
variable "vpc_cidr" {
type = string
}
variable "environment" {
type = string
}
# modules/vpc/outputs.tf
output "vpc_id" {
value = aws_vpc.this.id
}Terraform 상태 관리
로컬 상태
- 기본적으로
terraform.tfstate파일에 저장 - 단일 사용자 환경에 적합
- Git에 커밋하지 않도록 주의
원격 상태 (Remote State)
terraform {
backend "s3" {
bucket = "my-terraform-state"
key = "terraform.tfstate"
region = "ap-northeast-2"
encrypt = true
dynamodb_table = "terraform-state-lock"
}
}상태 잠금 (State Locking)
- 동시 실행 방지
- DynamoDB, Consul 등 사용
- 데이터 손실 방지
상태 백업
- 정기적인 백업
- 버전 관리
- 복구 계획 수립
Terraform 워크스페이스
워크스페이스 생성 및 사용
# 워크스페이스 목록
terraform workspace list
# 새 워크스페이스 생성
terraform workspace new dev
terraform workspace new staging
terraform workspace new prod
# 워크스페이스 전환
terraform workspace select dev
# 현재 워크스페이스 확인
terraform workspace show워크스페이스별 변수
# terraform.tfvars.dev
environment = "dev"
instance_type = "t2.micro"
# terraform.tfvars.prod
environment = "prod"
instance_type = "t3.large"Terraform 모범 사례
1. 코드 구조
- 모듈화된 구조
- 환경별 분리
- 명확한 네이밍
2. 상태 관리
- 원격 상태 사용
- 상태 잠금 활성화
- 정기적인 백업
3. 보안
- 비밀 정보는 변수로 관리
- Terraform Cloud/Enterprise의 변수 사용
- 최소 권한 원칙
4. 버전 관리
- 코드를 Git으로 관리
- 의미 있는 커밋 메시지
- 태그 사용
5. 테스트
terraform plan으로 검증- 스테이징 환경에서 테스트
- 점진적 배포
6. 문서화
- README 작성
- 변수 및 출력 설명
- 아키텍처 다이어그램
7. 리소스 태깅
tags = {
Environment = var.environment
Project = "my-project"
ManagedBy = "Terraform"
Owner = "devops-team"
}Terraform Cloud / Enterprise
Terraform Cloud
- 상태 관리
- 원격 실행
- 협업 기능
- 정책 관리
Terraform Enterprise
- 자체 호스팅
- 엔터프라이즈 기능
- 고급 보안
주요 프로바이더
클라우드 프로바이더
- AWS:
hashicorp/aws - Azure:
hashicorp/azurerm - GCP:
hashicorp/google - OCI:
oracle/oci
인프라 프로바이더
- Docker:
kreuzwerker/docker - Kubernetes:
hashicorp/kubernetes - VMware:
hashicorp/vsphere
기타 프로바이더
- GitHub:
integrations/github - Datadog:
datadog/datadog - PagerDuty:
pagerduty/pagerduty
Terraform의 장점
- 멀티 클라우드: 하나의 도구로 여러 클라우드 관리
- 선언적: 원하는 상태만 선언
- 멱등성: 안전한 반복 실행
- 상태 관리: 인프라 상태 추적
- 모듈화: 코드 재사용
- 계획 기능: 변경사항 미리 확인
Terraform의 단점
- 학습 곡선: HCL 문법 학습 필요
- 상태 파일: 상태 파일 관리 복잡
- 제한적 로직: 복잡한 로직 표현 어려움
- 프로바이더 의존: 프로바이더 업데이트 필요
Terraform 사용 사례
1. 인프라 프로비저닝
- 클라우드 리소스 생성
- 네트워크 구성
- 보안 그룹 설정
2. 환경 관리
- 개발, 스테이징, 프로덕션 환경
- 환경별 구성 관리
- 일관된 인프라
3. 멀티 클라우드
- 여러 클라우드 통합 관리
- 클라우드 간 마이그레이션
- 하이브리드 클라우드
4. 규정 준수
- 인프라 표준화
- 정책 적용
- 감사 추적
참고
- Terraform은 Infrastructure as Code의 강력한 도구입니다
- 작은 인프라부터 시작하여 점진적으로 확장하세요
- 모듈을 활용하여 코드 재사용성을 높이세요
- 상태 관리를 신중하게 계획하세요
- 정기적으로
terraform plan으로 검증하세요 - 보안을 위해 비밀 정보 관리를 철저히 하세요