IaC(Infrastructure as Code) with Terraform

최현섭
None
Published in
10 min readJul 15, 2021

DevOps, IaC, Terraform 알아보기

안녕하세요. Humanscape Software Engineer David 입니다.

IaC(Infrastructure as Code)의 탄생 배경인 DevOps부터 IaC 도구인 Terraform까지 차례로 알아보겠습니다.

DevOps

과거: 데이터 센터의 운영

데이터 센터가 운영되던 불과 몇 전에는 물리 서버 구축, 네트워크 연결, 전력 이중화 등의 업무는 운영조직(Ops)에서 담당하고, 구성된 서버에 올라가는 소프트웨어를 개발하는 일은 개발조직(Dev)에서 담당했습니다.

업무와 함께 책임도 분리되어있어서, 운영조직의 실수로 일부 서버 설정이 변경 되면 서비스가 불안정해질 수 있는 서로간에 의존성이 있고, 이를 파악하는데 많은 어려움이 있었습니다.

운영, 개발 조직 간 보이지 않는 벽 존재

현재: 클라우드의 등장

AWS, GCP, Azure와 같은 클라우드가 등장하고 데이터 센터를 관리하지 않게되면서 개발과 운영이 통합되는 변화가 이루어지고 있습니다. 물리 장비관리에 대부분의 시간을 쏟던 운영조직은 소프트웨어 구성과 형상관리, 배포 자동화와 같은 방법을 고민하게 됩니다.

결과적으로, 운영 조직과 개발 조직이 함께 일해야하는 시간이 많아지며 두 조직 간의 경계도 허물어지게 되었습니다. 이러한 변화의 움직임으로 DevOps가 등장하게 되었습니다.

102개의 wanted DevOps 포지션, 2021.7

DevOps는 애플리케이션과 서비스를 빠른 속도로 제공할 수 있도록 조직의 역량을 향상시키는 문화 철학, 방식 및 도구의 조합입니다. 기존의 소프트웨어 개발 및 인프라 관리 프로세스를 사용하는 조직보다 제품을 더 빠르게 혁신하고 개선할 수 있습니다. 이러한 빠른 속도를 통해 조직은 고객을 더 잘 지원하고 시장에서 좀 더 효과적으로 경쟁할 수 있습니다.

위는 AWS의 DevOps 정의입니다. 많은 곳에서 DevOps를 꽤 다르게 정의(Newrelic / Azure / Wikipedia / IBM / Redhat)하고 있지만 문화, 자동화, 측정, 공유의 핵심 가치를 가지고 있는 것과 소프트웨어를 전달하기 위한 절차와 방법을 훨씬 더 효율적으로 만드는 것에 목적이 있다는 건 모두 같은 목소리를 내고 있습니다.

IaC

인프라를 코드 형태로 작성, 정의, 배포하는 것을 의미하며 서버, 데이터베이스, 네트워크, 로그, 애플리케이션 설정, 배포 자동화까지 모든 것을 코드 형태로 관리하는 데 목적이 있습니다.

코드 형태로 작성하게 되면 DevOps의 핵심가치인 자동화를 극대화 할 수 있게 됩니다.

IaC 종류

  • ad hoc script: .sh 나 Dockerfile과 같은 bash script
  • 구성 관리: 서버에 소프트웨어를 설치하거나 관리하는 목적의 도구 (ex. Chef, Puppet, Ansible, Saltstack)
  • 서버 템플릿: 많은 서버를 배포하고 같은 코드를 서버마다 같은 설정으로 동일하게 수행하는 것이 아니라 소프트웨어와 수행 시에 필요한 설정과 의존성 있는 프로그램들을 포함해 특정 시점에 OS와 함께 snapshot하여 템플릿 이미지화 하는 것. (ex. Docker, Packer, Vagrant)
  • 서버 프로비저닝: 서버 인프라 자체를 구성하기 위한 도구, 데이터베이스, 네트워크 장비, 서브넷 설정 등을 모두 담당. (ex. Terraform, AWS CloudFormation, Openstack Heat)

IaC의 장점

  • 배포 자동화로 휴먼 오류를 줄이고 일관되게 배포 할 수 있게되어 속도와 안정성이 향상됩니다.
  • 누구나 인프라의 세세한 부분이 어떻게 이루어져있는지 코드로 확인 할 수 있습니다.
  • 인프라의 변경사항을 커밋 로그로 확인 할 수 있어 문제 발생시 롤백할 수도 있고, 히스토리를 확인할 수 있도록 버전 관리가 됩니다.
  • 변경 내역에 대해 코드 리뷰가 가능해집니다.
  • 모듈화가 가능해져 공통 부분에 대한 재사용이 가능합니다. 또 가용 영역 자체 문제로 재해 발생 시 다른 리전으로 쉽게 이전 구축할 수도 있습니다.
AWS console vs Terraform

AWS Console과 Terraform 통해 AWS 서울 리전에 t2.micro 인스턴스 생성을 비교해 본 예시입니다. AWS Console을 통해 인프라를 구축하게 되면 구성한 관리자만이 정보를 알고 있게 되고 생성, 수정, 변경에 실수가 발생할 수 있습니다.

puppet의 2016 DevOps 리포트에 따르면 IaC를 적용했을 때 배포 주기는 200배 이상, 장애 복구 시간은 24배 빨라졌으며, 개발에서 상용 서비스 적용을 거쳐야 하는 프로세스가 2,000배 이상 줄어들었다고 합니다.

왜 Terraform을 선택했나요?

