AWS 콘솔에서 마우스 클릭으로 인프라를 만드는 것은 쉽지만, 반복 작업이 되거나 인프라 규모가 커지면 지옥이 시작됩니다. "어? 보안 그룹 IP 누가 열었어?", "개발 환경이랑 운영 환경 설정이 왜 다르지?" 이런 문제를 근본적으로 해결하기 위해 인프라를 코드로 정의하고 관리하는 Terraform을 도입했습니다.
Terraform의 작업 흐름은 크게 3단계로 나뉩니다.
AWS 리전을 설정하고, Terraform State 파일(인프라 상태 저장소)을 로컬이 아닌 AWS S3에 저장하도록 설정하여 팀원 간 협업이 가능하게 합니다. DynamoDB를 사용하여 동시 수정 방지(Locking)도 적용합니다.
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/terraform.tfstate"
region = "ap-northeast-2"
encrypt = true
dynamodb_table = "terraform-lock"
}
}
provider "aws" {
region = "ap-northeast-2"
}
VPC, Subnet, Internet Gateway를 정의합니다.
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "main-vpc" }
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "ap-northeast-2a"
tags = { Name = "public-subnet" }
}
웹 서버를 위한 80, 443 포트와 SSH 22 포트(특정 IP만 허용)를 오픈합니다.
resource "aws_security_group" "web_sg" {
name = "web-sg"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "app_server" {
ami = "ami-0c9c942bd7bf113a2" # Ubuntu 22.04 LTS
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web_sg.id]
user_data = <<-EOF
#!/bin/bash
echo "Hello, Terraform" > index.html
nohup python3 -m http.server 80 &
EOF
tags = {
Name = "terraform-example-instance"
}
}
terraform init
terraform plan
terraform apply --auto-approve
명령어 실행 후 AWS 콘솔에 들어가 보면 우리가 코드로 정의한 그대로 VPC와 EC2가 생성된 것을 확인할 수 있습니다.
나중에 인프라를 삭제할 때도 terraform destroy 명령어 하나면 깔끔하게 정리됩니다.
Terraform 도입으로 인프라 변경 이력이 Git에 모두 남게 되었고, 유사한 환경(Staging, Prod)을 구축할 때 코드를 재사용(Module)할 수 있어 생산성이 비약적으로 향상되었습니다. 이제 인프라는 더 이상 '살아있는 생물'이 아니라 '잘 관리된 코드'가 되었습니다.