새소식

IaC/Terraform

2주차(3)_terraform.tfstate 란 무엇인가??

  • -
CloudNet@ 팀의 가시다님께서 Leading 하시는 Terraform T101 Study 내용 요약

 

해당 Terraform Study 는 Terraform Up and Running 책을 기반으로 진행 중입니다.

 

 

이번에는 terraform 에서 가장 중요한 부분 중 하나인 tfstate 파일에 대해서 알아보자 !



1. tfstate 파일이란??


Terraform 명령어를 통해 생성된 인프라 리소스에 대한 정보를 기록한 파일
  • 테라폼은 어떻게 리소스를 관리할까??
  • 어떤 리소스가 테라폼으로 만든 건지 어떻게 알지??

 

그에 대한 답은 바로 tfstate 파일 속에 있다.

 


우리가 "terraform apply" 명령어를 수행할 때,
테라폼은 기본적으로 명령어를 수행한 디렉토리에 terraform.tfstate 파일을 생성한다.

 

해당 파일 속에는 테라폼이 만들어낸 인프라 리소스 정보가 JSON 형태로 기록되어 있다.

 

백문이 불여일견 !
한번 직접 보도록 하자 !

 

 

1.1. tfstate 파일 생성

이전 게시글에서 작성했던 vpc.tf를 배포해보자

/// vpc.tf

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

resource "aws_vpc" "scott_vpc" {
  cidr_block       = "10.10.0.0/16"
  enable_dns_support   = true
  enable_dns_hostnames = true

  tags = {
    Name = "terraform-study"
  }
}

resource "aws_subnet" "scott_subnet_01" {
  vpc_id     = aws_vpc.scott_vpc.id
  cidr_block = "10.10.1.0/24"

  availability_zone = "ap-northeast-2a"
  map_public_ip_on_launch = true

  tags = {
    Name = "terraform-subnet-01"
  }
}

resource "aws_subnet" "scott_subnet_02" {
  vpc_id     = aws_vpc.scott_vpc.id
  cidr_block = "10.10.2.0/24"

  availability_zone = "ap-northeast-2c"
  map_public_ip_on_launch = true

  tags = {
    Name = "terraform-subnet-02"
  }
}


resource "aws_internet_gateway" "scott_igw" {
  vpc_id = aws_vpc.scott_vpc.id

  tags = {
    Name = "terraform-igw"
  }
}

resource "aws_route_table" "scott_rt" {
  vpc_id = aws_vpc.scott_vpc.id

  tags = {
    Name = "terraform-rt"
  }
}

resource "aws_route_table_association" "scott_rt_association_01" {
  subnet_id      = aws_subnet.scott_subnet_01.id
  route_table_id = aws_route_table.scott_rt.id
}

resource "aws_route_table_association" "scott_rt_association_02" {
  subnet_id      = aws_subnet.scott_subnet_02.id
  route_table_id = aws_route_table.scott_rt.id
}

resource "aws_route" "scott_default_route" {
  route_table_id         = aws_route_table.scott_rt.id
  destination_cidr_block = "0.0.0.0/0"
  gateway_id             = aws_internet_gateway.scott_igw.id
}

 

1.2. tfstate 파일 확인

  • 너무 길어서 중간은 생략했다.
{
  "version": 4,
  "terraform_version": "1.3.2",
  "serial": 9,
  "lineage": "02d98e55-ac7f-08da-c26a-2fd0d7e10df1",
  "outputs": {},
  "resources": [
    {
      "mode": "managed",
      "type": "aws_internet_gateway",
      "name": "scott_igw",
      "provider": "provider[\"registry.terraform.io/hashicorp/aws\"]",
      "instances": [
        {
          "schema_version": 0,
          "attributes": {
            "arn": "arn:aws:ec2:ap-northeast-2:{accountID}:internet-gateway/igw-0ce44b2abff1b04b0",
            "id": "igw-0ce44b2abff1b04b0",
            "owner_id": "{accountID}",
            "tags": {
              "Name": "terraform-igw"
            },
            "tags_all": {
              "Name": "terraform-igw"
            },
            "timeouts": null,
            "vpc_id": "vpc-0a1fd1ccf2b991695"
          },
        }
      ]
    }
  ]
}

 

위 파일을 보면 vpc.tf 파일로 생성한 리소스 정보가 그대로 들어가 있는 것을 확인할 수 있다.

 

테라폼에서는 plan 명령어를 입력할 때마다 tfstate 파일의 정보와 plan으로 입력된 정보를 비교하여 변동사항을 감지하게 된다.

 

 

tfstate 파일은 terraform 내부에서만 사용하는 Private API 이기 때문에, 사용자가 직접 수정을 가해서는 절대 안된다.


