티스토리 뷰
테라폼(Terraform)
하시코프에서 개발한 오픈소스 코드형 인프라(IaC) 도구입니다. 코드를 사용하여 인프라를 선언적으로 정의하고 프로비저닝(구축 및 관리)할 수 있게 해 준다.
테라폼은 사용자가 원하는 인프라의 최종 상태를 HCL이라는 전용 설정 언어를 사용하여 파일(.tf)로 작성한다. 이 코드는 단순히 명령을 순차적으로 나열하는 것이 아니라 어떤 리소스가 필요하다 고 선언하는 방식이다.
핵심 특징
이름 | 설명 |
IaC(Infrastructure as Code) | 인프라를 수동으로 설정하는 대신 코드로 정의하고 관리하는 자동화, 일관성, 반복 가능성을 확보한다. |
선언적 | 사용자는 무엇을 원하는지를 코드로 선언하면 테라폼이 어떻게 해당 상태에 도달할지(생성, 수정, 삭제)를 결정하고 실행한다. |
멀티 클라우드 지원 | AWS, GCP 같은 주요 클라우드 서비스뿐만 아니라 쿠버네티스, 도커 기타 등 다양한 인프라 환경을 Provider 개념을 통해 단일 도구로 관리할 수 있다. |
테라폼을 사용하는 이유
인프라 관리의 효율성, 안정성, 자동화를 극대화하기 위해서입니다. 수동으로 콘솔을 클릭 필요 없이 코드로 실행하는 것만으로 복잡한 인프라를 자동으로 구축하고 변경할 수 있다. 새로운 환경을 구축하거나 인프라 변경이 필요할 때 미리 작성된 코드를 재사용하여 빠르게 반복적으로 배포도 가능하다. 인프라 정의가 코드로 존재하기 때문에 Git과 같은 버전 관리 시스템에 저장하여 변경 이력을 추적하고 팀원과 안전하게 협업할 수 있다. 이것만으로도 충분히 큰 장점이다.
테라폼의 기본 동작 방식
HCL 언어로 원하는 인프라 리소스를 정의한 구성 파일을 작성하고 계획(plan) 명령을 실행하여 작성된 코드와 현재 인프라 상태를 비교하고 최종 상태에도 도달하기 위해 필요한 변경 사항을 미리 확인한다. 적용(apply) 명령을 실행하여 계획된 변경 사항을 실제 클라우드 인프라에 적용한다. 상태 파일(.tfstate)을 사용하여 실제 인프라의 현황과 코드에 정의된 원하는 상태를 매핑하고 추적한다.
위 내용처럼 인프라 관리에선 테라폼은 필수적인 요소이다. 테라폼 기본 개념과 간단한 실습을 통해 공부한다.
테라폼 기본 개념
이름 | 설명 |
resource | 실제로 생성할 인프라 자원을 의미한다 EC2, VPC, RDS 등 리소스를 블록을 사용하여 파일에 정의한다. |
provider | 테라폼과 특정 인프라 서비스( AWS Azure 등)를 API와 상호작용할 수 있도록 연결해주는 플러그인이다. |
output | 배포 완료 후 외부에 노출하고 싶은 특정 정보를 정의한다. 생성된 EC2의 퍼플릭 IP주소 등을 다른 시스템이나 사용자에게 보여주기 위해 사용한다. |
backend | 테라폼이 인프라의 현재 상태를 기록하는 상태 파일(.tfstate)을 저장할 위치를 설정한다. S3와 같은 원격 저장소에 저장하여 팀원간의 협업 및 안전성을 확보하는데 사용한다. |
module | 재사용 가능하도록 여러 개의 리소스를 묶어 놓은 논리적 그룹이자 캡슐화 단위이다. 복잡한 인프라를 구조화하고 동일한 구성을 여러 환경에 반복적으로 배포할 때 유용하다. |
state file(tfstate) | 테라폼이 현재까지 관리하고 배포한 인프라 자원의 실제 상태를 기록하는 파일이다. |
remote state | 테라폼에서 tfstate를 로컬이 아닌 원격 저장소에 보관하고 관리하는 방식을 의미한다. |
remote state의 필요성 및 역할
여러 팀원이 하나의 인프라를 동시에 관리할 때 각자의 로컬 상태 파일이 아닌 공유된 중앙 상태 파일을 사용해야 일관성을 유지하고 충돌을 방지할 수 있다. tfstate파일에는 인프라에 대한 중요한 정보(민감정보)가 포함되어 있다. 이를 안전한 클라우드 스토리지(S3)에 저장하여 로컬 유출 위험을 줄이고 백업 및 복구를 용이하게 한다. 여러 사용자가 동시에 apply를 실행하는 것을 방지하기 위해 원격 백엔드는 잠금 기능을 지원한다. 일관성을 잃는 것을 막아 준다.
테라폼 명령어
terraform init(초기화)
테라폼 작업 디렉터리를 초기화하고 구성 파일에 정의된 대로 작업을 수행할 준비를 마치는 명령어로 구성 파일에 명시된 Provider 플러그인과 그 버전을 검색하고 로컬에 다운로드한다. 백엔드 설정을 확인하고 상태 파일을 저장할 원격 저장소를 설정한다. 소스 코드를 참조하는 module을 준비한다 이 명령어는 테라폼 코드를 처음 작성하거나 새로운 Provider 또는 백엔드 설정 추가 변경했을 때 반드시 먼저 수행한다.
terraform plan(계획 수립)
현재 작성된 테라폼 코드와 실제 인프라 상태(tfstate) 파일 및 클라우드 서비스를 비교하여 앞으로 어떤 변경이 발생할지 실행 계획을 보여준다. 실제 인프라에 변경을 가하기 전에 오류가 없는지 미리 검토할 수 있는 안전한 기회를 제공한다. apply 실행 전에 plan을 실행하여 변경 사항을 확인하는 것은 인프라 운영의 필수 적이다.
terraform apply(적용)
plan명령으로 확인했던 실행 계획을 실제로 인프라에 적용하여 리소스를 생성 수정 또는 삭제한다. yes을 입력하여 적용을 승인하도록 요청합니다. 변경 사항이 성공적으로 적용되면 state file(tfstate)을 업데이트하여 인프라의 최종상태를 기록한다.
VPC를 테라폼을 이용해 코드로 구축 예제
이름 | 설명 |
VPC | AWS 클라우드에서 논리적으로 분리된 나만의 가상 네트워크 공간입니다. IP 주소 대역으 지정하여 생성하며 모든 AWS 리소스는 이 VPC내부에 존재합니다. |
서브넷 | VPC의 IP 주소 대역을 더 작게 나눈 네트워크 영역이다. 각 서브넷은 하나의 가용 영역에 속하며 용도에 따라 퍼플릭과 프라이빗으로 나눈다. |
라우팅 테이블 | 서브넷 내부에서 발생하는 네트워크 트래픽이 어디로 향해야 하는지 규칙을 정의하는 테이블이다. 각 서브넷은 반드시 하나의 라우팅 테이블과 연결되어야한다. |
인터넷 게이트웨이 IGW | VPC와 외부 인터넷 간의 통신을 가능하게 하는 게이트웨이이다. 퍼블릭 서브넷은 IGW를 통해 직접 인터넷과 통신할 수 있다. |
NAT Gateway NGW | 프라이빗 서브넷에 있는 리소스가 외부 인터넷으로의 아웃바운드 통신은 가능하지만 외부에서 해당 리소스로 인바운드 접근은 불가능하도록 해주는 서비스이다. 퍼블릭 서브넷에 위치하며 외부 통신을 위해 EIP와 연경된다. |
EIP | AWS에서 제공하는 고정된 공인 IP 주소로 NAT GW에 할당되어 외부 통신의 고정 IP역할을 한다. |
main.tf
resource "aws_vpc" "test_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "test-101"
}
}
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-2a"
tags = {
Name = "terraform-101-public-subnet"
}
}
resource "aws_subnet" "private_subnet" {
vpc_id = aws_vpc.test_vpc.id
cidr_block = "10.0.10.0/24"
tags = {
Name = "terraform-101-private-subnet"
}
}
resource "aws_internet_gateway" "igw" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "terraform-101-igw"
}
}
resource "aws_eip" "nat" {
lifecycle {
create_before_destroy = true
}
}
resource "aws_nat_gateway" "ngw" {
allocation_id = aws_eip.nat.id
subnet_id = aws_subnet.public_subnet.id
tags = {
Name = "terraform-101-ngw"
}
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "terraform-101-rt-public"
}
}
resource "aws_route_table_association" "route_table_association_public" {
subnet_id = aws_subnet.public_subnet.id
route_table_id = aws_route_table.public.id
}
resource "aws_route" "public_nat" {
route_table_id = aws_route_table.public.id
destination_cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.igw.id
}
resource "aws_route_table" "private" {
vpc_id = aws_vpc.test_vpc.id
tags = {
Name = "terraform-101-rt-private"
}
}
resource "aws_route_table_association" "route_table_association_private" {
subnet_id = aws_subnet.private_subnet.id
route_table_id = aws_route_table.private.id
}
resource "aws_route" "private_nat" {
route_table_id = aws_route_table.private.id
destination_cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.ngw.id
}
네트워크의 기본 틀
코드 리소스 | 역할 | 상세 설명 |
aws_vpc | 가상 네트워크 전체(VPC) | 모든 AWS 리소스가 위치할 나만의 격리된 사설 네이트워크 공간 10.0.0.0/16 |
aws_subnet.public_subnet | 퍼블릭 구역 | 외부 인터넷과 직접 통신이 가능한 영역으로 웹 서버의 로드 밸런서 등이 위치 10.0.1.0/24 |
aws_subnet.private_subnet | 프라이빗 구역 | 외부에서 직접 접근할 수 없도록 보호되는 영역으로 DB 서버등 중요한 리소스가 위치 10.0.10.0/24 |
퍼블릭 서브넷을 위한 인터넷 게이트웨이
코드 리소스 | 역할 | 상세 설명 |
aws_internet_gateway | 인터넷 정문 | VPC와 AWS외부 인터넷을 연경해주는 통로 |
aws_route(public_nat) | 퍼블릭 경로 | 퍼블릭 서브넷의 모든 외부 트래픽(0.0.0.0/0)이 IGW를 통해 인터넷으로 나가도록 규칙을 만듬 |
프라이빗 서브넷을 위한 NAT 게이트웨이
코드 리소스 | 역할 | 상세 설명 |
aws_eip | 고정 공인 IP | NAT GW에 할당할 고정 IP 주소 |
aws_nat_gatway | 프라이빗의 출구 | private_subnet의 서버들이 보안은 유지한 채 외부 인터넷으로 나갈수 있도록 돕는 장치 |
aws_route(private_nat) | 프라이빗 경로 | 프라이빗 서브넷의 모든 외부 트래픽이 NAT GW를 통해서만 나가도록 규칙을 만든다. 외부에서는 내부로의 직접 접근은 불가능 |
aws_route_table는 트래픽 경로 규칙을 담는 그릇(컨테이너)이며 route는 그 컨테이너 안에 들어가는 특정 트래픽을 전송 방향을 정의하는 개별 규칙이다.
variables.tf와 providers.tf은 AWS 환경에 리소스를 배포하는 데 필요한 기본 환경
provider.tf는 hashicorp/aws 프로바이더를 사용하여 AWS 리소스를 관리하며, 리전은 정의된 변수(var.region)를 따른다.
terraform {
required_version = ">= 1.6.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.55"
}
}
}
provider "aws" {
region = var.region
}
variables.tf는 AWS 리전 변수를 정의하고, ap-northeast-2를 기본값으로 설정하여 한국 리전에 인프라가 구축되도록 한다.
variable "region" {
description = "AWS 리전"
type = string
default = "ap-northeast-2"
}
'Backend' 카테고리의 다른 글
JPA에서 JDBC로 전환했더니 성능이 10배 빨라졌다 (0) | 2025.10.14 |
---|---|
다이어그램으로 보는 AWS VPC 통신 정리 (0) | 2025.10.08 |
왜 나는 RestClient를 선택했는가 (0) | 2025.09.23 |
쿠버네티스 핵심 개념 정리와 마이크로서비스 이해 (0) | 2025.09.19 |
Spring Boot에서 Redis 캐시 적용부터 Cluster 운영까지 (1) | 2025.09.12 |
- Total
- Today
- Yesterday
- zip
- isdigit
- combinations
- for
- Lower
- Python
- counter
- If
- bool
- function
- find
- Built-in Functions
- Lambda
- operators
- index
- Method
- isalpha
- permutations
- Upper
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |