Meetup Note
AWSKRUG
Infrastructure as Code

A Tour of IaC (lv.100)

Overview

Goal

  • 입문자를 위한 발표
  • IaC에 대한 소개
  • 현재 인기있는 IaC 도구를 소개
  • 무신사 사례를 들어 실무 관점에서의 IaC에 대해 이야기해봄

IaC가 뭔가?

→ Infrastructure as Code / 코드로 인프라를 관리하는 것

등장 배경

Case 1. 히스토리 관리

옛날에는 (온프렘에서는) 장비 구매하고 뭐 하고 한다고 결재 올리고 너무 복잡하고 길었음

→ 근데 클라우드로 오면서 인프라 추가/삭제 주기가 짧아짐

일단 쓰기 되게 편해져서 만들기는 했는데, 이걸 어떻게 관리하지? (ex. 이거 누가 만들었냐! 어… 퇴사한 A씨인데요?)

이 상태가 지속되면 인프라가 일단 있긴 한데, 이게 무슨 일을 하는지 몰라서 지울 수가 없음…

그렇게 공포의 인프라가 탄생

Case 2. 반복 작업의 자동화

요청이 들어왔다 “대규모 인프라를 만들어주세요!”

인스턴스를 100개 올려야하고 오토스케일링그룹 만들어줘야하고 SG 다 짜줘야하고…

내일까지 해달라고 하면 어떡하지…?

자동화 안 한 상태로 콘솔에서 하려면…

Case 3. 개발자의 인프라 관리

DevOps 전략이 대두되면서 개발자가 인프라 엔지니어링으로 넘어온 경우가 많음

코드를 다루던 사람이 인프라로 넘어오면? 인프라를 코드로! (쓰기도 편하고…)

그리고 변경 이력을 Git으로 관리할 수 있음. 히스토리 관리가 단번에 해결

IaC 도구들

Terraform 이전의 세계

먼 옛날에는… 셸 스크립트로 다 짰음

이후에는 Chef, Puppet, Ansible(Packer) 등이 쭉 나옴

얘네들의 특징

  • 신규 인프라를 프로비저닝하기보다는 기존 인프라에 대해 일괄 작업을 적용하는 방식이 많음
  • 절차적(명령형)에 가까운 코드 형식
    • 선언형과의 차이점? 선언형은 뭐 어떤 SG를 가질지 어떤 AMI를 쓸지 다 지정해주고 하는데
    • 절차적은? 명령 위주로 해서 쭉 짜고 들어감
  • 도구 수준에서는 멱등성을 보장하지 않음
    • 멱등성은? 여러 번 실행해도 동일한 결과가 나와야 함
      • Ex) 뭔가 타임스탬프같은 걸 기준으로 파일같은걸 만들었다. → 이걸 다시 실행하면? 파일이 또 생기는 것 = 멱등성이 보장되지 않음
    • 그래서 짜는 사람이 신경써서 해야 함
  • Dry run이 불가능함. 롤백이 어려움
    • 테라폼과의 가장 큰 차이점…
    • Dry run이 뭐냐? 이걸 실행했을 때 인프라가 어떻게 변할지를 알 수 없다. 일단 실행해야 그 결과가 어떻게 될지를 알 수 있다.
    • 테라폼은? 그냥 Plan 때려서 보면 되잖아

Terraform의 등장

IaC 도구는 Terraform 전과 후로 나뉜다고 해도 과언이 아님

장점

  • State가 존재한다는게 되게 특이
    • State란? 인프라의 상태. 실행을 했을 때의 인프라 상태를 저장해둠.
    • 인프라 변경사항을 추적하기 위해서 Diff 떠서 저장하는거
  • 선언적으로 인프라 상태를 정의 → 싱크는 Terraform (플러그인)이 알아서 다 해줌
    • 선언적으로 하면 뭐가 다른가? 인프라가 이렇게 되어 있어야 해! 라고 정의하는 것
    • 그걸 어떻게 인프라에 적용하는가?는 플러그인으로 추상화되어있음
    • 내 입장에서는 그냥 상태만 선언해두면 인프라 프로비저닝은 알아서 해주니까 신경쓸게 줄어듬. 코드 양도 줄어들고
  • Dry run이 가능하다 - Plan을 통해 코드를 반영했을 때 어떻게 될지 알 수 있다.
  • 생태계가 강력함. Provider가 진짜 많음. 4천개 가까이 있다니…