만약 해당 파일을 변경해야되는 상황이 있으면 terraform import 혹은 terraform state 명령을 이용해서 변경해야 한다.

해당 명령어는 이후에 다뤄보도록 하자 !

 

 

1.3. tfstate 파일 원격 저장

기본적으로 tfstate 파일은 테라폼 명령어를 수행한 Local 위치에 저장된다.
테라폼을 혼자 사용하는 경우라면 문제 없지만, 팀 단위로 사용할 때는 리소스 상태를 공유하지 못한다는 문제가 발생한다.

 

 

이 문제를 해결하기 위해 테라폼에서는 tfstate 파일을 원격에 저장하는 backend 기능이 존재한다.
보통 AWS에서 작업할 때는 이 backend 기능을 S3 를 활용해서 해결하게 된다.

 

 

backend 를 사용하여 원격 저장을 하면 리소스 상태가 공유되는 문제는 해결되지만 또 다른 문제에 직면하게 되는데,
바로 2명 이상이 동시에 테라폼 명령어를 수행할 경우이다.

 

그럴 경우, 데이터가 서로 충돌하게 되어 손실되거나 상태파일이 손상될 가능성이 존재한다.

 

이를 해결하기 위해 tfstate 파일 잠금 기능이 필요하게 된다.
보통 AWS 에서 작업할 때는 이 잠금 기능을 DynamoDB 를 통해 해결하게 된다.

 

 

1.4. tfstate 파일 격리

tfstate 파일을 격리한다는 것은 테라폼으로 구성되는 환경을 격리하는 것과 동일하다.

실제로는 Dev, Prod, Stg, QA 등 여러 환경이 존재하게 되는데 tfstate 파일을 격리하지 않고 한 곳에서 모두 관리하게 된다면, 한 곳의 실수가 다른 곳에 영향을 미칠 가능성도 존재한다.

 

이를 방지하기 위해 각 환경을 별도의 구성 파일로 정의하고 격리하는 것을 권장하고 있다.

 

 

테라폼에서는 2가지 격리 방법이 있다.

 

1. Workspace
  • 동일한 구성에서 빠르고 격리된 테스트 환경에 유용

테라폼은 기본적으로 default 라는 작업 공간에서 시작하고 따로 공간을 지정하지 않으면 default 를 사용한다.
쿠버네티스의 Namespace 와 유사한 기능이라고 생각하면 이해하기 쉽다.

 

workspace 를 유용하게 사용하기 위해 3항 연산자를 사용하는 것을 추천한다.

 

다음은 테라폼 명령어를 실행하는 workspace 가 default 일 경우 t2.micro 인스턴스 타입으로 ec2를 배포하고,
workspace 가 default 가 아닐 경우에는 t3.medium 인스턴스 타입으로 ec2를 배포하는 예시이다.


resource "aws_instance" "ubuntu" {
  ami                    = "ami-0e9bfdb247cc8de84"
  instance_type          = terraform.workspace -- "default" ? "t2.micro" : "t3.medium"
}

 

 

2. File Layout
  • 보다 강력하게 분리해야 하는 운영 환경에 적합

해당 격리 방안은 각 테라폼 구성 파일을 분리된 폴더에 넣어 관리하는 방법이다.

 

예를 들어 stage 환경에 관한 구성 파일은 모두 stage 폴더에 넣고,
production 환경에 관한 구성 파일은 모두 production 폴더에 넣어 관리하는 식이다.

 

해당 격리 방안은 Workspace 와는 다르게 환경 별로 다른 backend 를 구성할 수 있다는 아주 큰 강점이 있다.

 

1.5. terraform_remote_state

  • 만약 tfstate 파일을 원격 저장하거나 격리했을 경우,
    현재 작성하고 있는 테라폼 코드에서 해당 tfstate 파일에 들어가있는 정보가 필요하다면 어떻게 해야될까??

 

이를 해결하기 위한 것이 바로 "terraform_remote_state" 데이터 소스이다.


예를 들어 vpc 코드는 이미 배포되어 s3 저장소에 보관되고 있고, 현재 나는 ec2 코드를 작성 중이라고 하자.

ec2 배포에 필요한 vpc 정보가 필요한데, 이 때 "terraform_remote_state" 데이터 소스를 사용하여

원격에 저장된 vpc 정보를 불러와서 사용할 수 있다.

 

 


 

지금까지 테라폼 tfstate 파일에 대해서 이론적인 부분을 알아보았다.
다음 게시글에서는 실제 tfstate 파일을 격리, 잠금하고 상태 정보를 로컬로 불러오는 것을 실제로 해보자 !

Contents

포스팅 주소를 복사했습니다