5장 State

김진원·2023년 7월 28일

IaC

목록 보기
7/10

"테라폼으로 시작하는 IaC"책을 기준으로 4주차 정리 내용입니다.


프로비저닝 결과에 따른 State를 저장하고 모든 내용을 저장된 상태로 추적한다. State에는 작업자가 정의한 코드와 실제 반영된 프로비저닝 결과를 저장하고, 이 정보를 토대로 이후의 리소스 생성, 수정, 삭제에 대한 동작 판단 작업을 수행한다.


# 5.1 State의 목적과 의미

State로 대상 환경에 어떤 리소스가 테라폼으로 관리되는 리소스인지 판별하고 결과를 기록한다.

  • State 역할
  • State에는 테라폼 구성과 실제를 동기화하고 각 리소스에 고유한 아이디(리소스 주소)로 맴핑
  • 리소스 종속성과 같은 메타데이터를 저장하고 추적
  • 테라폼 구성으로 프로비저닝된 결과를 캐싱하는 역할을 수행

# random 프로바이더 & State 내용

resource "random_password" "mypass" {
  length           = 16
  special          = true
  override_special = "!#$%"
}

{
  "version": 4,
  "terraform_version": "1.5.2",
  "serial": 1,
  "lineage": "447822de-cfd3-2d4d-32d4-21ee99a1b2d9",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "random_password",
      "name": "mypw",
      "provider": "provider[\"registry.terraform.io/hashicorp/random\"]",
      "instances": [
        {
          "schema_version": 3,
          "attributes": {
            "bcrypt_hash": "$2a$10$84ketJYqHYqzGOKJN/709OzIrYzuHY8CawDxHq.EFMlh7p/yujifC",
            "id": "none",
            "keepers": null,
            "length": 16,
            "lower": true,
            "min_lower": 0,
            "min_numeric": 0,
            "min_special": 0,
            "min_upper": 0,
            "number": true,
            "numeric": true,
            "override_special": "!#$%",
            "result": "3wG9oUMHdeDAZDPS",
            "special": true,
            "upper": true
          },
          "sensitive_attributes": []
        }
      ]
    }
  ],
  "check_results": null
}

JSON 형태로 작성된 State를 통해 속성과 인수를 확인할 수 있다.

!!!password도 console로 볼 수 있을까?

다행히 sensitive value로 보이지 않는다.


# 5.2 State 동기화

테라폼 구성 파일은 기존 State와 구성을 비교해 실행 계획에서 생성, 수정, 삭제 여부를 결정한다.

https://kschoi728.tistory.com/135 출처

  • 테라폼 구성과 State 흐름 : Plan 과 Apply 중 각 리소스에 발생할 수 있는 네 가지 사항, 아래는 실행 계획 출력 기호와 의미
    기호의미
    +Create
    -Destroy
    -/+Replace
    ~Updated in-place

# 테라폼 구성에 추가된 리소스와 State에 따라 어떤 동작이 발생하는지 표와 유형 별 실습으로 확인하자

유형구성 리소스 정의State 구성 데이터실제 리소스기본 예상 동작
1있음리소스 생성
2있음있음리소스 생성
3있음있음있음동작 없음
4있음있음리소스 삭제
5있음동작 없음


#유형1

신규 리소스 정의로 Apply로 리소스 생성

locals {
  name = "mytest"
}

resource "aws_iam_user" "myiamuser1" {
  name = "${local.name}1"
}

resource "aws_iam_user" "myiamuser2" {
  name = "${local.name}2"
}


mytest1, mytest2 ID가 추가된 것을 확인할 수 있다.



#유형2

실제 리소스를 수동으로 제거하고 Apply를 진행하여 리소스 생성

# 실제 리소스 수동 제거
aws iam delete-user --user-name mytest1
aws iam delete-user --user-name mytest2
aws iam list-users | jq

수동으로 삭제!!

# 아래 명령어 실행 결과 차이는?
terraform plan
terraform plan -refresh=false



plan은 Real을 참조하여 생성하는 계획이 있지만, refresh=false는 실재하는 리소스를 확인하지 않고 State만 확인하기에 변화가 없다.



#유형3

Apply를 두 번을 진행, 코드/State/형상이 모두 일치한 경우

terraform apply -auto-approve
cat terraform.tfstate | jq .serial
terraform apply -auto-approve
cat terraform.tfstate | jq .serial


