기본
핵심 워크플로
terraform init # install providers & modules terraform plan # preview changes terraform apply # apply changes terraform destroy # tear down all resources
필수 명령어
terraform init작업 디렉터리 초기화, 프로바이더 다운로드
terraform plan적용 없이 실행 계획 표시
terraform apply인프라에 변경 사항 적용
terraform destroy관리 중인 모든 리소스 삭제
terraform fmt.tf 파일을 표준 스타일로 포맷
terraform validate구성 구문 검사
terraform show현재 상태 또는 계획 표시
terraform output출력 값 표시
프로바이더
프로바이더 구성
terraform { required_providers { aws = { source = "hashicorp/aws", version = "~> 5.0" } } } provider "aws" { region = "us-east-1" }
프로바이더 참고사항
source레지스트리 주소 (hashicorp/aws, hashicorp/google)
version버전 제약 (~> 5.0, >= 3.0, < 4.0)
.terraform.lock.hcl잠금 파일 — 버전 관리에 커밋
alias동일 프로바이더에 여러 구성 사용
리소스
리소스 블록
resource "aws_instance" "web" { ami = "ami-0c55b159cbfafe1f0" instance_type = "t3.micro" tags = { Name = "web-server" } }
리소스 메타 인수
depends_on다른 리소스에 대한 명시적 의존성
count여러 인스턴스 생성 (count = 3)
for_each맵 또는 집합에서 인스턴스 생성
provider기본값이 아닌 프로바이더 별칭 선택
lifecycle생성/업데이트/삭제 동작 커스터마이즈
리소스 참조
# type.name.attribute aws_instance.web.id aws_instance.web.public_ip aws_vpc.main.cidr_block
변수
변수 선언
variable "region" { type = string default = "us-east-1" } variable "instance_count" { type = number description = "Number of instances" }
변수 값 설정
-var 'region=us-west-2'CLI 플래그
-var-file=prod.tfvars.tfvars 파일에서 로드
terraform.tfvars존재하는 경우 자동 로드
TF_VAR_region환경 변수
Interactive prompt기본값 없을 때 plan/apply에서 입력 요청
변수 타입
string"us-east-1"
number42
booltrue / false
list(string)["a", "b"]
map(string){ key = "val" }
object({...})명명된 속성을 가진 구조 타입
출력
출력 정의
output "instance_ip" { value = aws_instance.web.public_ip description = "Public IP of the web server" } output "db_password" { value = random_password.db.result sensitive = true }
출력 명령어
terraform output모든 출력 표시
terraform output instance_ip특정 출력 표시
terraform output -json스크립팅용 JSON 형식
sensitive = trueCLI 출력에서 값 숨김
module.vpc.vpc_id자식 모듈 출력 접근
상태
원격 백엔드
terraform { backend "s3" { bucket = "my-tf-state" key = "prod/terraform.tfstate" region = "us-east-1" } }
상태 명령어
terraform state list상태 내 모든 리소스 목록
terraform state show <addr>리소스 속성 표시
terraform state mv <src> <dst>상태 내 리소스 이름 변경 / 이동
terraform state rm <addr>상태에서 리소스 제거 (인프라 유지)
terraform state pull원격 상태를 stdout으로 다운로드
terraform import <addr> <id>기존 인프라를 상태로 임포트
모듈
모듈 사용
module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "~> 5.0" cidr = "10.0.0.0/16" }
모듈 소스
"./modules/vpc"로컬 경로
"terraform-aws-modules/vpc/aws"Terraform 레지스트리
"github.com/org/repo//module"GitHub 리포지터리
"s3::https://bucket/module.zip"S3 버킷
모듈 구조
modules/vpc/ main.tf # resources variables.tf # input variables outputs.tf # output values
데이터 소스
기존 리소스 읽기
data "aws_ami" "ubuntu" { most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/*"] } owners = ["099720109477"] }
주요 데이터 소스
data.aws_ami필터로 AMI 조회
data.aws_vpc기존 VPC 조회
data.aws_caller_identity현재 AWS 계정 ID
data.aws_region현재 AWS 리전
data.terraform_remote_state다른 상태 파일의 출력 읽기
data.external데이터를 위해 외부 프로그램 실행
라이프사이클
라이프사이클 규칙
resource "aws_instance" "web" { lifecycle { create_before_destroy = true prevent_destroy = true ignore_changes = [tags] } }
라이프사이클 옵션
create_before_destroy기존 것 삭제 전 대체 리소스 생성
prevent_destroyterraform destroy로 이 리소스 대상 시 오류
ignore_changes나열된 속성의 드리프트 감지 안 함
replace_triggered_by참조 리소스 변경 시 강제 교체
preconditionapply 전 전제 조건 검증
postconditionapply 후 결과 검증
자주 쓰는 패턴
루프 및 조건
# for_each with a map resource "aws_iam_user" "users" { for_each = toset(["alice", "bob"]) name = each.value } # conditional resource count = var.create_db ? 1 : 0
유용한 함수
file("key.pub")파일 내용 읽기
join(", ", list)리스트를 문자열로 결합
lookup(map, key, default)폴백이 있는 맵 조회
length(list)요소 수
toset(["a", "b"])리스트를 집합으로 변환 (for_each용)
try(expr, fallback)expr 오류 시 폴백 반환
templatefile(path, vars)템플릿 파일 렌더링