단점

  • HCL : 테라폼에서 사용하는 언어. 선언형 인프라를 위해서 만들어진 언어긴 한데… 이게 좀 거시기함.
  • 사실상 CLI를 직접 래핑해서 실행시키는 것 이외에 자동화 구현이 어려움…
    • SDK같은 방식으로 뭔가 쓸 수 있는게 아니고, CLI를 그냥 실행시켜야하는 방식이라서 자동화 구현이 좀 곤란함
    • 코드를 통해서 셸 스크립트를 통해서 테라폼 apply를 때렸는데 안됐다. 이걸 어떻게 처리할건지?
  • 모듈이 있지만 재사용성이 다소 떨어짐
    • Variable같은건 매번 모두 선언해줘야 함
    • 저걸 극복하기 위해 나온게 Terragrunt

Terragrunt 등장

→ Terragrunt를 쓰면? Terraform을 사용하면서 해야하는 노가다 작업을 줄여줌

이걸 쓰면 ‘매번 복붙해야하는 코드의 양’을 줄여줌

그리고, 한 번에 여러 Terraform 모듈을 실행할 수 있음

하지만…

테라폼 파일을 한 디렉토리 안에 여러개를 넣을 수 있는데, Terragrunt는 한 개밖에 넣을 수 없고

data같은걸 terragrunt.hcl 내부에서 쓸 수 없어서 템플릿을 찍어내는데엔 유리하지만, 자유도가 떨어짐…

→ 테라폼의 전체 기능을 다 쓸 수 없음…

DRY하게 관리해줄 수있는 이유? 매번 관련된 모든 Terraform 모듈을 .terragrunt-cache 디렉토리에 복사해서 사용. → 그런데… 이렇게 하면 나중에 프로젝트 용량이 말도 안되게 늘어남

그 외…

  • CDK - AWS에서 만든 IaC 툴
    • 장점 : 여러 프로그래밍 언어를 지원함
    • 단점 : 프로비저닝할 때 CloudFormation을 사용함. AWS 인프라 + 쿠버네티스 정도만 사용 가능
  • CDKTF - CDK+Terraform
    • 장점
      • CDK의 장점을 모두 가지면서 CloudFormation을 쓰지 않음
      • Terraform의 Plan과 같은 기능도 모두 사용할 수 있음
    • 단점
      • 결국 CDK → Terraform 코드를 Generation 하는 방식
        • 그런데… 그렇게 Generate된 코드가 매우 더럽고 읽을 수가 없음…
      • 역시 AWS와의 결합도가 매우 높아짐
  • Pulumi
    • CDK와 마찬가지로 프로그래밍 언어로 인프라를 정의할 수 있음
    • 장점
      • CDK보다 지원하는 언어가 더 많고
      • (자체) Cloud 혹은 Self-hosted로 백엔드 서버를 제공해서 API 가지고 자동화 구현이 쉬움
    • 단점
      • 프로그래밍 언어를 쓸 수 있다 → 프로그래밍 언어를 사용하는 개발의 어려움과 문제점을 해결해야 한다. 프로젝트 구조부터… 재사용성을 위해서 추상화했던 것들이 막 레거시가 되고… 결국 그런 전철을 밟을 수 있다…
      • 할 수 있는게 많아진다 → 더 심각하게 망할 수 있다… 사람마다 언어의 취향이라던지 이걸 사용하는 DevOps/SRE 조직은 개발 조직이 아니다보니까… 쉽지 않음
      • Open된 이슈도 너무 많음… (프로덕션 환경에 사용하기 적합한가?)
  • CrossPlane - 쿠버네티스에서 도는 IaC 툴
    • 장점
      • 쿠버네티스를 쓰면, 클라우드 인프라도 쿠버네티스 매니페스트와 함께 관리할 수 있다
    • 단점
      • dry-run을 사용할 수 없음.
        • 대신, “인프라를 삭제해라”라는 명령이 명시적으로 있지 않는 한, 기존 인프라를 삭제하지 않음
        • 하지만… CRD Apply 때리는거 보면 알듯이 일단 Apply가 돼서 실행이 되어버리고, 뭔가 잘못된 yaml을 짰더라도 일단 실행이 되어버리고 그게 최종적으로 성공했는지 실패했는지를 파악하기가 좀 길어짐
  • 그 외에 IaC를 도와주는 친구들
    • Spacelift - IaC 관리 SaaS (약간 Terraform Cloud같은 느낌도 있음)
    • https://www.firefly.ai/ (opens in a new tab) - IaC와 실제 인프라 간의 간극을 메워줌. IaC의 커버리지를 보여주고, IaC로 관리되지 않는 IaC 코드도 자동으로 생성해줌
    • Snyk IaC - 코드 보안 솔루션의 IaC용 버전. IaC 코드의 취약점을 찾아 줌. (ex. 어? 이거 하면 이 부분때문에 인프라 취약점 있을 것 같은데?)
    • Atlantis - Terraform Git 저장소의 PR 자동화. PR이 올라오면 /plan 해서 결과를 보여주고 /apply 같은것도 다 해줌 👍
    • Terraformer - Terraforming 되어있지 않은 자원을 지정하면 자동으로 Terraform 코드를 짜줌. 근데 생성된 코드를 한 번도 그대로 써본 적이 없음. (커스텀 모듈을 사용하거나, 팀 내 컨벤션같은 이유때문에)

