들어가며
드디어 테라폼 스터디가 시작되었습니다. 이전 AEWS에서 EKS기반 Kubernetes 클러스터드를 구축하고 매니징 하는 방법에 대해서 스터디했을 때는 cloudformation을 이용하여 환경을 구축했었는데, 요즘에는 테라폼이 더욱 많이 사용되는 추세인 것 같습니다. 이번 기회에 테라폼을 열심히 학습하여 사내 클라우드 인프라를 IaC(Infra structure as a Code)로 전환을 하는 것을 목표로 잡았습니다. 이번 세미나에서도 역시 스터디 진행자 분께서 다양한 꿀팁과 함께 테라폼의 기본 개념에 대해 잘 설명해 주셨습니다.
* 본 스터디의 자료는 아래의 책을 기반으로 합니다.
테라폼으로 시작하는 IaC | 김민수, 김재준, 이규석, 이유종 | 링크
테라폼이란?
테라폼은 HashiCorp 사에서 개발한 IaC 도구입니다. 워크플로우에 집중하고, 코드로 인프라를 관리하며, 실용주의 철학을 담아 설계 했다고 합니다. 테라폼을 이용하면 다양한 인프라 환경(클라우드, 가상 머신, 로컬) 요소들을 자동화하고 관리할 수 있습니다.
실제로 많은 회사들이 테라폼을 통해 비즈니스 인프라를 관리하고 있으며, DevOps를 적용하여 자동으로 손쉽게 유지보수 하고 있습니다.
테라폼은 다음과 같이 3가지 유형으로 사용할 수 있습니다.
Community 버전은 Terafrom이라 불리는 형태로, 사용자의 컴퓨팅 환경에 오픈소스 바이너리툴인 테라폼을 통해 사용합니다.
Terraform Cloud는 HashiCorp사에서 관리하는 서버에서 SaaS 형태로 제공됩니다. Cloud 서비스이지만 500 resourecs 까지 무료로 사용할 수 있다고 합니다.
실행환경 구성
테라폼을 설치하는 방법은 다양하게 있으나, mac OS는 brew를 이용하여 쉽게 설치할 수 있습니다.
# tfenv 설치
brew install tfenv
# 설치 가능 버전 리스트 확인
tfenv list-remote
# 테라폼 1.5.6 버전 설치
tfenv install 1.5.6
# 테라폼 버전 정보 확인
terraform version
스터디에서 사용되는 IDE는 vscode 입니다. Visual Studio Code (VSCode)는 널리 사용되는 텍스트 에디터 중 하나로, 다양한 확장 기능(Extension)을 통해 여러 프로그래밍 언어와 도구에 대한 지원을 받을 수 있습니다. vscode를 설치한 후 아래의 세가지 Extention을 설치합니다.
HashiCorp HCL
- 기능: HCL (HashiCorp Configuration Language)는 HashiCorp에 의해 개발된, 테라폼 같은 HashiCorp 도구들에서 사용되는 설정 언어입니다. 이 확장 기능은 HCL 코드에 대한 문법 강조(syntax highlighting), 포맷팅, 그리고 자동 완성 기능을 제공합니다.
- 용도: 테라폼 .tf 파일이나. hcl 파일을 편집할 때 문법 오류를 쉽게 발견하고, 코드를 깔끔하게 유지할 수 있습니다.
HashiCorp Terraform
- 기능: 이 확장 기능은 테라폼 코드를 작성, 검증, 실행하기 위한 다양한 도구를 제공합니다. 문법 강조뿐만 아니라, 테라폼 명령어를 직접 VSCode 내에서 실행할 수 있는 기능, 코드 검증, 상태 관리 등이 포함되어 있습니다.
- 용도: 테라폼 프로젝트를 효율적으로 관리하고, 디버깅하는 데 도움이 됩니다. 특히 복잡한 테라폼 코드를 작성하거나, 여러 사람이 함께 작업할 때 유용합니다.
graphviz
- 기능: Graphviz는 그래프 시각화 소프트웨어입니다. 테라폼은 자원 간의 의존성을 그래프로 표현할 수 있고, 이 확장
기능은 그런 그래프를 시각화할 수 있는 도구를 제공합니다. - 용도: 테라폼 코드에서 정의한 인프라의 구조와 의존성을 이해하기 쉽게 시각적으로 표현해줍니다. terraform graph 명령어로 생성된 DOT 언어를 사용한 그래프 설명을 시각화할 때 유용합니다.
편의성을 위해 소스코드 편집시 자동으로 저장되도록 설정합니다.
- 설정 > 일반적으로 사용되는 설정 > Auto Save > afterDelay
다음으로는 AWS resource에 접근하기 위해 awscli를 설치합니다.
# brew를 이용하여 aws cli 설치
brew install awscli
# aws cli 버전 확인
aws --version
aws-cli/2.13.13 Python/3.11.5 Darwin/22.6.0 source/x86_64 prompt/off
# AWS 접속 권한 설정 (Access key, Secret key)
aws configure
# access_key, secret_key, region을 기입
# aws cli 사용을 통해 동작여부를 확인
aws s3 ls
HCL (HashiCorp Configuration Language)
HCL을 이용하면 코드를 통해 인프라를 관리하고 프로비저닝 할 수 있습니다. HCL은 인프라를 선언적(declarative)으로 관리할 수 있습니다. 또한 프로그래밍 언어처럼 조건문 처리 같은 동작이 가능하며, 함께 작업할 수 있는 기반을 제공합니다.
아래의 그림은 스터디에서 소개한 HCL과 JSON 포맷의 CloudFormation 구성인데, 이렇게 보니 좀 더 프로그래머 친화적인 언어의 느낌이 듭니다.
다음은 HCL의 문법에 대한 간략한 예시입니다.
// 한줄 주석 방법1
# 한줄 주석 방법2
/*
라인
주석
*/
locals {
key1 = "value1" # = 를 기준으로 키와 값이 구분되며
myStr = "TF ♡ UTF-8" # UTF-8 문자를 지원한다.
multiStr = <<EOF
Multi
Line
String
with anytext
EOF
boolean1 = true # boolean true
boolean2 = false # boolean false를 지원한다.
deciaml = 123 # 기본적으로 숫자는 10진수,
octal = 0123 # 0으로 시작하는 숫자는 8진수,
hexadecimal = "0xD5" # 0x 값을 포함하는 스트링은 16진수,
scientific = 1e10 # 과학표기 법도 지원한다.
# funtion 호출 예
myprojectname = format("%s is myproject name", var.project)
# 3항 연산자 조건문을 지원한다.
credentials = var.credentials == "" ? file(var.credentials_file) : var.credentials
}
테라폼 용어 정리
Resource
- 실제로 생성할 인프라 자원 입니다.
ex) aws_security_group, aws_lb, aws_instance
Provider
- Terraform으로 정의할 Infrastructure Provider를 의미합니다. Terraform Registry
Output
- 인프라를 프로비저닝 한 후 생성된 자원을 output으로 뽑을 수 있습니다. Output으로 추출한 부분은 이후에 remote state에서 활용할 수 있습니다.
Backend
- terraform의 상태를 저장할 공간을 지정하는 부분입니다. 현재 배포된 최신 상태를 외부에 저장하기 때문에 다른 사람과 협업이 가능하고, 저장 공간으로 AWS S3를 주로 사용합니다.
Module
- 공통적으로 활용할 수 있는 인프라 코드를 한 곳으로 모아서 정의하는 부분입니다. Module을 사용하면 변수만 바꾸서 동일한 리소스를 손쉽게 생성할 수 있습니다.
Remote state
- VPC, IAM 등과 같은 공용 서비스를 다른 서비스에서 참조할 수 있습니다.
tfstate파일(최신 테라폼 상태정보)이 저장되어 있는 backend 정보를 명시하면, terraform이 해당 backend에서 output정보를 가져옵니다.
테라폼 흐름
Terraform init
- Terraform에서 사용하는 리소스 프로바이더를 설치합니다. 지정한 backend에 상태 저장을 위한. tfstate 파일을 생성합니다. 기본적으로 로컬에 backend가 생성되고, 가장 마지막에 적용한 테라폼 내역이 저장됩니다.
- init 작업을 완료하면, local에는. tfstate에 정의된 내용을 담습니다. terraform 파일이 함께 생성됩니다.
- 기존에 다른 개발자가 이미. tfstate에 인프라를 정의해 놓은 것이 있다면, init을 통해 local에 sync를 맞출 수 있습니다.
Terraform plan
- 정의한 코드가 어떤 인프라를 만들게 되는지 미리 예측 결과를 보여줍니다. 단, plan을 한 내용에 에러가 없더라도 실제 적용 시엔 에러가 발생할 수 있습니다.
- plan 명령어는 어떠한 형상에도 변화를 주지 않습니다.
Terraform apply
- 실제로 인프라를 배포하기 위한 명령어입니다. apply를 완료하면, AWS 상에 실제로 해당 인프라가 생성되고 작업 결과가 backend의. tfstate 파일에 저장됩니다. 해당 결과는 local의. terraform 파일에도 저장됨
Terraform import
- AWS 인프라에 배포된 리소스를 terraform state로 옮겨주는 작업을 수행합니다.
- local의. terraform에 해당 리소스의 상태 정보를 저장해 주는 역할을 합니다. apply전까지는 backend에 저장되지 않으나, import 이후에 plan을 하면 로컬에 해당 코드가 없기 때문에 변경된다는 결과를 보여줍니다.
테라폼 블록
테라폼 블록은 테라폼 구성을 명시하는 데 사용됩니다. 스터디에서 강조한 내용은, 테라폼 블록을 구성할 때 버전 관련 정보들을 다음과 같이 명시적으로 선언해야 향후 필요한 조건을 개선하더라도 결과에 차이가 발생하지 않는다는 것입니다.
terraform {
required_version = "~> 1.3.0" # 테라폼 버전
required_providers { # 프로바이더 버전을 나열
random = {
version = ">= 3.0.0, < 3.1.0"
}
aws = {
version = "4.2.0"
}
}
cloud { # Cloud/Enterprise 같은 원격 실행을 위한 정보 [참고: Docs]
organization = "<MY_ORG_NAME>"
workspaces {
name = "my-first-workspace"
}
}
backend "local" { # state를 보관하는 위치를 지정 [참고: Docs, local, remote, s3]
path = "relative/path/to/terraform.tfstate"
}
}
테라폼으로 구성된 여러 프로젝트들을 살펴보며 자주 사용되는 블록을 정리해 보았습니다.
provider 블록:
- Terraform의 공급자(provider)를 지정하는 블록입니다.
- 예를 들어, AWS, Azure, Google Cloud Platform 등의 클라우드 서비스 공급자를 지정할 수 있습니다.
terraform 블록:
- Terraform의 설정 옵션을 지정하는 블록입니다.
- 예를 들어, 사용할 Terraform 버전, 백엔드 설정, 변수 정의 등을 포함할 수 있습니다.
resource 블록:
- Terraform으로 관리하고자 하는 인프라 리소스를 정의하는 블록입니다.
- 예를 들어, 가상 머신(VM), 네트워크, 로드 밸런서 등의 리소스를 정의할 수 있습니다.
data 블록:
- Terraform으로 데이터를 가져오는 블록입니다.
- 예를 들어, 클라우드 서비스의 AMI, VPC, 서브넷 등의 정보를 가져올 때 사용됩니다.
variable 블록:
- Terraform 변수를 선언하는 블록입니다.
- 변수를 사용하여 모듈화, 재사용성 및 유연성을 높일 수 있습니다.
output 블록:
- Terraform 실행 결과로 출력되는 값들을 정의하는 블록입니다.
- 예를 들어, 생성된 리소스의 IP 주소, 이름 등을 출력할 수 있습니다.
사용법
로컬에서 txt 파일을 생성하는 법과 종속성 설정 및 ec2 인스턴스 배포하는 실습을 진행했습니다.
종속성의 의미는 하나의 리소스를 생성함에 있어 사전 생성되어야 하는 리소스가 있어야 한다는 것입니다. 이러한 종속성은 1번 예시와 같이 직접 리소스의 값에 접근하여 생성하는 방법과, 2번 예시처럼 직접 depends_on을 이용하여 명시하는 방법이 있습니다.
복잡한 인프라를 생성하게 되면 다소 종속성이 많이 발생할 것 같네요.. 그래서 사전에 설치한 graphviz extention을 이용하여 종속성을 그래프 형태로 확인할 수 있습니다. 테라폼 소스코드 분석에 많은 도움이 될 것 같습니다.
예를 들어 이전 스터디에 참여하셨던 HallsHolicker님께서 만들어주신 EKS 기반 클러스터 생성 테라폼파일을 clone 하여 그래프를 생성해 보면, 이런 식으로 종속성들을 파악할 수 있게끔 나오게 됩니다.
HallsHolicker awes-study repository | 링크
terraform graph > graph-2.dot
결과는..
실습 - EC2 인스턴스 생성
cat <<EOT > main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_instance" "example" {
ami = "ami-084e92d3e117f7692"
instance_type = "t2.micro"
}
EOT
# 프로바이더 로드
terraform init
# 실행계획 확인
terraform plan
# 인프라 배포
terraform apply
#삭제
terraform destroy -auto-approve
실습 - local provider를 이용하여 파일 생성 및 종속성 확인
# 프로바이더 -> hashicorp local
resource "local_file" "abc" {
content = "123"
filename = "${path.module}/abc.txt"
}
resource "local_file" "def" {
content = "456!"
filename = "${path.module}/def.txt"
}
# 종속성 1
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
resource "local_file" "def" {
content = local_file.abc.content # 123!
filename = "${path.module}/def.txt"
}
# 종속성 2
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
resource "local_file" "def" {
**depends_on = [
local_file.abc**
]
content = "456!"
filename = "${path.module}/def.txt"
}
# graph 확인 > graph-2.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph
terraform graph > graph-2.dot
종속성 1
종속성 2
도전과제 (3번)
lifecycle의 precondition 실습 내용에서 step0.txt ~ step6.txt 총 7개의 파일 이름 중 하나가 일치 시 검증 조건 만족으로 코드 작성
참고: 링크
lifecycle.precondition 요소를 이용하여 프로비저닝 조건을 검증할 수 있습니다.
variable "file_name" {
default = "step6.txt"
}
resource "local_file" "abc" {
content = "test"
filename = "${path.module}/${var.file_name}"
lifecycle {
precondition {
condition = contains([
"step0.txt",
"step1.txt",
"step2.txt",
"step3.txt",
"step4.txt",
"step5.txt",
"step6.txt"
], var.file_name)
error_message = "File name is not \"step0 ~ 6.txt\""
}
}
}
default의 파일 명을 step0~6.txt로 했을 때는 다음과 같이 정상적으로 리소스가 생성되는 것을 확인할 수 있습니다.
반대로 step7.txt라는 값을 default에 설정하면 lifecycle에 선언해 둔 조건에 만족하지 못하여 다음과 같이 에러가 발생하게 됩니다.
동일한 과제를 제출하신 다른 분 께서는 정규표현식을 이용했습니다. 정규표현식을 쓰는 방법이 더 깔끔해 보이지만, 저는 다른 방법을 사용해 보고 싶어서 contains를 사용했는데요. 실무에서는 region과 같은 문자형 옵션을 판별하는데 쓰이는 것 같습니다.
마치며
이번 스터디에서는 기본적인 테라폼 개념과, 문법에 대해 다뤘습니다. 개인적으로 여러 매체를 통해 테라폼을 학습하고 있었지만, 버전관리나, 그래프 모듈, 테라폼 클라우드와 라이선스 정책과 같은 다양한 팁들을 얻을 수 있었습니다. 열심히 스터디를 완주하여, EKS 클러스터를 멋지게 테라폼으로 관리하는 날을 꿈꾸며 이번 포스팅을 마치겠습니다.
'클라우드 컴퓨팅 & NoSQL > [T101] 테라폼 기초 입문 스터디' 카테고리의 다른 글
[6주차] T101 테라폼 기초 입문 스터디 (23.10.08) (2) | 2023.10.10 |
---|---|
[5주차] T101 테라폼 기초 입문 스터디 (23.09.24) (1) | 2023.09.29 |
[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 |