Notice
Recent Posts
Recent Comments
Link
«   2024/12   »
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
Tags
more
Archives
Today
Total
관리 메뉴

Study_note

[Terraform] 상태 파일, 원격 Backend, remote_state (2) 본문

Terraform

[Terraform] 상태 파일, 원격 Backend, remote_state (2)

Study_note 2022. 9. 29. 10:52

상태파일

 

저번 글에서 말했듯이 apply 시 terraform.tfstate 파일이 생성된다 이걸 상태 파일이라 부르는데

 

이 파일에는 구성파일(.tf)의 테라폼 리소스가 실제 리소스의 표현으로 매핑되는 내용을 기록하며 사용자 정의 JSON 형태로 되어 있고 이는 terraform으로 구성된 인프라스터럭처의 현재 상태를 보여준다.

 

즉 apply 때마다 AWS에서 지금 작동 중인 EC2 인스턴스의 최신 상태를 가져와서 테라폼의 구성과 비교하여 어느 변경 사항을 적용해야 하는지 결정한다.

 

 

아래 사진 처럼 인프라 생성 시 terraform.tfstate  생성

 

하지만 개인이 사용할 시 문제가 되지 않지만 팀 단위로 사용을 한다면 문제가 발생한다.

  1. 상태 파일을 저장하는 공유 스토리지 : 인프라 업데이트 시 각 팀원이 동일한 상태 파일에 접근해야 한다.
    즉 상태 파일을 공유 위치에 저장해야 한다.
  2. 상태 파일 잠금 : 2명 이상의 팀원이 동시에 테라폼을 실행하는 경우 상태 파일 업데이트가 충돌할 수 있다.
  3. 상태 파일 격리 : 서비스가 변경될 때, 다른 서비스에 영향을 미치면 안 된다.
    즉 하나의 상태 파일에 모든 정의를 넣는 게 아니라 환경 별로 상태 파일 격리 

이러한 문제점을 해결하기 위해 버전 관리 시스템 대신 테라폼에 내장된 원격 Backend 기능을 사용한다.

( 기본 백앤드는 로컬 디스크에 상태 저장 - 원격 백앤드 공유 저장소에 상태 저장 )

  1. 수동 오류 : apply 명령을 실행할 때마다 해당 백엔드에 상태 파일을 자동으로 로드한다.
  2. 잠금 : apply 명령을 실행하면 테라폼은 자동으로 잠금을 활성화한다.
  3. 시크릿 : S3 버킷의 서버사이드 암호화 기능

백엔드로 s3를 사용한다

s3 : 관리형 서비스여서 관리 x, 고가용성 고 내구성, 암호화 및 버전 관리 지원, 다이나모 db를 통한 잠금 기능 지원

 

백앤드 구성은 아래와 같다

provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_s3_bucket" "terraform_state" {

  bucket = "terraform-test-kjh-s3"
 # 실수로 s3 삭제하는것을 방지
  lifeccle {
    prevent_destroy = true
  }

}

# Enable versioning so you can see the full revision history of your
# state files
resource "aws_s3_bucket_versioning" "enabled" {
  bucket = aws_s3_bucket.terraform_state.id
  versioning_configuration {
    status = "Enabled"
  }
}

# Enable server-side encryption by default
resource "aws_s3_bucket_server_side_encryption_configuration" "default" {
  bucket = aws_s3_bucket.terraform_state.id

  rule {
    apply_server_side_encryption_by_default {
      sse_algorithm = "AES256"
    }
  }
}

# Explicitly block all public access to the S3 bucket
resource "aws_s3_bucket_public_access_block" "public_access" {
  bucket                  = aws_s3_bucket.terraform_state.id
  block_public_acls       = true
  block_public_policy     = true
  ignore_public_acls      = true
  restrict_public_buckets = true
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = "terraform_test-kjh-dynamodb"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}
###### 주석 후 init 한번 하고 추가
terraform {
    backend "s3" { 
      bucket         = "terraform-test-kjh-s3" # s3 bucket 이름
      key            = "terraform/global/terraform.tfstate" # s3 내에서 저장되는 경로를 의미합니다.
      region         = "ap-northeast-2"  
      encrypt        = true
      dynamodb_table = "terraform_test-kjh-dynamodb" # 다이나모db 이름
    }
}

 

prevent_destroy = true : 실수로 s3를 삭제하는 것을 방지한다.

versioning                     :  s3 버킷에 버전 관리 활성화

aws_s3_bucket_server_side_encryption_configuration : s3 버킷에 기록된 모든 데이터에 서버 측 암호화를 설정

 

백엔드를 설치해도 같은 파일, 디렉토리 내에 상태 파일이 아닌 외부에서 상태 파일에 리소스를 참조할려면 불가능하다

이러한 불편함을 해결해주는게 terraform_remote_state로

참조할만한 리소스 요소들을 output을 통해 빼주어 상태파일에 따로 저장해주고 다른 디렉토리에서 리소스를 생성할 때  아래와 같이 terraform_remote_state를 사용하여 output을 통해 따로 저장했던 값들을 참조할 상태 파일 경로등을 입력하고 참조할 값들을 가져온다.

data "terraform_remote_state" "db" {
  backend = "s3"

  config = {
    bucket = # 백엔드 버킷
    key    = # 버킷 내부 참조할 .tfstate 파일 경로
    region = "us-east-2"
  }
}

# 아래와 같이 terraform_remote_state값 가져온다
    db_address  = data.terraform_remote_state.db.outputs.address
    db_port     = data.terraform_remote_state.db.outputs.port
    
 즉
 data.terraform_remote_state.<terraform_remote_state 이름>.outputs.<output에서 선언한 이름>

 

백앤드 생성

s3, 다이나모 db 테이블 생성 후 init -> 코드로 돌아와 원격 backend 구성 추가 후 init (즉 init 2번)

삭제

backend 구성 삭제 init -> destroy로 삭제 (즉 init으로 backend 상태 변경이라 이해)

 

상태 파일 격리

1. 작업 공간을 통한 격리

terraform workspace(테라폼 작업 공간)을 통해 테라폼 상태를 별도의 이름을 가진 여러 개의 작업 공간에 저장 가능

terraform workspace / show, list, select, new, delete로 구성 가능

백엔드 구성 시 key 값 지정 가능 또한 리소스 생성 시 지정 가능

(테라폼을  잘 안 써봐서 모르겠지만 2번이 훨씬 효율적인 거 같다.)

 

 

 

2. 파일 레이아웃을 이용한 격리

예를 들어 stage, dev, pro 등 이처럼 분리된 폴더를 사영하는 접근 방식을 사용하면 어떤 환경 배포할지 훨씬 명확해진다.

또한 격리 수준을 높이려면 구성 요소 단위 즉 vpc, sg 등 많이 사용할 수 있는 리소스일수록 작은 단위로 파일을 생성

위와 같이 환경 별로 지금은 main.tf로 전부 구성했지만 리소스마다 세세하게 구성한다

 

이렇게 리소스별로 파일을 격리할때 remote_state를 사용하면 가독성과 작업 효율성을 높힐 수 있다

 

Comments