Terraform #3

임상규·2023년 11월 16일
1

Terraform

목록 보기
3/3
post-thumbnail

count

  • 기본적으로 resource blockdms 실제 하나의 인프라 객체를 의미
  • 유사한 객체를 여러개의 block으로 관리하지 않고 하나의 block으로 관리할 때 사용
resource "aws_instance" "server_1" {
  ami           = "ami-a1b2c3d4"
  instance type = "t2.micro"
  
  tags = {
    Name = "Server 1"
  }
}

resource "aws_instance" "server_2" {
  ami           = "ami-a1b2c3d4"
  instance type = "t2.micro"
  
  tags = {
    Name = "Server 2"
  }
}
⬇️
resource "aws_instance" "server" {
  count = 2
  
  ami           = "ami-a1b2c3d4"
  instance_type = "t2.micro"
  
  tags = {
    Name = "Server %{count.index}"
  }
}
output "server_1" {
  value = aws_instance.server[1]
}

for_each

  • 값이 map, set으로 구성된 argument에 대한 처리가 필요한 경우에 사용
resource "aws_iam_user" "todd" {
  name = "Todd"
}

resource "aws_iam_user" "james" {
  name = "James"
}
⬇️
resource "aws_iam_user" "the-accounts" {
  for_each = toset( ["Todd", "James", "Alice", "Dottie"] )
  name     = each.key
}
resource "azurermm_resource_group" "rg" {
  for_each = {
    a_group = "eastus"
    another_group = "westus2"
  }
  name     = each.key
  location = each.value
}

상태 저장소 (backend)

backend란?

  • terraform은 영구적인 state data 파일을 계속 관리해야함
  • backend = state data 파일이 저장되는 위치

backend 종류

  • local: disk(HDD, SSD). 기본 설정
  • remote
    • Terraform Cloud
    • AWS S3
    • Kubernetes secret
    • Postgres DB
    • Gitlab

remote backend 문제점

  • S3와 같이 누구든 볼 수 있는 저장소라면 민감정보(pw, key)는 분리가 필요
  • 민감정보는 환경변수로 분리하여 backend-config 옵션을 통해서 사용하는것을 권장

상태 관리

  • terraform은 인프라나 설정에 대해서 무조건 state(상태)로 저장함
  • state는 기본적으로 terraform.tfstate 라는 로컬 파일에 저장됨
    • backend가 remote인 경우에는 환경마다 다름
  • state는 terraform 으로 선언된 설정과 실제 인프라 객체를 매핑하기 위해 존재함
  • 즉, state가 없으면 terraform 으로 인프라 관리를 할 수 없음

state 파일시스템 문제점

  • state 파일이 저장된 위치의 성능에 따라서 terraform 성능에 영향이 발생함
    • plan/apply 실행 시 매번 로컬에 저장된 state와 API로 호출된 값을 비교
    • -refresh=false 옵션을 통해서 로컬에 저장된 state만으로 비교 가능
    • remote backend 사용 시 환경에 따라서 추가 지연 발생 가능

S3 문제점

  • 하나의 terraform module을 여러명이 관리할 때 state 파일을 공유해야함
    • backend를 remote로 사용
  • 하지만 S3와 같은 파일시스템을 사용할 경우에 동시에 동일한 state 파일에 접근한다면 충돌이 발생
  • state 파일도 손상 및 인프라 설정 꼬임 발생
  • state locking 하기 위해서는 dynamoDB 설정도 추가가 필요함

state 파일 분리

  • 여러개의 환경을 관리할 때 locking이 발생하여 수정을 못하는 경우가 발생
    • A가 운영환경에 배포하는 동안 locking이 발생하여 B는 개발환경 테스트가 불가능
  • 환경별로 상태 파일을 분리가 필요
    • 디렉토리를 분리 (환경별로 root module 생성)
    • workspace 분리

리소스 강제 교체

  • terraform taint / untaint
    • 강제로 리소스를 재생성하는 방법
    • Elastic IP 재생성, 비정상적인 리소스 처리를 위해 사용
  • 현재는 deprecated 되었으며 아래 명령어로 대체됨
terraform apply -replace="aws_instance_example[0]"

workspace

  • 환경에 따라서 state를 관리하고자 할 때 사용하는 기능
  • workspace 별로 state가 별도로 저장됨
  • 일부 backend만 multiple workspace 지원
    • kubernetes
    • Local
    • Postgres
    • Remote (Terraform Cloud)
    • S3

Terraform 운영전략

backend

  • 개인 (소규모) 프로젝트: local
  • 협업이 필요하거나 팀 단위 관리가 필요한 경우: Terraform Cloud, Gitlab
  • 다중 환경/계정 사용시 = 다중 workspace, S3 (+ dynamoDB)
  • backend 설정에서는 표현식이나 변수 사용이 불가능하므로 단일 버킷 사용 권장
    • terraform cli 옵션 중 -backend-config를 통해서 값을 바꿀 수 있음
  • 다중계정으로 S3 사용 시 assume role을 통해서 다른 계정에 접근
  • S3 cross account 설정을 통해서 사용할 경우, 운영계정의 access key 관리를 위한 정책이 필요
  • 되도록 운영계정은 role base로 운영

workspace

  • 환경 분리, 다중 계정 관리: workspace
  • 다중 계정과 환경을 한번에 관리
    • terraform은 동일한 환경을 재사용할 때 유리
  • 테스트하기 위해서 개발환경이 있는데 개발/운영 환경이 달라진다면
    • workspace를 쓰기보다는 sub(child) module로 분리

directory

  • 파일은 최대한 분리
    • 리소스 타입, 서비스 단위
  • 큰 서비스(애플리케이션)는 sub module
    • module화의 장점: 개념적으로 분리하기 쉬워짐 (label name을 짧게 가능)
  • sub module이 너무 커지면 프로젝트로 분리
    • module 간에 output으로 참조하던 부분은 data로 처리
    • sub module state import/export는 공식적인 지원 X
  • 환경 (dev/prd) 별로 sub module로 나누는 방식은 권장 X
    • 물론 워크로드에 따라서 오히려 좋을 수 있음
profile
Cloud Engineer / DevOps Engineer

0개의 댓글