Post

Terraform Backend(Remote State)

Terraform Backend

Backend

์›๊ฒฉ์œผ๋กœ State ํŒŒ์ผ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด์„ , Backend Block์ด ํ•„์š”ํ•˜๋‹ค. Terraform Backend Block๋งŒ ๊ตฌ์„ฑํ•˜๊ณ , ์„ธ๋ถ€์ ์ธ ๋‚ด์šฉ์„ ์„ค์ •ํ•˜์ง€ ์•Š์œผ๋ฉด Terraform์€ ์ž๋™์œผ๋กœ Local Backend๋กœ ์„ค์ •ํ•œ๋‹ค. ์•„๋ž˜์™€ ๊ฐ™์ด ์›๊ฒฉ์œผ๋กœ ์ƒํƒœํŒŒ์ผ์„ ๊ด€๋ฆฌํ•˜๋ฉด, state locking ๊ธฐ๋Šฅ๋•๋ถ„์— ํ˜‘์—…ํ•  ๋•Œ ์•ˆ์ „ํ•œ ์ž‘์—…์ด ๊ฐ€๋Šฅํ•˜๋ฉฐ ๋ฏผ๊ฐํ•œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ์•”ํ˜ธํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ ๋„ ํ•œ๋‹ค.

์ง€์›๋ชฉ๋ก์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

  • local
  • remote : Terraform Cloud
  • azurerm
  • consul
  • cos
  • gcs
  • http
  • Kubernetes
  • oss
  • pg
  • s3

Remote State

๋งŒ์•ฝ, ํŒ€๊ฐ„์˜ ํ˜‘์—…์ด ํ•„์š”ํ•  ๋•Œ state ํŒŒ์ผ์„ ๋กœ์ปฌ์— ์ €์žฅํ•˜๋ฉด ๋‹ค๋ฅธ ํŒ€์›๋“ค์€ ์•Œ๋งž์€ ์ƒํƒœ๋ฅผ ๊ณต์œ ๋ฐ›์ง€ ๋ชปํ•˜๊ธฐ์— ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋ฅผ ๊ณต์œ ํ•ด์•ผ ํ•˜๋ฉฐ, ๋งŒ์•ฝ ๋™์‹œ์— ์ž‘์—…ํ•  ๊ฒฝ์šฐ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•œ๋‹ค.

ํŒ€ ๋‹จ์œ„๋กœ ์ž‘์—…ํ•  ๋•Œ๋Š” ํŒ€์›๋“ค์ด ๋ฐฐํฌ ์ƒํƒœ๋ฅผ ์•Œ๊ณ , ๋ˆ„๊ฐ€ ๋จผ์ € ์ ์šฉํ•  ์ง€ ์ˆœ์„œ๋„ ์•Œ์•„์•ผ ํ•œ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด ์„œ๋กœ๊ฐ€ ์„œ๋กœ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๋ฎ์–ด์“ฐ๊ฒŒ ๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์›๊ฒฉ์œผ๋กœ ์ €์žฅ์„ ํ•œ๋‹ค๋ฉด ํŒŒ์ดํ”„๋ผ์ธ์— ์˜ํ•ด ์ž๋™์œผ๋กœ ์ตœ์‹  ์ƒํƒœ(state:latest)๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ๋‹ค.

  • ์•„๋ž˜์˜ ์˜ˆ์‹œ๋Š” S3 ๋ฒ„ํ‚ท์„ ํ†ตํ•ด state๋ฅผ ์›๊ฒฉ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ชจ์Šต์ด๋‹ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "4.24.0"
    }
  }
  backend "s3" {
    bucket         = "env0-acme-tfstate"
    dynamodb_table = "env0-acme-tfstate-lock"
    key            = "acme-demo-s3"
    region         = "us-west-2"
    role_arn       = "arn:aws:iam::..." 
    # external_id    = "value" 
  }
}
provider "aws" {
  region = "us-west-2"
}

State locking

์›๊ฒฉ ๋ฐฑ์—”๋“œ์˜ ๊ฒฝ์šฐ ์ƒํƒœ ์žฅ๊ธˆ์„ ์‚ฌ์šฉํ•ด ๋™์ผํ•œ ์ƒํƒœ์— ๋Œ€ํ•ด Terraform์ด ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค.

