7장 협업

김진원·2023년 8월 11일

IaC

목록 보기
9/10

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

인프라의 규모가 커지고 종류가 다양해질수록 공동 작업자는 작성된 코드를 점검하고 서로의 코드를 학습할 수 있는 협업 환경을 구성한다.
협업을 위한 환경을 구성하는 요소는 다수의 작업자가 유지 보수할 수 있는 VCS와 테라폼 State를 중앙화하는 중앙 저장소가 대표작이다.
출처 - https://kschoi728.tistory.com/139, 협업을 위한 중앙 저장소 고려사항 단계


유형 1: VCS/중앙 저장소 X

  • 동일한 대상을 관리하는 여러 작업자는 동일한 프로비저닝을  위해 각자 자신이 작성한 코드를 수동으로 공유가 필요
  • 작업자의 수가 늘어날수록 코드 동기화는 어려워지고, 각 작업자가 작성한 코드를 병합하기도 어렵다. VCS 도입 시점이다.

유형 2: VCS(SVN, Git), 중앙 저장소 O

  • 형성관리 도구를 통해 여러 작업자가 동일한 테라폼 코드를 공유해 구성 작업
  • 변경 이력 관리 및 이전 버전으로 롤백 가능
  • 공유 파일은 테라폼 구성파일과 State
  • 작업자가 서로 다른 프로비저닝한 State 결과를 공유를 위해서 백엔드(공유 저장소) 설정을 제공

유형 3: VCS(GitHub), 중앙 저장소 O

  • 테라폼 코드 형상관리를 위한 중앙 저장소 + State 백엔드 → 작업자는 개별적으로 프로비저닝을 테스트하고 완성된 코드를 공유
  • State 는 중앙 관리되어, 작업자가 프로비저닝을 수행하면 원격 State의 상태를 확인하고 프로비저닝 수행

# 7.1 형상관리 도구(VCS)

  • SVN : 중앙 저장소에서 코드와 히스토리를 관리하는 방식
  • Git : 분산형 관리 시스템으로 작업 환경에서도 별도로 코드 히스토리를 관리하고 중앙 저장소와 동기화

# 7.1.1 Git

Git은 코드 형상관리를 작업 환경인 로컬 저장소와 리모트 저장소에 저장할 수 있다.

  • 로컬 저장소 : 작업자 로컬 환경에 저장되는 개인 전용 저장소
  • 리모트 저장소 : 코드 형상관리 이력과 코드가 원격지에서 관리되고 여러 사람이 공유하는 저장소

깃 용어 설명

용어표현설명
branch브랜치분기, “main” 또는 “master”의 주 브랜치에서 갈라져 나온 별도의 버전의 작업 공간
chechout체크아웃지정한 브랜치로 전환하는 작업, 파일이 대상 브랜치의 색인과 파일로 업데이트됨
clone복제리모트 저장소로부터 로컬 저장소로 복제
fork포크/분기리모트 저장소로부터 로컬 저장소로 복제하지만 새로운 저장소로 구성
fetch페치리모프 저장소에서 오브젝트를 로컬 저장소로 가져오는 동작
HEAD헤드현재 체크아웃된 브랜치의 최종 변경을 가리키는 이름
add추가작업 중인 공간에서 다음 커밋으로 변경을 기록하기 전까지 변경분을 추적
commit커밋로컬 저장소에 변경 사항을 기록
merge머지/병합깃으로 관리하는 오브젝트의 불일치한 내용을 병합
pull풀/가져오기브랜치의 내용을 리모트 저장소로부터 fetch 한 후 병합
push푸시/저장하기로컬의 수정 내용을 리모트 저장소에 저장
pull requestPR/풀 리퀘스트분기된 브랜치 또는 저장소에서 지정한 저장소의 브랜치로의 병합 요청
  • 코드 추가와 변경 사항을 저장소에 기록하려면 커밋이라는 절차가 필요하다. 커밋을 수행하면 이전 커밋 시점부터 현재 상태까지의 변경 이력이 기록된다

# 7.1.2 GitHub

Git은 리모트 저장소가 있어야 코드 수준에서 다른 작업자와 협업 가능하다. 협업은 리모트 저장소를 관리하며 데이터를 올리고(Push) 받는 (Pull) 것이다.

  • 대표적인 리모트 저장소는 GitHub, GitLab, Bitbucket이 있다.


# 7.2

GitHub는 Fork 기능을 제공해 기존 리모트 저장소를 본인의 저장소로 복사할 수 있습니다. Fork한 저장소는 원본 저장소와 연결되어 있어 이후 변경 사항을 원본 저장소에 적용하는 요청(Pull Request)이 가능합니다.