두 번째는 No changes로 출력된다.



#유형4

코드에서 일부 리소스 삭제 후 Apply

# 리소스 하나 삭제
locals {
  name = "mytest"
}

resource "aws_iam_user" "myiamuser1" {
  name = "${local.name}1"
}



serial은 증가하고, 2개의 instance(EC2 instance 아니고, terraform에서 구별하는 instance)는 한 개로 되었습니다.



#유형5

이미 만들어진 리소스만 있다면 테라폼의 State에 없는 내용으로 관리되지 않아 아무 작업도 수행할 수 없다.

  • 처음부터 테라폼으로 관리되지 않는 리소시인 경우
  • 테라폼으로 생성하고 구성과 State가 삭제된 경우

위의 두 가지로 정의할 수 있습니다.



#유형6 (추가!!)

실수로 tfstate 파일을 삭제한 경우에 plan/apply

# 실수로 tfstate 파일 삭제
rm -rf terraform.tfstate*

#
terraform plan
terraform plan -refresh=false

#
terraform apply -auto-approve
terraform state list
cat terraform.tfstate | jq


plan이 참조하는 State 파일이 없으므로 생성하지만, apply에서 실제로 생성하게되면 존재하기에 에러가 발생한다.

복구 방법은 !! Import !!로 해결한다.


# 5.3 워크스페이스

!! 상태 파일 격리 소개 State File Isolation

  • 테라폼 상태를 격리하지 않았을 때 발생하는 일
  • 환경을 격리하는 방법
  1. 작업 공간을 통한 격리 Isolation via workspaces
    • 동일한 구성에서 빠르고 격리된 테스트 환경에 유용
  2. 파일 레이아웃을 이용한 격리 Isolation via file layout
    • 보다 강력하게 분리해야 하는 운영 환경에 적합
    • 테라폼 프로젝트의 파일 레이아웃 설명
      • 각 테라폼 구성 파일을 분리된 폴더에 넣기. (예. stage , prod)
      • 각 환경에 서로 다른 백엔드 구성. (예. S3 버킷 백엔드의 AWS 계정을 분리)

State를 관리하는 논리적인 가상 공간을 워크스페이스라고 한다.

https://kschoi728.tistory.com/136 출처

  • 연습 ec2 코드
resource "aws_instance" "mysrv1" {
  ami           = "ami-0ea4d4b8dc1e46212"
  instance_type = "t2.micro"
  tags = {
    Name = "t101-week4"
  }
}

  • 신규 워크스페이스 생성 및 확인
# 새 작업 공간 workspace 생성 : mywork1
terraform workspace new mywork1
terraform workspace show

# 서브 디렉터리 확인
tree terraform.tfstate.d
terraform.tfstate.d
└── mywork1

# plan 시 어떤 결과 내용이 출력되나요?
terraform plan

# apply 해보자!
terraform apply -auto-approve

# 워크스페이스 확인
terraform workspace list

기본 워크스페이스는 default로 지정되어 있지만, 새로운 워크스페이스를 만드면 다른 State 파일을 참조하므로 새로운 Instance가 만들어진다!


1. 장점

  • 하나의 루트 모듈에서 다른 환경을 위한 리소스를 동일한 테라폼 구성으로 프로비저닝하고 관리
  • 기존 프로비저닝된 환경에 영향을 주지 않고 변경 사항 실험 가능
  • 깃의 브랜치 전략처럼 동일한 구성에서 서로 다른 리소스 결과 관리

2. 단점

  • State가 동일한 저장소(로컬 또는 백엔드)에 저장되어 State 접근 권한 관리가 불가능
  • 모든 환경이 동일한 리소스를 요구하지 않을 수 있으므로 테라폼 구성에 분기 처리가 다수 발생 가능
  • 프로비저닝 대상에 대한 인증 요소를 완벽히 분리하기 어려움 → 가장 큰 단점은 완벽한 격리가 불가능 ⇒ 해결하기 위해 루트 모듈을 별도로 구성하는 디렉터리 기반의 레이아웃을 사용할 수 있다 or Terraform Cloud 환경의 워크스페이스를 활용

2개의 댓글

comment-user-thumbnail
2023년 7월 28일

좋은 글 감사합니다. 자주 올게요 :)

1개의 답글