상세 컨텐츠

본문 제목

[테라폼/Terraform]테라폼 상태 관리/백엔드

Development/테라폼

by J-Developer 2022. 5. 31. 14:58

본문

반응형

 

▶ 테라폼 상태란?

 

해당 파일에는 테라폼을 실행 시 매핑되는 리소스들의 상태값을 가지고 있습니다.

기본적으로 /foo/bar 폴더에서 테라폼을 실행하면 JSON 형태의 /foo/bar/terraform.tfstate 파일을 생성합니다.

 

ex) terraform.tfstate 예시

{
  "version": 4,
  "terraform_version": "1.1.9",
  "serial": 6,
  "lineage": "xxxxxxxxxxxxxxxx",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "google_compute_firewall",
      "name": "default",
      "provider": "provider[\"registry.terraform.io/hashicorp/google\"]",
      "instances": [
        {
          "schema_version": 1,
          "attributes": {
            "allow": [
              {
                "ports": [
                  "8080"
                ],
                "protocol": "tcp"
              }
            ],
            "creation_timestamp": "2022-04-24T03:21:09.940-07:00",
            "deny": [],
            "description": "",
            "destination_ranges": [],
            "direction": "INGRESS",
            "disabled": false,
            "enable_logging": null,
            "id": "xxxxxxxxxxxxxxxx",
            "log_config": [],
            "name": "webserver-firewall",
            "network": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "priority": 1000,
            "project": "terraform",
            "self_link": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
            "source_ranges": [],
            "source_service_accounts": [],
            "source_tags": [
              "web"
            ],
            "target_service_accounts": [],
            "target_tags": [
              "web"
            ],
            "timeouts": null
          },
          "sensitive_attributes": [],
          "private": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
        }
      ]
    }
  ]
}

즉, plan 명령어의 출력은 코드상의 설계와 실제 인프라의 설계의 차이를 보여준다고 생각하면 됩니다.

상태파일은 프라이빗이며 직접 편집하거나 수정해서는 안됩니다. 파일 상태를 조작해야 하는 경우 terraform import, terraform state 명령을 통해 조작을 해야 합니다.

테라폼을 실제 운영 환경에서 팀 단위로 사용하고자 할 때는 다음과 같은 몇 가지 문제에 직면하게 됩니다.

 

  • 테라폼을 사용하여 인프라를 업데이트하려면 각 팀원이 동일한 테라폼 상태 파일에 엑세스해야 하므로, 상태 파일을 공유 위치에 저장해야 합니다.
  • 두 팀원이 동시에 테라폼을 실행하는 경우 여러 테라폼 프로세스가 상태 파일을 동시에 업데이트하여 충돌을 일으킬 수 있습니다. 이러한 상태가 되면 데이터가 손실되거나 상태 파일이 손상될 수 있습니다.
  • 인프라를 변경할 때는 다른 환경을 격리하는 것이 가장 좋습니다. 예를 들어 테스트 환경을 변경할 경우 실수로 운영 환경이 중단되는 경우가 없는지 확인해야 합니다.

 

 

상태 파일 공유

테라폼의 상태 파일을 깃과 같은 형상관리 시스템에 공유하는 것은 다음과 같은 이유 때문에 부적절합니다.

 

1. 변경 사항을 실행하고 나서 푸시하는 것을 잊어버리는 경우가 있습니다.

2. 여러 명의 팀 구성원이 동시에 하나의 상태 파일에 apply 명령을 실행하지 못하게 하는 잠금 기능을 제공하지 않습니다.

3. 테라폼의 상태 파일은 모든 데이터를 평문으로 저장하기에 보안적으로 적절하지 않습니다.

 

이의 문제와 같은 상황을 해결하기 위해서는 테라폼에 내장된 원격 백엔드 기능을 사용하여 클라우드 스토리지에 저장하는 것이 좋습니다.

 

1. 원격 백엔드 구성 시 테라폼은 plan이나 apply 명령을 실행할 때마다 해당 백엔드에서 상태 파일을 자동으로 로드합니다. apply 명령을 실행한 후에는 상태 파일을 백엔드에 자동 저장합니다.

2. apply 명령을 실행 시 자동으로 잠금을 활성화합니다. -lock-timeout=<TIME>을 사용하면 apply 명령을 실행할 때 잠금이 해제되기까지 테라폼이 얼마 동안 대기하도록 할지 설정합니다.

3. 데이터를 보내거나 상태 파일을 저장할 때 암호화하는 기능을 지원합니다.

 

ex) GCP 스토리지 생성 리소스

provider "google" {
  credentials = file("key2.json")
  project = "terraform-348208"
  region = "asia-northeast3"
}

resource "random_id" "instance_id" {
  byte_length = 8
}