Ansible과의 비교도 있었지만 Kubernetes와 Docker를 사용하고 있기 때문에 서버 구성 관리는 어느정도 되고 있다고 판단해 서버 프로비저닝 도구들 중 비교해 보았습니다.

Terraform vs CloudFormation vs Openstack Heat

CloudFormation은 AWS만 지원하기 때문에 멀티 클라우드 대응이 필요한 상황으로 보기에서 제외되었고, Openstack Heat는 Terraform과의 개발, 커뮤니티 활성도를 주요하게 비교했고 차이가 크다고 판단해 Terraform을 선택하게 되었습니다.

2021.7 기준

stackoverflow 질문: terraform 9,327 / openstack: 2,818

facebook 커뮤니티 멤버: terraform 15,000 / openstack: 6,800

github

githubcompare.com

최근 Terraform 1.0 이 릴리즈 된 것도 한 몫 한 것 같습니다.

Terraform 실습

간단한 AWS 인프라를 구성하는 실습과 함께 Terraform을 알아보겠습니다.

환경 구성

실습 전 환경 구성은 아래 링크로 대신합니다.

코드 작성

환경 설정 후 아래 코드를 main.tf 파일에 작성합니다.

main.tf

위 코드는 AWS의 미국 서부(오레곤) 리전에 app_server라는 이름의 instance를 생성하는 최소 요건의 코드입니다. 크게 terraform {}, provider {}, resource {} 블록으로 구성되어 있습니다. 각각을 살펴보겠습니다.

- terraform {}

terraform 블록은 기본적으로 terraform registry 의 provider를 설치합니다.

registry.terraform.io/providers/hashicorp/aws 를 줄여 hashcorp/aws로 provider를 정의할 수 있습니다. 버전은 선택적으로 정의할 수 있고, 선택하지 않으면 최신 버전으로 설치가 됩니다.

- provider “참조 provider 명” {}

환경 설정으로 aws 권한으로 terraform을 실행하기 때문에 자격 증명 없이 provider 정의가 가능합니다.

- resource “참조 resource 명” “resource 명”{}

resource는 참조할 resource 명, resource 명으로 선언됩니다. 위 코드의 경우 resource의 id를 참조하고 싶을 경우 aws_instance.app_server.id 와 같은 형태로 코드 내에서 참조 할 수 있습니다. 예시로 간단하게 리소스가 구성되었지만 VPC, subnet, security group등 다양한 설정 추가가 가능합니다.

terraform registry의 official 마크를 확인해주세요.

terraform registry의 provider, module, resource는 되도록 official 마크를 확인하고 사용해 주세요.

배포

Terraform의 배포는 크게 init, plan, apply 3가지 단계로 이루어집니다.

$ terraform init

처음 실행을 할 때, 새로운 구성을 추가 하거나, 기존 구성을 변경했을 때 init 명령어를 통해 디렉토리를 초기화 해주어야합니다.

.terraform 디렉터리를 생성해서 위 코드의 aws provider를 설치하고 .terraform.lock.hcl 파일에 버전을 기록하여 이후 변경을 감지할 수 있도록 합니다.

init 결과

$ terraform plan

plan 명령어로 배포 전 기존 인프라와 비교해 어떤 변화가 있는 지 확인 할 수 있습니다.

plan은 결과로 모든 변경사항을 자세히 보여주고 마지막 라인에 변경에 대한 요약이 있습니다.

Plan: 1 to add, 0 to change, 0 to destroy.
plan 결과

$ terraform apply

apply 명령어는 plan에서 확인한 변화 내용을 실제로 배포하는 명령어입니다.

apply 결과

간혹 plan에서 문제 없이 확인이 되었는데, 이름이 겹치거나 다른 곳에서 참조중인 인프라를 변경하려고 할 때 apply 에서 오류가 발생하고는 합니다. 오류 메시지는 친절한 편이고 terraform + aws는 커뮤니티가 잘 되어있어 디버깅은 어렵지 않습니다.

디버깅 할 때 편하게 하고자 AWS Console을 직접 변경하게 되면 terraform 과 혼용해서 인프라 구성을 건드리다보니 히스토리 파악이 안되어서 꼬이는 상황이 발생하게 됩니다.

정신 건강을 위해 AWS Console을 통해 바로 해결하고 싶더라도 초기 구성 후에는 terraform을 통해 쭉- 관리하시는 것이 좋습니다.

초기 인프라를 구성할 때는 init, plan, apply 과정에 기다리는 시간이 은근히 오래 걸립니다. 시행착오를 최소화하기 위해 어느정도 학습 후 인프라 구성을 시작하시는 것을 추천드립니다.

실제로 잘 생성된 인스턴스 :)

실습 후 정리

$ terraform destroy

마무리

DevOps, IaC, 간단한 실습과 함께 Terraform까지 알아보았습니다.

저는 요즘 조금 복잡한 실습을 해보고 있는데, 코드로 인프라가 추상화 되고, 보안까지 신경 써야하다 보니 많은 시행착오를 겪고 있습니다.

그래도 Terraform을 통해 IaC 구성을 잘해놓으면 장점이 더 많을 것 같다는 생각입니다.

다음 포스트에서는 좀 더 다양한 경험과 시행착오를 공유드릴 수 있도록 하겠습니다.

감사합니다.

[참고]

Terraform Up & Running / Terraform AWS Build / Terraform vs Ansible

Walk with us!

기술이 세상을 더 아름답게 할 수 있다고 믿으신다면, 휴먼스케이프와 함께 소중한 뜻을 펼칠 수 있습니다.
함께 걸어가며 성장하실 분, 언제든지 연락해주세요 :)

휴먼스케이프 개발자 채용공고 보러가기

--

--