본문 바로가기

IaC/terraform

[terraform] terraform에서 consul 사용하기 / local statefile consul로 migration하기

consul 이란?

공식문서에서는 consul을 다음과 같이 얘기하고 있다. 

Consul은 완전한 기능을 갖춘 서비스 메시 솔루션을 제공하는 다중 네트워킹 도구입니다. 
멀티클라우드 및 하이브리드 클라우드 환경에서 마이크로서비스 및 클라우드 인프라 운영의 네트워킹 및 보안 문제를 해결합니다. 

하지만 이번 포스팅에서는 서비스 메시로서의 consul 역할 보다는 terraform 에서 remote state file 이 저장될 수 있는 backend type중의 하나로 이용해보려고 한다. consul의 key value store에 값을 저장하는 방법과 consul의 KV store(Key Value), ACL system에 대해 알아볼 것이다.

consul 설치하기

https://www.consul.io/downloads 홈페이지에서 OS에 맞는 바이너리 파일을 설치할 수 있다.

나는 맥유저니까 맥 설치만 적어두겠다.

brew tap hashicorp/tap
brew install hashicorp/tap/consul

terraform backend type으로 consul 적용해보기

config.hcl 작성

consul 서버의 설정값을 작성한다.

## server.hcl

ui = true
server = true
bootstrap_expect = 1
datacenter = "dc1"
data_dir = "./data"

acl = {
    enabled = true
    default_policy = "deny"
    enable_token_persistence = true
}

ui를 활성화 함으로써 consul에서 진행되는 작업을 확인할 수 있다.

bootstrap_expect의 값을 1로 설정함으로써 consul 클러스터에 뜨는 노드 갯수를 설정할 수 있다.(노드 하나만 띄움)

키/값 데이터 및 기타 데이터들이 저장되는 데이터 디렉토리는 ./data 이다.

마지막으로 접근통제를 컨트롤 할 수 있는 acl을 설정한다. (원래 되어있지 않다 추가할 경우 consul을 재시작 해주어야 한다.)

기본적으로 deny를 설정해두었기 때문에 명시적으로 허용하지 않는 이상 접근이 거부된다. 

그리고 토큰 지속성의 값을 true로 함으로써 토큰을 디스크에 유지하고 agent가 재시작 되는 경우 다시 가져온다.

consul 서버 생성 및 로컬 주소 바인딩

consul agent -bootstrap -config-file="config/consul-config.hcl" -bind="127.0.0.1"

위에 작성한 config.hcl 파일을 config/consul-config.hcl 에 저장하고 로컬 주소(127.0.0.1)로 바인딩한다.

토큰 생성 / 환경변수 등록

acl을 설정하였기 때문에 consul에 접근하기 위해 토큰을 가져온다.

# 토큰 생성
consul acl bootstrap

결괏값에서 secret ID를 이용하여 consul_http_token 환경변수를 설정한다. 이렇게 하면 consul 명령어를 사용할 때마다 이 환경변수를 확인하게 된다. (루트 시크릿 토큰)

export CONSUL_HTTP_TOKEN=016d284a-6db6-e76d-8cbf-8c7a3f8957b3

consul resource 이용

consul provider 생성

provider "consul" {
  address    = "127.0.0.1:8500"
  datacenter = "dc1"
}

consul의 기본 포트는 8500번. datacenter는 위의 config.hcl에서 설정한 값을 입력하면 된다.

consul resource 생성

resource "consul_keys" "networking" {

  key {
    path  = "networking/configuration/"
    value = ""
  }

  key {
    path  = "networking/state/"
    value = ""
  }
}

resource "consul_keys" "applications" {

  key {
    path  = "applications/configuration/"
    value = ""
  }

  key {
    path  = "applications/state/"
    value = ""
  }
}

resource "consul_acl_policy" "networking" {
  name  = "networking"
  rules = <<-RULE
    key_prefix "networking" {
      policy = "write"
    }

    session_prefix "" {
      policy = "write"
    }
    RULE
}

resource "consul_acl_policy" "applications" {
  name  = "applications"
  rules = <<-RULE
    key_prefix "applications" {
      policy = "write"
    }

    key_prefix "networking/state" {
      policy = "read"
    }

    session_prefix "" {
      policy = "write"
    }

    RULE
}

resource "consul_acl_token" "mary" {
  description = "token for Mary Moe"
  policies    = [consul_acl_policy.networking.name]
}

resource "consul_acl_token" "sally" {
  description = "token for Sally Sue"
  policies    = [consul_acl_policy.applications.name]
}

이번 실습에서 networking 과 application 두개의 key/value 를 생성한다.

mary는 네트워크 관리자이고 sally는 어플리케이션 관리자로 권한이 다른 각각의 토큰을 발생한다.

mary가 네트워킹(vpc 등) 자원을 생성(쓰기)하면, sally는 mary가 생성한 네트워킹 자원을 참고(읽기)하여 어플리케이션을 생성(쓰기)할 수 있다.

마지막 consul_acl_token 으로 생성된 토큰의 정보를 가지고 있어야 하니 output을 이용하여 토큰값을 확인한다.

output "mary_token_accessor_id" {
  value = consul_acl_token.mary.id
}

output "sally_token_accessor_id" {
  value = consul_acl_token.sally.id
}

발행된 consul token을 이용하여 접근자 ID가져오기

consul acl token read -id <Mary's token>
consul acl token read -id <Sally's token>

consul UI 확인

http://127.0.0.1:8500 접속해서 ACCESS CONTROLS > Tokens 들어가서 제일 처음에 생성했던 루트 토큰의 시크릿 ID를 이용하여 로그인한다

테라폼 구성파일에서 생성한 것 처럼 메리/샐리의 토큰, policy, appcliation/networking 의 key/value가 존재하는 것을 확인할 수 있다. (테라폼파일 apply했으면)

하지만 아직 각 key/value에 대한 state들은 비어있다.

이제 로컬에 생성되어 있는 statefile을 consul에 migration 해본다.

statefile이 있는 directory에서 backend.tf 생성

기존에 상태파일이 있던 디렉토리에서 backend.tf를 생성한다.

# backend.tf

## Move this backend file to m3 when migrating state
terraform {
  backend "consul" {
    address = "127.0.0.1:8500"
    scheme  = "http"
  }
}

제일 위에서 설정했던 토큰 환경변수의 값을 mary의 것으로 변경하고 테라폼 구성을 초기화 한다.

-backend-config 옵션을 이용하여 초기화 중에 backend 구성 설정이 포함된 파일을 제공할 수 있다.

export CONSUL_HTTP_TOKEN=<mary's token>
terraform init -backend-config="path=networking/state/globo-primary"

globo-primary는 json이 값으로 저장되는 키이다. (즉 consul에서 networking/state/globo-primary 위치에 statefile이 json 형태로 저장된다.)

init 명령어 후에 새로운 backend로 상태파일을 이동시킬지 물어본다.

주의점! Do you want to copy existing state to the new backend? 라고 물어보면서 cp 가 아닌 mv를 실행한다. (갑자기 로컬에 있는 상태파일이 사라져서 당황했음..😓)

텅... 비어버린 local statefile

짜잔 아까 -backend-config 옵션으로 지정했던 path에 json 형태로 기존 statefile이 저장된다.

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

[terraform] variables and outputs  (0) 2023.03.13
[terraform] terraform associate (002) 합격 후기  (0) 2023.03.01
[terraform]테라폼 시작하기  (0) 2023.02.13