resource "google_storage_bucket" "terraform_state" {

  # 버킷 이름
  name = "terraform-up-and-running-state-${random_id.instance_id.hex}"

  # 버킷을 삭제할 때 해당 버킷에 포함된 모든 객체를 삭제합니다.
  force_destroy = true

  location = "ASIA"

  storage_class = "Standard"

  # 실수로 S3 버킷을 삭제하는 것을 방지합니다.(생명주기 설정)
  lifecycle {
    prevent_destroy = true
  }

  # 코드 이력을 관리하기 위해 상태 파일의 버전 관리를 활성화합니다.
  versioning {
    enabled = false
  }

  // GCP는 스토리지 디폴트가 암호화

}

terraform {
  backend "gcs" {
    bucket = "terraform-up-and-running-state-0d9027ef04cb8b9b"
    credentials = "key2.json"
  }
}

 

테라폼으로 구글 클라우드 스토리지 버킷을 생성하고 백엔드를 구성하는 코드입니다.

먼저 스토리지를 생성 후 backend를 적용해야 합니다.

AWS의 경우 버킷과 다이나모DB를 사용하여 Lock을 걸지만, GCP 경우 스토리지만으로 Lock을 걸 수 있는 듯 합니다.

 

ex) AWS S3 생성 리소스

provider "aws" {
  region = "us-east-2"
}

resource "aws_s3_bucket" "terraform_state" {

  bucket = var.bucket_name

  // This is only here so we can destroy the bucket as part of automated tests. You should not copy this for production
  // usage
  force_destroy = true

  # 상태 파일의 이력관리를 위해
  # 버전관리 기능을 활성화 합니다.
  versioning {
    enabled = true
  }

  # Enable server-side encryption by default
  server_side_encryption_configuration {
    rule {
      apply_server_side_encryption_by_default {
        sse_algorithm = "AES256"
      }
    }
  }
}

resource "aws_dynamodb_table" "terraform_locks" {
  name         = var.table_name
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}

 

 

GCP 스토리지 백엔드 참조
https://www.terraform.io/language/settings/backends/gcs
 

Backend Type: gcs | Terraform by HashiCorp

Terraform can store the state remotely, making it easier to version and work with in a team.

www.terraform.io

 

AWS S3 백엔드 참조
https://www.terraform.io/language/settings/backends/s3
 

Backend Type: s3 | Terraform by HashiCorp

Terraform can store state remotely in S3 and lock that state with DynamoDB.

www.terraform.io

 

 

▶ 상태 파일 공유

테라폼 백엔드에는 몇 가지 단점이 있습니다.

 

1. 2단계로 백엔드를 구성해야 합니다.

 

- 백엔드 구성 시

  • 테라폼 코드를 작성하여 S3 버킷 및 다이나모DB 테이블을 생성하고 해당 코드를 로컬 백엔드와 함께 배포해야합니다.
  • 테라폼 코드로 돌아가서 원격 백엔드 구성을 추가합니다. 새로 생성된 S3 버킷과 다이나모 DB 테이블을 사용하고, init 명령을 실행하여 로컬 상태를 S3에 복사합니다.

 

- 백엔드 삭제 시

  • 백엔드 구성을 제거한 다음 init 명령을 실행하여 테라폼 상태를 로컬 디스크에 다시 복사합니다.
  • destroy 명령을 실행하여 S3 버킷 및 다이나모DB 테이블을 삭제합니다.

 

2. 테라폼의 백엔드 블록에서는 변수나 참조를 사용할 수 없다는 점입니다.

해당 단점의 유일한 해결책은 init 명령어 실행 시 -backend-config 옵션을 통해 변수를 전달하는 것 입니다.(2019년 5월 기준)

 

# backend.hcl

bucket = "terraform-running-state"
region = "us-east-2"
dynamodb_table = "terraform-running-locks"
encrypt = true

$ terraform init -backend-config=backend.hcl

 

위와 같은 hcl 코드를 작성한 뒤 terraform init -backend-config=backend.hcl 명령어를 실행할 수 있습니다. 이 외의 방법으로는 단점을 보완해주는 오픈 소스 도구인 테라그런트(Terragrunt)를 사용하는 것입니다.

 

백엔드 구성 참조
https://www.terraform.io/language/settings/backends/configuration
 

Backend Configuration - Configuration Language | Terraform by HashiCorp

Terraform is an open-source infrastructure as code software tool that enables you to safely and predictably create, change, and improve infrastructure.

www.terraform.io

 

더보기

※ 테라그런트란?

테라폼에서 필연적으로 발생하는 중복 코드를 줄여주는 툴.

테라그런트의 명령어는 내부적으로 테라폼 명령어로 변환되어 실행되며, 모든 테라폼의 명령어를 사용할 수 있습니다.

 

 

 

참조 : https://book.naver.com/bookdb/book_detail.naver?bid=20489970
 

테라폼 업앤러닝

이 책은 예제 소개를 뛰어넘어 실제 환경에서 테라폼을 사용하는 방법에 중점을 두고 만들어졌다. 외국어에 능통해지려면 원어민과 대화하고, 외국어 TV 쇼를 보고, 외국 음악을 듣는데 시간을

book.naver.com

 

반응형

관련글 더보기

댓글 영역