OS์—์„œ ๋™๊ธฐํ™”๋ฅผ ๋ฐฐ์› ์„ ๋•Œ์™€ ๊ฐ™์ด locking์„ ํ†ตํ•ด terraform์€ ์ž‘์—…์„ ํ์— ๋Œ€๊ธฐ์‹œ์ผœ, ๋™์‹œ์ž‘์—…์„ ๋ฐฉ์ง€ํ•œ๋‹ค. ๋ฐฉ๋ฒ•์€ ์•„๋ž˜์™€ ๊ฐ™๋‹ค.

๋จผ์ € DynamoDB์— ํ…Œ์ด๋ธ”์„ ๋งŒ๋“ ๋‹ค. ์ด ํ…Œ์ด๋ธ”์€ tfstate๋ฅผ S3์— ๊ด€๋ฆฌํ•˜๋ฉด์„œ ๋™์‹œ์— ์ž‘์—…์ด ์ผ์–ด๋‚˜์ง€ ์•Š๋„๋ก ํ•˜๋Š” Lock ํ…Œ์ด๋ธ”์ด๋‹ค. Lock ํ…Œ์ด๋ธ”์€ ์„ ํƒ์‚ฌํ•ญ์ด๋‚˜ Lock ํ…Œ์ด๋ธ”์ด ์žˆ๋‹ค๋ฉดย plan์ด๋‚˜ย apply๋ฅผ ํ•  ๋•Œ ๋จผ์ € ์ž ๊ทธ๊ณ  ์ž‘์—…์ด ๋๋‚˜๋ฉด ์ž ๊ธˆ์„ ํ•ด์ œํ•˜๊ฒŒ ๋œ๋‹ค.

  • terrafrom state ํŒŒ์ผ ๊ด€๋ฆฌ + Lock ํ…Œ์ด๋ธ”์šฉ Dynamodb ๋ฆฌ์†Œ์Šค
1
2
3
4
5
6
7
8
9
10
11
resource "aws_dynamodb_table" "terraform_state_lock" {
  name = "TerraformStateLock"
  read_capacity = 5
  write_capacity = 5
  hash_key = "LockID"

  attribute {
    name = "LockID"
    type = "S"
  }
}
  • Terraform ์„ค์ •
1
2
3
4
5
6
7
8
9
10
11
terraform {
  required_version = ">= 0.9.5"
  backend "s3" {
    bucket = "kr.ne.outsider.terraform.state"
    key = "test/terraform.tfstate"
    region = "ap-northeast-1"
    encrypt = true
    lock_table = "TerraformStateLock"
    acl = "bucket-owner-full-control"
  }
}

์ด๋Ÿฌ๊ณ  ๋งŒ์•ฝ plan ์ด๋‚˜, apply๋ฅผ ์ ์šฉํ•œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด Lock์„ ๊ด€๋ฆฌํ•œ๋‹ค.

1
2
3
4
$ terraform plan
...

Releasing state lock. This may take a few moments...

์‹ค์Šต

์•„๋ž˜ ์‹ค์Šต์€ T101์—์„œ ์ง„ํ–‰ํ•œ ์ฝ”๋“œ์ด๋‹ค. S3 + dynamodb_table์„ ์ด์šฉํ•œ๋‹ค. lock ๊ตฌํ˜„ ๋ฐ ํ™•์ธํ•˜๋Š” ์ฝ”๋“œ์ด๋‹ค. ๋™์‹œ์— ์ž‘์—…ํ•˜๋ฉด locking state ์—๋Ÿฌ ๋ฉ”์‹œ์ง€ ๋ฐœ์ƒํ•ด์•ผํ•˜์ง€๋งŒ, ์ƒ๊ฐ๋ณด๋‹ค ์ฝ”๋“œ๊ฐ€ ๋นจ๋ฆฌ ์‹คํ–‰๋˜์–ด ์—ฌ๊ธฐ์„œ๋Š” lock state ๋ฉ”์„ธ์ง€๋ฅผ ๋ณด๊ธฐ ํž˜๋“ค๋‹ค. ๊ธฐ์—…์ด๋‚˜ ํฐ ํ”„๋กœ์ ํŠธ์˜ ์ธํ”„๋ผ์ธ ๊ฒฝ์šฐ ์œ ์šฉํ•˜๊ฒŒ ์“ฐ์ผ ๋“ฏํ•˜๋‹ค.

