관리 메뉴

근묵자흑

Terraform State 본문

IaC/terraform

Terraform State

Luuuuu 2024. 12. 29. 18:30

상태 관리

terraform plan, apply 명령어를 실행하면 테라폼이 이전 생성한 리소스를 찾아 업데이트 할 수 있다.
그럼 아래 와 같은 궁금증이 생길 수있다.

  1. 리소스 관리는 어떻게 진행되는가?
  2. 인프라 상태를 어떻게 탐지하는가?
  3. 테라폼 프로젝트의 파일 레이아웃, 격리, 잠금 등에 미치는 영향을 어떻게 탐지하는가?

Terraform state 란?

테라폼은 생성한 인프라에 대한 정보를 테라폼 상태 파일에 기록 및 trraform.tfstate 파일 생성 (.json)

테라폼을 실행할 때마다 AWS 에서 이 EC2 인스턴스의 최신 상태를 가져와서 테라폼의 구성과 비교.
그 후 변경 사항을 적용해야 하는지 결정 할 수 있다.

실제 운영환경에서는 팀단위로 사용됨으로 아래와 같은 몇가지 유의사항이 있다.

  1. 상태파일을 저장하는 공유 스토리지
  2. 상태 파일 잠금
  3. 상태 파일 격리

상태 파일 공유

tfstate 파일을 버전 관리 시스템에 저장하는 것은 아래와 같은 이유로 옳지 않다.

  1. 수동오류
  2. 잠금 기능 제공 유무
  3. 보안 (암호화)

버전 관리 시스템을 사용하지 않고, 테라폼에 내장된 백엔드 기능을 사용하는 것이 좋다.
테라폼 백엔드는 상태를 로드하고 저장하는 방법을 결정한다.
위의 문제를 어떻게 해결되는지 확인 가능하다.

  1. 수동오류 --> 백엔드에서 상태파일을 자동 로드
  2. 잠금 기능 제공 유무 --> terraform apply 명령을 실행 시 자동 잠금기능 제공
  3. 보안 --> 평문으로 저장되지 않음.

S3 & dynamoDB

terraform backend 단점

1. 2단계 작업이 필요하다.

  1. 테라폼 코드를 작성하여 S3 버킷 및 다이나모DB 테이블을 생성하고 해당 코드를 로컬 백엔드와 함께 배포
  2. 원격 backend 구성을 추가

새로 생성된 S3 버킷과 다이나모DB 테이블을 사용하여, terraform init 명령을 실행하여 로컬 상태를 S3에 복사해야한다. S3와 DB를 삭제하려면 이 단계를 반대로 수행하면 된다.

2. backend 블록에서는 변수나 참조를 사용할 수 없다

terroaform {
   backend "s3" {
     bucket        = var.bucket
     region         = var.region
     dynamodb_table     = var.dynamodb_table
     key        = "example/terraform.tftstae"
     encrypt        = true
   }
}

HCP Terraform

테라폼은 다양한 백엔드를 지원하지만 프로비저닝 하는 대상과 함께 운영하기도 한다.
하시코프에서는 프로비저닝 대상과 별개로 State를 관리할 수 있도록 SaaS 환경인 HCP Terraform을 제공하며 State 관리 기능을 무상으로 제공한다.

terraform {
  cloud {
    organization = "terraform-up-and-running-kikim"

    workspaces {
      name = "terraform-state"
      # 또는 여러 워크스페이스를 패턴으로 관리하고 싶다면:
      # tags = ["team:devops", "env:prod"]
    }
  }
}

상태 파일 격리

현업 이슈로 인해 같은 운영 환경에서 중단이 발생 할 수 있다.
전체 파일이 손상 된 경우 모든 환경의 인프라가 손상될 우려가 있다.

  1. 작업 공간을 통한 격리
terraform workspace new new-workspace
  1. 파일 레이아웃을 통한 격리

trraform_remote_state 데이터 소스

웹 서버 클러스터가 MySQL 데이터베이와 통신해야 한다고 가정해보자.
웹 클러스터는 MySQL 데이터베이스보다 훨씬 자주 배포할 것이므로 실수로 데이터베이스를 손상 시키고 싶지 않다면,
웹 서버 클러스터와 MySQL 데이터베이스 설정을 같은 위치에 정의하지 않아야 한다.

mysql/main.tf 파일의 S3 저장하도록 모듈 구성

terraform {
  backend "s3" {

    # This backend configuration is filled in automatically at test time by Terratest. If you wish to run this example
    # manually, uncomment and fill in the config below.

    bucket         = "terraform-state-bucket-test-1"
    key            = "stage/data-stores/mysql/terraform.tfstate"
    region         = "ap-southeast-1"
    dynamodb_table = "TerraformState"
    encrypt        = true

  }
}

데이터베이스를 생성 시키고 준비가 되었다면 웹 서버 클러스터에 해당 주소와 포트를 저공해야합니다.

데이터베이스 주소와 포트값은 stage/data-stores/mysql/terraform.tfstate 경로에 있는 S3 버킷의 테라폼 상태 파일에 저장됩니다.

webserver-cluster/main.tf 파일에 terraform_remote_state 데이터 소스를 추가하여 엡 서버 클러스터 코드가 이 상태 파일에서 데이터를 읽도록 할 수 있습니다.

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

 config = {
   bucket = var.db_remote_state_bucket
   key    = var.db_remote_state_key
   region = "ap-southeast-1"
 }
}

...

resource "aws_launch_template" "example" {
  name_prefix   = "terraform-example"
  image_id      = "ami-0df7a207adb9748c7"
  instance_type = "t2.micro"

  vpc_security_group_ids = [aws_security_group.instance.id]

  user_data = base64encode(templatefile("user-data.sh", {
    server_port = var.server_port
    db_address  = data.terraform_remote_state.db.outputs.address
    db_port     = data.terraform_remote_state.db.outputs.port
  }))

  lifecycle {
    create_before_destroy = true
  }
}

위 코드는 아래 링크를 통해 전체 코드를 확인 할 수 있습니다.

https://github.com/gs-kikim/terraform_up_and_running/tree/main/03.terraform-state/3.5.terrform-remote-state

'IaC > terraform' 카테고리의 다른 글

테라폼 팁과 요령: 반복문, if문, 배포 및 주의사항  (3) 2025.01.12
Terraform Module  (8) 2025.01.05
테라폼 로드밸런서 배포  (5) 2024.12.22
왜 테라폼 인가?  (4) 2024.12.15
workflow  (7) 2024.11.05