Infrastructure As Code
줄여서 IaC는 "코드 기반으로 인프라 스트럭쳐를 정의하고 프로비저닝하는 것"이다.
인프라는 기존의 수동 방식으로도 충분히 구성할 수 있다. 그럼에도 많은 기업들이 IaC를 도입하고 있으며, 이에 대한 관심도 꾸준히 증가하고 있다.
대체 왜 기업들은 IaC에 주목하는 것일까?
IaC는 왜 필요하고 어떤 장점을 가지고 있는지 자세히 알아보도록 하자.
IaC의 탄생 배경
과거에는 서버, 네트워크, 스토리지 같은 인프라를 물리적으로 구축하고 수작업으로 관리해야 했다. 설정을 변경하거나 새로운 자원을 추가하는 데 시간이 오래 걸렸고, 특히 개발, 스테이징, 운영 환경 등 유사한 설정을 일관되게 복제하는 일도 어려웠다. 이러한 수작업 과정에서는 종종 휴먼 에러가 발생했고, 안정적이고 일관된 관리가 힘들었다.
AWS, Azure, GCP 같은 클라우드 서비스가 등장하면서 상황이 달라지기 시작했다. 가상화된 자원으로 인프라를 손쉽게 구성할 수 있게 되면서, 기존의 관리 방식으로는 클라우드가 제공하는 유연성과 확장성을 온전히 활용하기가 어려워졌다.
또한, DevOps 문화가 확산되면서 개발과 운영이 통합되고 빠른 배포와 잦은 변경이 요구되었고, 이에 맞춰 인프라 역시 빠르게 변경될 필요성이 커졌다.
이러한 흐름 속에서 탄생한 개념이 바로 "코드로 인프라를 관리하자"는 IaC 이다. 커지는 인프라 규모와 복잡한 구성, 빠른 변경, 자동화에 대한 요구를 충족시키며 안정적으로 인프라를 관리하기 위해 IaC의 필요성이 커지고 있다.
IaC 의 장점
IaC의 구체적인 장점은 다음과 같이 요약할 수 있다.
- 자동화
- 일관성
- 버전 관리 및 협업
- 복구 및 확장
각 장점은 구체적으로 무엇을 말하는 것일까? 하나씩 알아 보도록 하자.
자동화
기존 방식과 IaC 로 AWS에 EC2 인스턴스 20개를 생성하는 일을 생각해보자.
기존 방식은 다음과 같은 과정을 20번 반복해야 한다.
1. AWS 콘솔 로그인
2. EC2 대시보드 접속
3. 인스턴스 타입 선택
4. 네트워크 설정
5. 스토리지 구성
6. 태그 추가
7. 보안그룹 설정
...
이러한 수동 작업은 시간이 오래 걸릴 뿐만 아니라 각 단계마다 실수할 가능성이 존재한다. 또한 작업자가 바뀌면 동일한 과정을 숙지하고 반복해야 한다.
IaC의 경우는 어떨까? 코드를 작성하고 명령어만 실행시키면 20대의 인스턴스가 즉시 생성된다.
(예시 - Terraform)
resource "aws_instance" "web" {
count = 20
ami = "ami-0123456789"
instance_type = "t2.micro"
tags = {
Name = "web-server-${count.index + 1}"
}
}
이처럼 IaC를 통한 자동화로 다음과 같은 장점을 가진다.
- 반복 작업을 줄여 작업 시간을 단축할 수 있다.
- 반복 작업 중 발생할 수 있는 휴먼 에러를 방지할 수 있다.
- 작성된 코드를 재사용하여 동일 작업을 쉽게 반복할 수 있다.
일관성
이번에는 개발, 스테이징, 운영 환경을 구축하는 상황을 생각해보자.
각 환경들은 서버의 인스턴스 유형과 같은 일부 설정만 다르고, 기본적인 인프라 구성은 동일해야 한다.
기존 방식은 각 환경을 구축할 때 마다 동일한 작업을 반복해야 한다. 그 과정에서 설정을 누락하거나, 다르게 설정하는 등 의도치 않은 차이가 발생할 수 있다.
[개발 환경]
1. EC2 생성 (t2.micro)
2. nginx 설치
3. 방화벽 설정 (80 포트 오픈)
4. 로그 설정
[스테이징 환경]
1. EC2 생성 (t2.small)
2. nginx 설치
3. 방화벽 설정 (80 포트 오픈)
4. 로그 설정
[운영 환경]
1. EC2 생성 (t2.large)
2. nginx 설치
3. 방화벽 설정 (80 포트 오픈)
4. 로그 설정
IaC 방식을 이용한다면 환경 구축이 쉬워진다. 다음 예시 처럼 동일한 코드를 사용하고 환경별 차이점만 변수로 관리한다면 모든 환경에서 일관된 구성을 보장할 수 있다. 인스턴스 크기는 달라지더라도 기본 구성은 항상 동일하게 적용된다.
# 환경별 변수 파일 (variables.tf)
variable "environment" {
description = "Environment type"
}
# 환경별 설정
locals {
instance_type = {
dev = "t2.micro"
stg = "t2.small"
prod = "t2.medium"
}
}
# 인프라 정의 (main.tf)
resource "aws_instance" "web" {
instance_type = local.instance_type[var.environment]
security_group = aws_security_group.web.id
}
resource "aws_security_group" "web" {
to_port = 80
cidr_blocks = ["0.0.0.0/0"]
}
*예시를 위해 일부 설정을 생략함
이처럼 동일한 코드를 환경별 변수만 다르게 적용함으로써 설정 차이로 인한 장애를 예방하고 일관된 인프라를 보장할 수 있게 된다.
버전 관리 및 협업
IaC를 통해 작성된 인프라 코드는 Git과 같은 버전 관리 시스템으로 관리할 수 있다. 덕분에 변경 이력 추적과 문제 발생 시 원인 파악이 용이하며, 코드 리뷰를 통한 협업과 휴먼 에러 방지가 가능하다.
여기서 의문이 들 수 있다. 기존의 수동 방식에서도 인프라 구성 방법을 문서화하고, 그 문서를 버전 관리할 수 있지 않은가?
이에 대한 답은 기존 방식과 IaC 차이점인 "실행 가능한 코드"와 "신뢰할 수 있는 단일 정보원"이라는 특징에서 찾을 수 있다.
기존 방식의 문서는 단순한 "의도된 상태"를 나타낸다. 인프라 구성을 위한 지침이지만, 실제로 인프라가 그 문서대로 구성되었는지는 보장할 수 없다. 인프라를 구성하는 작업자가 문서를 따르지 않았거나, 실수할 수 있다. 반면 IaC에서는 코드가 곧 인프라의 "실제 상태"다. 코드 자체가 실행되어 정의된 대로 정확하게 인프라를 구성한다.
즉, 기존 방식은 "이렇게 할 것이다"는 의도를 관리한다면, IaC는 "이렇게 되었다"는 상태를 관리하는 것이다.
EC2 인스턴스 5대를 코드로 관리하는 중 누군가 콘솔에서 직접 1대를 삭제했다고 가정해보자. IaC 도구는 이런 불일치를 감지하고 자동으로 복구할 수 있다. 코드가 인프라의 진짜 상태이며, 실제 환경은 코드에 맞추어 조정되는 것이다.
그러므로 인프라 변경은 반드시 코드를 통해 이루어져야 하며, 정기적인 상태 확인을 통해 코드와 실제 인프라 간의 일치 여부를 확인해야 한다.
복구 및 확장
재난, 재해가 발생한 상황을 가정해보자. 현재 재난, 재해로 인해 특정 리전의 서비스에 장애가 발생한 상황이다.
기존 방식은 다음과 같은 절차를 거칠 것이다.
1. 장애 리전 확인
2. 새로운 리전에 VPC 생성
3. 서브넷 구성
4. 보안 그룹 설정
5. EC2 인스턴스 생성
6. 로드밸런서 설정
7. 데이터베이스 복구
...
이러한 복구 작업을 수동으로 진행해야 하며, 긴급한 상황 속에서 실수할 가능성이 높아진다.
하지만 코드를 사용한다면 간단한 일이다.
# 기존 코드에서 리전만 변경
provider "aws" {
region = "ap-northeast-2" # 서울 리전으로 변경
}
module "web_service" {
source = "./modules/web_service"
environment = "production"
instance_count = 3
}
기존에 작성한 코드에서 리전만 변경하고 실행한다면, 인프라 전체가 새로운 리전에 동일하게 구성된다.
확장이 필요한 경우도 마찬가지다. 트래픽이 증가해서 서버를 추가해야 하는 경우
# 인스턴스 수만 변경
module "web_service" {
source = "./modules/web_service"
environment = "production"
instance_count = 5 # 3대에서 5대로 증가
}
인스턴스 수만 수정하면 인프라를 확장할 수 있다.
즉, IaC를 사용하면 인프라의 복구와 확장이 쉬워진다. 모든 인프라가 코드로 정의되어 있기 때문에 장애 상황이나 규모 확장이 필요할 때 신속하고 정확한 대응이 가능해진다.
IaC 의 단점
물론 IaC가 장점만을 가지고 있는 만능의 도구는 아니다.
우선 진입장벽이 존재한다. 기존에 익숙하게 사용한 콘솔 조작이 아닌, IaC 도구 사용법과 관련 개념을 추가로 학습해야한다.
또한, 간단한 인프라 구성의 경우 오히려 수동 작업이 더 효율적일 수 있다. IaC는 설정해야 할 옵션이 많고 알아야 할 것들이 많은데, 단순한 테스트 환경을 구성하는 데 이런 작업들이 오버헤드가 될 수 있다.
마지막으로 IaC로 정의할 수 없는 설정들이 존재한다. 웹 콘솔이나 CLI로는 가능하지만 IaC로는 불가능한 설정과 옵션들이 있다. 클라우드 서비스는 보통 API-First 정책을 따르지만, 일부 신규 기능이나 마이너한 기능들은 IaC Provider에 반영되기 까지 시간이 걸린다. 물론 Terraform의 AWS Provider와 같은 메이저 Provider들은 새로운 기능도 비교적 빠르게 지원되긴 한다.
'공부' 카테고리의 다른 글
Git CLI - 기초02 (0) | 2022.03.12 |
---|---|
Git CLI - 기초01 (0) | 2022.03.06 |
Git 이란 무엇인가? (0) | 2022.03.06 |