본문 바로가기
IT & Tech 정보

🚀 Terraform으로 AWS 인프라 코드 관리

by 지식과 지혜의 나무 2025. 5. 25.
반응형


안녕하세요!
이번에는 Terraform을 활용해 AWS 인프라를 코드로 선언하고 관리하는 과정을 단계별로 살펴보겠습니다.
Provider 설정부터 VPC·EC2·S3 리소스 정의, 모듈화, 원격 상태 관리까지 실무에 바로 적용 가능한 예제를 담았습니다.



📋 목차
1. Terraform & IaC 개요
2. 프로젝트 초기 설정
3. AWS Provider 설정
4. 리소스 정의 예제
5. 변수와 출력
6. 모듈화(Module) 사용
7. 원격 상태(Remote State) 관리
8. Terraform 워크플로우 (init·plan·apply·destroy)
9. 실전 팁 & 주의사항
10. 마무리



1️⃣ Terraform & IaC 개요
• Infrastructure as Code (IaC): 모든 인프라 설정을 코드로 관리 → 버전 관리, 재현성, 협업 용이
• Terraform: HashiCorp에서 만든 선언형 IaC 도구
• HCL(HashiCorp Configuration Language) 사용
• State 파일로 실제 인프라 상태 추적
• 플랜(plan) 기능으로 변경사항 사전 검토



2️⃣ 프로젝트 초기 설정

# 1) 작업 디렉터리 생성
mkdir terraform-aws-demo && cd terraform-aws-demo

# 2) Terraform 설치 확인
terraform -v

# 3) 디렉터리 구조 예시
# terraform-aws-demo/
# ├─ main.tf
# ├─ variables.tf
# ├─ outputs.tf
# └─ modules/
#    └─ vpc/
#       ├─ main.tf
#       ├─ variables.tf
#       └─ outputs.tf




3️⃣ AWS Provider 설정

# main.tf
terraform {
  required_version = ">= 1.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
}

provider "aws" {
  region  = var.aws_region
  profile = var.aws_profile
}

# variables.tf
variable "aws_region" {
  description = "AWS 리전"
  type        = string
  default     = "ap-northeast-2"
}

variable "aws_profile" {
  description = "AWS CLI 프로파일 이름"
  type        = string
  default     = "default"
}




4️⃣ 리소스 정의 예제

4-1. VPC 생성

# main.tf (계속)
resource "aws_vpc" "main" {
  cidr_block           = "10.0.0.0/16"
  enable_dns_hostnames = true
  tags = {
    Name = "demo-vpc"
  }
}

resource "aws_subnet" "public" {
  vpc_id            = aws_vpc.main.id
  cidr_block        = "10.0.1.0/24"
  availability_zone = "${var.aws_region}a"
  tags = {
    Name = "demo-public-subnet"
  }
}

4-2. EC2 인스턴스 생성

resource "aws_instance" "app" {
  ami           = data.aws_ami.ubuntu.id
  instance_type = "t3.micro"
  subnet_id     = aws_subnet.public.id

  tags = {
    Name = "demo-instance"
  }
}

data "aws_ami" "ubuntu" {
  most_recent = true
  owners      = ["099720109477"] # Canonical
  filter {
    name   = "name"
    values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
  }
}

4-3. S3 버킷 생성

resource "aws_s3_bucket" "static" {
  bucket = "demo-static-bucket-${random_id.bucket_id.hex}"
  acl    = "public-read"

  website {
    index_document = "index.html"
  }

  tags = {
    Name = "demo-static"
  }
}

resource "random_id" "bucket_id" {
  byte_length = 4
}




5️⃣ 변수와 출력

# variables.tf (추가)
variable "instance_type" {
  description = "EC2 인스턴스 타입"
  type        = string
  default     = "t3.micro"
}

# outputs.tf
output "vpc_id" {
  description = "생성된 VPC ID"
  value       = aws_vpc.main.id
}

output "instance_public_ip" {
  description = "EC2 퍼블릭 IP"
  value       = aws_instance.app.public_ip
}

output "s3_bucket_url" {
  description = "S3 정적 웹사이트 URL"
  value       = aws_s3_bucket.static.website_endpoint
}

• terraform apply -var="instance_type=t3.small" 으로 변수 오버라이드 가능



6️⃣ 모듈화(Module) 사용

modules/vpc/main.tf

resource "aws_vpc" "this" {
  cidr_block = var.cidr_block
  tags = { Name = var.name }
}

resource "aws_subnet" "public" {
  vpc_id     = aws_vpc.this.id
  cidr_block = var.public_cidr
  tags       = { Name = "${var.name}-public" }
}

modules/vpc/variables.tf

variable "name" {
  type = string
}

variable "cidr_block" {
  type = string
}

variable "public_cidr" {
  type = string
}

modules/vpc/outputs.tf

output "vpc_id" {
  value = aws_vpc.this.id
}

output "subnet_id" {
  value = aws_subnet.public.id
}

main.tf에서 모듈 호출

module "vpc" {
  source      = "./modules/vpc"
  name        = "demo-vpc"
  cidr_block  = "10.0.0.0/16"
  public_cidr = "10.0.1.0/24"
}

# 이후 aws_instance에 module.vpc.subnet_id 사용
subnet_id = module.vpc.subnet_id




7️⃣ 원격 상태(Remote State) 관리

# main.tf 상단에 추가
terraform {
  backend "s3" {
    bucket         = "my-terraform-state-bucket"
    key            = "demo/terraform.tfstate"
    region         = var.aws_region
    dynamodb_table = "terraform-locks"
    encrypt        = true
  }
}

• S3에 상태 파일 저장, DynamoDB로 락킹(lock) 관리
• terraform init 시 자동 설정



8️⃣ Terraform 워크플로우

# 1) 초기화
terraform init

# 2) 변경사항 미리보기
terraform plan -out=tfplan

# 3) 적용
terraform apply tfplan

# 4) 정리(제거)
terraform destroy

• plan 후 apply 권장 → 의도치 않은 리소스 생성을 방지



9️⃣ 실전 팁 & 주의사항
• State 보안: S3 버킷 접근 권한 최소화, 버전 관리 활성화
• 변수 관리: terraform.tfvars·환경별 .auto.tfvars 활용
• 민감 정보: DB 암호 등은 sensitive = true 변수로 표시
• DRY(Don’t Repeat Yourself): 모듈 재사용으로 코드 중복 방지
• 테스트: terratest·kitchen-terraform으로 인프라 테스트 자동화



🔚 마무리

Terraform으로 AWS 인프라를 선언적으로 관리하는 방법을 알아봤습니다.
이제 코드 한 줄 변경만으로 VPC·EC2·S3 리소스를 생성·수정·삭제할 수 있으니,
여러분의 프로젝트에 IaC를 도입해 보세요!

반응형