cloudNet@ 팀의 가시다 님이 진행하는 테라폼 102 스터디 1주차 정리입니다.
1주차 내용:
테라폼 HCL 분석
1. 테라폼 HCL
HCL이란?
hashiCorp Configuration Language은 하시코프사에서 IaC와 구성 정보를 명시하기 위해 개발된 오픈 소스 도구이다
HCL 특징 ?
- 선언적 특성을 가지며, 튜링-complete한 언어적 특성을 갖는다.
- 튜링 complete란? 어떤 프로그래밍 언어나 추상 기계가 튜링 기계와 동일한 계산 능력을 가진다는 의미이다.
- 즉, 그안에서 프로그래밍 언어와 같이 조건문,for문,while 등 자동화에 필요한 동작들이 가능하다.
- 자동화와 더불어, 쉽게 버저닝해 히스토리를 관리하고 함께 작업 할 수 있는 기반을 제공. ( SCM과 연계 가능 )
- 예시 ***
# HCL
resource "local_file" "abc" {
content = "abc!"
filename = "${path.module}/abc.txt"
}
# JSON
{
"resource": [
{
"local_file": [
{
"abc": [
{
"content":"abc!",
"filenale":"${path.module}/abc.txt"
}
]
}
]
}
]
}
- HCL을 사용하면 동일한 내용을 JSON 으로 표현하는 것 보다 더 간결하고 읽기 쉽게 작성된다.
2. 테라폼 블록
테라폼 블록이란?
테라폼 버전이나 , 프로바이더 버전과 같은 값들을 설정하고, 멱등성을 보장하기 위해서 이러한 부분을 명시적으로 선언하고
필요 조건들을 입력하여, 실행오류를 최소화 하기 위해 사용된다.
예시 ***
terraform {
required_version = "~> 1.3.0" # 테라폼 버전
required_providers { # 프로바이더 버전을 나열
random = {
version = ">= 3.0.0, < 3.1.0"
}
aws = {
version = "4.2.0"
}
}
cloud { # Cloud/Enterprise 같은 원격 실행을 위한 정보
organization = "<MY_ORG_NAME>"
workspaces {
name = "my-first-workspace"
}
}
backend "local" { # state를 보관하는 위치를 지정
path = "relative/path/to/terraform.tfstate"
}
}
- 테라폼 내에서 버전이 명시되는 부분은 (테라폼, 프로바이더, 모듈 ) 3군데 인데, 버전 체계는 시멘틱 버전 관리 방식을 따른다.
- 시멘틱 버전 관리 방식이란?
- Major 버전 : 내부 동작의 API가 변경 또는 삭제되거나 하위 호환이 되지 않는 버전
- Minor 버전 : 신규 기능이 추가되거나 개선되고 하위 호환이 가능한 버전
- Patch 버전 : 버그 및 일부 기능이 개선된 하위 호환이 가능한 버전
# version = Major.Minor.Patch
version = 1.3.4
- 테라폼 버전 : terraform version 명령어 입력시 확인 가능하다.
# 테라폼 버전에 대한 문제가 생길수 있는 경우를 한번 살펴보자
# 테라폼 eks 배포 플러그인을 보면 1.3 버전 이상의 terraform 버전을 요구하는것을 알 수 있다.
terraform {
# 이부분은 왜 주석처리 되있을까?
/*
cloud {
workspaces {
name = "learn-terraform-eks"
}
}
*/
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.4.0"
}
}
required_version = ">= 1.3"
##...
}
- 프로바이더 버전
- 테라폼 0.13 버전 이후 부터는 terraform 블록 안에서 프로바이더 버전을 정의
- 모듈 버전
- Module은 공통으로 활용할 수 있는 다수의 .tf 파일들로 모아 정의하는 것으로 라이브러리 같은 개념으로 사용하며 Module Block을 통해 선언합니다.
- Root Module과 Child Module로 분류됩니다.
- Root Module - 작업을 수행하는 디렉터리에 있는 테라폼 코드 모음
- Child Module - 다른 Module에서 참조하여 사용하는 테라폼 코드 모음
- Module의 하위 Argument 중 Source를 통해 참조할 Module을 명시합니다. (Local paths, Terraform Registry, Github, G3 Buckets, GCS buckets 등)
- 테라폼은 Terraform Registry로 다양한 Module의 저장소를 제공합니다.
- Module을 처음 사용 시 반드시 terraform init 을 실행해야 합니다.
module "webserver_cluster" {
source = "../../../modules/services/webserver-cluster"
}
3. 백엔드 블록
- 백엔드 블록의 구성은 테라폼 실행 시 저장되는 State(상태 파일)의 저장 위치를 선언한다.
- 주의할 점은 하나의 백엔드만 허용한다는 점이다.
- 테라폼은 State 데이터를 사용하여 리소스를 탐색하고 추적 한다.
- 작업자 간의 협업을 고려한다면 테라폼으로 생성한 리소스의 상태 저장 파일을 공유할 수 있는 외부 백엔드 저장소가 필요하다.
- 기본적으로 활성화되는 백엔드는 local이다.
- 상태를 작업자의 로컬 환경에 저장하고 관리하는 방식이다.
- 이 밖의 다른 백엔드 구성은 동시에 여러 작업자가 접근해 사용할 수 있도록 공유 스토리지 같은 개념을 갖는다.
- 공유되는 백엔드에 State가 관리되면 테라폼이 실행되는 동안.terraform.tfstate.lock.info 파일이 생성되면서 해당 State를 동시에 사용하지 못하도록 잠금 처리를 한다.
- state파일이 테라폼에 어떤 영향을 미치는지 알아보자
cat <<EOT > main.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "local_file" "abc" {
content = "123456!"
filename = "${path.module}/abc.txt"
}
EOT
- terraform apply
- 실행후 생성되는 terraform.tfstate 파일을 확인해볼것이다.
terraform apply
------------------------------------------------------------------------
Plan: 1 to add, 0 to change, 0 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_instance.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Still creating... [20s elapsed]
aws_instance.example: Still creating... [30s elapsed]
aws_instance.example: Creation complete after 31s [id=i-0c9fd8aa1a2556fce]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
{
"ID":"2aa5287d-aa2c-c6d9-1554-daf2c60b120d",
"Operation":"OperationTypeApply", # 어떤 동작으로 인해 잠금 파일이 생성되었는지?
"Info":"","Who":"mzc01-kook@MZC01-KOOK.local", # 작업자 정보
"Version":"1.3.2", # 테라폼 버전
"Created":"2023-07-05T04:18:26.998256Z",
"Path":"terraform.tfstate" # 잠김 파일 위치
}
- 수정이 있을시 어떻게 될까?
ls terraform.tfstate*
# 2개 파일이 생성되있다.
# terraform.tfstate terraform.tfstate.backup
- 이번에는 백엔드 블록을 통해 path를 수정해보도록 하겠다.
terraform {
backend "local" {
path = "state/terraform.tfstate"
}
}
resource "local_file" "abc" {
content = "123456!"
filename = "${path.module}/abc.txt"
}
- 백엔드가 수정되었으니 init을 다시 해주어야 한다.
# init 시 백엔드 변경에 따른 마이그레이션 안내
terraform init
...
Enter a value: yes
...
#
ls terraform.tfstate*
tree state
cat state/terraform.tfstate | jq
cat state/terraform.tfstate | jq -r .serial
#
terraform apply -auto-approve
- 백엔드에 state파일의 경로를 수정해 주었더니 의도한대로 로컬 위치에 저장이 되었다.
4. 리소스 블록
- 리소스 선언은 리소스 유형, 동일한 유형에 대한 식별자 역할
- 이름,구성 인수들이 이름 뒤에 중괄호 내에 선언됨
resource "local_file" "abc" {
content = "123"
filename = "${path.module}/abc.txt"
}
resource "aws_instance" "web" {
ami = "ami-a1b2c3d4"
instance_type = "t2.micro"
}
- 종속성 :
- resource, module 선언으로 프로비저닝 되는 각 요소의 생성 순서를 구분 짓을수 있다.
- depends_on 이라는 메타인수를 사용하여 종속성을 부여한다.
- 종속성에 대한 확인은 VS Code의 확장 Extension pack 중 graphviz을 설치하여 그림으로 확인할수 있다.
- 설치 후에 apply 하고 나서 terraform graph > graph-1.dot
- 해당 파일을 VSCode에서 확인 하면 알수없는 파일형태로 보이지만 오른쪽 구석에 dot 클릭하면 그림으로 볼수 있다.
- 종속성을 부여하는 2가지 방법
- depends_on을 활용할수 있다.
- 테라폼 파일을 작성할때 두개의 리소스 간의 참조값을 활용하여 만들수 있다.
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
resource "local_file" "def" {
depends_on = [ # depends_on을 사용하는 방법
local_file.abc
]
content = "456!"
filename = "${path.module}/def.txt"
}
resource "local_file" "abc" {
content = "123!"
filename = "${path.module}/abc.txt"
}
resource "local_file" "def" {
content = local_file.abc.content # 참조값을 활용하는 방법
filename = "${path.module}/def.txt"
}
- 리소스 속성에서 참조 가능한 값은 인수, 속성이다.
- 인수: 리소스 생성시 사용자가 선언하는 값
- 속성: 사용자가 설정하는 것은 불가능 하지만, 리소스 생성 이후 획득 할수 있는 리소스 고유 값
# Terraform Code
resource "<리소스 유형>" "<이름>" {
<인수> = <값>
}
# 리소스 참조
<리소스 유형>.<이름>.<인수>
<리소스 유형>.<이름>.<속성>
- 수명주기
- lifecycle은 말그대로 리소스의 수명 주기를 작업자가 의도적으로 변경 할수 있는 메타인수이다.
- create_before_destroy (bool): 리소스 수정 시 신규 리소스를 우선 생성하고 기존 리소스를 삭제
- prevent_destroy (bool): 해당 리소스를 삭제 Destroy 하려 할 때 명시적으로 거부
- ignore_changes (list): 리소스 요소에 선언된 인수의 변경 사항을 테라폼 실행 시 무시
- precondition: 리소스 요소에 선언해 인수의 조건을 검증
- postcondition: Plan과 Apply 이후의 결과를 속성 값으로 검증
- create_before_destroy : 리소스 수정 시 신규 리소스를 우선 생성하고 기존 리소스를 삭제하는 메카니즘
- 기본적으로 default는 삭제 후 생성 이므로, 라이프사이클 부분을 생략해도 똑같이 동작한다.
- 하지만 생성되는 리소스가 기존 리소스로 인해 생성이 실패되거나 삭제 시 함께 삭제될 수 있으니 주의해야 한다.
- 잘못된 사례 1 : 리소스의 명시적 구분이 사용자가 지정한 특정 이름이나 ID인 경우 기존 리소스에 할당되어 있기 때문에 생성 실패
- 잘못된 사례 2 : 생성 후 삭제 시 동일한 리소스에 대한 삭제 명령이 수행되어 리소스가 모두 삭제
- 하지만 생성되는 리소스가 기존 리소스로 인해 생성이 실패되거나 삭제 시 함께 삭제될 수 있으니 주의해야 한다.
resource "local_file" "abc" {
content = "lifecycle - step 1"
filename = "${path.module}/abc.txt"
lifecycle {
create_before_destroy = false
}
}
- 삭제 후 create 해서 replace 하는것을 확인 할 수 있다.
Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.
local_file.abc: Refreshing state... [id=7e817d811209db576335597bcd326518fe13398b]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# local_file.abc must be replaced
-/+ resource "local_file" "abc" {
~ content = "lifecycle - step 1" -> "lifecycle - step 111111111" # forces replacement
~ content_base64sha256 = "mWPFMXSOz+Q/uQKVbykSD/aZqtO8THFqRCcH2NaqkXc=" -> (known after apply)
~ content_base64sha512 = "Wa0KB/Qm0YIFpVWUcDMFSiC42nNRLzGsB+MOox8EnJMWGwJ5gkfx4GdODN9BX9lPO+C1lWMAhUNTOLD6j1cBRg==" -> (known after apply)
~ content_md5 = "973913f00967dad5c7f311448854eadf" -> (known after apply)
~ content_sha1 = "7e817d811209db576335597bcd326518fe13398b" -> (known after apply)
~ content_sha256 = "9963c531748ecfe43fb902956f29120ff699aad3bc4c716a442707d8d6aa9177" -> (known after apply)
~ content_sha512 = "59ad0a07f426d18205a555947033054a20b8da73512f31ac07e30ea31f049c93161b02798247f1e0674e0cdf415fd94f3be0b595630085435338b0fa8f570146" -> (known after apply)
~ id = "7e817d811209db576335597bcd326518fe13398b" -> (known after apply)
# (3 unchanged attributes hidden)
}
테라폼은 immutable 하다.
'DevOps > Terraform' 카테고리의 다른 글
[T102 2주차] (6) 테라폼 반복문 (0) | 2023.07.10 |
---|---|
[T102 2주차] (5) 테라폼 VPC (1) | 2023.07.06 |
[T102 2주차] (4) 테라폼 기본 사용법(2) (0) | 2023.07.06 |
[T102 1주차] (2) 테라폼 설치 (0) | 2023.07.02 |
[T102 1주차] (1) 테라폼과 IAC ? (1) | 2023.07.02 |