π‘cloudNet@ νμ κ°μλ€ λμ΄ μ§ννλ Terraform 101 Study 4κΈ° 4μ£Όμ°¨ λ΄μ©μΌλ‘,
[ν λΌνΌμΌλ‘ μμνλ IaC] λμλ₯Ό μ°Έμ‘°νμμ΅λλ€. κ°μ¬ν©λλ€..
1. νλ‘λ°μ΄λ
ν λΌνΌμ terraform λ°μ΄λ리 νμΌμ μμμΌλ‘ λ‘컬 νκ²½μ΄λ λ°°ν¬ μλ²μ κ°μ μ격 νκ²½μμ μνλ λμμ νΈμΆνλ λ°©μμΌλ‘ μ€νλλ€. μ΄λ ‘μνλ λμ’μ νΈμΆνλ λ°©μμ΄ μλ‘ λ€λ₯΄μ§λ§ λμμ 곡κΈμ μ¦, νλ‘λ°μ΄λκ° μ 곡νλ APIλ₯Ό νΈμΆν΄ μνΈμμ© νλ€.
μ¬κΈ°μ ν λΌνΌμ΄ λμκ³Όμ μνΈμμ©μ ν μ μλλ‘ νλ κ²μ΄ νλ‘λ°μ΄λμ΄λ€.
κ° νλ‘λ°μ΄λμ API ꡬνμ μλ‘ λ€λ₯΄μ§λ§ μ΄μ ν¬μ€ν μμ μ΄ν΄λ³Έ ν λΌνΌμ κ³ μ λ¬Έλ²μΌλ‘ λμΌν λμμ μννλλ‘ κ΅¬νλμ΄ μλ€.
νλ‘λ°μ΄λλ νλ¬κ·ΈμΈ ννλ‘ ν λΌνΌμ κ²°ν©λμ΄ λμμ΄ λλ ν΄λΌμ°λ, SaaS, κΈ°ν μλΉμ€ APIλ₯Ό μ¬μ©ν΄ λμμ μννλ€. κ° νλ‘λ°μ΄λλ ν λΌνΌμ΄ κ΄λ¦¬νλ 리μμ€ μ νκ³Ό λ°μ΄ν° μμ€λ₯Ό μ¬μ©ν μ μλλ‘ μ°κ²°νλ€.
μ¦, ν λΌνΌμ νλ‘λ°μ΄λ μμ΄λ μ΄λ€ μ’ λ₯μ μΈνλΌλ μλΉμ€λ κ΄λ¦¬ν μ μλ€.
λλΆλΆμ νλ‘λ°μ΄λλ λμ μΈνλΌ νκ²½μ΄λ μλΉμ€ νκ²½μ λν΄ λ¦¬μμ€λ₯Ό κ΄λ¦¬νλ―λ‘, νλ‘λ°μ΄λλ₯Ό ꡬμ±ν λλ λμκ³Όμ μ°κ²°κ³Ό μΈμ¦μ νμν μ λ³΄κ° μ 곡λμ΄μΌ νλ€.
μΌλΆ νλ‘λ°μ΄λλ μ νΈλ¦¬ν°μ μΈ μΈ‘λ©΄μΌλ‘ λ‘컬μμ λμνλ€.
κ° νλ‘λ°μ΄λλ ν λΌνΌ μ€ν νμΌκ³Όλ λ³λλ‘ μ체 κ΄λ¦¬λκ³ κ²μλλ€. ν λΌνΌ λ μ§μ€νΈλ¦¬ μ¬μ΄νΈμμ μ£Όμ νλ‘λ°μ΄λμ κ΄λ ¨ λ¬Έμλ₯Ό νμΈν μ μλ€.
https://registry.terraform.io/browse/providers
1.1 νλ‘λ°μ΄λ ꡬμ±
νλ‘λ°μ΄λ ꡬμ±μ λν μꡬμ¬νμ 곡μ λ μ§μ€νΈλ¦¬ μ¬μ΄νΈμ 곡κ°λμ΄ μλ κ° νλ‘λ°μ΄λ κ΅¬μ± λ°©μμ μ°Έκ³ νλ κ²μ΄ μ μμ΄λ€.
local νλ‘λ°μ΄λμ²λΌ νλ‘λ°μ΄λλ₯Ό μν λ³λ ꡬμ±μ΄ νμνμ§ μμ κ²½μ°λ μμ§λ§, AWSμ κ°μ ν΄λΌμ°λ νλ‘λ°μ΄λμ κ²½μ°λ AWS μ격μ¦λͺ μ 보μ 리μ μ΄λ¦ λ±μ μ μνκΈ°λ νλ€.
κ° νλ‘λ°μ΄λμ user provider λ²νΌμ μ ννμ¬ λ²μ μ λ§λ μ μ λ°©λ²μ νμΈν μ μλ€.
λ‘컬 μ΄λ¦κ³Ό νλ‘λ°μ΄λ μ§μ
terraform λΈλ‘μ required_providers λΈλ‘ λ΄μ <λ‘컬 μ΄λ¦> = { } μΌλ‘ μ¬λ¬ κ°μ νλ‘λ°μ΄λλ₯Ό μ μν μ μλ€. μ¬κΈ°μ μ¬μ©λλ λ‘컬 μ΄λ¦μ ν λΌνΌ λͺ¨λ λ΄μμ κ³ μ ν΄μΌ νλ€.
λ‘컬 μ΄λ¦κ³Ό 리μμ€ μ λμ¬λ λ 립μ μΌλ‘ μ μΈλλ©°, κ° νλ‘λ°μ΄λμ μμ€ κ²½λ‘κ° μ§μ λλ©΄ νλ‘λ°μ΄λμ κ³ μ μ λμ¬κ° μ 곡λλ€. λ§μΌ λμΌν μ λμ¬λ₯Ό μ¬μ©νλ νλ‘λ°μ΄λκ° μ μΈλλ κ²½μ° λ‘컬 μ΄λ¦μ λ¬λ¦¬νμ¬ κ΄λ ¨ 리μμ€μμ μ΄λ€ νλ‘λ°μ΄λλ₯Ό μ¬μ©νλμ§ λͺ μμ μΌλ‘ μ§μ ν μ μλ€.
μλ₯Ό λ€μ΄ λ€μμ main.tfμμμ²λΌ λμΌν http μ΄λ¦μ μ¬μ©νλ λ€μμ νλ‘λ°μ΄λκ° μλ κ²½μ° κ° νλ‘λ°μ΄λμ κ³ μ ν μ΄λ¦μ λΆμ¬νκ³ λ¦¬μμ€μ λ°μ΄ν° μμ€μ μ΄λ€ νλ‘λ°μ΄λλ₯Ό μ¬μ©ν μ§ provider μΈμμ λͺ μνλ€. λ¨, λμΌν sourceμ λν΄ λ€μμ μ μλ λΆκ°λ₯νλ€.
λ€μμ λμΌν http μ λμ¬λ₯Ό μ¬μ©νλ λ€μμ νλ‘λ°μ΄λ μ¬μ©μ μ μμ΄λ€.
terraform {
**required_providers** {
architech-http = {
source = "architect-team/**http**"
version = "~> 3.0"
}
http = {
source = "hashicorp/**http**"
}
**aws-http** = {
source = "terraform-aws-modules/**http**"
}
}
}
data "**http**" "example" {
**provider = aws-http**
url = "https://checkpoint-api.hashicorp.com/v1/check/terraform"
request_headers = {
Accept = "application/json"
}
}
λ¨μΌ νλ‘λ°μ΄λμ λ€μ€ μ μ
λμΌν νλ‘λ°μ΄λλ₯Ό μ¬μ©νμ§λ§ λ€λ₯Έ 쑰건μ κ°λ κ²½μ°, μ¬μ©λλ 리μμ€λ§λ€ λ³λλ‘ μ μΈλ νλ‘λ°μ΄λλ₯Ό μ§μ ν΄μΌ νλ κ²½μ°κ° μλ€.
μλ₯Ό λ€λ©΄ AWS νλ‘λ°μ΄λλ₯Ό μ¬μ©νλλ° μλ‘ λ€λ₯Έ κΆνμ IAMμ κ°λ Access ID λλ λμ 리μ μ μ§μ ν΄μΌ νλ κ²½μ°μ΄λ€. μ΄ λλ νλ‘λ°μ΄λ μ μΈμμ aliasλ₯Ό λͺ μνκ³ μ¬μ©νλ 리μμ€μ λ°μ΄ν° μμ€μμλ provider λ©νμΈμλ₯Ό μ¬μ©ν΄ νΉμ νλ‘λ°μ΄λλ₯Ό μ§μ ν μ μλ€.
provider λ©νμΈμμ μ§μ λμ§ μμ κ²½μ° aliasκ° μλ νλ‘λ°μ΄λκ° κΈ°λ³Έ νλ‘λ°μ΄λλ‘ λμνλ€.
μλ μμ λ 리μ μ λ€λ₯΄κ² ꡬμ±ν AWS νΈλ‘λ°μ΄λλ₯Ό aws_instanceμ μ§μ νλ λ°©λ²μ΄λ€.
λ¨μΌ νλ‘λ°μ΄λμ λ€μ€ μ μ μ 리μμ€μμ νΉμ νλ‘λ°μ΄λλ₯Ό μ μνλ λ°©λ²
provider "**aws**" {
region = "ap-southeast-1"
}
provider "**aws**" {
**alias = "seoul"**
region = "ap-northeast-2"
}
resource "**aws**_instance" "app_server1" {
ami = "ami-06b79cf2aee0d5c92"
instance_type = "t2.micro"
}
resource "**aws**_instance" "app_server2" {
**provider = aws.seoul**
ami = "ami-0ea4d4b8dc1e46212"
instance_type = "t2.micro"
}
μ€ν κ²°κ³Ό. κ° μμΈλ¦¬μ κ³Ό μ±κ°ν΄ 리μ μ μμ±λμλ€.
νλ‘λ°μ΄λ μꡬμ¬ν μ μ
ν λΌνΌ μ€ν μ μꡬλλ νλ‘λ°μ΄λ μꡬμ¬νμ terraform λΈλ‘μ required_providers λΈλ‘μ μ¬λ¬ κ°λ₯Ό μ μν μ μλ€. sourceμλ νλ‘λ°μ΄λ λ€μ΄λ‘λ κ²½λ‘λ₯Ό μ§μ νκ³ versionμ λ²μ μ μ½μ λͺ μνλ€.
λ€μμ νλ‘λ°μ΄λ μꡬμ¬ν μ μ λΈλ‘μ΄λ€.
terraform {
required_providers {
<νλ‘λ°μ΄λ λ‘컬 μ΄λ¦> = {
source = [<νΈμ€νΈ μ£Όμ>/]<λ€μμ€νμ΄μ€>/<μ ν>
version = <λ²μ μ μ½>
}
...
}
}
- νΈμ€νΈ μ£Όμ : νλ‘λ°μ΄λλ₯Ό λ°°ν¬νλ μ£Όμλ‘μ κΈ°λ³Έκ°μ registry.terraform.io
- λ€μμ€νμ΄μ€ : μ§μ λ λ μ§μ€νΈλ¦¬ λ΄μμ ꡬλΆνλ λ€μμ€νμ΄μ€λ‘, 곡κ°λ λ μ§μ€νΈλ¦¬ λ° Terraform Cloudμ λΉκ³΅κ° λ μ§μ€νΈλ¦¬μ νλ‘λ°μ΄λλ₯Ό κ²μνλ μ‘°μ§μ μλ―Έ
- μ ν : νλ‘λ°μ΄λμμ κ΄λ¦¬λλ νλ«νΌμ΄λ μλΉμ€ μ΄λ¦μΌλ‘ μΌλ°μ μΌλ‘ μ λμ¬μ μΌμΉνλ μΌλΆ μμΈκ° μμ μ μμ
νλ‘λ°μ΄λλ κΈ°λ₯μ΄λ μ‘°κ±΄μ΄ μκ°μ΄ μ§λ¨μ λ°λΌ λ³κ²½λ μ μλ€. μ΄ κ°μ λ³κ²½μ νΉμ λ²μ μ λͺ μνκ±°λ λ²μ νΈνμ±μ μ μν λ, versionμ λͺ μν μ μλ€. μ΄ κ°μ΄ μλ΅λλ κ²½μ° terraform initμ νλ λΉμμ κ°μ₯ μ΅μ λ²μ μΌλ‘ μ νλλ€.
νλ‘λ°μ΄λ μ€μΉ
ν λΌνΌμ μ€ννκΈ° μ terraform init λͺ λ Ήμ ν΅ν΄ μ μλ νλ‘λ°μ΄λλ₯Ό λ€μ΄λ‘λ, 볡μ¬, μΊμμμ μ½μ΄μ€κ² λλ€. νμ μ§μ λ ꡬμ±μ λν΄ λμΌν νλ‘λ°μ΄λλ₯Ό μ€μΉνλλ‘ νλ €λ©΄ ν λΌνΌ ꡬμ±μ μ¬μ©λλ νλ‘λ°μ΄λμ λν΄ λͺ μμ μΌλ‘ terraform λΈλ‘μ μ μνκ±°λ .terraform.lock.hcl μ κΈ νμΌμ μ½λ μ μ₯μμ 곡μ νλ λ°©μμ΄ μꡬλλ€.
μ΄μ μ μ΄ν΄λ³Έ κ²μ²λΌ required_providersμ μ§μ λ νλ‘λ°μ΄λκ° μλ κ²½μ° μ½λμ ꡬμ±μμ μ¬μ© μ¬λΆμ κ΄κ³μμ΄ νλ‘λ°μ΄λλ₯Ό λ€μ΄λ‘λνκ² λκ³ , required_providersμ μ§μ νμ§ μλλΌκ³ ν λΌνΌ κ΅¬μ± μ½λμ¬μμ μ¬μ©λ νλ‘λ°μ΄λλ₯Ό ν λΌνΌμμ μΆλ‘ ν΄ μ΅μ λ²μ μ νλ‘λ°μ΄λλ₯Ό λ€μ΄λ‘λ νλ€.
νλ‘λ°μ΄λ κ° μ ν μ¬λΆ
ν΄λΌμ°λλ₯Ό λμμΌλ‘ ν λΌνΌμ μ¬μ©νλ κ²½μ° λ€λ₯Έ ν΄λΌμ°λ νλ‘λ°μ΄λλ‘ μ νμ΄ κ°λ₯ν κΉ? λΆκ°λ₯νλ€.
ν λΌνΌμ μΈνλΌμ λν λ¨μΌ νλ‘λΉμ λ λκ΅¬λ‘ μ¬μ©λμ§λ§ λμμ΄ λλ νκ²½μ μλ‘ λ€λ₯Έ APIλ‘ κ΅¬νλ νλ‘λ°μ΄λκ° μ 곡λλ€. μλ₯Ό λ€μ΄ AWS ꡬμ±μ Azureλ‘, Azureμ ꡬμ±μ GCPλ‘ μ ννλκ² λΆκ°λ₯νμ§λ§ IaCλ‘μμ ν λΌνΌμ νΉμ±μ΄ μμ ν¨μ¨μ λνμ€λ€.
νλ‘λ°μ΄λ κ° λμλλ 리μμ€ μμ
1.2 νλ‘λ°μ΄λ μμ½μμ€ν
ν λΌνΌμ μμ½μμ€ν μ μ¬μ©μκ° μ¬μ©νλ λ°©μκ³Ό ꡬ쑰μ ν λΌνΌμ μ μ©ν μ μλλ‘ μ€κ³λλ€. μμ½μμ€ν μ μν ν λΌνΌ ν΅ν©μ μν¬νλ‘ ννΈλμ μΈνλΌ ννΈλλ‘ λλλ€.
μν¬νλ‘ ννΈλλ ν λΌνΌ μ€ν λ° Terraform Cloud/Enterpriseμ μ°κ³νμ¬ λμνλ κΈ°λ₯μ μ 곡νλ νλͺ©μΌλ‘ μ΄λ£¨μ΄μ Έ μλ€.
λνμ μΌλ‘ ν λΌνΌ ꡬμ±μ κ΄λ¦¬νκΈ° μν VCSλ₯Ό μ 곡νλ κΉνλΈ, GitLab, Bitbucket, Azure Devopsκ° νλͺ©μ ν΄λΉνλ€.
νλ‘λ°μ΄λμ κ²½μ° μΈνλΌ ννΈλμ ν΄λΉλλ€. μΈνλΌ ννΈλλ μ¬μ©μκ° ν λΌνΌμΌλ‘ λμ νλ«νΌμ APIλ‘ μνΈμμ© κ°λ₯ν 리μμ€λ₯Ό κ΄λ¦¬ν μ μλλ‘ νλ€.
μΈνλΌ ννΈλμ λΆλ₯μ νλ‘λ°μ΄λ λμμ λ€μκ³Ό κ°λ€.
**νΌλΈλ¦ ν΄λΌμ°λ**
- IaaS, SaaS λ° PaaSλ₯Ό ν¬ν¨ν λ€μν μλΉμ€λ₯Ό μ 곡νλ λκ·λͺ¨ κΈλ‘λ² ν΄λΌμ°λ μ 곡
**컨ν
μ΄λ μ€μΌμ€νΈλ μ΄μ
**
- 컨ν
μ΄λ νλ‘λΉμ λ λ° λ°°ν¬λ₯Ό μ§μ
**IaaS(Infrastructure-as-a-Service)**
- μ€ν 리μ§, λ€νΈμνΉ λ° κ°μνμ κ°μ μ루μ
μ μ 곡νλ μΈνλΌ λ° IaaS μ 곡
**보μ λ° μΈμ¦**
- μΈμ¦ λ° λ³΄μ λͺ¨λν°λ§ νλ«νΌ
**μμ° κ΄λ¦¬**
- μννΈμ¨μ΄ λΌμ΄μ μ€, νλμ¨μ΄ μμ° λ° ν΄λΌμ°λ 리μμ€λ₯Ό λΉλ‘―ν μ£Όμ μ‘°μ§ λ° IT 리μμ€μ μμ° κ΄λ¦¬λ₯Ό μ 곡
**CI/CD**
- μ§μμ μΈ ν΅ν© λ° μ§μμ μΈ μ 곡/λ°°ν¬
**λ‘κΉ
λ° λͺ¨λν°λ§**
- λ‘κ±°, μΈ‘μ λꡬ λ° λͺ¨λν°λ§ μλΉμ€μ κ°μ μλΉμ€λ₯Ό ꡬμ±νκ³ κ΄λ¦¬νλ κΈ°λ₯
**μ νΈλ¦¬ν°**
- μμ κ° μμ±, νμΌ μμ±, http μνΈ μμ© λ° μκ° κΈ°λ° λ¦¬μμ€μ κ°μ λμ°λ―Έ κΈ°λ₯
**ν΄λΌμ°λ μλν**
- κ΅¬μ± κ΄λ¦¬μ κ°μ μ λ¬Ένλ ν΄λΌμ°λ μΈνλΌ μλν κ΄λ¦¬ κΈ°λ₯
**λ°μ΄ν° κ΄λ¦¬**
- λ°μ΄ν° μΌν° μ€ν 리μ§, λ°±μ
λ° λ³΅κ΅¬ μ루μ
**λ€νΈμνΉ**
- λΌμ°ν
, μ€μμΉ, λ°©νλ²½ λ° SD-WAN μ루μ
κ³Ό κ°μ λ€νΈμν¬λ³ νλμ¨μ΄ λ° κ°μνλ μ νκ³Ό ν΅ν©
**VCS(λ²μ μ μ΄ μμ€ν
)**
- Terraform λ΄μμ VCS(λ²μ μ μ΄ μμ€ν
) νλ‘μ νΈ, ν λ° λ¦¬ν¬μ§ν 리μ μ€μ
**ν΅μ λ° λ©μμ§**
- ν΅μ , μ΄λ©μΌ λ° λ©μμ§ νλ«νΌκ³Ό ν΅ν©
**λ°μ΄ν°λ² μ΄μ€**
- λ°μ΄ν°λ² μ΄μ€ 리μμ€λ₯Ό νλ‘λΉμ λ λ° κ΅¬μ±νλ κΈ°λ₯
**PaaS(Platform-as-a-Service)**
- λ€μν νλμ¨μ΄, μννΈμ¨μ΄ λ° μ ν리μΌμ΄μ
κ°λ° λꡬλ₯Ό μ 곡νλ νλ«νΌ λ° PaaS
**μΉ μλΉμ€**
- μΉ νΈμ€ν
, μΉ μ±λ₯, CDN λ° DNS μλΉμ€
νΌλΈλ¦ ν΄λΌμ°λ νλ‘λ°μ΄λ
ν λΌνΌμ μ νλ κ²½λ‘ μ€ νΌλΈλ¦ ν΄λΌμ°λ νκ²½μ νλ‘λΉμ λ νλ €λ κ²½μ°κ° λ§λ€. ν λΌνΌ λΏλ§ μλ λ§μ IaC λκ΅¬κ° ν΄λΌμ°λ νλ‘λΉμ λμ νμ©λλ€.
νΌλΈλ¦ ν΄λΌμ°λλ μ€κ³ λ¨κ³μμ λλΆλΆμ 리μμ€ κ΅¬μ±μ λν΄ API κΈ°λ°μ κ³ λ €νκΈ° λλ¬Έμ ν λΌνΌμΌλ‘ νλΆν 리μμ€ κ΅¬μ±μ΄ κ°λ₯νλ€.
컨ν μ΄λ μ€μΌμ€νΈλ μ΄ν°
λνμ μΌλ‘ λ Έλ§λ, μΏ λ²λ€ν°μ€, λμ², νμ£Όλ₯Ό μλ‘€ λ€ μ μλλ°, μ΅μ μ€μΌμ€νΈλ μ΄μ λꡬλ€μ μ λ§λ€μ IaC λ°©μμ μ§μνμ§λ§ ν λΌνΌ κ°μ μν κΈ°λ° λμμ μννμ§λ μλλ€.
κ·Έλμ ν λΌνΌμ΄ μ 곡νλ μ½λμ μΈ κΈ°λ₯κ³Ό ν¨μ λ° λ³μλ₯Ό κΈ°λ°μΌλ‘ κΈ°μ‘΄ IaC λ°©μ λλΉ ν λΌνΌμ κ΅¬μ± λ°©μμ νμ©ν μ μκ³ , λ°°ν¬ νκ²½μ΄ λλ ν΄λΌμ°λμ IaaS νκ²½μ ν λΌνΌμΌλ‘ ꡬμ±ν ν μ ν리μΌμ΄μ μ λ°°ν¬ν μ μλ€.
SaaS μλΉμ€
μ€μΉνκ³Ό λ¬λ¦¬ SaaS μλΉμ€λ κ°λ³ κ³μ κ΄λ¦¬, μ κ·Ό κ΄λ¦¬, λ€νΈμν¬ κ΅¬μ± λ± κ° SaaS μλΉμ€λ§λ€ λ 립μ μΌλ‘ μ 곡νλ 리μμ€μ λν΄ κ΄λ¦¬κ° νμνλ€.
κΈ°ν μ루μ
μΈνλΌ νκ²½μ λ€νΈμν¬ μ₯λΉ, λ°©νλ²½, μ€ν 리μ§, λͺ¨λν°λ§ λꡬ λ± APIλ₯Ό μ 곡νλ κ° μ루μ λν ν λΌνΌ νλ‘λ°μ΄λκ° μ 곡λμ΄ μ루μ μ λν μ€μ μ΄ κ°λ₯νλ€.
1.3 νλ‘λ°μ΄λ κ²½νν΄λ³΄κΈ°
μ€μ΅μΌλ‘ 2κ°μ 리μ μ Ubuntu EC2λ₯Ό λ°°ν¬ν΄λ³΄κ² λ€.
λ€μκ³Ό κ°μ΄ tf νμΌμ μμ±νλ€. 리μ λ³ AMI ID κ°μ΄ λ€λ₯΄λ―λ‘, νν°λ₯Ό νμ©νλ€.
ec2.tf
resource "aws_instance" "region_1" {
**provider = aws.region_1**
**ami = data.aws_ami.ubuntu_region_1.id**
instance_type = "t2.micro"
}
resource "aws_instance" "region_2" {
**provider = aws.region_2**
**ami = data.aws_ami.ubuntu_region_2.id**
instance_type = "t2.micro"
}
# provider_data.tf
provider "aws" {
region = "ap-northeast-2"
alias = "region_1"
}
provider "aws" {
region = "ap-southeast-1"
alias = "region_2"
}
data "aws_region" "region_1" {
provider = aws.region_1
}
data "aws_region" "region_2" {
provider = aws.region_2
}
data "aws_ami" "ubuntu_region_1" {
provider = aws.region_1
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
data "aws_ami" "ubuntu_region_2" {
provider = aws.region_2
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"]
}
}
μ€ν κ²°κ³Ό
2κ°μ§ μ£Όμ μ¬ν!!
- Warning 1 : Multiregion is hard νλ‘λμ
μμ€μ λ©ν° 리μ μ μ΄λ ΅λ€
- Active-Active λ©ν° 리μ μλΉμ€λ₯Ό μν΄μ ‘μ§μκ° μ§μ° μκ°, κ³ μ ID, μ΅μ’ μΌκ΄μ±’ λ± μ¬λ¬κ°μ§ κ³ λ €μ¬νμ΄ λ§μμ μ½μ§ μλ€.
- Warning 2 : Use aliases sparingly Alias λ₯Ό λΉλ²νκ² μ¬μ©νμ§ λ§μ
- λ³μΉμ μ¬μ©νμ¬ λ 리μ μ λ°°ν¬νλ λ¨μΌ ν λΌνΌ λͺ¨λμ ν 리μ μ΄ λ€μ΄ μ, plan κ³Ό apply μλκ° μ€ν¨ν©λλ€
- νλ‘λμ νκ²½μ λ©ν° 리μ μ λ³μΉμ μ¬μ©νλ κ²λ³΄λ€λ, 3μ₯μμ μ€λͺ ν κ² μ²λΌ νκ²½μ μμ ν 격리ν΄μΌ ν©λλ€.
- μ΄λ₯Ό ν΅ν΄ μν₯λλ₯Ό μ΅μν ν μ μμ΅λλ€.
2. State
ν λΌνΌμ Stateful(μνκ° μλ) μ ν리μΌμ΄μ μ΄λ€. νλ‘λΉμ λ κ²°κ³Όμ λ°λ₯Έ State(μν)λ₯Ό μ μ₯νκ³ νλ‘λΉμ λν λͺ¨λ λ΄μ©μ μ μ₯λ μνλ‘ μΆμ νλ€.
λ‘컬 μ€ν νκ²½μμλ terraform.tfstate νμΌμ JSON ννλ‘ μ μ₯λκ³ , νμ΄λ μ‘°μ§μμμ 곡λ κ΄λ¦¬λ₯Ό μν΄μλ μ격 μ μ₯μμ μ μ₯ν΄ κ³΅μ νλ λ°©μμ νμ©νλ€.
Stateμλ μμ μκ° μ μν μ½λμ μ€μ λ°μλ νλ‘λΉμ λ κ²°κ³Όλ₯Ό μ μ₯νκ³ μ΄ μ 보λ₯Ό ν λλ‘ λ¦¬μμ€ μμ±, μμ , μμ μ λν λμ νλ¨ μμ μ μννλ€.
2.1 Stateμ λͺ©μ κ³Ό μλ―Έ
μ½λ λ³κ²½ ν apply λͺ λ Ήμ μ€ννλ©΄ μ΄μ μ μμ±λ 리μμ€μ λΉκ΅ν΄ μμ±, μμ , μμ λμμ΄ μνλλ κ²μ νμΈνλ€. ν λΌνΌμ stateλ₯Ό μ¬μ©ν΄ λμ νκ²½μμ μ΄λ€ 리μμ€κ° ν λΌνΌμΌλ‘ κ΄λ¦¬λλ 리μμ€μΈμ§ νλ³νκ³ κ²°κ³Όλ₯Ό κΈ°λ‘νλ€.
stateμ μν μ λ€μκ³Ό κ°λ€.
- Stateμλ ν λΌνΌ ꡬμ±κ³Ό μ€μ λ₯Ό λκΈ°ννκ³ κ° λ¦¬μμ€μ κ³ μ ν μμ΄λ(리μμ€ μ£Όμ)λ‘ λ§΅ν
- 리μμ€ μ’ μμ±κ³Ό κ°μ λ©νλ°μ΄ν°λ₯Ό μ μ₯νκ³ μΆμ
- ν λΌνΌ ꡬμ±μΌλ‘ νλ‘λΉμ λ κ²°κ³Όλ₯Ό μΊμ±νλ μν μ μν
State λμ νμΈμ μ§νν΄λ³΄κ² λ€. λ€μκ³Ό κ°μ΄ random νλ‘λ°μ΄λλ₯Ό μ¬μ©νλ€.
resource "random_password" "cwpass" {
length = 16
special = true
override_special = "!#$%"
}
μ€ν κ²°κ³Ό
μμ±λ terraform.tfstate νμΌ
{
"version": 4,
"terraform_version": "1.8.5",
"serial": 1,
"lineage": "9e0a46f9-e624-8325-dfc4-a23598c54f07",
"outputs": {},
"resources": [
{
"mode": "managed",
"type": "random_password",
"name": "cwpass",
"provider": "provider[\"registry.terraform.io/hashicorp/random\"]",
"instances": [
{
"schema_version": 3,
"attributes": {
"bcrypt_hash": "$2a$10$oftud8/FQL4lTJ2vKUtdhuJd4MyDKiaF1vxKUnp8Z6S6Eg385vq7a",
"id": "none",
"keepers": null,
"length": 16,
"lower": true,
"min_lower": 0,
"min_numeric": 0,
"min_special": 0,
"min_upper": 0,
"number": true,
"numeric": true,
"override_special": "!#$%",
"result": "y49WJijtbeoshyOC",
"special": true,
"upper": true
},
"sensitive_attributes": [
[
{
"type": "get_attr",
"value": "bcrypt_hash"
}
],
[
{
"type": "get_attr",
"value": "result"
}
]
]
}
]
}
],
"check_results": null
}
ν λΌνΌμμλ μ΄ JSON ννλ‘ μμ±λ Stateλ₯Ό ν΅ν΄ μμ±κ³Ό μΈμλ₯Ό μ½κ³ νμΈν μ μλ€. ν λΌνΌμμλ typeκ³Ό nameμΌλ‘ κ³ μ ν 리μμ€λ₯Ό λΆλ₯νλ©° ν΄λΉ 리μμ€μ μμ±κ³Ό μΈμλ₯Ό ꡬμ±κ³Ό λΉκ΅ν΄ λμ 리μμ€λ₯Ό μμ±, μμ , μμ νλ€.
! Stateλ ν λΌνΌλ§μ μν APIλ‘ μ μν μλ μλ€.
planμ μ€ννλ©΄ μ묡μ μΌλ‘ refresh λμμ μννλ©΄μ 리μμ€ μμ±μ λμ(ν΄λΌμ°λ, SaaS λ±) κ³Ό Stateλ₯Ό κΈ°μ€μΌλ‘ λΉκ΅νλ κ³Όμ μ κ±°μΉλ€. μ΄ μμ μ νλ‘λΉμ λ λμμ μλ΅ μλμ κΈ°μ‘΄ μμ±λ stateμ 리μμ€ μμ λ°λΌ μλ μ°¨μ΄κ° λ°μνλ€.
λλμ 리μμ€λ₯Ό κ΄λ¦¬ν΄μΌ νλ κ²½μ° plan λͺ λ Ήμμ -refresh=false νλκ·Έλ₯Ό μ¬μ©ν΄ Stateλ₯Ό κΈ°μ€μΌλ‘ μ€ν κ³νμ μμ±νκ³ , μ΄λ₯Ό μ€νμ νμ©ν΄ λμ νκ²½κ³Όμ λκΈ°ν κ³Όμ μ μλ΅ν μ μλ€.
# μ€ν κ³ν μμ± μ μ μ₯λμ΄ μλ Stateμ μ€μ νμμ λΉκ΅νλ κΈ°λ³Έ μ€ν
time terraform **plan**
# μ€ν κ³ν μμ± μ μ€μ νμκ³Ό λΉκ΅νμ§ μκ³ μ€ν κ³νμ μμ±νλ -refresh=false μ΅μ
time terraform plan **-refresh=false**
μν νμΌ νμΈ μ€μ΅
λ€μκ³Ό κ°μ΄ tf νμΌμ μμ±νλ€.
# vpc.tf
provider "aws" {
region = "ap-northeast-2"
}
resource "**aws_vpc**" "**myvpc**" {
cidr_block = "10.10.0.0/16"
tags = {
Name = "**t101-study**"
}
}
λ€μκ³Ό κ°μ΄ tagλ₯Ό μμ νκ³ λ€μ μ€νν΄λ³΄κ² λ€.
provider "aws" {
region = "ap-northeast-2"
}
resource "aws_vpc" "myvpc" {
cidr_block = "10.10.0.0/16"
tags = {
Name = "tf-state"
}
}
λ€μκ³Ό κ°μ΄ λ°±μ νμΌμ΄ μμ±λλ€. λ°±μ νμΌκ³Ό λ΄μ©μ λΉκ΅ν΄λ³΄κ² λ€.
2.2 State λκΈ°ν
ν λΌνΌ κ΅¬μ± νμΌμ κΈ°μ‘΄ Stateμ ꡬμ±μ λΉκ΅ν΄ μ€ν κ³νμμ μμ±, μμ , μμ μ¬λΆλ₯Ό κ²°μ νλ€κ³ μ΄μ μ μ€λͺ νλ€.
λ€μμ Planκ³Ό Apply μ€μ κ° λ¦¬μμ€μ λ°μν μ μλ λ€ κ°μ§ μ¬νμ΄λ€. Replace λμμ κΈ°λ³Έκ°μ μμ ν μμ±νμ§λ§ lifecycleμ create_before_destory μ΅μ μ ν΅ν΄ μμ± ν μμ λ₯Ό μννλλ‘ μ€μ ν μ μλ€.
κΈ°νΈ | μλ―Έ |
---|---|
+ | Create |
- | Destroy |
-/+ | Replace |
~ | Updated in-place |
ν λΌνΌ ꡬμ±μ μΆκ°λ 리μμ€μ Stateμ λ°λΌ μ΄λ€ λμμ΄ λ°μνλμ§ λ€μ μ€μ΅μΌλ‘ νμΈν΄λ³΄κ² λ€.
μ ν | κ΅¬μ± λ¦¬μμ€ μ μ(*.tf) | State κ΅¬μ± λ°μ΄ν° | μ€μ 리μμ€ | κΈ°λ³Έ μμ λμ |
---|---|---|---|---|
1 | μμ | 리μμ€ μμ± | ||
2 | μμ | μμ | 리μμ€ μμ± | |
3 | μμ | μμ | μμ | λμ μμ |
4 | μμ | μμ | 리μμ€ μμ | |
5 | μμ | λμ μμ |
μ ν1 : μ κ· λ¦¬μμ€ μ μ > Apply > 리μμ€ μμ±
λ€μκ³Ό κ°μ΄ tf νμΌμ μμ±νκ³ μ€ννκ² λ€.
locals {
name = "mytest"
}
resource "aws_iam_user" "myiamuser1" {
name = "${local.name}1"
}
resource "aws_iam_user" "myiamuser2" {
name = "${local.name}2"
}
μ ν2 : μ€μ 리μμ€ μλ μ κ±° > Apply > 리μμ€ μμ±
μ€μ 리μμ€λ₯Ό μλ μ κ±°νκ³ κ²°κ³Όλ₯Ό νμΈν΄λ³΄κ² λ€.
λ€μκ³Ό κ°μ΄ iam μ μ λ₯Ό μλ μμ ν ν, μ μμ μΌλ‘ μμ λ κ²μ νμΈνλ€.
κ·Έλ¦¬κ³ planμ μ€νν κ²°κ³Όμ refresh λ¨κ³λ₯Ό μλ΅ν κ²°κ³Όλ₯Ό λΉκ΅ν΄λ³΄κ² λ€.
devcw@woos-dev-server:/mnt/c/Users/chanw/OneDrive/λ°ν νλ©΄/terraform/5.2$ terraform plan
aws_iam_user.myiamuser1: Refreshing state... [id=mytest1]
aws_iam_user.myiamuser2: Refreshing state... [id=mytest2]
.
.
Plan: 2 to add, 0 to change, 0 to destroy.
devcw@woos-dev-server:/mnt/c/Users/chanw/OneDrive/λ°ν νλ©΄/terraform/5.2$ terraform plan -refresh=false
No changes. Your infrastructure matches the configuration.
plan μ€ν κ²°κ³Ό 리μμ€ μ μμ Stateκ° μμ§λ§ μ€μ¬νλ λμμ΄ μμ΄ λ€μ μμ±νλ μ€ν κ³νμ΄ λνλλ€.
κ·Έλ¦¬κ³ λλ²μ¨°λ‘ Refresh λ¨κ³λ₯Ό μλ΅ν κ²½μ° μ€ν κ³νμ λ³κ²½μ΄ μλ κ²μ νμΈν μ μλ€.
λ€μ applyλ₯Ό μ§ννκ³ , iam μ¬μ©μλ₯Ό νμΈνλ€.
μ ν3 : Apply > Apply < μ½λ, State, νμ λͺ¨λ μΌμΉν κ²½μ°
ν λΌνΌ ꡬμ±μ μ μλ 리μμ€λ‘ μμ±λ νλ‘λΉμ λ κ²°κ³Όκ° Stateμ μκ³ μ€μ 리μμ€λ μλ κ²½μ°λΌλ©΄ ν λΌνΌμ κ΄λ ¨ 리μμ€μ λν λ³κ²½ κ³νμ λ°μμν€μ§ μλλ€.
μ μ ν 2μ λ€μ terraform applyλ₯Ό μνν΄ νλ‘λΉμ λ κ²°κ³Όκ° μλ κ²½μ° planμΌλ‘ μ€ν κ³νμ μμ±ν΄λ λ³κ²½ μ¬νμ΄ μλ€.
terraform apply -auto-approve
cat terraform.tfstate | jq .serial
terraform apply -auto-approve
cat terraform.tfstate | jq .serial
terraform apply -auto-approve
cat terraform.tfstate | jq .serial
μ ν4 : μ½λμμ μΌλΆ 리μμ€ μμ > Apply
ꡬμ±, State, μ€μ 리μμ€κ° μλ μνμμ ν λΌνΌ ꡬ문μ μμ νλ©΄ μ¬μ©μλ μλμ μΌλ‘ ν΄λΉ 리μμ€λ₯Ό μμ νλ κ²μ΄λ€.
ν λΌνΌμ κ΅¬μ± νμΌμ κΈ°μ€μΌλ‘ Stateμ λΉκ΅ν΄ μμ λ ꡬμ±μ μ€μ 리μμ€μμ μ κ±°νλ€.
λ€μκ³Ό κ°μ΄ tf νμΌμ μμ νλ€.
locals {
name = "mytest"
}
resource "aws_iam_user" "myiamuser1" {
name = "${local.name}1"
}
μ ν5
μ΄λ―Έ λ§λ€μ΄μ§ 리μμ€λ§ μλ€λ©΄ ν λΌνΌμ stateμ μλ λ΄μ©μ΄λ―λ‘ ν λΌνΌμΌλ‘ κ΄λ¦¬λμ§ μλλ€.
λ°λΌμ ν΄λΉ 리μμ€μ λν΄μλ μ무 μμ λ μνν μ μλ€.
- μ²μλΆν° ν λΌνΌμΌλ‘ κ΄λ¦¬λμ§ μμ 리μμ€μΈ κ²½μ°
- ν λΌνΌμΌλ‘ μμ±νκ³ κ΅¬μ±κ³Ό Stateκ° μμ λ κ²½μ°
ν λΌνΌμΌλ‘ κ΄λ¦¬λμ§ μμ 리μμ€λ₯Ό ν λΌνΌμΌλ‘ κ΄λ¦¬νλ λ°©λ²μ μΆνμ λ€λ€λ³΄κ² λ€.
μ ν6 : μλ‘ tfstate νμΌ μμ > plan/apply
μ€μλ‘ tfsate νμΌμ μμ ν μν©μ κ°μ νμ¬ νμΈν΄λ³΄κ² λ€.
# μ€μλ‘ tfstate νμΌ μμ
**terraform state list**
*aws_iam_user.myiamuser1*
rm -rf terraform.tfstate*
#
**terraform plan**
aws iam list-users | jq
**terraform plan -refresh=false
#
terraform apply -auto-approve**
terraform state list
**cat terraform.tfstate | jq**
# iam μ¬μ©μ 리μ€νΈ νμΈ
aws iam list-users | jq
μ μν©μμ 볡ꡬ? νλ λ°©λ²μ? import λ± λ°©λ²μ΄ μλ€.
Import Terraform configuration | Terraform | HashiCorp Developer
# iam μ¬μ©μ 리μ€νΈ νμΈ
aws iam list-users | jq
# import λμλ§ : λΉ¨κ°μ μ€λͺ
μΆλ ₯...
terraform import
# ADDRμ 리μμ€μ£Όμ , IDλ
# terraform [global options] import [options] ADDR ID
**terraform import aws_iam_user.myiamuser1 mytest1**
*aws_iam_user.myiamuser1: Importing from ID "mytest1"...
aws_iam_user.myiamuser1: Import prepared!
Prepared aws_iam_user for import
aws_iam_user.myiamuser1: Refreshing state... [id=mytest1]
**Import successful!**
The resources that were imported are shown above. These resources are now in
your Terraform state and will henceforth be managed by Terraform.*
#
terraform state list
cat terraform.tfstate | jq
terraform apply -auto-approve
3. μν¬μ€νμ΄μ€
Stateλ₯Ό κ΄λ¦¬νλ λ Όλ¦¬μ μΈ κ°μ 곡κ°μ μν¬μ€νμ΄μ€λΌκ³ νλ€. ν λΌνΌ κ΅¬μ± νμΌμ λμΌνμ§λ§ μμ μλ μλ‘ λ€λ₯Έ Stateλ₯Ό κ°λ μ€μ λμμ νλ‘λΉμ λν μ μλ€.
μν¬μ€νμ΄μ€λ κΈ°λ³Έμ μΌλ‘ defaultλ‘ μ μλλ€. λ‘컬 μμ νκ²½μ μν¬μ€νμ΄μ€ κ΄λ¦¬λ₯Ό μν CLI λͺ λ ΉμΌλ‘ workspaceκ° μλ€.
μ¬μ© μ€μΈ μν¬μ€νμ΄μ€ νμΈμ μν΄ terraform workspace list λͺ λ ΉμΌλ‘ νμΈν΄λ³΄λ©΄ κΈ°λ³Έ default μΈ λ€λ₯Έ μν¬μ€νμ΄μ€λ μκ³ μ¬μ©μ€μΈ μν¬μ€νμ΄μ€μμ λνλ΄κΈ° μν΄ μμ * κΈ°νΈκ° λΆμ΄ μλ€.
μ€μ΅μ μν΄ λ€μκ³Ό κ°μ΄ tfνμΌμ μμ± ν μ€ννλ€.
resource "aws_instance" "mysrv1" {
ami = "ami-0ea4d4b8dc1e46212"
instance_type = "t2.micro"
tags = {
Name = "t101-study"
}
}
λ€μκ³Ό κ°μ΄ μ κ· μν¬μ€νμ΄μ€λ₯Ό μμ±νκ³ νμΈνλ€.
terraform plan κ²°κ³Ό 리μμ€κ° μλ‘ μμ±λλ κ²μ νμΈν μ μλ€.
applyλ₯Ό μ€ννλ, κ° μν¬μ€νμ΄μ€ λ³ μμ 리μμ€κ° λΆλ¦¬λμ΄ μ€νλμλ€λ κ²μ νμΈν μ μλ€.
- μ₯μ
- νλμ λ£¨νΈ λͺ¨λμμ λ€λ₯Έ νκ²½μ μν 리μμ€λ₯Ό λμΌν ν λΌνΌ ꡬμ±μΌλ‘ νλ‘λΉμ λνκ³ κ΄λ¦¬
- κΈ°μ‘΄ νλ‘λΉμ λλ νκ²½μ μν₯μ μ£Όμ§ μκ³ λ³κ²½ μ¬ν μ€ν κ°λ₯
- κΉμ λΈλμΉ μ λ΅μ²λΌ λμΌν ꡬμ±μμ μλ‘ λ€λ₯Έ 리μμ€ κ²°κ³Ό κ΄λ¦¬
- λ¨μ
- Stateκ° λμΌν μ μ₯μ(λ‘컬 λλ λ°±μλ)μ μ μ₯λμ΄ State μ κ·Ό κΆν κ΄λ¦¬κ° λΆκ°λ₯
- λͺ¨λ νκ²½μ΄ λμΌν 리μμ€λ₯Ό μꡬνμ§ μμ μ μμΌλ―λ‘ ν λΌνΌ ꡬμ±μ λΆκΈ° μ²λ¦¬κ° λ€μ λ°μ κ°λ₯
- νλ‘λΉμ λ λμμ λν μΈμ¦ μμλ₯Ό μλ²½ν λΆλ¦¬νκΈ° μ΄λ €μ
μ€ν°λ μΆκ°
→ κ°μ₯ ν° λ¨μ μ μλ²½ν κ²©λ¦¬κ° λΆκ°λ₯
⇒ ν΄κ²°νκΈ° μν΄ λ£¨νΈ λͺ¨λμ λ³λλ‘ κ΅¬μ±νλ λλ ν°λ¦¬ κΈ°λ°μ λ μ΄μμμ μ¬μ©ν μ μλ€ or Terraform Cloud νκ²½μ μν¬μ€νμ΄μ€λ₯Ό νμ©