들어가며
이번 포스팅에서는 지금까지 배운 Terraform 개념들을 활용하여 실제 업무를 수행할 때 혼자가 아닌 팀, 조직단위에서 관리를 하는 방법들에 대하여 배웠습니다. 그리고 말로만 듣던 TFC를 직접 이용해 보면서(먼저 활용해볼 수 있었는데도 말이죠.. ^^;) 편안하고 운영 환경을 잘 관리하기 위한 여러 가지 기능들을 사용해 보았습니다.
* 본 스터디의 자료는 아래의 책을 기반으로 합니다.
테라폼으로 시작하는 IaC | 김민수, 김재준, 이규석, 이유종 | 링크
협업
형상관리 도구를 통해 여러 작업자가 동일한 테라폼 코드를 공유해 구성하여 작업하게 됩니다. 이럴 때는 Locking이나 스테이트 저장소 관리 등의 이슈가 발생하게 됩니다. 스터디에서 권장하는 방법은 tf 파일과, state file을 분리하여 관리하는 것을 권고합니다. 이를 위해 tf파일은 github, state file은 테라폼 클라우드를 이용하여 관리하는 방식에 대해 설명합니다.
State 백엔드
지난 스터디에서 State 백엔드에 관해 배웠었는데 이는 이번시간에 이야기할 협업에 필요합니다!
https://devlos.tistory.com/80
State 백엔드를 구성하는 목적에 대해서는 다음과 같은 3가지 관점이 있습니다.
- 관리 : 지속적인 State 백업을 위해서 local 이외의 저장소가 필요합니다.
- 공유 : 다수의 작업자가 동일한 State로 접근해 프로비저닝하기 위한 공유 스토리지가 필요 합니다.
- 격리 : 민감한 데이터가 State 파일에 저장될 가능성을 고려하여, 각각의 환경에 따라 접근 권한 제어가 필요합니다.
협업 실습(Feat. state backend)
사전작업 (예제 코드 다운로드)
github > Settings > Developer Settings에서 Personal Access Token을 생성합니다.
실습코드 Fork
다음으로 스터디에서 실습하는 교재에 있는 소스코드를 Fork 합니다.
Fork 대상 -링크
Create fork를 하게 되면 계정에 fork가 완료됩니다.
terrafrom 코드를 git으로 관리할 때는 다음과 같은 ignore 설정들이 있습니다.
- .terraform 디렉터리 : init 실행 시 작성되므로 제외합니다. init은 로컬에서 관리하면 되니까요.
- .tfstate 파일 : 프로비저닝 결과 데이터 소스 정보, 민감 데이터가 포함, 다른 사용자가 같은 State 파일을 사용하는 경우 인프라 불합치를 유발하기 때문에 생략합니다. 이 tfstate 파일은 terraform cloud에서 관리합니다.
- tfvars 파일 : 프로비저닝 시 적용할 변수 값을 보관하는 파일로, 작업자마다 별도 변수를 사용하기 때문에, 포함하지 않습니다. 이 역시 terraform cloud에서 관리합니다.
- 시크릿 파일(pem 포함) : 인프라 구성에 필요한 시크릿 정보 파일은 보안상의 이유로 리포지토리에 올리지 않습니다.
- terraformrc 파일 : 작업자의 CLI 설정 파일로 각각 다른 정보를 관리하기 때문에 제외합니다.
이제 실습을 위해 코드를 로컬로 복제합니다.
git clone https://github.com/adm-winitech-rnd/terraform-aws-collaboration.git
간단한 텍스트 파일 push를 통해 정상적으로 git 로그인이 되어 있는지 확인합니다.
git add test.txt
git commit -m "first commit"
git push
다음으로 2개의 사용자 (Tom, Jerry)를 이용한 테스트를 위해 동일한 환경을 2개의 디렉터리를 만듭니다.
cd ..
mv terraform-aws-collaboration terraform-aws-collaboration-tom
cp -r terraform-aws-collaboration-tom terraform-aws-collaboration-jerry
테라폼 클라우드(TFC) 계정 생성
테라폼 클라우드는 State 관리 기능을 무료로 제공하고 있기 때문에 사용하는 것이 좋습니다. (리소스가 많으면 유료입니다!)
TFC에 관한 내용은 이전 스터디 자료에서 확인하실 수 있습니다. 링크
TFC 계정 생성은 다음의 링크를 통해서 가능합니다 - https://app.terraform.io
TFC 계정을 생성하고 나면 다음과 같이 workflow 세팅이 나옵니다. 여기에서 Create a new organization을 만듭니다. 조직명은 TFC에서 고유해야 합니다!
다음으로 아래와 같이 로그인을 하고, 토큰을 생성합니다.
terraform login
로그인이 완료되면 다음과 같이 로컬에 token을 저장할 수 있습니다.
❯ cat ~/.terraform.d/credentials.tfrc.json | jq
{
"credentials": {
"app.terraform.io": {
"token": "4TktPgkGUT~~~
}
}
}
로컬 state 관리 방식을 통한 리소스 프로비저닝
다음과 같이 tom 디렉터리에서 프로비저닝을 수행합니다.
# 작업 경로를 tom으로 이동
cd ..
cd terraform-aws-collaboration-tom
# 리소스 프로비저닝
terraform init
terraform plan -var=prefix=dev
terraform apply -auto-approve -var=prefix=dev
# 로컬 state 확인
terraform workspace list
terraform state list
ls terraform.tfstate*
terraform output
다음으로 jerry를 이용하여 배포해 보면, 예상과 같이 프로비저닝 된 리소스와 관계없이 프로비저닝이 가능하다고 확인됩니다.
# 2번째 작업자로 이동
cd ..
cd terraform-aws-collaboration-jerry
terraform init && terraform plan -var=prefix=dev
즉 로컬에서 TfC를 이용하지 않고 작업했을 때는 이러한 형태로 중복된 리소스 생성이 가능합니다.
TFC로 state를 관리하여 리소스를 프로비저닝
이번에는 TFC설정을 각각의 작업자에 지정해 줍니다. 클라우드 블록을 생성하게 되면 로컬이 아니라 원격지에서 스테이트를 관리하게 됩니다.
현재는 TFC 워크 스페이스에 아무것도 없는 상황입니다.
terraform init을 이용하게 되면, 기존의 리소스를 TFC로 마이그레이션 하는 작업이 수행됩니다.
다음과 같이 테라폼 클라우드에 state 가 이관된 모습을 확인할 수 있습니다.
이제 TFC에서 관련 리소스들과 아웃풋을 모두 확인할 수 있습니다 :)
마이그레이션이 끝난 상황이기 때문에, 로컬에서 state를 삭제해도, plan의 결과가 유지되는 것을 확인할 수 있습니다.
이제 앞서 만들어놓은 2번째 사용자 jerry에서 terraform plan 수행을 하게 되면, 이전과 다르게 state가 비교되어 변경사항이 없다는 것을 확인할 수 있습니다.
cd ..
cd terraform-aws-collaboration-jerry
git pull
terraform init
terraform plan -var=prefix=dev
스테이트 잠금 실습
다음으로 jerry에서 소스코드를 변경하여 apply를 수행합니다.
리소스를 변경하고 apply 직전까지 둡니다.
state lock을 통해 동시에 리소스가 변경되는 문제를 예방할 수 있습니다.
jerry에서 yes를 통해 프로비저닝을 수행하면, TFC에서 state 변경내용에 대해 확인도 가능합니다!
TFC 실습 - 링크
다음 조건을 만족하게 코드를 구현해 봅시다.
조건
- Terraform Cloud를 State 백엔드로 구성
- Workspace 이름 : terraform-edu-part1-assessment
- 실행 모드는 local
- AWS 공통 Tag : Project = “workshop”
- aws_instance는 반복문을 사용해 3개 구성
- EIP를 제거하고 EC2에서 public ip를 자체 사용하도록 구성
- placeholder 변수는 아래 3가지가 각각의 aws_instance에 적용되도록 구성
풀이
1. TFC 설정을 추가하고, workspace name을 다음과 같이 변경했습니다.
이렇게 하면 다음과 같이 plan이 TFC에서 동작하게 됩니다.
2. count를 이용하여 리소스를 여러 개로 생성시킵니다.
3. 다음으로 eip를 제거하고, aws_instance의 public_ip를 사용하도록 설정을 변경합니다.
4. placeholder의 이미지를 순서대로 사용할 수 있도록 variable을 수정합니다.
5. 여러 placeholder를 사용할 수 있도록 remote execution의 참조를 count로 대체합니다.
6. 마지막으로 output에서 각각의 instance ip를 확인할 수 있도록 for 문을 이용하여 출력을 수정합니다.
teraform apply를 수행하면 다음과 같이 결과를 확인할 수 있습니다!
고양이와 개.. 그리고 곰!!!!
TFC의 workspace overview에서 세 개의 instance가 생성된 것 역시 확인이 가능합니다.
워크플로
개인 vs 팀 워크플로
개인의 워크플로는 다음과 같이 3가지 단계로 이루어집니다.
Write 단계에서 테라폼 코드를 작성하고, Plan을 통해 적용하려는 코드의 실행 계획을 통해 리뷰를 해봅니다. 적용해도 될 것 같다는 판단이 서게 되면 Apply를 통해서 실제 인프라 환경을 프로비저닝 합니다.
팀 단위의 워크플로우도 이와 크게 다르지 않습니다.
다만 위에서 설명드린 개인의 워크플로우를 하나의 Write단계로 봤을 때 여러 번의 Write 단계가 실행되고, 팀원 간 Plan을 통한 리뷰를 통해 코드를 검증합니다. 이러한 과정이 끝나면 Apply를 통해 실제 인프라 환경을 프로비저닝 하게 됩니다.
Write 단계에서 Apply를 수행할 수 있는 이유는 가상 테스트환경 (이를테면 Github Action Plugin)을 통해 수행할 수 있기 때문입니다.
다수팀의 워크플로우는 팀 단위에서 더욱 확장된 개념입니다.
여러 개의 팀이 관리하는 리소스는 분리되어야 합니다. 이러한 분리된 리소스를 관리하기 위해서는 R&R에 따른 워크스페이스 분리가 필요합니다. 또한 하나의 팀의 작업 결과가 공유되어 다른 팀에서 검토가 가능하도록 안내하는 형태의 파이프라인이 구축되어야 합니다.
(책에 그림이 잘 나와있어요..! )
격리구조
테라폼 수준의 격리 목표는 State를 분리하는 것입니다. 각각의 환경은 독립적으로 구축이 되되, 다른 환경과 영향을 받지 않는 격리된 구조가 필요합니다. 리소스가 많아지면서 배포하는 속도도 느려지고, 조직의 기민성이 줄어들게 되므로 마이크로서비스의 느낌으로 적절한 단위로 분리를 하는 전략이 중요하다고 합니다.
Github Action을 이용한 프로비저닝 파이프라인 설계
Github Action은 CI/CD를 수행하기 위한 파이프라인 구축하기 편리한 툴입니다. 실제로 필자의 조직에서도 Github Action을 이용하여 Application단의 CI/CD 파이프라인을 구성하여 프로젝트를 진행하고 있기 때문에 굉장히 친숙하게 느껴졌습니다.
소스코드 설정
git clone https://github.com/devlos0322/terraform-aws-github-action
# 확인
tree terraform-aws-github-action
cd terraform-aws-github-action
코드의 action.yaml 파일의 TF_VERSION을 1.5.6으로 변경하고, organization을 각자의 organization으로 수정했습니다.
다음으로 TFC와 연동하여 init을 수행합니다.
실습의 내용은 개발자가 feature Branch에 코드를 전달하고, Github Action에서 Sand Box를 통해 기능을 테스트한 후, PR을 날리게 됩니다. 그다음 SCAN과정을 통해 코드 검증 및 결과를 공지하게 되고, 관리자가 확인한 후 Main Branch에서 SCAN을 한 후 코드를 병합하고 실제 환경에 배포되게 됩니다.
SCAN 과정에서는 다음과 같은 내용이 수행됩니다.
- Check out code : 검증을 위해 저장소의 코드를 체크아웃
- Run terrascan : 테라폼 코드 검증 도구인 Terrascan을 실행
- Upload SARIF file : 검증의 결과(정적 분석 결과 표준 포맷)를 업로드하여 정상적으로 작성된 코드가 되었다고 판단
다음으로는 Terrafom 과정을 수행합니다. (Github repository 코드 참고)
- Check out code : 검증을 위해 저장소의 코드를 체크아웃
- Configure AWS credentials : AWS 환경을 프로비저닝 하기 위한 Credential 설정
- Terraform fmt : 표준 스타일 수정 대상 확인
- Terraform init : 테라폼 실행을 위한 init 수행
- Terraform validate : 코드 문법 오류 검사
- Terraform plan : 실행 계획 확인
- env.TF_LOG: info : 로그 수준을 info로 출력해 실행 디버깅
- Plan output : 풀 리퀘스트인 경우 실행 계획을 정리해 출력
- Terraform apply : 메인 브랜치 변경 시에만 Apply 수행
Secret 설정
Github Action에서 AWS와 TFC에 접근할 수 있도록 하기 위하여 다음과 같이 secret을 설정합니다.
실습 조건
실습 환경에서 조건은 다음과 같습니다.
- 브랜치 이름 : add-env-variable
- 테라폼 입력 변수 추가
- 이름 : environment
- 설명 : Define infrastructure’s environment
- 타입 : string
- 기본값 : dev
- 변수 확인
- 조건 : dev, qa, prod 인 경우 허용
- 에러 메시지 : The environment value must be dev, qa, or prod.
- aws_vpc의 tags.environment를 입력 변수 environment 값으로 선언
다음과 같이 브랜치를 생성하고 main.tf, variable.tf 소스코드를 수정합니다.
git branch -M add-env-variable
조건 확인 및 에러메시지 출력 설정이 완료되었습니다.
다음으로 PR에 대한 Merge를 수행합니다!
Scan 과정이 잘 수행되는군요!
Terrafom 과정도 잘 수행되었네요!
리소스도 잘 생성되었습니다.
[! 중요!] Destroy를 통해 리소스도 잘 삭제해 줍니다.
terraform destroy
마치며
이번 포스팅에서는 이전 시간에 배운 Terraform Backend를 실제로 활용하여 협업의 관점에서 TFC를 사용하는 것에 대해 배웠고, 실습을 통해 경험해 보았습니다. 확실히 글로 읽는 것과 실습해보는 것의 차이는 체감이 확 다르네요. 잘 구성된 실습 예제들을 통해 대규모 환경에서 어떻게 TFC를 활용하는지, 그리고 왜 필요한지에 대해서 간접적으로 체험해 볼 수 있었습니다.
Github Action을 활용한 IaC 파이프라인 구성도 직접 해보니, 회사에 도입할 때 어떤 식으로 해야 할지 감이 왔습니다. 조직에서 관리하는 클라우드 인프라 리소스가 많지 않기 때문에, 계정을 만든 이상 적극적으로 활용해야겠다는 다짐을 했지요..
긴 포스팅을 따라와 주시느라 고생 많으셨습니다, 감사합니다!
'클라우드 컴퓨팅 & NoSQL > [T101] 테라폼 기초 입문 스터디' 카테고리의 다른 글
[6주차] T101 테라폼 기초 입문 스터디 (23.10.08) (2) | 2023.10.10 |
---|---|
[4주차] T101 테라폼 기초 입문 스터디 (23.09.17) (0) | 2023.09.23 |
[3주차] T101 테라폼 기초 입문 스터디 (23.09.10) (2) | 2023.09.15 |
[2주차] T101 테라폼 기초 입문 스터디 (23.08.27) (0) | 2023.09.08 |
[1주차] T101 테라폼 기초 입문 스터디 (23.08.27) (0) | 2023.09.01 |