💡 핵심 요약 (Executive Summary)
본 가이드는 iac terraform 핵심 가이드 및 실전 아키텍처의 핵심 개념, 실전 구성 명령어 및 아키텍처 베스트 프랙티스를 다룹니다. 클라우드 네이티브 및 인프라 엔지니어링 실무에 즉시 활용 가능하도록 체계적으로 정리했습니다.
📑 Table of Contents
Setup
-
brew:
-
snap:
bash
sudo snap install terraform --classic -
amd64:
bash
sudo apt update sudo apt install unzip wget -q https://releases.hashicorp.com/terraform/1.4.5/terraform_1.4.5_linux_amd64.zip unzip terraform_1.4.5_linux_amd64.zip rm terraform_1.4.5_linux_amd64.zip sudo mv terraform /usr/local/bin/terraform terraform version
Getting start
bash
# 최초 .tf파일 작성 후
terraform init
find .terraform
>>>
.terraform
.terraform/providers
.terraform/providers/registry.terraform.io
.terraform/providers/registry.terraform.io/cloudflare
.terraform/providers/registry.terraform.io/cloudflare/cloudflare
.terraform/providers/registry.terraform.io/cloudflare/cloudflare/4.45.0
.terraform/providers/registry.terraform.io/cloudflare/cloudflare/4.45.0/darwin_arm64
.terraform/providers/registry.terraform.io/cloudflare/cloudflare/4.45.0/darwin_arm64/LICENSE
.terraform/providers/registry.terraform.io/cloudflare/cloudflare/4.45.0/darwin_arm64/CHANGELOG.md
.terraform/providers/registry.terraform.io/cloudflare/cloudflare/4.45.0/darwin_arm64/terraform-provider-cloudflare_v4.45.0
.terraform/providers/registry.terraform.io/cloudflare/cloudflare/4.45.0/darwin_arm64/README.md
<<<
terraform plan
terraform apply --auto-approve
Exec
main
bash
Main commands:
init Prepare your working directory for other commands
validate Check whether the configuration is valid
plan Show changes required by the current configuration
apply Create or update infrastructure
destroy Destroy previously-created infrastructure
# directory 내 .tf파일을 읽은 후 provider generate
terraform init
# 유효성 검증
terraform plan
# 변경 사항 적용: 테라폼 구성 파일(.tf 파일)에 정의된 리소스를 클라우드 서비스나 인프라에 추가, 수정 또는 삭제
terraform apply
# 변경 사항 적용, 자동승인
terraform apply --auto-approve
# 특정 리소스를 제거하거나 전체 인프라를 삭제할 경우 사용. -target 옵션을 사용하면 특정 리소스 지정하여 삭제
terraform destroy -target=cloudflare_record.test01
import
bash
# 클라우드에서 현재 인프라상태를 tf파일로 가져옴
terraform import $resource ${filename}.tf
- 기존에 운영중인 인프라의 상태를 terraform의 상태에 추가할 수 있지만 리소스파일은 직접 작성해야 함.
refresh
bash
# .tf파일을 클라우드 리소스의 실제 상태와 동기화
terraform refresh
apply vs refresh
- terraform apply:
– 목적: 구성 파일의 변경 사항을 실제 인프라에 적용합니다.
– 인프라 변경: 예, 실제로 인프라를 변경합니다.
– 상태 파일 업데이트: 변경 후 상태 파일을 업데이트합니다.
– 예: 새 리소스를 생성하거나 기존 리소스를 수정합니다. - terraform refresh:
– 목적: 현재 인프라 상태를 상태 파일과 동기화합니다.
– 인프라 변경: 아니요, 인프라에는 영향을 주지 않습니다.
– 상태 파일 업데이트: 상태 파일만 업데이트합니다.
– 예: 외부에서 수동으로 변경된 리소스를 반영합니다.
state
bash
# 상태 파일에 있는 모든 리소스를 나열합니다.
terraform state list
terraform state list $resource
# 특정 리소스를 상태 파일에서 제거합니다(이후 리소스 재생성을 위해 사용).
terraform state rm $resouce
# 리소스를 상태 파일 내에서 다른 이름이나 위치로 이동합니다.
terraform state mv ?
console
bash
# exec
terraform console
in Console
The terraform console command will read the Terraform configuration in the current working directory and the Terraform state file from the configured backend so that interpolations can be tested against both the values in the configuration and the state file.
With the following main.tf:
bash
variable "apps" {
type = map(any)
default = {
"foo" = {
"region" = "us-east-1",
},
"bar" = {
"region" = "eu-west-1",
},
"baz" = {
"region" = "ap-south-1",
},
}
}
resource "random_pet" "example" {
for_each = var.apps
}
Executing terraform console will drop you into an interactive shell where you can test interpolations to:
Print a value from a map:
bash
> var.apps.foo
{
"region" = "us-east-1"
}
Filter a map based on a specific value:
bash
> { for key, value in var.apps : key => value if value.region == "us-east-1" }
{
"foo" = {
"region" = "us-east-1"
}
}
Check if certain values may not be known until apply:
bash
> random_pet.example
(known after apply)
Test various functions:
bash
> cidrnetmask("172.16.0.0/12")
"255.240.0.0"
Features
이미 존재하는 리소스를 terraform state에 반영하기
bash
#terraform import cloudflare_record.terraform_managed_resource_8334085269f2bfedeec66692be31e568_0 ee7cc1e47eda0114152493a289367e3f/8334085269f2bfedeec66692be31e568
# zone resource
terraform import ${resource_type}.${record_name} zones/${zone_id}/${record_id}
# account resource
terraform import ${resource_type}.${record_name} accounts/${account_id}/${record_id}
시나리오
bash
# already exist 발생
terraform apply
>>>
│ Error: expected DNS record to not already be present but already exists
│
│ with cloudflare_record.terraform_managed_resource_8334085269f2bfedeec66692be31e568_0,
│ on main-cloudflare_record.tf line 1, in resource "cloudflare_record" "terraform_managed_resource_8334085269f2bfedeec66692be31e568_0":
│ 1: resource "cloudflare_record" "terraform_managed_resource_8334085269f2bfedeec66692be31e568_0" {
│
╵
╷
│ Error: expected DNS record to not already be present but already exists
│
│ with cloudflare_record.terraform_managed_resource_4481868c29b29cbfe3db0e29b4925cf0_1,
│ on main-cloudflare_record.tf line 10, in resource "cloudflare_record" "terraform_managed_resource_4481868c29b29cbfe3db0e29b4925cf0_1":
│ 10: resource "cloudflare_record" "terraform_managed_resource_4481868c29b29cbfe3db0e29b4925cf0_1" {
│
<<<
# 항상 creating 상태
terraform plan
>>>
Terraform will perform the following actions:
# cloudflare_record.terraform_managed_resource_4481868c29b29cbfe3db0e29b4925cf0_1 will be created
+ resource "cloudflare_record" "terraform_managed_resource_4481868c29b29cbfe3db0e29b4925cf0_1" {
+ allow_overwrite = false
+ content = "\"f9ab45e0-52b0-494c-b780-1c064cae4a92\""
+ created_on = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ metadata = (known after apply)
+ modified_on = (known after apply)
+ name = "_cf-custom-hostname"
+ proxiable = (known after apply)
+ proxied = false
+ ttl = 1
+ type = "TXT"
+ value = (known after apply)
+ zone_id = "ee7cc1e47eda0114152493a289367e3f"
}
# cloudflare_record.terraform_managed_resource_8334085269f2bfedeec66692be31e568_0 will be created
+ resource "cloudflare_record" "terraform_managed_resource_8334085269f2bfedeec66692be31e568_0" {
+ allow_overwrite = false
+ content = "domain-placeholder.cloudflare-ui.com"
+ created_on = (known after apply)
+ hostname = (known after apply)
+ id = (known after apply)
+ metadata = (known after apply)
+ modified_on = (known after apply)
+ name = "fredric18.uk"
+ proxiable = (known after apply)
+ proxied = true
+ ttl = 1
+ type = "CNAME"
+ value = (known after apply)
+ zone_id = "ee7cc1e47eda0114152493a289367e3f"
}
<<<
# import 수행
terraform import ${resource_type}.${record_name} ${zone_id}/${record_id}
# 다시 Planning
terraform plan
>>>
# cloudflare_record.terraform_managed_resource_4481868c29b29cbfe3db0e29b4925cf0_1 will be updated in-place
~ resource "cloudflare_record" "terraform_managed_resource_4481868c29b29cbfe3db0e29b4925cf0_1" {
+ allow_overwrite = false
+ content = "\"f9ab45e0-52b0-494c-b780-1c064cae4a92\""
id = "4481868c29b29cbfe3db0e29b4925cf0"
name = "_cf-custom-hostname"
tags = []
# (10 unchanged attributes hidden)
}
# cloudflare_record.terraform_managed_resource_8334085269f2bfedeec66692be31e568_0 will be updated in-place
~ resource "cloudflare_record" "terraform_managed_resource_8334085269f2bfedeec66692be31e568_0" {
+ allow_overwrite = false
+ content = "domain-placeholder.cloudflare-ui.com"
id = "8334085269f2bfedeec66692be31e568"
name = "fredric18.uk"
tags = []
# (10 unchanged attributes hidden)
}
<<<
Leave a Reply