Terraform과 AWS 함께 사용하기: 완벽 가이드
Terraform과 AWS 함께 사용하기: 완벽 가이드
인프라 관리는 수동 콘솔 클릭과 취약한 스크립트에서 버전 관리, 검토, 공유가 가능한 선언형 코드로 진화했습니다. Amazon Web Services에서 구축하는 팀에게 Terraform은 IaC(Infrastructure as Code)의 표준이 되었으며, Terraform과 AWS를 효과적으로 사용하는 방법을 아는 것은 이제 클라우드 엔지니어의 핵심 역량입니다. 이 가이드에서는 AWS 프로바이더 설정부터 프로덕션 수준의 리소스 배포까지 전체 워크플로우를 안내합니다.
학습 내용
이 가이드를 마치면 AWS에서의 완전한 Terraform 워크플로우(프로바이더 구성, 리소스 정의, 상태 관리, 팀 협업)를 이해하게 됩니다. Terraform의 선언형 접근 방식을 사용하여 AWS 인프라를 자신 있게 배포, 업데이트, 삭제할 수 있게 되며, 프로젝트를 구조화하는 명확한 방법론을 갖추게 됩니다. 또한 잘못된 AWS 계정에 배포하는 등의 비용이 많이 드는 실수를 방지하는 실용적인 안전장치도 배웁니다.
핵심 개념 이해: 프로바이더, 리소스, 상태
설정을 작성하기 전에 Terraform의 기본 구성 요소를 이해하는 것이 좋습니다. AWS 네이티브이며 리소스가 AWS 계정 내에서 생성된다고 가정하는 AWS CloudFormation과 달리, Terraform은 클라우드에 종속되지 않으며 특정 API와 상호작용하는 프로바이더를 명시적으로 선언해야 합니다.
프로바이더란?
프로바이더는 Terraform과 대상 플랫폼 간의 브리지 역할을 하는 플러그인입니다. AWS 프로바이더는 Terraform이 AWS API를 호출하여 리소스를 생성, 읽기, 업데이트, 삭제할 수 있게 해줍니다. Terraform은 AWS, Kubernetes, Helm, 타사 SaaS 도구 등 여러 프로바이더를 지원하므로, 동일한 설정 내에서 Amazon EKS 클러스터를 프로비저닝하고 Helm 차트를 배포할 수 있습니다.
리소스와 데이터 소스
리소스는 인프라의 구성 요소(EC2 인스턴스, S3 버킷, 보안 그룹)를 정의합니다. 리소스는 선언형으로 선언됩니다. 즉, 무엇을 원하는지 지정하면 Terraform이 어떻게 생성할지 결정합니다.
반면 데이터 소스는 AWS에서 기존 리소스에 대한 정보를 조회합니다. 예를 들어, 변경되거나 리전에 따라 달라질 수 있는 AMI ID를 하드코딩하는 대신 데이터 소스를 사용하여 최신 Amazon Linux 2023 AMI를 동적으로 가져올 수 있습니다.
상태: 진실의 원천
Terraform은 관리하는 리소스를 추적하는 상태 파일을 유지합니다. 이 상태는 설정을 실제 인프라에 매핑하며, 업데이트 계획, 드리프트 감지, 리소스 정리 삭제에 필수적입니다. 팀 환경에서는 충돌을 방지하고 일관성을 보장하기 위해 Amazon S3와 같은 원격 백엔드에 상태를 저장하는 것이 좋습니다.
시작하기: 도구 설치 및 AWS 자격 증명 구성
사전 요구 사항
설정을 작성하기 전에 로컬 환경을 준비하세요:
- Terraform CLI 1.5 이상 – 바이너리를 다운로드하고 PATH에 추가하세요.
- AWS CLI – 설치하고 충분한 권한이 있는 IAM 자격 증명으로 구성하세요.
- AWS 계정 – 예상치 못한 요금을 방지하려면 프리 티어를 사용하여 연습하세요.
AWS 프로바이더 인증
Terraform의 AWS 프로바이더는 AWS CLI와 동일한 방법으로 인증합니다. 가장 간단한 방법은 IAM 자격 증명으로 환경 변수를 설정하는 것입니다:
export AWS_ACCESS_KEY_ID=<your_access_key>
export AWS_SECRET_ACCESS_KEY=<your_secret_key>
또는 Terraform은 ~/.aws/credentials의 기본 자격 증명 파일을 읽을 수 있습니다.
1단계: 첫 번째 Terraform 설정 작성
프로젝트용 새 디렉토리를 만들고 프로바이더와 리소스를 정의하세요. Terraform 설정 파일은 HCL(HashiCorp Configuration Language)을 사용하며 .tf 확장자로 끝납니다.
terraform 블록
terraform 블록은 프로바이더 소스와 버전 제약 조건을 포함하여 Terraform 자체를 구성합니다. 프로바이더 버전을 고정하면 프로바이더가 업데이트될 때 예상치 못한 드리프트를 방지할 수 있습니다.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
required_version = ">= 1.2"
}
source 인수는 Terraform 레지스트리의 프로바이더를 가리킵니다. HashiCorp가 AWS 프로바이더를 유지 관리하므로 소스는 hashicorp/aws입니다.
provider 블록
provider 블록은 기본 리전을 포함하여 AWS 프로바이더를 구성합니다:
provider "aws" {
region = "us-west-2"
}
EC2 인스턴스 정의
resource 블록은 인프라 구성 요소를 선언합니다. 다음은 데이터 소스를 사용하여 최신 Ubuntu AMI를 가져오는 EC2 인스턴스를 정의하는 방법입니다:
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd-gp3/ubuntu-noble-24.04-amd64-server-*"]
}
}
resource "aws_instance" "app_server" {
ami = data.aws_ami.ubuntu.id
instance_type = "t2.micro"
tags = {
Name = "terraform-demo"
}
}
AMI에 데이터 소스를 사용하면 설정이 동적이고 여러 리전에서 이식 가능하게 유지됩니다.
2단계: 초기화, 계획, 적용
Terraform 워크플로우는 세 가지 핵심 명령어로 구성됩니다:
terraform init
작업 디렉토리를 초기화합니다. 필요한 프로바이더 플러그인을 다운로드하고 백엔드를 설정합니다:
terraform init
Terraform은 required_providers 블록을 읽고 지정한 AWS 프로바이더 버전을 설치합니다.
terraform plan
Terraform이 인프라에 적용할 변경 사항을 미리 봅니다:
terraform plan
계획은 추가, 수정, 삭제를 보여줍니다. 적용 전에 실수를 발견할 수 있는 기회입니다.
terraform apply
설정을 적용하여 리소스를 생성합니다. Terraform이 계획을 다시 보여주고 확인을 요청합니다:
terraform apply
yes를 입력하여 진행합니다. Terraform이 EC2 인스턴스를 프로비저닝하고 결과를 출력합니다.
terraform destroy
작업이 끝나면 요금을 방지하기 위해 정리합니다:
terraform destroy
Terraform은 상태 파일을 기반으로 삭제할 항목을 계산하고 확인을 요청합니다.
3단계: 보안 그룹 및 프로비저닝 로직 추가
네트워크 액세스 없이는 서버가 무용지물입니다. 인바운드 및 아웃바운드 트래픽을 제어하는 보안 그룹을 추가하세요:
resource "aws_security_group" "web" {
name = "web-sg"
description = "HTTP 및 SSH 허용"
vpc_id = var.vpc_id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"] # SSH 제한
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
vpc_security_group_ids 인수에서 aws_security_group.web.id를 참조하여 EC2 인스턴스에 보안 그룹을 연결하세요.
사용자 데이터로 소프트웨어 설치 자동화
EC2 사용자 데이터를 사용하여 인스턴스가 처음 부팅될 때 소프트웨어를 설치하세요. 예를 들어, Amazon Linux 2023에 Nginx를 설치하는 경우:
resource "aws_instance" "web" {
ami = data.aws_ami.al2023.id
instance_type = "t3.micro"
vpc_security_group_ids = [aws_security_group.web.id]
key_name = var.key_name
user_data = <<-EOF
#!/bin/bash
dnf install -y nginx
systemctl start nginx
echo "<h1>Hello from Terraform</h1>" > /usr/share/nginx/html/index.html
EOF
}
사용자 데이터는 초기 부팅 중에 실행되며, 추가 구성 관리 도구 없이 인스턴스를 부트스트랩하는 간단한 방법입니다.
4단계: 변수, 출력, 모듈 사용
재사용성을 위한 변수
값을 하드코딩하면 설정이 취약해집니다. variables.tf 파일에 변수를 정의하세요:
variable "instance_type" {
description = "EC2 인스턴스 유형"
type = string
default = "t2.micro"
}
variable "aws_region" {
description = "AWS 리전"
type = string
default = "us-west-2"
}
var.instance_type으로 설정에서 변수를 참조하세요.
정보 표시를 위한 출력
출력을 사용하면 적용 후 인스턴스의 공용 IP와 같은 정보를 검색할 수 있습니다:
output "instance_public_ip" {
description = "EC2 인스턴스의 공용 IP"
value = aws_instance.app_server.public_ip
}
재사용 가능한 구성 요소를 위한 모듈
모듈은 여러 프로젝트에서 공유할 수 있는 여러 리소스의 컨테이너입니다. Terraform 레지스트리는 수천 개의 커뮤니티 모듈을 제공하며, 직접 작성할 수도 있습니다. 모듈을 사용하면 루트 설정이 깔끔하게 유지되고 재사용성이 향상됩니다.
5단계: 원격 상태 및 팀 협업
팀 환경에서 상태를 로컬에 저장하는 것은 위험합니다. 상태가 오래되거나 다른 사용자의 변경 사항과 충돌할 수 있습니다. 일반적으로 DynamoDB를 사용한 상태 잠금과 함께 Amazon S3를 사용하여 원격 백엔드를 구성하세요:
terraform {
backend "s3" {
bucket = "my-terraform-state-bucket"
key = "prod/terraform.tfstate"
region = "us-west-2"
encrypt = true
dynamodb_table = "terraform-locks"
}
}
이 구성은 적용 작업 중에 상태가 공유되고 잠겨 있어 상태 파일을 손상시킬 수 있는 동시 수정을 방지합니다.
6단계: 보안 모범 사례
특정 AWS 계정으로 프로바이더 제한
가장 위험한 실수 중 하나는 잘못된 AWS 계정에 대해 Terraform을 실행하는 것입니다. 예를 들어, 개발 환경에 배포하려고 했지만 실수로 프로덕션 자격 증명을 사용하는 경우입니다. 프로바이더 블록의 allowed_account_ids 설정은 안전망을 만듭니다:
provider "aws" {
region = "us-west-2"
allowed_account_ids = ["123456789012"] # 이 계정만 허용
}
다른 계정의 자격 증명으로 Terraform을 실행하려고 하면 계획이 즉시 오류를 발생시켜 비용이 많이 드는 실수를 방지합니다.
정적 키 대신 IAM 역할 사용
EC2 인스턴스의 경우 항상 정적 자격 증명을 포함하는 대신 IAM 인스턴스 프로필을 사용하세요. 이렇게 하면 보안이 향상되고 자격 증명 순환이 간소화됩니다.
버전 관리 및 검토
모든 Terraform 설정은 버전 관리에 저장되어야 합니다. 인프라 변경에 대한 풀 리퀘스트는 애플리케이션 코드와 마찬가지로 검토되어야 합니다. 이것이 IaC의 핵심 가치입니다.
CI/CD 파이프라인에서 Terraform과 AWS 사용 방법
Terraform을 CI/CD 파이프라인에 통합하면 배포를 자동화하고 일관성을 강화합니다. 일반적인 GitHub Actions 워크플로우:
name: Terraform Apply
on:
push:
branches: [ main ]
jobs:
terraform:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: hashicorp/setup-terraform@v1
- name: Terraform Init
run: terraform init
- name: Terraform Plan
run: terraform plan
- name: Terraform Apply
run: terraform apply -auto-approve
이 접근 방식은 수동 적용 단계를 제거하고 모든 메인 브랜치 병합이 검토되고 테스트된 인프라를 배포하도록 보장합니다.
자주 묻는 질문
1. Terraform과 AWS CloudFormation의 차이점은 무엇인가요?
Terraform은 클라우드에 종속되지 않으며 AWS, Azure, Google Cloud 및 수백 개의 다른 프로바이더를 지원하는 반면, CloudFormation은 AWS 전용입니다. Terraform은 또한 plan/apply 단계가 있는 더 유연한 워크플로우를 제공하고 더 다양한 타사 리소스를 지원합니다.
2. Terraform은 내 인프라의 상태를 어디에 저장하나요?
기본적으로 Terraform은 상태를 로컬 terraform.tfstate 파일에 저장합니다. 프로덕션 및 팀 사용의 경우 Amazon S3와 같은 원격 백엔드를 구성하여 상태를 중앙에 저장하고 잠금으로 충돌을 방지해야 합니다.
3. Terraform 모듈이란 무엇이며 왜 사용해야 하나요?
모듈은 여러 프로젝트에서 재사용할 수 있는 여러 리소스의 컨테이너입니다. 모듈을 사용하면 중복이 줄어들고 일관성이 강화되며 Terraform 레지스트리를 통해 팀 간에 인프라 패턴을 공유할 수 있습니다.
4. 실수로 잘못된 AWS 계정에 배포하는 것을 어떻게 방지하나요?
AWS 프로바이더 블록에서 allowed_account_ids 설정을 사용하여 Terraform을 특정 계정 ID로 제한하세요. 자격 증명이 허용된 목록과 일치하지 않으면 Terraform이 변경을 수행하기 전에 오류를 발생시킵니다.
5. terraform plan과 terraform apply의 차이점은 무엇인가요?
terraform plan은 Terraform이 인프라에 적용할 변경 사항을 미리 봅니다. terraform apply는 해당 변경 사항을 실행합니다. 리소스를 수정하기 전에 항상 plan을 먼저 실행하여 실수를 발견하세요.
출처
- Terrateam, "AWS에서 Terraform으로 Nginx 배포 방법" (2026)
- AWS Prescriptive Guidance, "Terraform 리소스 및 프로바이더 이해" (2024)
- AWS Prescriptive Guidance, "Terraform AWS 프로바이더 모범 사례" (2024)
- HashiCorp Developer, "인프라 생성" (2025)
- Refine, "AWS에서 Terraform 시작하기" (2024)
- DevelopersIO, "Terraform AWS 프로바이더 allowed_account_ids" (2025)
- GitHub, "terraform-basics-aws" 저장소
— Editorial Team
아직 댓글이 없습니다.