CLOUDWAVE

IaC : Terraform - 테라폼 소개, 테라폼 환경 구축

갬짱 2025. 2. 7. 22:34

 

테라폼 소개

클라우드 및 온프레미스 리소스를 모두 정의할 수 있는 코드형 인프라 관리도구

일관된 워크플로우로 전반적인 인프라 수명주기를 관리하고 프로비저닝하는 역할

 

DevOps란

  • 전통적인 운영작업(Ops) : 개발후 코드를 배포하고 실행하는 작업, 수동으로 수행 → 눈송이 서버(snowflake server)(미묘하게 다른 구성, 종속성 설치가 상이) → 버그의 수 증가, 가동 중단 및 다운타임 자주 발생
  • 최근의 운영작업 : 인프라를 클라우드 환경으로 전환 + 자동화 도구를 이용하여 소프트웨어적으로 제어
  • 코드를 지속적으로 통합하고 배포가능한 상태로 유지 = 실행환경(runtime)을 일관적으로 유지
  • DevOps의 핵심가치(4가지) : 문화, 자동화, 측정(모니터링 도구), 공유(약어로 CAMS라고도 함-git,notion)
    ** 자동화 ⇒ 코드를 통해 인프라 관리 ( IaC )

 

코드형 인프라( IaC )

코드를 작성하고 실행하여 인프라를 정의, 배포, 업데이트 및 제거하는 것

하드웨어 까지 포함하여 모든 측면을 소프트웨어로 취급하는 방식 → 빠른 배포, 빠른 오류복구, 짧은 리드타임

 

[ IaC도구 5가지 ]

 

(1) 애드훅( Ad hoc ) 스크립트 : 스크립트 언어(예: Bash, Ruby, Python)를 사용하여 각 단계를 코드로 정의하고 실행

  • 범용 프로그래밍 언어(GPL : 특정목적에 국한되지 않고 다양하게 사용 → 입력, 처리, 출력의 전과정)를 사용 → 각 개발자가 자신의 스타일을 사용하여 작업을 수행 ↔ IaC용 언어 : 간결한 API를 제공, 코드에 특정 구조를 적용
  • 선언적으로 동작하지 않음 → 코드의 유지관리 어려움 임시 스크립트로 소규모 일회성 작업에 이용
# Update the apt-get cache
sudo apt-get update
# Install PHP and Apache
sudo apt-get install -y php apache2
# Copy the code from the repository
sudo git clone <https://github.com/brikis98/php-app.git> /var/ww
# Start Apache
sudo service apache2 start

종속성을 설치하고, Git 저장소에서 일부 코드를 확인하고, Apache 웹 서버를 실행하여 웹 서버를 구성하는 bash 스크립트

 

(2) 구성관리 도구 : 구축된 기존서버에 소프트웨어를 설치하고 관리 ( Ansible, Chef, Puppet )

- name: Update the apt-get cache
  apt:
    update_cache : yes
- name: Install PHP
  apt:
    name: php
- name: Install Apache
  apt:
    name: apache2
- name: Copy the code from the repository
  git: repo=https://github.com/brikis98/php-app.git dest=/var/
- name: Start Apache
  service: name=apache2 state=started enabled=yes

bash스크립트와 동일하게 Apache웹서버를 구성하는 Ansible의 역할 web-server.yaml

 

[ 구성관리 도구의 장점 ]

  • 코딩규칙 : 일관되고 예측가능한 구조를 갖춤
  • 멱등성 : 현재 상태를 판단하여 작업 수행여부를 결정
  • 분산 : 로컬시스템뿐아니라 다수의 원격서버를 관리하기 위해 설계됨

 

여러개의 서버주소가 포함된 호스트 파일(inventory) 생성

[webservers]
11.11.11.11
11.11.11.12
11.11.11.13
11.11.11.14
11.11.11.15

 

Ansible 플레이북 정의 → 플레이북 실행 ( ansible-playbook playbook.yaml )

- hosts: webservers
  roles: web-server

 

 