AWS S3/DynamoDB ๋ฐฑ์—”๋“œ

์•„๋ž˜๋Š” ๊ด€๋ จ ์ฝ”๋“œ์ด๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
provider "aws" {
  profile = "eks"
  region  = "ap-northeast-2"
}

resource "aws_s3_bucket" "mys3bucket" {
  bucket = "kane-t101study-tfstate"
}

# Enable versioning so you can see the full revision history of your state files
resource "aws_s3_bucket_versioning" "mys3bucket_versioning" {
  bucket = aws_s3_bucket.mys3bucket.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_dynamodb_table" "mydynamodbtable" {
  name         = "terraform-locks"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "LockID"

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

output "s3_bucket_arn" {
  value       = aws_s3_bucket.mys3bucket.arn
  description = "The ARN of the S3 bucket"
}

output "dynamodb_table_name" {
  value       = aws_dynamodb_table.mydynamodbtable.name
  description = "The name of the DynamoDB table"
}

EC2๋ฅผ ๋ฐฐํฌํ•˜๋Š” ์ฝ”๋“œ์— ์•„๋ž˜์™€ ๊ฐ™์€ ์›๊ฒฉ backend๋ฅผ ์„ค์ •ํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
terraform {
  backend "s3" {
    bucket = "kane-t101study-tfstate"
    key    = "dev/terraform.tfstate"
    region = "ap-northeast-2"
    dynamodb_table = "terraform-locks"
    # encrypt        = true
  }
}

๋ฐฐํฌํ•œ ํ›„, AWS ์ฝ˜์†”์— ์ ‘์†ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด table์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Untitled.png

์ด์ œ, s3๋ฅผ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋ฉฐ Terraform์„ ๋ฐฐํฌํ•˜์—ฌ state ํŒŒ์ผ์ด ์ •์ƒ์ ์œผ๋กœ ๋ณ€๊ฒฝ๋˜๋Š” ์ง€ ํ™•์ธํ•œ๋‹ค.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
while true; do aws s3 ls s3://$NICKNAME-t101study-tfstate --recursive --human-readable --summarize ; echo "------------------------------"; date; sleep 1; done

Total Objects: 0
   Total Size: 0 Bytes
------------------------------
Mon Aug 28 00:50:18 KST 2023

Total Objects: 0
   Total Size: 0 Bytes
------------------------------
...
# ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ
------------------------------
Mon Aug 28 00:53:16 KST 2023
2023-08-28 00:50:56   21.1 KiB dev/terraform.tfstate

Total Objects: 1
   Total Size: 21.1 KiB
------------------------------
Mon Aug 28 00:53:17 KST 2023
2023-08-28 00:53:18   22.4 KiB dev/terraform.tfstate
------------------------------
...
# ๋ฆฌ์†Œ์Šค ์—…๋ฐ์ดํŠธ
------------------------------
Total Objects: 1
   Total Size: 22.4 KiB
------------------------------
# ๋ฆฌ์†Œ์Šค ์‚ญ์ œ
...
------------------------------
Mon Aug 28 00:56:04 KST 2023
2023-08-28 00:56:03  180 Bytes dev/terraform.tfstate

Total Objects: 1
   Total Size: 180 Bytes
------------------------------
Mon Aug 28 00:56:05 KST 2023

์•„๋ž˜์™€ ๊ฐ™์ด ์ฝ˜์†”์—์„œ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ƒ์„ฑ ์ˆœ์„œ๋Š” ์•„๋ž˜์—์„œ๋ถ€ํ„ฐ ์œ„ ๋ฐฉํ–ฅ์ด๋‹ค.

Untitled.png

This post is licensed under CC BY 4.0 by the author.