Owner는 본인의 ID를 선택하면 됩니다.


# 7.2.1 공유 제외 대상

테라폼 런타임 시 생성되는 파일, 실행 결과물, 개별 사용자 설정 파일, 시크릿 정보는 Git의 관리 대상에서 제외해야 한다.

  • .terraform 디렉터리: init 실행 시 작성되므로 제외
  • *.tfstate 파일: 프로비저닝 결과 데이터 소스 정보, 민감 데이터가 포함되거나 다른 사용자가 같은 State 파일 사용 시 인프라 불합치 유발
  • *.tfvars 파일: 변수 값을 보관하는 파일, 작업자마다 별도 변수 사용
  • 시크릿 파일: 인프라 구성에 필요한 시크릿 정보 함유
  • terraformrc 파일: 작업자의 CLI 설정 파일

# 7.2.2 로컬 저장소에 복제

로컬 작업 환경을 위한 리모트 저장소의 내용을 복제합니다.

  • 코드 협업을 위한 1인 2역을 준비 : 복제한 디렉터리 변경 및 추가 복사
    - terraform-aws-collaboration-tom : tom 작업 디렉터리
    - terraform-aws-collaboration-jerry : jerry 작업 디렉터리

# 7.2.3 Push & Pull

Commit된 코드는 로컬 저장소에 기록되며 Push를 하기 전까지는 리모트 저장소에 공유되지 않는다. 또한 작업 중 Pull을 통해 리모트 저장소의 변경 사항을 로컬 저장소에 반영합니다.

  • tom 디렉터리의 main.tf 파일 코드 내용 수정
...
provider "aws" {
  region = var.region
  default_tags {
    tags = {
      Project = "T101-Study-6week"
    }
  }
}
...
  • 수정된 코드를 Commit하고 리모트 저장소에 Push
cd terraform-aws-collaboration-tom
git remote get-url origin
git add main.tf
git commit -m "add default tags & project name"
git push

  • jerry 디렉토리에서 Pull

T101-Study-6week으로 변경된 내용을 볼 수 있다.


# 7.2.4 Pull Request

  • Push와 Pull로도 코드 협업이 가능하지만 다른 사람의 커밋을 확인하기가 쉽지 않고, 리모트 저장소에 푸시할 때가 되어야 충돌 상황을 확인하게 된다는 단점이 있다.
  • 작업된 테라폼 코드에 대한 자연스러운 리뷰와 메인스트림 main branch의 병합을 관리하기 위해 Pull Request 방식을 사용한다.
  • Git으로 코드를 관리할 때 주로 사용되는 브랜치 branch를 이용하는 방안으로, 작업자가 코드 수정을 위해 메인과 별개의 브랜치를 생성하고 작업 후 본인의 브랜치를 Push하고 코드 관리자에게 검토 후 병합을 요청하는 방식이다.

# 1단계 코드 작성자

코드 충돌을 유발하기 위해 앞 실습의 결과로 tom이 메인 브랜치에 Push한 상황에서 jerry가 Owner 항목을 jerry & tom 으로 변경하고 싶어한다.

  • 다른 branch를 생성한다.

checkout말고 최근에는 switch를 사용할 수 있다.!!

  • Pull Request는 코드를 머지 Merge 하는 관리자에게 자신이 수정한 내용을 메인 코드병합해달라는 요청을 하는 것이다.
  • Push로 코드를 merge하는 것과는 다르게 Pull Request는 코드 리뷰를 강제하기 때문에 코드 변경 사항을 검토할 수 있다.

# 코드 관리자

  • 리모트 저장소의 쓰기 권한이 있는 관리자는 Pull Request가 발생하면 코드를 기존 코드에 merge할 권한을 갖는다.
  • Pull Request에는 요청자의 변경 사항이 표기된다. Pull Request 수행 방식은 세 가지를 지원하나 여기서는 기본 설정대로 진행한다
    1. Create a merge commit : 브랜치의 모든 commit이 병합을 통해 기본 브랜치에 추가
    2. Squash and Merge : 브랜치의 변경 이력을 모두 합쳐 새로운 commit을 생성하고 메인에 추가
    3. Rebase and Merge : 브랜치 변경 이력이 각각 메인에 추가

# 2단계 코드 작성자

merge가 완료되면 작업자는 메인 브랜치로 이동 후 풀을 수행해 코드를 동기화하고 기존 브랜치를 삭제한다.

# 코드 협업자

머지 이후 코드를 작업하는 작업자는 개별 로컬 저장소에 새로운 코드를 가져올 수 있다.

# terraform-aws-collaboration-tom 디렉터리에서 아래 작업 수행
cd ..
cd terraform-aws-collaboration-tom
git checkout main
git pull