(3) 템플릿 도구 : 운영체제와 독립적으로 세부적인 구성정보들을 스냅샷(캡처)하는 서버 이미지를 생성 ( Docker, Packer, Vagrant ) ( ↔ 여러 대의 서버에서 동일한 코드를 실행하는 구성방식 )

  • 불변(immutable) 인프라 의 핵심요소 : 보통 템플릿 생성후 IaC도구를 이용하여 서버에 이미지를 배포 → 배포후에는 변경이 필요없도록 최적화하여 구축( 업데이트가 필요한 경우 새 이미지를 생성하여 새 서버에 배포 ) 서버는 절대 변하지 않기에 배포된 내용을 추론하기 쉬움
  • 가상머신 : 하드웨어를 포함한 전체 컴퓨터 시스템을 에뮬레이트( 하이퍼바이저 사용 ) → 호스트 시스템 및 다른 VM이미지와 완전히 격리된 환경에서 동일한 방식으로 실행, 하드웨어 오버헤드 발생
    • Packer : 프로덕션 AWS 계정에서 실행하는 AMI와 같이 프로덕션 서버 위에서 직접 실행하는 이미지를 생성
    • Vagrant : VirtualBox 이미지와 같이 개발 컴퓨터에서 실행하는 이미지를 생성
  • 컨테이너 : OS의 사용자 공간을 에뮬레이트
    컨테이너 엔진을 실행하여 격리된 프로세스, 메모리, 네트워킹을 생성 격리 및 보안수준은 VM보다 낮지만 CPU 또는 메모리 오버헤드가 거의 없음
    • Docker : 개별 애플리케이션의 이미지를 생성 → Docker 엔진으로 실행

 

  • 일반적인 패턴 : Packer를 사용하여 Docker 엔진이 설치된 AMI를 생성 → AWS 계정의 서버 클러스터에 해당 AMI를 배포 → 해당 클러스터 전체에 개별 Docker container를 배포하여 애플리케이션을 실행

 

 

(4) 오케스트레이션 도구 : 컨테이너화된 애플리케이션의 배포, 확장, 관리 및 모니터링을 자동화하는 도구 ( kubernetes )

  • Kubernetes : 컨테이너를 코드로 관리하는 방법을 정의
    • 서버그룹인 kubernetes cluster를 배포( 대부분의 CSP에서 클러스터 배포를 지원 : EKS, GKE, AKS )
    • 동작중인 클러스터 서버에 Docker 컨테이너를 YAML 코드로 실행
    • Pod : 함께 실행할 하나 이상의 Docker 컨테이너 그룹 → 고가용성 측면에서 예약 알고리즘을 사용하여 클러스터의 node에서 각 pod가 배포할 위치를 자동으로 파악 → 여러 서버에서 여러개의 pod를 실행하고 클러스터를 지속적으로 모니터링하여 실행을 확인하고 자동으로 교체

 

(5) 프로비저닝 도구 : 서버 인프라를 생성 ( Terraform, CloudFormation, OpenStack Heat, Pulumi )

프로비저닝과 함께 서버 템플릿이 작동 ⇒ 불변인프라의 일반적인 패턴

 

 

테라폼의 동작방법

Terraform : HashiCorp에서 만들고 Go 프로그래밍 언어로 작성된 오픈 소스 도구

  • HCL( Hashicorp Configuration language )문법을 사용 → JSON과 유사, YAML처럼 들여쓰기가 필수는 아니지만 가독성을 위해 권장됨( 확장자는 .tf파일 )
  • 내부적으로 테라폼 바이너리가 사용자를 대신하여 클라우드 공급자(벤더)에게 API 호출 벤더( provider = CSP )마다 호출방식이 다름( 종속적 )

 

IaC 도구들간 차이점

  • 구성관리와 프로비저닝
    • 구성 관리 도구 : Chef, Puppet, Ansible
    • 프로비저닝 도구 : CloudFormation, Terraform, OpenStack Heat, Pulumi
    • 인기 있는 조합 : Terraform을 사용하여 서버를 프로비저닝하고 Ansible을 사용하여 각각을 구성
  • 가변 인프라와 불변 인프라
    • 가변 인프라 IaC : 변경가능한 인프라 패러다임을 기본으로 함 → 서버의 고유한 변경기록을 구축 ( Chef, Puppet, Ansible )
      • 미묘한 구성버그가 발생 ( 눈송이 서버 )
    • 불변 인프라 IaC : phoenix server를 추구 → 변경사항 발생시 기존 이미지를 재사용하는게 아니라 처음부터 모든 스택을 새로 설치 ( Docker 또는 Packer )
      • 프로덕션 환경에서도 정확히 동일한 방식으로 작동할 가능성이 높아 효과적임
      • Docker : source code → image화, configuration → configmap, secret으로 구현, data → volume으로 생성 각 역할을 분리( 지속적으로 변경하는 config, vol은 분리 )하여 image의 **변경을 최소화( read-only )**하고 재사용시 주입하는 개념으로 사용
  • 절차적 언어와 선언적 언어
    • 절차적 언어 : 최종상태를 달성하는 방법을 단계별로 코드작성( 위에서 아래로 순서대로 실행 ) - Ansible, Chef
    • 선언적 언어 : 원하는 최종상태를 지정하는 코드를 작성 - Terraform, CloudFormation, Puppet, OpenStack, Heat, Pulumi
      • terraform : 모든 코드를 메모리에 적재 → 동작순서를 자동으로 지정( 종속성에 따라 순서부여 ) 원하는 최종 상태를 선언하고 Terraform이 해당 최종 상태에 도달하는 방법을 파악하기 때문에 Terraform은 과거에 생성된 모든 상태도 인식 ⇒ 계획명령으로 변경사항을 파악가능

