- IaC를 사용하면 인프라의 원하는 최종 상태만 산언하면 되고 IaC가 관리와 프로비저닝을 처리함.
[4가지 과제]
- 높은 비지니스 수요로 인해 업계 전체에 걸쳐 IT 인프라를 빠르게 확장해야 함.
- 빠른 확장에 따라 인프라를 규모에 맞게 일관되게 관리하는 등의 새로운 운영 및 기술적 병목 현상을 극복해야 함.
- 인프라가 변경되면 DevOps팀은 협업하고 변경 사항을 감사하는 데 어려움을 겪는 경우가 많음. 성공적인 배포를 위해서는 의사소통 격차를 해소하는 것이 필수적.
- 양과 규모가 증가하면서 인간의 수동적 오류도 발생.
[IaC의 장점]
- 선언적: 특정 변경을 하기 위해 정확안 단계 순서를 지정하는 대신, 인프라의 원하는 상태에 집중할 수 있음.
(예) 프로덕션 레이블을 사용하여 두 지역에 걸쳐 세 개의 서브넷을 지정할 수 있음.
Terraform은 기존 서브넷에 레이블을 추가하고 추가 지역에 두 개의 새로운 서브넷을 만들어서 원하는 상태와 일치하도록 라이블 상태를 업데이트 함.
IaC 도구는 선언적 추상화를 통해 구현 세부 정보를 관리함으로 사용자는 원하는 상태에 대한 변경 사항에 집중할 수 있음.
이러한 선언적 접근 방식을 사용하면 시스템 관리자에게 묻지 않고도 누구나 인프라 상태를 읽을 수 있음.
- Code management: 애플리케이션 소스 코드와 동일한 방식으로 관리됨.
일반적으로 Google cloud console에서 직접 변경하는 경우, 수동으로 중요한 변경사항을 식별해야 함. 이는 오류가 발생하기 쉬운 프로세스임.
IaC를 사용하면 버전과 인프라 변경 사항에 대한 전체 기록을 볼 수 있음.
인프라 전체 기록은 커밋 로그에 기록됨. 버전 제어를 통해 개발자는 변경 사항에 대해 협업할 수 있음.
(예) 방화벽을 열어야 하는 경우, 관리자가 열어줄 때까지 기다리기 보다, 간단히 풀 리퀘스트를 제출하여 포트를 열수있음.
- Auditable: 인프라의 감사 가능한 내역 기능을 제공함.
감사 로그에서 변경 사항을 확인할 수 있지만 해당 변경 사항이 적용된 이유를 이해하는 것은 어려운 경우가 많음. IaC를 사용하면 설명을 포함할 수 있음.
- Portable: 규칙을 캡슐화하고 공유 템플릿에서 지속적으로 인프라를 구축할 수 있는 재사용 가능한 모듈을 빌드 할 수 있음.
인프라를 수동으로 재구축하는 대신, 동일한 템플릿의 여러 인스턴스를 다양한 애플리케이션이나 지역에 배포할 수 있음.
Google cloud는 Cloud Foundation Toolkit에서 찾을 수 있는 재사용 가능한 모듈을 개발했음.
재사용 가능하고, 문서화되고, 테스트된 인프라 코드 라이브러리를 사용하면 인프라를 더 쉽게 확장하고 발전시킬 수 있음.
[프로비저닝 vs. 구성관리]
- 기본적으로 IaC는 클라우드 리소스의 프로비저닝과 관리에 사용되고 구성관리가 VM OS 수준 구성에 사용됨.
(예) IaC의 인프라는 VM인스턴스를 생성하고 프로비저닝하고, 구성 관리를 통해 VM의 내불르 구성함.
구성 관리란 이 색션에서 다루는 것보다 더 광범위한 주제임.
간단하게 말해서, 애플리케이션 종속성을 위해 VM을 구성하는 것과 같은 활동은 구성 관리로 간주됨.
구성은 종종 서비스 시작, 종속성 설치, 애플리케이션 설치, 업데이트 실행 등의 수동 작업으로 구성됨.
IaC는 애플리케이션 코드를 실행하는 데 필요한 인프라를 배포하기 위해 Google Cloud API를 조작하는 프레임워크를 말함.
이와 대조적으로 구성 관리란 패키지 구성과 소프트웨어 유지 관리를 말함.
프로비저닝과 구성을 구별하기 위한 사례
IaC는 Google cloud에 GKE 클러스터를 시작하는 데 관련된 작업을 자동화하고, 구성 관리 기능은 컨테이너를 GKE 클러스터에 배포하는 데 관련된 작업을 자동화 함.
코드로서 인프라를 이해하는 데 있어 중요한 원칙은 그것이 선언적이라는 것.
대부분의 프로그래밍 언어는 명령형 모델을 사용하는데, 여기서는 5개의 서버를 만드는 것과 같이 수행하고자 하는 정확한 작업을 지정할 수 있음.
이 모델은 인프라에 어려움을 줌. 스크립트를 다시 실행하면 일부가 존재하더라도 5개의 새 서버가 생성될 수 있기 때문.
필수 워크플로우로 인해 라이브 인프라와 원하는 상태 간의 차이점을 파악하기 어려워서 리소스 생성이 반복됨.
IaC를 사용하면 인프라의 원하는 상태를 선언하는 도구가 세부 정보를 결정하게 할 수 있음.
[Terraform]
리소스의 예로는 가상 머신, 컨테이너, 스토리지, 네트워크 등이 있음.
Terraform을 사용하면 인프라를 HashiCorp Configuration Language(HCL)이라는 간단하고 사람이 읽을 수 있는 언어로 코드로 표현할 수 있음.
Terraform은 구성 파일을 읽고 변경 사항에 대한 실행 계획을 제공하며, 이를 검토 적용 및 프로비저닝할 수 있음.
높은 수준에서 Terraform을 사용하면 운영자가 Google Cloud 공급자에 대한 리소스의 정의가 포함된 파일을 작성하고 해당 리소스 생성을 자동화할 수 있음.
[Terraform features]
- 다중클라우드 및 다중 API 지원
Terraform은 GitHub, Kubernetes와 같은 API 노출 서비스와 Google Cloud 외에도 모든 주요 클라우드 공급자를 지원함.
- 엔터프라이즈 지원을 포함하여 셀프 호스팅부터 완전 관리형까지 세 가지 에디션이 제공됨.
- Google Cloud 배포를 위한 공개적으로 사용이 가능한 모듈이 있는 레지스트리를 포함한 대규모 커뮤니티
- 구성보다는 인프라 프로비저닝이 중요.
Google Cloud용 Terraform을 사용하면 리소스를 프로비저닝할 수 있음. 즉, 리소스 블록을 사용하여 VM, 네트워크, 방화벽과 같은 인프라 요소를 정의할 수 있음.
리소스간의 명시적 종송성을 만들면 특정 리소스는 다른 리소스가 생성된 후에만 생성될 수 있음. 재사용 가능한 모듈을 만들면 주어진 리소스를 생성하는 방법을 표준화할 수 있음.
검증 규칙을 사용하여 주어진 리소스 인수에 대해 제공되는 값을 제한할 수 있음.
[IaC configuration workflow]
- Scope: Confirm the resources required for a project
- Author: Author the configuration files based on the scope
- Initialize: Download the provider plugins and initialize directory
- Plan: View execution plan for resources created, modified, or destroyed
- Apply: Create actual infrastructure resources
[Terraform use case]
- Manage infrastructure: 변경 불가능한 접근 방식이 사용. 즉, 서비스와 인프라를 업그레이드하거나 수정하는 데 관련된 복잡성을 줄이는 코드를 작성
- Track changes: 새로운 변경 사항이 계획되거나 적용될 때마다 Terraform이 인프랄 상태를 수정하기 전에 변경 사항을 승인하는 메시지가 표시됨.
Terraform을 사용하여 인프라를 생성하면 상태 파일이 자동으로 생성됨. 상태파일은 인프라의 현재 상태를 반영하고 구성에서 수정된 Google Cloud 리소스의 양과 유형을 제공.
- Automate changes: 변경사항을 자동화하는데 사용. 구성파일은 본질적으로 선언적이므로 인프라를 구축하기 위해 자세한 지침을 작성할 필요가 없음. 당신은 단지 최종 상태만 정의.
Terraform은 종속성을 관리하고 리소스를 프로비저닝함.
- Standardize the configuration: 구성을 표준화하는데에도 사용됨.
모듈을 사용하면 시간을 절약하고 모범 사례를 구현할 수 있음. Terrform Registry에서 공개적으로 사용 가능한 모듈을 활용할 수 있음.
Terraform을 사용하면 팀에서 프로비저닝하고 사용할 수 있는 리소스 유형에 대한 정책적용을 자동화할 수도 있음.
[Using terraform]
- 구성 파일에 인프라를 코드로 작성해야 함.
구성 파일은 Terraform에 프로비저닝하려는 리소스를 설명함.
- Terraform은 원하는 상태에 대한 실행 계획을 생성한 다움,
- 해당 계획을 실행하여 설명된 인프라를 구축
- 구성이 변경되면 Terraform은 변경된 내용을 확인하고 적용할 수 있는 증분 실행 계획을 만들 수 있음.
[에디션]
- Commuity Edition: 로컬 머신이나 클라우드의 컴퓨팅 리소스에 다운로드할 수 있는 뮤료 소프트웨어 버전
버전관리 기능이 없음. CLI만 제공
- Cloud Edition. GUI. 협업 환경에 유용. [무료, 표준, 플러스] 플랜. 동시배포. 운영 오버헤드가 낮음.
- Enterprize Edition:GUI. 동시배포. 온프레미스 또는 귀하가 제어하는 인프라에 호스팅. 운영 오버헤드가 높음.
[HCL syntax]
- Blocks: 블럭은 간단할 수도 있고, 다른 블럭을 포함하도록 중첩될 수도 있음. [<block type> "<block lable>" "<block lable>"]
- Arguments: 블럭의 일부이며 이름에 값을 할당하는 데 사용. 일부 블록에는 필수 인수가 있고, 다른 블록에는 선택 인수가 있음.
- Identifiers: 인수, 블록 유형 또는 Terraform 특정 구성 요소의 이름. 식별자에는 문자, 밑줄, 하이픈, 숫자가 포함될 수 있지만 숫자로 시작할 수는 없음.
- Expressions: 표현식은 코드 블록 내의 식별자에 값을 할당하는 데 사용될 수 있음. 간단할수도 있고 복잡할수도 있음.
- Comments: #로 시작. single line.
[Concepts]
- 리소스는 인프라 구성요소를 정의하는 코드블럭.
리소스는 키워드 resource로 식별. 그 뒤에 리소스의 유형과 사용자 지정 이름이 붙음.
리소스 유형은 구성에 정의된 공급자에 따라 달라짐.
Terraform은 리소스 유형과 리소스 이름을 사용하여 인프라 요소를 식별함.
- providers.tf에는 공급자 관련 정보
Terraform은 공급자가 선언되면 루트 구성에서 공급자 플러그인을 다운로드함.
공급자는 특정 API를 Terraform 리소스로 노출하고 상호 작용을 관리함.
공급자 구성은 Terraform 구성의 루트 모듈에 속함.
- variables.tf
입력변수는 Terraform의 매개변수 역할을 하므로 소스 코드를 변경하지 않고도 쉽게 사용자 정의하고 공유할 수 있음.
변수가 정의되면 런타임에 해당 값을 설정하는 다양한 방법이 있음. 여기에는 변수, CLI옵션, 키 또는 값 파일 등이 있음.
리소스 속성은 런타임에 정의하거나 확장자가 .tvars인 파일에서 중앙에서 정의할 수 있음.
배포 계획에서 속성을 쉽게 분리할 수도 있음.
- terraform.tvars
변수 입력값. 이 파일이나 CLI등에서 설정.
- outputs.tf
리소스의 출력값을 보관.
Terraform이 관리하는 각 인스턴스는 구성의 다른 곳에서 사용할 수 있는 값을 갖는 속성을 내보냄.
필요한 경우 풀력 값은 해당 정보 중 일부를 노출하는 방법임.
일부 리소스 속성은 생성 시 계산됨.
(예) 버킷 생성 시 리소스의 셀프 링크나 버킷의 URL이 생성됨. 이러한 계산된 속성은 버킷에 액세스하거나 객체를 업로드하는 데 필요할 수 있음.
출력값을 사용하면 이 정보를 출력하고 접근 가능하게 만들 수 있음.
출력키워드(Outputs:) 뒤의 레이블은 이름이며, 유효한 식별자아여 함.
루트 모듈에서는 이 이름이 뷰어에 표시됨.
자식 모듈에서는 값에 접근하는 데 사용할 수 있음.
값의 인수는 사용자에게 결과를 반환하는 표현식을 받음.
- terraform.tfstate
리소스의 상태를 상태파일에 저장.
기본적으로 상태 파일은 로컬에 저장되지만 원격에도 저장할 수 있음. 팀 환경에서 작업할 때는 원격저장이 종종 선호되는 방식임.
자동으로 생성되고 갱신됨으로 수정하면 안됨.
- Modules
단일 디렉토리에 있는 Terraform 구성 파일의 집합.
하나 이상의 .tf 파일이 들어 있는 단일 디렉토리로 구성된 간단한 구성조차도 모듈로 간주됨.
모듈은 Terraform에서 코드를 재사용하는 기본 방법. 코드를 검색할 수 있는 소스를 지정하여 재사용함.
소스는 로렄이거나 원격일 수 있음.
HashiCorp 모듈 레지스트리에서 업스트림 모듈을 사용할 수도 있고, 직접 만들 수도 있음.
[command]
- terraform init: 공급자 초기화
- terraform plan: 리소스 미리보기.
- terraform apply: 리소스 생성
- terraform destroy: 리소스 파괴
- terraform fmt: 표준 규칙에 맞게 자동으로 포맷(형식)을 지정. 마치 Prettier나 Black 같은 포맷터 도구라고 생각하면 됩니다!
[IaC for Google Cloud]
- Introduction to resources
- Meta-arguments for resources
- Resource dependencies
- Variables
- Variables best practices
- Output values
- Terraform Registry and Cloud Foundation Toolkit
[Meta-arguments]
- count: 정의한 값에 따라 여러 인스턴스를 생성
- for_each: 맵이나 문자열 집합에 따라 여러 인스턴스를 생성
- depends_on: 명시적 종속성을 지정하는데 사용
- lifecycle: 리소스의 생명주기를 정의. 규정준수 목적으로 리소스 파괴를 방지하고 교체된 리소스를 파괴하기 전에 리소스를 만들수 있음. 가용성을 위해 자주사용됨.
- provider: 기본이 아닌 공급자 구성을 선택함. 공급자에 대해 기본값을 포함하여 여러 구성을 가질수 있음.
[count]
- 중복으로 선언하지 말고 수식으로 사용 할 수 있음. 0부터 시작. 보간법을 사용해서 문자열에 count 인덱스 변수를 포함함.
count = 3
name = "dev_VM${count.index +1}"
> "보간법"은 두 점 사이의 값을 추정하거나 중간 값을 계산할 때 사용하는 수학적 기법이에요. 데이터를 부드럽게 연결하거나 누락된 값을 채우는 데 자주 사용돼요. 영어로는 interpolation이라고 해요.
- 일부 인수에 정수에서 직접 파생될 수 없는 고유한 값이 필요한 경우 for_each를 사용하는 것이 더 안전.
for_each인수는 값의 문자열이나 맵에 할당될 수 있음.
for_each = toset(["web1", "web2", "web3"])
tags = {
Name = each.key
}
[Dependency graph]
- 인프라를 구축하는 동안 인프라가 어떻게 연결되고 상호 의존적인지 시각적으로 표현.
- 종속성 그래프는 배포하기 전에 인프라를 이해하는 데 도움이 됨.
- 속성은 런타임 동안 보간되고, 변수, 출력, 값, 공급자와 같은 기본요소는 종속성 트리에서 연결됨.
- Terraform은 올바른 작업 순서를 결정하기 위해 종속성 그래프를 만듬
- 여러 리소스가 있는 더 복잡한 사례에서 Terraform은 안전하다고 판단될 때 병렬로 작업을 수행함.
- Implicit dependency 암시적 의존성. 알려져 있음.
- Explicit dependency 명시적 의존성. 알려져 있지 않음.
하나의 리소스 생성이 다른 리소스에서 생성된 정보에 따라 달라짐.
(예) 네트워크가 생성되지 않으면 컴퓨팅 인스턴스를 생성할 수 없음. 마찬가지로, 정적 IP가 예액될 때까지 Compue Engine 인스턴스에 정적 IP주소를 할달할 수 없음. 이러한 종속성은 암묵적임.
리소스가 다른 리소스가 생성된 뒤에야 생성되어야 한다면, Terraform에서 볼 수 없는 종속성을 명시적으로 언급해야 함.
(예) 특정 Cloud Storage 버킷을 사용하여 애플리케이션을 실행하는 경우, 해당 종속성은 애플리케이션 코드 내부에서 구성되므로 Terraform에서는 볼 수 없음. depend_on을 사용하여 명시적으로 선언.
depends_on = [<resource_type>.<resource_name>]
[Variables]
- 변수를 사용하면 리소스 간에 공유되는 값을 매개변수화할 수 있음.
입력 변수는 Terraform의 매개변수 역할을 하므로 소스 코드를 변경하지 않고도 쉽게 사용자 정의하고 공유할 수 있음.
변수가 정의되면 런타임에 해당 값을 설정하는 다양한 방법이 있음. 여기에는 변수, CLI옵션, 키 또는 값 파일 등이 있음.
- 변수는 변수 블럭에 선언해야 함. variable.tf
variable "<variable_name>" {
type = <variable_tpye>
description = "" #문서화에 사용됨으로 관리자보다는 사용자 관점에서 작성되어야.
default = ""
sensitive = true/false # 명력 출력이나 로그 파일에 민감정보가 표시되지 않도록 보호하는 목적.
}
- 변수에 대한 필수 인수가 없음으로 변수 블록은 비어 있을 수 있음.
- 변수 타입: Bool, Number, String
- 변수의 사용은 var.<변수이름>
- 기본값은 환경값이나 .tfvars파일 또는 -var 옵션에 값을 할당하여 재정의 할 수 있음.
[변수적용]
- .tfvars
tf apply -var-file my-vars.tfvars
- CLI # 가장 높은 순위
tf apply -var project_id="project_id"
- environment variables
$TF_VAR_project_id="project_id" \
tf apply
- terraform.tfvars / terraform.tfvars.json, .auto.tfvars, auto.tfvars.json
tf apply
- validation 블럭이 있음
variable "test" {
type = string
validation {
condition = conditions(["A", "B", "C"], var.storageclass)
error_message = "Allow storage class are.."
}
}
[values 베스트 프랙티스]
- 각 인스턴스나 환경에 따라 달라지는 값만 매개변수화 함.
변수를 노출할지 여부를 결정할 때, 해당 변수를 변경하기 위한 구체적인 사용 사례가 있는지 확인.
변수가 필요할 가능성이 작다면 공개하지 말아야.
기본값을 사용하여 변수를 변경하거나 추가하는 것은 이전 버전과의 호환성이 있지만, 변수를 제거하는 것은 그렇지 못함.
루트 모듈의 경우 .tfvars 변수 파일을 사용하여 변수에 값을 제공함. var파일과 명령줄 옵션을 번갈아 사용하지 말것.
명령줄 옵션은 일시적이고 잊기 쉬우며, 소스제어에 체크인 할 수 없음.
- 변수에 용도나 목적에 맞는 설명적 이름을 지정. 디스크 크기나 RAM크기와 같은 숫자 값을 나타내는 변수는 단위를 사용하여 이름을 지정해야 함.
Google Cloud API에는 표준 단위가 없음으로 이 명명규칙을 따르면 구성 유지 관리자가 에상하는 입력 단위가 명확해짐.
조건 논리를 단순화하려면 Bool변수에 긍정적 이름을 지정
(예) enable_external_access
- 변수에는 설명이 있어야 함.
[Output values]
- 출력값은 일반 프로그램 언어의 반환값과 유사. 출력을 사용하면 명령줄에서 생성한 인프라 리소스에 대한 정보를 볼 수 있음.
- 가장 일반적인 사용은 배포 후 CLI에서 루트 모듈 리소스 속성을 인쇄하는 것.
대부분의 서버 세부 정보는 배포 시에 걔산되며, 생성 이후에만 추론할 수 있음.
- 출력 값은 한 리소스에서 생성된 정보를 다른 리소스로 전달하는 데에도 사용됨.
(예) IP주소와 같은 서버별 값을 아 정보가 필요한 다른 리소스로 추론할 수 있음.
- 출력값은 출력 블럭을 사용하여 선언됨.
output "name" {
description = "Note"
value = <resource_type>.<resource_name>.<attribute>
sensitive = true/false
}
- 어디에나 선언 될 수있지만, 권장되는 곳은 output.tf라는 별도 파일에 선언하는 것임.
[outputs 베스트 프랙티스]
- 계산된 정보와 같은 유용한 정보만 출력
- 단순히 변수를 반복하거나 알려진 정보를 제공하는 값은 출력하지 말것.
(예) 네트워크 리소스 id는 리소스의 식별자이고, Gateway_ip4는 네트워크에서 기반 라우팅을 위한 게이트웨이 주소. self_link는 생성된 리소스의 URI.
- 변수와 마찬가지로 의미 있는 이름과 설명을 제공할 것.
- 모든 출력값을 output.tf라는 파일에 포함하도록 코드를 구성.
- 민감한 출력을 표시. 민감한 상태를 수동으로 관리하는 대신. 민감한 상태 관리에 대한 기본 제공 지원을 활용.
[The Registry]
- 대화형 모듈
- 모든 인프라 API를 관리하는 플러그인, 일반적인 인프라 구성 요소를 빠르게 구성하는 사전 제작된 모듈, 고품질 Terraform 코드를 작성하는 방법에 대한 예시 제공.
- CFT Cloud Foundation Toolkit 사용가능. CFT는 Google Cloud 모범 사례를 반영하는 Terraform용 일련의 참조 모듈을 제공. Terraform 블루프린트라고 부름.
- Terraform모듈과 End-To-End 모듈 예제를 모아 단일 단위로 복제하고 빠른 프로토타입을 만들거나 조직에서 사용할 수 있도록 분해 및 수정한 CFF Cloud Foundation Fabirc도 있음.
- CFT는 구글 직원이 관리함.
- CFT를 사용하면, 각 프로젝트의 역할을 개별적으로 업데이트하는 대신, 동일한 모듈 내에서 여러 프로젝트의 IAM 역할을 유지 관리할 수 있음.
[Infrastructure Manager]
- 인프라스트럭처 관리자 또는 인프라 관리자는 Google Cloud 인프라 리소스의 배포와 관리를 자동화하는 관리형 서비스.
- Infra Manager는 리소스에 대한 애플리케이션 배포를 관리하지 않음.
- 애플리케이션 배포를 관리하려면 Cloud Build 및 Cloud Deploy와 같은 Google Cloud제품을 사용할 수 있음.
혹은 타사 도구나 툴 체인을 사용할 수 있음.
[Module]
(예) 사용자 지정 네트워크에서 웹 서버를 만들어야 함.
[Terraform state]
- 인프라 구성의 메타데이터 저장소
- Terraform은 관리하는 리소스의 상태를 상태 파일에 저장함.
- 기본적으로 상태는 terraform.tfstate라는 파일에 저장되지만, 팀 환경에 권장되는 원격으로 저장가능함.
- Terraform은 로컬 상태를 사용하여 계획을 만들고 인프라를 변경함.
어떤 작업도 수행하기 전에 Terraform은 실제 인프라로 상태를 업데이트하기 위해 새로 고침을 수행함.
Terraform state의 주요 목적은 원격 시스템의 객체와 구성에서 선언된 리소스 인스턴스간의 바인딩을 저장하는 것임.
Terraform이 구성 변경에 대응해 원격 객체를 생성하면 특정 리소스 인스턴스에 대해 해당 원격 객체의 ID를 기록함.
그러면 Terraform은 향후 구성 변경에 대응하여 해당 객체를 업데이트하거나 삭제할 가능성이 있음.
리소스 블록 내에서 생성된 모든 인프라 구성 요소는 Terraform 상태 내에서 해당 이름으로 식별됨.
처음으로 Terraform 구성을 적용하면 인프라 리소스가 생성되고 리소스 블럭에 언급된 이름에 대한 참조가 포함된 상태 파일이 자동으로 생성됨.
리소스에 이미 Terraform 상태 파일 내에 항목이 있는 경우 Terraform은 구성을 상태 파일과 현재 라이브 상태와 비교하고 비교를 바탕으로 계획이 생성됨.
계획이 적용되면 정의된 구성에 맞게 리소스가 업데이트됨.
구성이 적용되면 Terraform 상태 파일이 업데이트되어 인프라의 현재 상태로 반영됨.
원격 API 제한으로인해 인수를 제자리에서 업데이트할 수 없는 경우 리소스가 파괴되고 다시 생성됨.(엥?)
현재 구성에서 리소스가 제거되었지만 상태 파일에 항목이 있는 경우 Terraform은 구성을 비교하여 더 이상 존재하지 않는 리소스를 삭제함.
[Store state files]
- 여러 개발자가 동시에 Terraform을 실행하고 각 머신이 현재 인프라에 대한 자체적인 이해를 가지고 있는 경우 기본 구성은 까다로워질 수 있음.
- 팀인 경우 상태파일을 중앙에 원격으로 저장해야함.
[Issue with storing the Terraform state locally]
- No shared access: 공유되는 위치에 저장해야함
- No locking: 파일을 잠글수 없음. 동시에 Terraform을 실행하면, 여러 Terraform 프로세스가 상태 파일을 업데이트하기 때문에 RACE(Race 경쟁) 조건이 발생할 수 있음.
아러한 조건은 충돌, 데이터 손실, 상태 파일 손상으로 이어질 수 있음.
- No confidentiality: 기밀이 제공되지 않음.
[Benefits of storing state file in a remote location]
- Automatic update
원격 백엔드를 구성하면 Terraform은 계획을 실행하거나 명령을 적용할 때마다 백엔드에서 상태를 자동으로 로드함.
또한 각 적용 후 백엔드에 상태 파일을 자동으로 저장하므로 수동 오류가 발생할 가능성이 없음.
- Locking
원격 클라우드 스토리지 버킷은 기본적으로 상태 잠금을 지원함.
여러 개발자가 동시에 Terraform을 실행하더라도 동시 업데이트로 인해 파일이 손상되지 않도록 파일을 잠글 수 있음.
- Secure access
원격 파일 저장은 로컬 저장보다 더 안전함.
클라우드 스토리지 버킷은 기본적으로 전송 중 암호화와 디스크 암호화를 지원함.
Cloud storage에는 액세스 권한을 구성하는 여러 가지 방법이 포함되어 있어 상태 파일에 누가 액세스할 수 있는지 제어할 수 있음.
(예) 버킷에 IAM 정책을 사용할 수 있음.
Cloud Storage 버킷은 저장 시 암호화되지만, 고객이 제공한 암호화 키를 사용하면 보안을 더 강화할 수 있음. GOOGLE_ENCRYPTION_KEY환경변수를 사용하면 보호계층을 추가로 제공할 수 있음.
비밀은 처음부터 상태 파일에 있어서는 안 되지만, 방어를 위한 추가 조치로 항상 상태를 암호화해야함.
- main.tf에 Google Cloud 버킷 리소스 선언
backend.tf 선언. 리소스 타입이 backend임
terraform {
backend "gcs" {
bucket = "..."
prefix = "terraform/state"
}
}
Terraform은 명령을 실행하기 전에 이 버킷에서 최신 상태를 가져오고, 명령을 실행한 후에는 최신 상태를 버킷에 푸시함.
[Terraform state best practices]
- 팀 환경에서 원격 상태를 사용하면 상태 파일을 잠그고 버전관리할 수 있음.
버전 제어에서 중요한 정보를 분리하고, 빌드 시스템과 권한이 높은 관리자만 원격 상태 버킷에 액세스할 수 있도록 해야함.
실수로 개발 상태를 소스 제어에 커밋하는 것을 방지하려면 Terraform 상태 파일에 .gitignore를 사용해야함.
- 비밀을 상태에 저장하면 안됨.
- 상태파일을 암호화해야함.
- 상태를 수동으로 수정하지 말아야 함.