# 7.3 State 백엔드

테라폼의 State를 저장하는 위치를 설정한다. State는 프로비저닝 결과를 추적하고 비교 과정에 사용되므로 빈도와 규모가 커질수록 엄격한 관리가 요구된다.

  • 구성 목적
    • 관리 : 지속적인 State 백업을 위해서 local 이외의 저장소가 필요
    • 공유 : 다수의 작업자가 동일한 State로 접근해 프로비저닝하기 위한 공유 스토리지 필요
    • 격리 : 민감한 데이터가 State 파일에 저장될 가능성을 고려하여, 각각의 환경에 따라 접근 권한 제어 필요

# 7.3.1 Terraform Cloud (TFC) 백엔드

하시코프에서 프로비저닝 대상과 별개로 State를 관리할 수 있도록 SaaS 환경인 TFC를 제공하며 State 관리 기능은 무상을 제공한다.

  • 제공 기능 : 기본 기능 무료, State 히스토리 관리, State lock 기본 제공, State 변경에 대한 비교 기능
  • Free Plan 업데이트 : 사용자 5명 → 리소스 500개, 보안 기능(SSO, Sentinel/OPA로 Policy 사용)

# TFC 계정 생성

  • https://app.terraform.io/ 링크 접속 후 하단에 free account 클릭 → 계정 생성 후 이메일 확인 → 암호 입력 후 로그인

  • TFC 초기 설정 화면 → 사용자의 고유 조직 이름 생성 : t102test


# 7.3.2 백엔드 구성

tom 루트 모듈과 jerry 루트 모듈을 사용해 공통 백엔드 구성과 동작을 확인한다. 두 작업자가 동일한 AWS 인프라를 프로비저닝하기를 원하는 상황이라 간주합니다.


cd ..
cd terraform-aws-collaboration-tom

terraform init
terraform plan -var=prefix=dev
terraform apply -auto-approve -var=prefix=dev

terraform workspace list
terraform state list
ls terraform.tfstate*
terraform output

# TFC를 통한 작업 결과 공유 설정

TFC의 workspaces는 CLI에서의 workspace처럼 테라폼 구성과는 별개로 State를 관리하는 단위이다.

  • tom 루트 모듈에 main.tf 파일 수정
terraform {
  cloud {
    organization = "<MY_ORG_NAME>"         # 생성한 ORG 이름 지정
    hostname     = "app.terraform.io"      # default

    workspaces {
      name = "terraform-aws-collaboration"  # 없으면 생성됨
    }
  }

파일 내용이 존재하지 않는다.


TFC 전용 워크스페이스(State 백엔드 역할만 수행) 확인 → 선택 후 좌측에 Settings 클릭 → General

  • 실행 모드 변경 : Execution Mode 에서 Local 선택 → 하단의 Save settings 클릭하여 변경 적용
    • Remote : 테라폼 실행을 Terraform Cloud에서 수행
    • Local : 테라폼 실행은 작업자 환경 또는 연결된 외부 환경에서 실행해 State만을 동기화
    • Agent : 테라폼 실행을 사용자 지정 Agent(설치된 서버 환경)에서 수행 (Business 플랜에서 활성화)
  • 이후 [States] 탭에서 terraform init을 통해 마이그레이션된 State 업로드 정보 확인

Replaced 되어 버린다.


  • jerry 루트 모듈에서 확인

다시 Replaced 됩니다.


# 7.3.3 백엔드 활용

TFC State 잠금 기능 : 프로비저닝 수행 시 동일한 State 접근 못하게 잠금하여 State 마지막 상태에 대한 무결성 확보합니다.

  • Jerry가 프로비저닝 실행 시 변경 사항이 발생하도록 코드를 수정한다고 가정하여, null_resource에 정의한 내용이 항상 수행되도록 trigger를 추가함
    • trigger에 timestamp() 함수를 지정하면 테라폼 프로비저닝 실행마다 다른 값이 저장되므로 항상 변경을 유발함
  • jerry 루트 모듈에서 main.tf 파일 코드 변경 및 실행
resource "null_resource" "configure-cat-app" {
  depends_on = [aws_eip_association.hashicat]

  triggers = {
    build_number = timestamp()
  }
  • Lock이 걸렸다는 에러 발생

  • TFC Workspace에서 State 확인

  • jerry 루트 모듈 실행

terraform apply -var=prefix=dev
...
Enter a value: yes
  • TFC Wockspace에서 State Newer에서 변경 사항 확인

1개의 댓글

comment-user-thumbnail
2023년 8월 11일

좋은 정보 얻어갑니다, 감사합니다.

답글 달기