궁금한게 많은 개발자 노트

[ IaC ] Terraform state lock 본문

카테고리 없음

[ IaC ] Terraform state lock

궁금한게 많은 개발자 2023. 10. 31. 00:26

Terraform에서 tfstate 파일은 인프라스트럭처의 현재 상태를 저장하는 중요한 파일입니다. 이 파일은 Terraform이 관리하는 리소스의 상태 및 구성 정보를 추적하고 관리하는 데 사용됩니다. 로컬에서 관리하면 유실이나, 여러 사람이 협업할 때 동기화 문제가 발생할 수 있으므로 Terraform의 tfstate 파일을 원격으로 관리하면 여러 사람이 여러 환경에서 인프라스트럭처를 공유하고 협업할 때 유용합니다.

 

  • Remote State Backends:
    원격 tfstate 관리를 위한 가장 일반적인 방법은 Terraform의 "Remote State Backends"를 사용하는 것입니다. 이러한 백엔드는 tfstate 파일을 중앙 원격 위치에 저장하고 여러 사용자 또는 환경 간에 공유할 수 있도록 합니다. 
  • Remote Locking:
    동시에 여러 사용자가 인프라스트럭처를 수정하려고 할 때 충돌을 방지하려면 "Remote Locking"을 사용할 수 있습니다. 이는 동시에 여러 Terraform 실행이 tfstate 파일을 수정하지 못하도록 합니다. 원격 상태 백엔드에는 종종 이러한 잠금 메커니즘이 내장되어 있습니다.
  • Access Control and Authentication:
    원격 tfstate 관리에서는 액세스 제어 및 인증이 중요합니다. 백엔드에 액세스하는 사용자 및 서비스가 올바르게 인증되고 권한이 부여되어야 합니다.
  • Encryption:
    보안을 위해 tfstate 데이터를 암호화하는 것이 중요합니다. 대부분의 원격 상태 백엔드는 데이터를 암호화하고, TLS(전송 계층 보안)를 사용하여 데이터 전송을 보호합니다.
  • Versioning and History:
    tfstate 파일의 버전 관리는 중요합니다. Terraform이 업데이트됨에 따라 인프라스트럭처의 이전 상태로 롤백하거나 변경 내역을 검토할 수 있어야 합니다.

 

Terraform backend는 tfstate파일을 어디에 저장하고 읽어올지에 대한 설정을 의미합니다. 일반적으로 s3 저장소에 tfstate를 저장하는 편이며, 단순히 파일을 저장하는 것 뿐만 아니라, tfstate를 관리하면서 동시에 여러 명이 해당 파일에 접근하여 작업하지 않도록 DynamoDB에서 Lock테이블을 생성하여 관리합니다.

 

Terraform은 state파일에 접근하기 전 DynamoDB에 lock데이터를 입력하는데, 이 때 이미 누군가에 의해 Lock데이터가 입력되어 있다면 에러를 반환하도록 조건부 요청으로 PUT을 합니다. 

DynamoDB에서 PutItem의 기본 동작은 ‘덮어쓰기’ 입니다.
동일 키의 항목이 테이블이 이미 존재하는 경우 DynamoDB는 새 데이터로 덮어쓰기를 하며 에러를 반환하지 않습니다. 이를 위해 Terraform에서는 DynamoDB에 lock 데이터를 put 할 때 단순히 PutItem을 하는 것이 아닌 ‘조건부 요청’
으로 PutItem 을 수행해 기존 데이터가 있는 경우 강제로 에러를 반환하도록 합니다.

조건부 요청이란?
AWS는 DynamoDB에서의 CUD(Put, Update, Delete) 는 unconditional, 무조건적이라고 합니다.
해당 요청은 반드시 수행되며, 기존에 데이터가 있는 경우 덮어씁니다.
이를 무조건 성공하게 하지 않고, 특정 경우에만 성공하도록 조건을 걸게하는 옵션이 ‘조건부 요청’ 이라는 옵션입니다. 사용방법은 아래와 같이 CUD 요청에 옵션으로 condition-expression 을 주면 됩니다.
aws dynamodb put-item --table-name ProductCatalog --item file://item.json --condition-expression "attribute_not_exists(Id)"

 

 

https://developer.hashicorp.com/terraform/language/state/locking

 

State: Locking | Terraform | HashiCorp Developer

Terraform stores state which caches the known state of the world the last time Terraform ran.

developer.hashicorp.com

 

아래는 tfstate를 원격에서 관리하기 위해 backend를 구성하는 예시이며,

backend s3 block은 주석 처리하고 s3와 DynamoDB가 생성된 후에 주석을 풀고 terraform init을 실행해야 합니다.

provider "aws" {
  region = "us-west-2"

resource "aws_s3_bucket" "tfstate_bucket" {
  bucket = "my-terraform-state-bucket"
  acl    = "private"
}

resource "aws_s3_bucket_versioning" "tfstate-versioning" {
  bucket = aws_s3_bucket.test-tfstate.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_dynamodb_table" "tfstate_lock" {
  name           = "tfstate-lock"
  billing_mode   = "PAY_PER_REQUEST"
  hash_key       = "LockID"
  attribute {
    name = "LockID"
    type = "S"
  }
}

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.0"
    }
  }
  backend s3 {
    bucket         = "tfstate_bucket"
    key            = "terraform.tfstate"
    region         = "us-west-2"
    encrypt        = true
    dynamodb_table = "terraform-tfstate-lock"
  }
}

 

 

 

 

 

 

Comments