무신사에서는 어떻게 하는가?

현재 무신사에서의 IaC 현황

  • Terragrunt를 사용해서 AWS 자원을 관리하고 있음
    • 원래 Terraform만 쓰다가 관리가 너무 어려워져서…
  • Apply는 각자 Local에서 실행함 (Terraform cloud, Atlantis 없음)
    • 근데… Apply 해놓고 push 안 해서 sync 틀어지는 경우가 종종 있음
    • 그래서 Atlantis 도입해서 Git PR을 거쳐서 실행시키면 좋겠다고 생각 중
  • EKS도 사용하다보니 AWS 자원은 Terragrunt, EKS 자원은 YAML(+Helm) 저장소를 왔다갔다 하는게 꽤 피곤함
    • 저장소가 너무 많음…
    • 컨텍스트 스위칭 무한으로 발생. 시간도 많이 걸리고…
  • IaC 적용 안 한 AWS 자원들
    • VPC, Subnets, Route Tables : 한 번 설정하면 바꿀 일도 거의 없음. 바꾸는 걸 로컬에서 누군가가 실행하는 것도 원치 않았고 (너무 크리티컬하니까…)
      • 근데 최근부터는 신규 계정에서는 Terraforming 함
    • Route53 : IaC 도입 이전에 설정된게 있어서 import가 좀 껄끄러웠고, alias는 콘솔에서 하는게 더 편했음. 그리고 뭔가 잘못해서 롤백을 해도, 전파때문에 시간이 또 꽤 걸림
    • ALB Listener Rules : AWS 콘솔 업데이트 전에는 상대 순서만 정하면 돼서 콘솔이 더 편했음 (테라폼에서는 무조건 숫자를 지정해줘야 함). 그런데 이제는 콘솔에서 Priority를 무조건 숫자를 넣어야하기로 바뀌었음. 그래서 이제는 테라포밍할까 고민 중
      • 테라폼은 인덱스 뭔가 하나를 바꾸면 나머지 인덱스가 다 바뀌게 되는데, 그러면 나머지를 다 Recreate해버림
    • ASG : CodeDeploy를 통해 B/G 배포하면 다 지워버려서 테라폼으로 관리하기가 다소 까다로움

Terraform 사용기

Terraform/Terragrunt에 대한 불만

  • Terragrunt 캐시 용량 : 작업하다보면 100GB는 우습게 넘어감…
  • 이미 존재하는 리소스를 테라포밍할 때 꽤 어렵다. Terraformer는 Terragrunt 쓰는 환경에선 아예 쓸 수도 없고…
  • 인프라가 커지면 결국 인프라 사이의 상관관계가 복잡해지면서 다른 모듈의 output을 참조하게 되는데, 이러면 apply 시간이 너무나도… 길어짐…
    • SG같은거 막 엄청 복잡하게 꼬여있고 그러면 다른 곳에서 막 참조해오고 그래야해서 apply하는게 시간이 너무 오래 걸림

HCL에 대한 불만

  • IDE 지원이 미묘함 : Terraform만 쓰는 경우에는 좀 낫긴 한데 (얘도 잘 안되긴 함), Terragrunt를 사용하면 자동완성도 안되고, 코드 참조해서 추적하는 것도 안됨
  • 애초에 선언적 Configuration Language이지 프로그래밍 언어가 아님.
    • 조금이라도 복잡하게 뭔가 만드려고 하면… 기본적으로는 안됨. 조금이라도 복잡하면 눈물의 ‘null resource’ 서커스를 해야 함.
    • 심지어 “XX가 있으면 YY 리소스를 만들지마!” 같은 조건절 제어도 언어 레벨에서 지원하지 않음… 그래서 count=0 같은 꼼수를 써야 함
  • Terraform 코드 (*.tf)는 사실 HCL도 아님… : 엄밀히 따지면 HCL Parser같은걸로 파싱이 안되고, 커스터마이징이 들어가있음. 그래서 뭔가 프로그래머블하게 접근하기가 다소 까다로움.

자동화의 어려움

원래 하고싶었던 건, 개발팀이 뭔가 신청하면 Terragrunt 코드를 자동으로 생성해서 코드와 인프라를 찍어내고 싶었음.

문제점 - Python으로 자동화 코드를 작성하는데, Terragrunt 역시 파이썬 라이브러리가 따로 없음. → 셸로 그냥 실행해야 함. 그래서 뭔가 에러가 나면 이걸 어떻게 해야할지 처리가 매우 힘듦