[ AMI를 실행하기 위해 10개의 서버(AWS 용어의 EC2 인스턴스)를 배포하는 작업 ]

- ec2:
	connt:20
	image: ami-0fb653ca2d3203ac1
	instance_type: t2.micro

 

절차적인 Ansible

resource "aws_instance" "example" {
	count = 10
	ami = "ami-0fb653ca2d3203ac1"
	instance_type = "t2.micro"
}

선언적인 Terraform

=> 코드의 수정 관리에서 선언적인 문법이 더욱 유용함

 

  • 범용 언어와 도메인 특정 언어
    • 범용언어( GPL ) Chef : Ruby 지원 Pulumi : JavaScript, TypeScript, Python, Go, C#, Java 등을 지원 ⇒ 큰 생태계와 성숙한 도구(품질)
    • 도메인별 언어( DSL : 특정 도메인, 기능에 특화 ) : 테라폼의 HCL, 젠킨스의 groovy, puppet의 puppet language, Ansible, CloudFormation 및 OpenStack Heat의 YAML ⇒ 배우기 쉬움, 명확하고 간결함, 균일함( 예측가능, 하나의 기능에 한가지 방법 ex. Terraform을 사용하여 AWS에 서버를 배포하는 방법은 실제로 한 가지 )
  • 마스터 서버의 유무
    클라이언트(CLI)를 사용하여 마스터서버(agent)에 새 명령을 실행하여 작업수행( agent쪽으로 요청하여 수행하는 방식 )
    ⇒ 중앙저장소의 역할, 구성 드리프트를 방지하는 장점을 가짐
    ⇒ 추가 인프라, 유지보수, 보안상 단점을 가짐
    • Chef 및 Puppet : 인프라 상태를 저장하고 업데이트를 배포하기 위해 마 스터 서버를 실행
    • ansible, terraform은 이와 달리 동작하여 저렴한 비용, 호환성이 좋음

 

테라폼 환경 구축

테라폼 패키지 다운로드 & AWS API 사용환경을 구축 = 인가된 사용자임을 증명(IAM사용자를 생성하고 인증 key를 이용)

 

(1) IAM 사용자 생성후 권한부여 ( AdministerAccess 정책을 부여 )

  • 대부분의 리전에서 계정 생성 시 기본 VPC가 자동으로 생성
  • AWS 기본동작 :: 사용자가 VPC를 명시적으로 지정하지 않으면 2013년 이후 생성된 모든 AWS 계정의 일부인 기본 VPC에 리소스가 배포
    ⇒ 테라폼에서 기본 VPC관련 리소스를 사용하고자 하지 않는다면 vpc_id 또는 subnet_id 매개변수를 직접 지정
  • 기본 VPC는 region당 1개가 생성public subnet들이 가용영역당 생성( 고정된 설정값 : IGW가 연결된 라우팅 테이블이 자동연결, 기본 NACL과 보안그룹 자동할당, public IP 자동부여 )

(2) 사용자 보안자격증명에서 액세스키를 만들고 저장 → 사용사례 : CLI( AWS CLI ), 서드파티( terraform등 ) 등

access key ID : AKIA*************JAY

secret access key : 5Q**********************************AC

 

(3) 테라폼 설치 → 운영체제의 패키지 관리자를 사용하는 것이 쉽고 바람직하다. ( macOS에서는 Homebrew, Windows에서는 Chocolatey, amazon linux에서는 yum )

yum의 repo 다운로드 → repo를 이용하여 테라폼 패키지 설치( controller )

curl -o /etc/yum.repos.d/terraform.repo <https://rpm.releases.hashicorp.com/AmazonLinux/hashicorp.repo>
curl -o /etc/yum.repos.d/terraform.repo <https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo>
yum install -y terraform

+) OpenTofu : Terraform의 오픈소스 포크 ( 설치 프로세스는 다르지만 사용법과 구축은 거의 동일 )

 

(4) AWS 자격증명 : 2가지 방식

  • aws cli 설치하여( sudo yum install awscli ) → aws configure 명령이용
aws configure

 

  • 환경변수로 세팅하여 aws configure → 환경 변수는 현재 셸에만 적용되므로 컴퓨터를 재부팅하거나 새 터미널 창을 열면 이러한 변수를 다시 내보내야함
export AWS_ACCESS_KEY_ID=[액세스 키 ID]
export AWS_SECRET_ACCESS_KEY=[비밀 액세스 키]

⇒ 자격증명의 확인 : 홈 디렉토리 내 .aws/credentials 파일 / aws s3 ls : 현재 계정에서 접근 가능한 S3 버킷 목록 → 버킷 목록이 출력되거나 아무것도 출력되지 않음