Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
๋ฆฌ์์ค๊ฐ ์ ๊ณ ์ธ๋ถ ์์กด์ฑ์ด ์์. ๋จ์ผ AWS ๊ณ์ . ๋จ์ผ ์ง์ญ. ๋จ์ผ ํ๊ฒฝ.
์
์ฌ๋ฌ AWS ๊ณ์ ๋ฐ ํ๊ฒฝ, Terraform์ ์ฌ์ฉํ๋ ๊ธฐ์กด์ ์ธํ๋ผ ๋ชจ๋
์
๋ง์ AWS ๊ณ์ , ๋ง์ ์ง์ญ, ๋ณต์ฌ-๋ถ์ฌ๋ฃ๊ธฐ๋ฅผ ์ค์ด๋ ์ผ์ด ์๊ธํจ, ์ฌ์ฉ์ ์ง์ ์ธํ๋ผ ๋ชจ๋, ๊ณผ๋ํ ๊ตฌ์ฑ(composition) ์ฌ์ฉ. Terraform์ ์ฌ์ฉ.
WIP
๋งค์ฐ ๋๊ท๋ชจ
์ฌ๋ฌ ๊ณต๊ธ์(AWS, GCP, Azure). ๋ค์ค ํด๋ผ์ฐ๋ ๋ฐฐํฌ. Terraform์ ์ฌ์ฉ.
์๋์ค
์ค๊ฐ ๊ท๋ชจ
์ฌ๋ฌ AWS ๊ณ์ ๋ฐ ํ๊ฒฝ, ๊ธฐ์กด ์ธํ๋ผ ๋ชจ๋, Terrgrunt๋ฅผ ์ฌ์ฉํ ๊ตฌ์ฑ(composition) ํจํด.
์๋์ค
๋๊ท๋ชจ
๋ง์ AWS ๊ณ์ , ๋ง์ ์ง์ญ, ๋ณต์ฌ-๋ถ์ฌ๋ฃ๊ธฐ๋ฅผ ์ค์ด๋ ์ผ์ด ์๊ธํจ, ์ฌ์ฉ์ ์ง์ ์ธํ๋ผ ๋ชจ๋, ๊ณผ๋ํ ๊ตฌ์ฑ(composition) ์ฌ์ฉ. Terragrunt ์ฌ์ฉ.
์๋์ค
๋งค์ฐ ๋๊ท๋ชจ
์ฌ๋ฌ ํ๋ก๋ฐ์ด๋(AWS, GCP, Azure), ๋ฉํฐ ํด๋ผ์ฐ๋ ๋ฐฐํฌ, Terragrunt ์ฌ์ฉ.
์๋์ค
์ด ์๋ด์์ ์ค๋ช ๋ ๋ด์ฉ ์ค ์ผ๋ถ๋ฅผ ์ฐ์ตํ๊ณ ์๋ ํ๋ ๋ถ๋ค์ ์ํ ์ํฌ์๋ ์์ต๋๋ค.
๋ด์ฉ์ ์ฌ๊ธฐ์ ์์ต๋๋ค.
https://github.com/antonbabenko/terraform-best-practices-workshop
๊ณต์ Terraform ๋ฌธ์๋ ๊ตฌ์ฑ(configuration)์ ๋ชจ๋ ์ธก๋ฉด์ ์์ธํ ์ค๋ช ํฉ๋๋ค. ์ด ์น์ ์ ๋๋จธ์ง ๋ถ๋ถ์ ์ดํดํ๋ ค๋ฉด ์ฃผ์ ๊น๊ฒ ์ฝ์ผ์ธ์
์ด ์น์ ์์๋ ์ด ์ฑ ์์ ์ฌ์ฉ๋๋ ์ฃผ์ ๊ฐ๋ ์ ์ค๋ช ํฉ๋๋ค.
๋ฆฌ์์ค๋ is aws_vpc, aws_db_instance ๋ฑ์
๋๋ค. ๋ฆฌ์์ค๋ ์ด๋ ํ ํ๋ก๋ฐ์ด๋์ ์ํ๋ฉฐ ์ธ์(arguments)๋ฅผ ์๋ฝํ๊ณ ์์ฑ(attributes)์ ์ถ๋ ฅ(output)ํ๋ฉฐ ์๋ช
์ฃผ๊ธฐ(lifecycle)๋ฅผ๊ฐ์ง๋๋ค. ๋ฆฌ์์ค๋ ์์ฑ, ๊ฒ์, ์
๋ฐ์ดํธ ๋ฐ ์ญ์ ํ ์ ์์ต๋๋ค.
๋ฆฌ์์ค ๋ชจ๋์ ๊ณตํต ์์ (์: AWS VPC Terraform ๋ชจ๋์ด VPC, ์๋ธ๋ท, NAT ๊ฒ์ดํธ์จ์ด ๋ฑ์ ์์ฑํจ)์ ํจ๊ป ์ํํ๋ ์ฐ๊ฒฐ๋ ๋ฆฌ์์ค์ ์งํฉ์ ๋๋ค. ์ด๋ ๊ณต๊ธ์ ๊ตฌ์ฑ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋ฉฐ, ์ด๋ ๊ณต๊ธ์์ ๊ตฌ์ฑ์ ๋ฐ๋ผ ๋ค๋ฅด๋ฉฐ, ๊ณต๊ธ์ ๊ตฌ์ฑ ์์์ ์ ์ํ๊ฑฐ๋ ์์ ์์ค์ ๊ตฌ์กฐ(์: ์ธํ๋ผ ๋ชจ๋)์์ ์ ์ํ ์ ์์ต๋๋ค.
์ธํ๋ผ ๋ชจ๋์ ๋ ผ๋ฆฌ์ ์ผ๋ก ์ฐ๊ฒฐ๋์ง๋ ์์ง๋ง ํ์ฌ ์ํฉ/ํ๋ก์ ํธ/์ ์ ์์ ๋์ผํ ๋ชฉ์ ์ ์ํํ๋ ๋ฆฌ์์ค ๋ชจ๋์ ์งํฉ์ ๋๋ค. ๊ณต๊ธ์์ ๋ํ ๊ตฌ์ฑ์ ์ ์ํ๊ณ ๋ค์ด์คํธ๋ฆผ ๋ฆฌ์์ค ๋ชจ๋ ๋ฐ ๋ฆฌ์์ค๋ก ์ ๋ฌ๋ฉ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ ผ๋ฆฌ์ ๊ตฌ๋ถ์(์: AWS Region, Google Project)๋น ํ๋์ ์ํฐํฐ์์ ์์ ํ๋๋ก ์ ํ๋ฉ๋๋ค.
์๋ฅผ ๋ค์ด terraform-aws-atlantis ๋ชจ๋์ terraform-aws-vpc ๋ฐ terraform-aws-security-group๊ณผ ๊ฐ์ ๋ฆฌ์์ค ๋ชจ๋์ ์ฌ์ฉํ์ฌ AWS Fargate์์ Atlantis๋ฅผ ์คํํ๋ ๋ฐ ํ์ํ ์ธํ๋ผ๋ฅผ ๊ด๋ฆฌํฉ๋๋ค.
๋ ๋ค๋ฅธ ์๋ก terraform-aws-modules ๋ชจ๋์ ์ฌ๋ฌ ๊ฐ ํจ๊ป ์ฌ์ฉํ์ฌ ์ธํ๋ผ๋ฅผ ๊ด๋ฆฌํ๊ณ ๋์ปค ๋ฆฌ์์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋์ปค ์ด๋ฏธ์ง๋ฅผ ๊ตฌ์ถ, ํธ์ ๋ฐ ๋ฐฐํฌํ๋ terraform-aws-cloudquery ๋ชจ๋์ด ์์ต๋๋ค. ์ด ๋ชจ๋ ๊ฒ์ด ํ ์ธํธ๋ก ์ด๋ฃจ์ด์ง๋๋ค.
๊ตฌ์ฑ์ ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ถ๋ฆฌ๋ ์ฌ๋ฌ ์์ญ(์: AWS ์ง์ญ, ์ฌ๋ฌ AWS ๊ณ์ )์ ๊ฑธ์ณ ์กด์ฌํ ์ ์๋ ์ธํ๋ผ ๋ชจ๋์ ๋ชจ์์ ๋๋ค. ๊ตฌ์ฑ์ ์ ์ฒด ์กฐ์ง์ด๋ ํ๋ก์ ํธ์ ํ์ํ ์ ์ฒด ์ธํ๋ผ๋ฅผ ์ค๋ช ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
๊ตฌ์ฑ์ ๊ฐ๋ณ ๋ฆฌ์์ค๋ฅผ ๊ตฌํํ๋ ๋ฆฌ์์ค ๋ชจ๋๋ค๋ก ์ด๋ฃจ์ด์ง ์ธํ๋ผ ๋ชจ๋์ ๋๋ค.
์ญ์์ ๋ง: ์ด ์ฑ ์์๋ ์ด๋ค ๋์์ ์ด๋ฃจ๋ ๊ตฌ์ฑ ์์์ ์งํฉ์ ์๋ฏธํ๋ composition๊ณผ ์ํํธ์จ์ด๋ ํ๊ฒฝ ๋ฑ์ ์์ธ ์ต์ ์ ์ค์ ํ๋ค๋ ์๋ฏธ์ configuration์ด๋ผ๋ ์ฉ์ด๊ฐ ๋ง์ด ์ฐ์ ๋๋ค. ์ฐ๋ฆฌ๋ง๋ก ์ฎ๊ธฐ๋ฉด ๋ ๋ค '๊ตฌ์ฑ'์ผ๋ก ๋ฒ์ญ์ด ๋๊ธฐ ๋๋ฌธ์ ์ด๋ป๊ฒ ํ ๊น ๊ณ ๋ฏผํ๋ค๊ฐ, ํ๊ตญ์ด๋ก ์ด ์ฑ ์ ์ ํ์๋ ๋ ์๋ถ๋ค๊ป ๊ฐ์ฅ ํธ์ํ๊ณ ์ดํดํ๊ธฐ ์ฌ์ด ๋ฐฉ๋ฒ์ด๊ธฐ๋ฅผ ๋ฐ๋ผ๋ ๋ง์์์ '๊ตฌ์ฑ'์ด๋ผ๊ณ ์ฐ๊ณ ๊ดํธ ์์ ์์ด ์๋ฌธ์ ์ฉ์ด๋ฅผ ๋ณ๊ธฐํ๋ ๋ฐฉ์์ ์ ํํ์ต๋๋ค. ๋ชจ์ชผ๋ก ๋ฒ์ญ์ด ๋์์ด ๋๊ธฐ๋ฅผ ๋ฐ๋ผ๋ฉฐ, composition์ ๊ตฌ์ฑ๊ณผ configuration์ ๊ตฌ์ฑ์ด ํผ๋ ์์ด ์ ์ ๋ฌ๋๊ธฐ๋ฅผ ๋ฐ๋๋๋ค.
๋ฐ์ดํฐ ์์ค๋ ์ฝ๊ธฐ ์ ์ฉ ์์ ์ ์ํํ๋ฉฐ ํ๋ก๋ฐ์ด๋ ๊ตฌ์ฑ์ ๋ฐ๋ผ ๋ฆฌ์์ค ๋ชจ๋ ๋ฐ ์ธํ๋ผ ๋ชจ๋์์ ์ฌ์ฉ๋ฉ๋๋ค.
๋ฐ์ดํฐ ์์ค terraform_remote_state๋ ์์ ๋ชจ๋ ๋ฐ ๊ตฌ์ฑ(compositions)์ ์ ์ฐฉ์ ์ญํ ์ ํฉ๋๋ค.
๋ฐ์ดํฐ ์์ค external(์ธ๋ถ)๋ ์ธ๋ถ ํ๋ก๊ทธ๋จ์ด ๋ฐ์ดํฐ ์์ค ์ญํ ์ ํ์ฌ, ํ ๋ผํผ ๊ตฌ์ฑ(configuration)์ ๋ค๋ฅธ ๊ณณ์์ ์ฌ์ฉํ ์ ์๋๋ก ์์์ ๋ฐ์ดํฐ๋ฅผ ๋ ธ์ถ์ํต๋๋ค. ์๋กterraform-aws-lambda module์ด ์์ต๋๋ค. ์ฌ๊ธฐ์ ํ์ผ ์ด๋ฆ์ ์ธ๋ถ ํ์ด์ฌ ์คํฌ๋ฆฝํธ๋ฅผ ํธ์ถํ์ฌ ๊ณ์ฐ๋ฉ๋๋ค.
๋ฐ์ดํฐ ์์ค http๋ ์ฃผ์ด์ง URL๋ก HTTP GET ์์ฒญ์ ๋ณด๋ด๊ณ ์๋ต์ ๋ํ ์ ๋ณด๋ฅผ ๋ด๋ณด๋ ๋๋ค. ์ด๋ ๋ค์ดํฐ๋ธ Terraform ํ๋ก๋ฐ์ด๋๊ฐ ์กด์ฌํ์ง ์๋ ์๋ํฌ์ธํธ์์ ์ ๋ณด๋ฅผ ์ป๋ ๋ฐ ์ ์ฉํ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค.
์ธํ๋ผ ๋ชจ๋ ๋ฐ ๊ตฌ์ฑ(compositions)์ Terraform state๋ฅผ ๋ค๋ฅธ ์ฌ์ฉ์๊ฐ ์ ์ด ๊ฐ๋ฅํ ๋ฐฉ์(์: ACL ์ง์ , ๋ฒ์ ๊ด๋ฆฌ, ๋ก๊น )์ผ๋ก ๊ฒ์ํ ์ ์๋ ์๊ฒฉ ์์น์ ์ง์์์ผ์ผ ํฉ๋๋ค.
ํ๋กํ์ด๋, ํ๋ก๋น์ ๋ ๋ฐ ๊ธฐํ ๋ช ๊ฐ์ง ์ฉ์ด๋ ๊ณต์ ๋ฌธ์์ ๋งค์ฐ ์ ์ค๋ช ๋์ด ์์ผ๋ฏ๋ก ์ฌ๊ธฐ์ ๋ฐ๋ณตํ ํ์๊ฐ ์์ต๋๋ค. ์ ์๊ฐ์๋ ์ข์ Terraform ๋ชจ๋์ ์ฐ๋ ๊ฒ๊ณผ๋ ๊ฑฐ์ ๊ด๋ จ์ด ์์ต๋๋ค.
๊ฐ๋ณ ๋ฆฌ์์ค๋ ์ธํ๋ผ์ ์์์ ๊ฐ์ผ๋ฉฐ ๋ฆฌ์์ค ๋ชจ๋์ ๋ถ์(์ฌ๋ฌ ๊ฐ์ ์์๋ก ๊ตฌ์ฑ๋จ)์ ๊ฐ์ต๋๋ค. ๋ชจ๋์ ๋ฒ์ ์ด ๊ด๋ฆฌ๋๊ณ ๊ณต์ ๊ฐ ๊ฐ๋ฅํ ๊ฐ์ฅ ์์ ๋จ์์
๋๋ค. ๋ชจ๋์๋ ์ ํํ ์ธ์ ๋ชฉ๋ก์ด ์์ผ๋ฉฐ, ํด๋น ๋จ์๊ฐ ํ์ํ ๊ธฐ๋ฅ์ ์ํํ๋๋ก ๊ธฐ๋ณธ ๋
ผ๋ฆฌ๋ฅผ ๊ตฌํํฉ๋๋ค. ์๋ฅผ ๋ค์ด terraform-aws-security-group ๋ชจ๋์ ์
๋ ฅ์ ๊ธฐ๋ฐ์ผ๋ก ๋ฆฌ์์ค aws_security_group ๋ฐ aws_security_group_rule์ ์์ฑํฉ๋๋ค. ์ด ๋ฆฌ์์ค ๋ชจ๋ ์์ฒด๋ฅผ ๋ค๋ฅธ ๋ชจ๋๊ณผ ํจ๊ป ์ฌ์ฉํ์ฌ ์ธํ๋ผ ๋ชจ๋์ ๋ง๋ค ์ ์์ต๋๋ค.
๋ถ์(๋ฆฌ์์ค ๋ชจ๋ ๋ฐ ์ธํ๋ผ ๋ชจ๋) ์ ๋ฐ์ ๋ฐ์ดํฐ์ ๋ํ ์ก์ธ์ค๋ ๋ชจ๋์ ์์ํ(outputs) ๋ฐ ๋ฐ์ดํฐ ์์ค(data sources)๋ฅผ ์ฌ์ฉํ์ฌ ์ด๋ฃจ์ด์ง๋๋ค.
๊ตฌ์ฑ(compositions) ๊ฐ ์ก์ธ์ค๋ ์๊ฒฉ ์ํ(remote state)์ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋๋ ๊ฒฝ์ฐ๊ฐ ๋ง์ต๋๋ค. ๊ตฌ์ฑ ๊ฐ์ ๋ฐ์ดํฐ๋ฅผ ๊ณต์ ํ๋ ๋ฐฉ๋ฒ์๋ ์ฌ๋ฌ ๊ฐ์ง๊ฐ ์์ต๋๋ค.
์์์ ์ค๋ช ํ ๊ฐ๋ ์ ์์ฌ ์ฝ๋(pseudo-relations)๋ก ํํํ๋ค๋ฉด ๋ค์๊ณผ ๊ฐ์ด ๋ณด์ผ ๊ฒ์ ๋๋ค.
# ํ๊ตญ์ด
๊ตฌ์ฑ-1 {
์ธํ๋ผ-๋ชจ๋-1 {
๋ฐ์ดํฐ-์์ค-1 => d1
๋ฆฌ์์ค-๋ชจ๋-1 {
๋ฐ์ดํฐ-์์ค2 => d2
๋ฆฌ์์ค-1 (d1, d2)
๋ฆฌ์์ค-2 (d2)
}
๋ฆฌ์์ค-๋ชจ๋-2 {
๋ฐ์ดํฐ-์์ค-3 => d3
๋ฆฌ์์ค-3 (d1, d3)
๋ฆฌ์์ค-4 (d3)
}
}
}# ์์ด(English)
composition-1 {
infrastructure-module-1 {
data-source-1 => d1
resource-module-1 {
data-source-2 => d2
resource-1 (d1, d2)
resource-2 (d2)
}
resource-module-2 {
data-source-3 => d3
resource-3 (d1, d3)
resource-4 (d3)
}
}
}Terraform ์ฝ๋ ๊ตฌ์กฐ์ ๊ด๋ จ๋ ์ง๋ฌธ์ ์ปค๋ฎค๋ํฐ์์ ๊ฐ์ฅ ์์ฃผ ๋ฌป๋ ์ง๋ฌธ์ ๋๋ค. ์ฐ๋ฆฌ ๋ชจ๋๊ฐ ์ด๋ ์์ ์๊ฐ ํ๋ก์ ํธ์ ๊ฐ์ฅ ์ ํฉํ ์ฝ๋ ๊ตฌ์กฐ๊ฐ ๋ฌด์์ผ์ง ๊ณ ๋ฏผํด๋ณด๊ธฐ๋ ํ์ฃ .
์ด๋ ๋ง์ ํด๊ฒฐ์ฑ ์ด ์กด์ฌํ๋ ์ง๋ฌธ ์ค ํ๋์ด๋ฉฐ ๋ณดํธ์ ์ธ ์กฐ์ธ์ ๋๋ฆฌ๊ธฐ๊ฐ ๋งค์ฐ ์ด๋ ต์ต๋๋ค. ๋ฐ๋ผ์ ์ฐ๋ฆฌ๊ฐ ๋ค๋ฃจ๊ณ ์ ํ๋๊ฒ์ด ๋ฌด์์ธ์ง ์ดํดํ๋ ๊ฒ๋ถํฐ ์์ํด ๋ด ์๋ค.
ํ๋ก์ ํธ์ ๋ณต์ก์ฑ์ ์ด๋ป๊ฒ ๋๋์?
๊ด๋ จ ๋ฆฌ์์ค ์
Terraform ํ๋ก๋ฐ์ด๋ ์(์๋ "๋ ผ๋ฆฌ์ ์ ๊ณต์(logical providers)"์ ๋ํ ์ฐธ๊ณ ์ฌํญ์ ํ์ธํ์ธ์)
์ธํ๋ผ๊ฐ ์ผ๋ง๋ ์์ฃผ ๋ณ๊ฒฝ๋ฉ๋๊น?
์/์ฃผ/์ผ์ 1ํ๋ถํฐ
์ง์์ ์ผ๋ก๊น์ง(์ ์ปค๋ฐ์ด ์์ ๋๋ง๋ค)
์ฝ๋ ๋ณ๊ฒฝ ๊ฒ์์? ์ ์ํฐํฉํธ๊ฐ ๋น๋๋๋ฉด CI ์๋ฒ๊ฐ ์ ์ฅ์๋ฅผ ์ ๋ฐ์ดํธํ๋๋ก ํ์ฉํฉ๋๊น?
๊ฐ๋ฐ์๋ง ์ธํ๋ผ ์ ์ฅ์์ ํธ์ํ ์ ์์ต๋๋ค.
๋๊ตฌ๋ PR์ ์ด์ด ๋ฌด์์ ๋ํ ๋ณ๊ฒฝ์ด๋ ์ ์ํ ์ ์์ต๋๋ค(CI ์๋ฒ์์ ์คํ๋๋ ์๋ํ๋ ์์ ํฌํจ).
์ด๋ค ๋ฐฐํฌ ํ๋ซํผ์ด๋ ๋ฐฐํฌ ์๋น์ค๋ฅผ ์ฌ์ฉํ์๋์?
AWS CodeDeploy, Kubernetes ๋๋OpenShift์๋ ์ฝ๊ฐ ๋ค๋ฅธ ์ ๊ทผ ๋ฐฉ์์ด ํ์ํฉ๋๋ค.
ํ๊ฒฝ์ ์ด๋ป๊ฒ ๊ทธ๋ฃนํ๋๋์?
ํ๊ฒฝ, ์ง์ญ, ํ๋ก์ ํธ๋ณ
๋ชจ๋ ์ฝ๋๋ฅผ main.tf์ ๋ฃ๋ ๊ฒ์ ํ๋ก์ ํธ๋ฅผ ๋ง ์์ํ๊ฑฐ๋ ์์ ์ฝ๋๋ฅผ ์์ฑํ ๋๋ ์ข์ ์๊ฐ์ ๋๋ค. ๋ค๋ฅธ ๋ชจ๋ ๊ฒฝ์ฐ์๋ ๋ค์๊ณผ ๊ฐ์ด ์ฌ๋ฌ ํ์ผ์ ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ถํ ํ๋ ๊ฒ์ด ๋ ์ข์ต๋๋ค.
main.tf - ๋ชจ๋, ๋ก์ปฌ ๋ฐ ๋ฐ์ดํฐ ์์ค๋ฅผ ํธ์ถํ์ฌ ๋ชจ๋ ๋ฆฌ์์ค ์์ฑ
variables.tf - main.tf์์ ์ฌ์ฉ๋๋ ๋ณ์ ์ ์ธ์ ํฌํจํฉ๋๋ค
outputs.tf - main.tf์์ ์์ฑ๋ ๋ฆฌ์์ค์ ์ถ๋ ฅ(outputs)์ ํฌํจํฉ๋๋ค.
versions.tf - Terraform ๋ฐ ํ๋ก๋ฐ์ด๋์ ๋ํ ๋ฒ์ ์๊ตฌ ์ฌํญ์ ํฌํจํฉ๋๋ค.
terraform.tfvars๋ ์ธ์๋ ์ด๋์๋ ์ฌ์ฉํ๋ฉด ์ ๋ฉ๋๋ค.
์ ์ ์์ ๋ฆฌ์์ค๋ก ์์ ํ๋ ๊ฒ์ด ๋ ์ฝ๊ณ ๋น ๋ฆ ๋๋ค.
terraform plan ๋ฐ terraform apply๋ ๋ชจ๋ ํด๋ผ์ฐ๋ API ํธ์ถ(์: AWS, GCP, Azure)์ ๋ณด๋ด ๋ฆฌ์์ค ์ํ๋ฅผ ํ์ธํฉ๋๋ค.
์ ์ฒด ์ธํ๋ผ๋ฅผ ๋จ์ผ ๊ตฌ์ฑ(composition)์ผ๋ก ๊ตฌ์ฑ(configure)ํ๋ ๊ฒฝ์ฐ ์๊ฐ์ด ๋ค์ ๊ฑธ๋ฆด ์ ์์ต๋๋ค.
๋ฆฌ์์ค๊ฐ ์ ์ ๊ฒฝ์ฐ ํญ๋ฐ ๋ฐ๊ฒฝ(์ญ์ฃผ: blast radius. ๋ณด์ ์นจํด์ ๊ฒฝ์ฐ ๋ฌธ์ ๊ฐ ์๊ฒผ์ ์ ๊ทธ ์ฌํ๋ก ์ํฅ์ ๋ฐ๋ ๋ฒ์๋ฅผ ํญ๋ฐ์ ๋ฐ๊ฒฝ์ ๋น์ )์ด ๋ ์์ต๋๋ค.
๊ด๋ จ๋์ง ์์ ๋ฆฌ์์ค๋ฅผ ๋ณ๋์ ๊ตฌ์ฑ(composition)์ ๋ฐฐ์นํ์ฌ ์๋ก ๊ฒฉ๋ฆฌํ๋ฉด ๋ฌธ์ ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์ํ์ด ์ค์ด๋ญ๋๋ค.
์๊ฒฉ ์ํ(remote state)๋ฅผ ์ฌ์ฉํด ํ๋ก์ ํธ๋ฅผ ์์ํ์ธ์. ์ด์ ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
๋ ธํธ๋ถ์ ์ธํ๋ผ์ ๋จ์ผ ์ง์ค ๊ณต๊ธ์(infrastructure source of truth)์ ์ํ ์ฅ์๊ฐ ์๋๋๋ค.
tfstate ํ์ผ์ git์์ ๊ด๋ฆฌํ๋ ๊ฒ์ ํฌ๊ฒ์ดํธ์ ์์์
๋๋ค.
๋์ค์ ์ธํ๋ผ ๊ณ์ธต์ด ์ฌ๋ฌ ๋ฐฉํฅ(์์กด์ฑdependencies ๋๋ ๋ฆฌ์์ค ์)์ผ๋ก ์ฆ๊ฐํ๊ธฐ ์์ํ๋ฉด ์ํฉ์ ์ ์ดํ๊ธฐ๊ฐ ๋ ์ฌ์์ง ๊ฒ๋๋ค.
์ผ๊ด๋ ๊ตฌ์กฐ์ ์ ์ค์ฒํ์ธ์.
์ ์ฐจ์ ์ฝ๋์ ๋ง์ฐฌ๊ฐ์ง๋ก Terraform ์ฝ๋๋ ๋ฌด์๋ณด๋ค ์ฌ๋๋ค์ด ์ฝ์ ์ ์๋๋ก ์์ฑ๋์ด์ผ ํฉ๋๋ค. 6๊ฐ์ ํ์ ๋ณ๊ฒฝ ์ฌํญ์ด ๋ฐ์ํ๋๋ผ๋ ๊ตฌ์กฐ์ ์ผ๊ด์ฑ์ด ์๋ค๋ฉด ๋์์ด ๋ ๊ฒ๋๋ค.
Terraform ์ํ ํ์ผ์์ ๋ฆฌ์์ค๋ฅผ ์ด๋ํ ์ ์์ง๋ง ๊ตฌ์กฐ์ ์ด๋ฆ ์ง์ ์ด ์ผ๊ด๋์ง ์์ ๊ฒฝ์ฐ ์ด๋ํ๊ธฐ๊ฐ ๋ ์ด๋ ค์ธ ์ ์์ต๋๋ค.
๋ฆฌ์์ค ๋ชจ๋์ ์ต๋ํ ๋จ์ํ๊ฒ ์ ์งํ์ธ์.
๋ณ์๋ก ์ ๋ฌํ ์ ์๊ฑฐ๋ ๋ฐ์ดํฐ ์์ค๋ฅผ ์ฌ์ฉํ์ฌ ๊ฒ์ํ ์ ์๋ ๊ฐ์ ํ๋์ฝ๋ฉํ์ง ๋ง์ธ์.
๋ฐ์ดํฐ ์์ค์ terraform_remote_state๋ฅผ ํนํ ๊ตฌ์ฑ(composition) ๋ด ์ธํ๋ผ ๋ชจ๋ ๊ฐ์ ์ ์ฐฉ์ ๋ก ์ฌ์ฉํ์ธ์.
์ด ์ฑ ์์๋ ์์ ํ๋ก์ ํธ๋ค์ด ์๊ท๋ชจ ์ธํ๋ผ๋ถํฐ ๋๊ท๋ชจ ์ธํ๋ผ๊น์ง ๋ณต์ก์ฑ์ ๋ฐ๋ผ ๊ทธ๋ฃนํ๋์ด ์์ต๋๋ค. ์ด ๋ถ๋ฆฌ๋ ์๊ฒฉํ์ง ์์ผ๋ฏ๋ก ๋ค๋ฅธ ๊ตฌ์กฐ๋ ํ์ธํ์ธ์.
์ธํ๋ผ๊ฐ ์๋ค๋ ๊ฒ์ ์์กด์ฑ๋ ์ ๊ณ ๋ฆฌ์์ค๋ ์ ๋ค๋ ๊ฒ์ ์๋ฏธํฉ๋๋ค. ํ๋ก์ ํธ๊ฐ ์ฑ์ฅํจ์ ๋ฐ๋ผ Terraform ๊ตฌ์ฑ(configurations) ์คํ์ ์ฐ๊ฒฐํ๊ณ , ๋ค์ํ ์ธํ๋ผ ๋ชจ๋์ ์ฐ๊ฒฐํ๊ณ , ๊ตฌ์ฑ(composition) ๋ด์์ ๊ฐ์ ์ ๋ฌํด์ผ ํ ํ์์ฑ์ด ๋ถ๋ช ํด์ง๋๋ค.
๊ฐ๋ฐ์๊ฐ ์ฌ์ฉํ๋ ์ค์ผ์คํธ๋ ์ด์ ์๋ฃจ์ ์๋ ์ต์ 5๊ฐ์ง ๊ทธ๋ฃน์ด ์์ต๋๋ค.
ํ ๋ผํผ๋ง ์ฌ์ฉํฉ๋๋ค. ๋งค์ฐ ๊ฐ๋จํฉ๋๋ค. ๊ฐ๋ฐ์๋ ์์ ์ ์๋ฃํ๋ ค๋ฉด Terraform๋ง ์๋ฉด ๋ฉ๋๋ค.
Terragrunt. ์ ์ฒด ์ธํ๋ผ๋ฅผ ์กฐ์จํ๊ณ ์์กด์ฑ์ ์ฒ๋ฆฌํ๋ ๋ฐ ์ฌ์ฉํ ์ ์๋ ์์ ์ค์ผ์คํธ๋ ์ด์ ๋๊ตฌ์ ๋๋ค. Terragrunt๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์ธํ๋ผ ๋ชจ๋ ๋ฐ ๊ตฌ์ฑ(composition)์ผ๋ก ์๋ํ๋ฏ๋ก ์ฝ๋์ ์ค๋ณต์ ์ค์ ๋๋ค.
์ธํ์ฐ์ค(in-house) ์คํฌ๋ฆฝํธ. ์ค์ผ์คํธ๋ ์ด์ ์ ์ํ ์ถ๋ฐ์ ์ผ๋ก, ๊ทธ๋ฆฌ๊ณ Terragrunt๋ฅผ ๋ฐ๊ฒฌํ๊ธฐ ์ ์ ์ฌ์ฉํ๊ณคํฉ๋๋ค.
Ansible ๋๋ ์ ์ฌํ ๋ฒ์ฉ ์๋ํ ๋๊ตฌ. ์ฃผ๋ก Ansible ์ดํ์ Terraform์ ์ฑํํ๊ฑฐ๋ Ansible UI๋ฅผ ์ ๊ทน์ ์ผ๋ก ์ฌ์ฉํ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
๋ฐ ๊ธฐํ Kubernetes์์ ์๊ฐ์ ๋ฐ์ ์๋ฃจ์ . ๋๋ก๋ Kubernetes ์ํ๊ณ๋ฅผ ํ์ฉํ๊ณ ์กฐ์ ๋ฃจํ ๊ธฐ๋ฅ์ ์ฌ์ฉํด ์ํ๋ Terraform ๊ตฌ์ฑ(configuration) ์ํ๋ฅผ ๋ฌ์ฑํ๋ ๊ฒ์ด ํฉ๋ฆฌ์ ์ ๋๋ค. ์์ธํ ๋ด์ฉ์ ๋น๋์ค๋ฅผ ์ฐธ์กฐํ์ธ์.
์ด๋ฅผ ์ผ๋์ ๋๊ณ ์ด ์ฑ ์์๋ ์ด๋ฌํ ํ๋ก์ ํธ ๊ตฌ์กฐ ์ค ์ฒ์ ๋ ๊ฐ, Terraform๋ง ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์ Terragrunt๋ฅผ ์์๋ด ๋๋ค.
๋ค์ ์ฅ์์ ๋๋ ์ ์ฝ๋ ๊ตฌ์กฐ ์๋ฅผ ์ฐธ์กฐํ์ธ์.
์ถ์ฒ:
์ด ์์์๋ ๋ค์์ ์ฌ์ฉํ๋ ์ค๊ฐ ๊ท๋ชจ ์ธํ๋ผ์ ๋ํ Terraform ๊ตฌ์ฑ(configurations)์ ๊ตฌ์กฐํํ๋ ์์ ์ฝ๋๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
AWS ๊ณ์ 2๊ฐ
2๊ฐ์ ๋ณ๋ ํ๊ฒฝ(์๋ฌด๊ฒ๋ ๊ณต์ ํ์ง ์๋ prod ๋ฐ stage). ๊ฐ ํ๊ฒฝ์ ๋ณ๋์ AWS ๊ณ์ ์ ์กด์ฌ
๊ฐ ํ๊ฒฝ์ ์์ ์ ๊ณต๋๋ ๊ธฐ์กด ์ธํ๋ผ ๋ชจ๋(alb)์ ๋ค๋ฅธ ๋ฒ์ ์ ์ฌ์ฉํฉ๋๋ค.
๋ก์ปฌ ๋๋ ํ ๋ฆฌ์์ ์์ค๋ฅผ ์ ๊ณตํ๋ฏ๋ก ๊ฐ ํ๊ฒฝ์ ๊ฐ์ ๋ฒ์ ์ ๋ด๋ถ ๋ชจ๋ modules/network์ ์ฌ์ฉํฉ๋๋ค.
์ธํ๋ผ๊ฐ ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ถ๋ฆฌ๋ ํ๋ก์ ํธ์ ์ ํฉ(๋ณ๋์ AWS ๊ณ์ ๋ค์ด ์ฐ์)
AWS ๊ณ์ ๊ฐ์ ๊ณต์ ๋ ๋ฆฌ์์ค๋ฅผ ์์ ํ ํ์๊ฐ ์๋ ๊ฒฝ์ฐ(ํ๊ฒฝ 1๊ฐ = AWS ๊ณ์ 1๊ฐ = ์ํ ํ์ผ 1๊ฐ)์ ์ข์
ํ๊ฒฝ ๊ฐ์ ๋ณ๊ฒฝ ์ฌํญ์ ์กฐ์ ํ ํ์๊ฐ ์๋ ๊ฒฝ์ฐ์ ์ ํฉ
์ธํ๋ผ๋ฆฌ์์ค๊ฐ ํ๊ฒฝ๋ณ๋ก ์๋์ ์ผ๋ก ๋ฌ๋ผ ์ผ๋ฐํํ ์ ์๋ ๊ฒฝ์ฐ(์: ์ด๋ค ๋ฆฌ์์ค๊ฐ ํน์ ํ๊ฒฝ์ด๋ ์ผ๋ถ ์ง์ญ์ ์์)
ํ๋ก์ ํธ๊ฐ ์ปค์ง์ ๋ฐ๋ผ ์ด๋ฌํ ํ๊ฒฝ์ ์๋ก ์ต์ ์ํ๋ก ์ ์งํ๋ ๊ฒ์ ๋์ฑ ์ด๋ ค์์ง๋๋ค. ๋ฐ๋ณต ๊ฐ๋ฅํ ์์ ์ ์ธํ๋ผ ๋ชจ๋(๊ธฐ์กด ๋ชจ๋ ๋๋ ๋ด๋ถ ๋ชจ๋) ์ฌ์ฉ์ ๊ณ ๋ คํด ๋ณด์ธ์.

์ถ์ฒ: https://github.com/antonbabenko/terraform-best-practices/tree/master/examples/small-terraform
์ด ์์์๋ ์ธ๋ถ ์์กด์ฑ์ ์ ํ ์ฌ์ฉํ์ง ์๋ ์๊ท๋ชจ ์ธํ๋ผ์ ๋ํ Terraform ๊ตฌ์ฑ(configurations)์ ๊ตฌ์กฐํํ๋ ์์ ์ฝ๋๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
ํ๋ก์ ํธ๋ฅผ์์ํ๊ณ ์งํํด ๊ฐ๋ฉด์ ๋ฆฌํฉํ ๋งํ๊ธฐ์ ๋ฑ์ ๋๋ค.
์๊ท๋ชจ ๋ฆฌ์์ค ๋ชจ๋์ ์ ํฉ
์๊ท๋ชจ ๋ฐ ์ ํ ์ธํ๋ผ ๋ชจ๋(์: terraform-aws-atlantis)์ ์ ํฉ
์์์ ๋ฆฌ์์ค์ ์ ํฉ(20~30๊ฐ ๋ฏธ๋ง)
๋ฆฌ์์ค ์๊ฐ ์ฆ๊ฐํ๋ ๊ฒฝ์ฐ, ๋ชจ๋ ๋ฆฌ์์ค์ ๋ํ ๋จ์ผ ์ํ ํ์ผ์ Terraform ์์
ํ๋ก์ธ์ค๋ฅผ ๋๋ฆฌ๊ฒ ๋ง๋ค ์ ์์ต๋๋ค(๋ฆฌ์์ค ์๋ฅผ ์ ํํ๋ ค๋ฉด -target ์ธ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค).
locals๋ฅผ ์ฌ์ฉํด ๋ฆฌ์์ค ๊ฐ์ ๋ช
์์ ์์กด์ฑ ์ง์ ํ๊ธฐTerraform ๊ตฌ์ฑ(configurations)์ ์ง์ ์ ์ธ ์์กด์ฑ์ด ์๋ ๊ฒฝ์ฐ์๋ ํน์ ๋ฆฌ์์ค๊ฐ ์ญ์ ๋์ด์ผ ํจ์ Terraform์ ์๋ ค์ฃผ๋ ์ ์ฉํ ๋ฐฉ๋ฒ์ ๋๋ค.
https://raw.githubusercontent.com/antonbabenko/terraform-best-practices/master/snippets/locals.tf
var.website๊ฐ ๋น ๋งต์ด ์๋ ๊ฒฝ์ฐ ํ์์ ์ธ์ index_document๋ฅผ ๋ฐ๋์ ์ค์ ํด์ผ ํฉ๋๋ค.
์ ํ์ ์ธ์ error_document๋ ์๋ตํ ์ ์์ต๋๋ค.
variable "website" {
type = map(string)
default = {}
}
resource "aws_s3_bucket" "this" {
# omitted...
dynamic "website" {
for_each = length(keys(var.website)) == 0 ? [] : [var.website]
content {
index_document = website.value.index_document
error_document = lookup(website.value, "error_document", null)
}
}
}website = {
index_document = "index.html"
}์ด ๋ฌธ์๋ Terraform ์ฌ์ฉ์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ์ค๋ช ํ๊ณ Terraform ์ฌ์ฉ์๋ค์ด ๊ฒช๋ ๊ฐ์ฅ ํํ ๋ฌธ์ ์ ๋ํ ๊ถ์ฅ ์ฌํญ์ ์ ๊ณตํฉ๋๋ค.
์ ๊ฐ๋ ฅํ๋ฉฐ(์ง๊ธ ์ต๊ฐ์ ํด์ด ์๋๋ผ๋ฉด) ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉ๋๋ ๋๊ตฌ ์ค ํ๋๋ก, ์ธํ๋ผ๋ฅผ ์ฝ๋๋ก ๊ด๋ฆฌํ ์ ์์ต๋๋ค. ๊ฐ๋ฐ์๋ค์ด ๋ง์ ์ผ์ ํ ์ ์๋๋ก ํด์ฃผ๋ฉฐ ์ง์๊ณผ ํตํฉ์ ์์ฝ๊ฒ ๋ง๋ค์ด ์ค๋๋ค.
์ด ์ฑ ์์ ์ค๋ช ํ๋ ์ ๋ณด์ ์ผ๋ถ๋ ๋ชจ๋ฒ ์ฌ๋ก์ฒ๋ผ ๋ณด์ด์ง ์์์ง ๋ชจ๋ฆ ๋๋ค. ์ ๋ ์ด๋ฅผ ์ธ์งํ๊ณ ์์ต๋๋ค. ๋ฐ๋ผ์ ๋ ์๋ค์ด ์ฌ์ฉ์๋ค์ด ์ ํธํ๋ ๋น์ทํ ๋ฐฉ์๊ณผ ์ ๊ณ์์ ํ๋ฆฝ๋ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ๊ตฌ๋ถํ ์ ์๋๋ก, ๋ฌธ๋งฅ์ ๋ํ ํํธ์ ์์ด์ฝ์ ์ฌ์ฉํด ๊ฐ ํ์ ํญ๋ชฉ๊ณผ ๊ด๋ จ๋ ๋ชจ๋ฒ ์ฌ๋ก์ ๊น์ด๋ฅผ ํ์ํด ๋์์ต๋๋ค.
์ด ์ฑ ์ 2018๋ ํ์ด์ด ๊ฐ๋ํ ๋ง๋๋ฆฌ๋์์ ์งํ์ ์์ํ์ผ๋ฉฐ, ์ฌ๊ธฐ ์ด ์ฃผ์์์ ์ฝ์ด๋ณผ ์ ์์ต๋๋ค. .
Terraform 1.0์์ ์ฌ์ฉํ ์ ์๋ ์ค์ง์ ๋ชจ๋ฒ ์ฌ๋ก๋ฅผ ์ง๋ ๋ช ๋ ๊ฐ ์ ๋ฐ์ดํธํด ์์ต๋๋ค. ๊ฒฐ๊ณผ์ ์ผ๋ก ์ด ์ฑ ์๋ Terraform ์ฌ์ฉ์๋ค์ ์ํ, ๋ ผ๋์ ์ฌ์ง๊ฐ ์๋ ๋ชจ๋ฒ ์ฌ๋ก์ ๊ถ์ฅ ์ฌํญ์ด ๋๋ถ๋ถ ํฌํจ๋์ด ์๋ค๊ณ ํ ์ ์์ต๋๋ค.
Please if you want to become a sponsor.
์ด ์ฑ ์ ๋ค๋ฅธ ์ธ์ด๋ก ๋ฒ์ญํ๋ ๋ฐ ๊ธฐ์ฌํ๊ณ ์ถ๋ค๋ฉด ์ ์๊ฒ ์ฐ๋ฝ์ฃผ์ธ์.
์๊ฐ์ด ์ง๋จ์ ๋ฐ๋ผ ์ปค๋ฎค๋ํฐ๊ฐ ์ฑ์ํด๊ฐ๊ณ ์๋ก์ด ์์ด๋์ด๊ฐ ๊ตฌํ ๋ฐ ๊ฒ์ฆ๋์ด๊ฐ์ ๋ฐ๋ผ ์ ๋ ํญ์ ํผ๋๋ฐฑ์ ๋ฐ์ ์ด ์ฑ ์ ์ ๋ฐ์ดํธ ํ๊ณ ์ ํฉ๋๋ค.
ํน์ ์ฃผ์ ์ ๊ด์ฌ์ด ์๋ค๋ฉด ๋ค๋ฃจ์ด์ก์ผ๋ฉด ํ๋ ์ด์์ ์์ง์๊ฐ๋ฝ์ ๋๋ฌ์ฃผ์ธ์. ๊ธฐ์ฌํ๊ณ ์ถ์ ์ฝํ ์ธ ๋ฅผ ๊ฐ์ง๊ณ ๊ณ์๋ฉด ์ด์์ ์์ฑํด ํ ๋ฆฌํ์คํธ๋ฅผ ์ ์ถํด ์ฃผ์ธ์(์ด ๋จ๊ณ์์๋ ๋นผ์ด๋ ๊ธ์์จ๋ฅผ ๊ฑฑ์ ํ ํ์๊ฐ ์์ต๋๋ค!).
์ด ์ฑ ์ ๋ค์ํ ๊ธฐ๊ณ ์์ ๋ฒ์ญ๊ฐ์ ๋์์ ๋ฐ์ ๊ฐ ์ ์งํ๊ณ ์์ต๋๋ค.
์ด ์ ์๋ฌผ์ Apache 2 ๋ผ์ด์ ์ค์ ๋ฐ๋ผ ๋ผ์ด์ ์ค๊ฐ ๋ถ์ฌ๋ฉ๋๋ค. ์์ธํ ๋ด์ฉ์ ๋ฅผ ์ฐธ์กฐํ์ธ์.
๋ณธ ์ปจํ ์ธ ์ ์ ์์ ๊ธฐ์ฌ์๋ ๋ณธ ์ปจํ ์ธ ์์ ๋ฐ๊ฒฌ๋๋ ์ ๋ณด์ ์ ํจ์ฑ์ ๋ณด์ฅํ์ง ์์ต๋๋ค. ๊ทํ๋ ๋ณธ ์ปจํ ์ธ ์์ ์ ๊ณต๋๋ ์ ๋ณด๋ ์์ ๋กญ๊ฒ ์ ๊ณต๋๋ฉฐ, ๊ทํ์ ๋ณธ ์ปจํ ์ธ ๋๋ ํ๋ก์ ํธ์ ๊ด๋ จ๋ ์ฌ๋๋ค ์ฌ์ด์ ๊ทธ ์ด๋ค ์ข ๋ฅ์ ํฉ์๋ ๊ณ์ฝ๋ ์ด๋ฃจ์ด์ง์ง ์๋๋ค๋ ์ ์ ์ดํดํ์ ์ผ ํฉ๋๋ค. ์ค๋ฅ ๋๋ ๋๋ฝ์ด ๊ณผ์ค, ์ฌ๊ณ ๋๋ ์ด๋ค ๊ธฐํ ์์ธ์ ์ํ ๊ฒ์ด๋ , ๋ณธ์ ์์ ๊ธฐ์ฌ์๋ ์ปจํ ์ธ ์ ํฌํจ๋๊ฑฐ๋, ๊ด๋ จ๋๊ฑฐ๋, ์ฐ๊ฒฐ๋ ์ ๋ณด์ ์ค๋ฅ ๋๋ ๋๋ฝ์ผ๋ก ์ธํ ๊ทธ ์ด๋ ํ ์์ค, ์์ ๋๋ ์ค๋จ์ ๋ํด์ ๋น์ฌ์์๊ฒ ๊ทธ ์ด๋ ํ ์ฑ ์๋ ์ง์ง ์์ผ๋ฉฐ ๊ทธ์ฑ ์์ ๋ถ์ธํจ์ ์ฌ๊ธฐ๋ฐํ๋๋ค.
์ ์๊ถยฉ 2018-2023 ์๋ ๋ฐ๋ฒค์ฝ Anton Babenko.
์ถ์ฒ:
์ด ์์์๋ ๋ค์์ ์ฌ์ฉํ๋ ๋๊ท๋ชจ ์ธํ๋ผ์ ๋ํ Terraform ๊ตฌ์ฑ(configurations)์ ๊ตฌ์กฐํํ๋ ์์ ์ฝ๋๊ฐ ํฌํจ๋์ด ์์ต๋๋ค.
AWS ๊ณ์ 2๊ฐ
์ง์ญ 2๊ณณ
2๊ฐ์ ๊ฐ๋ณ ํ๊ฒฝ(์๋ฌด๊ฒ๋ ๊ณต์ ํ์ง ์๋ prod ๋ฐ stag). ๊ฐ ํ๊ฒฝ์ ๋ณ๋์ AWS ๊ณ์ ์ ์กด์ฌํ๋ฉฐ ๋ ์ง์ญ ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ํฌ๊ดํฉ๋๋ค
๊ฐ ํ๊ฒฝ์ ์์ ์ ๊ณต๋๋ ๊ธฐ์กด ์ธํ๋ผ ๋ชจ๋(alb)์ ๋ค๋ฅธ ๋ฒ์ ์ ์ฌ์ฉํฉ๋๋ค.
๋ก์ปฌ ๋๋ ํ ๋ฆฌ์์ ์์ค๋ฅผ ์ ๊ณตํ๋ฏ๋ก ๊ฐ ํ๊ฒฝ์ ๊ฐ์ ๋ฒ์ ์ ๋ด๋ถ ๋ชจ๋ modules/network์ ์ฌ์ฉํฉ๋๋ค.
์ธํ๋ผ๊ฐ๋ ผ๋ฆฌ์ ์ผ๋ก ๋ถ๋ฆฌ๋ ํ๋ก์ ํธ์ ์ ํฉ(AWS ๊ณ์ ๋ณ๋)
AWS ๊ณ์ ๊ฐ์ ๊ณต์ ๋ ๋ฆฌ์์ค๋ฅผ ์์ ํ ํ์๊ฐ ์๋ ๊ฒฝ์ฐ(ํ๊ฒฝ 1๊ฐ = AWS ๊ณ์ 1๊ฐ = ์ํ ํ์ผ 1๊ฐ)
ํ๊ฒฝ ๊ฐ์ ๋ณ๊ฒฝ ์ฌํญ์ ์กฐ์ ํ ํ์๊ฐ ์๋ ๊ฒฝ์ฐ์ ์ ํฉ
์ธํ๋ผ ๋ฆฌ์์ค๊ฐ ํ๊ฒฝ๋ณ๋ก ์๋์ ์ผ๋ก ๋ฌ๋ผ ์ผ๋ฐํํ ์ ์๋ ๊ฒฝ์ฐ(์: ์ด๋ค ๋ฆฌ์์ค๊ฐ ํน์ ํ๊ฒฝ์ด๋ ์ผ๋ถ ์ง์ญ์ ์์)
ํ๋ก์ ํธ๊ฐ ์ปค์ง์ ๋ฐ๋ผ ์ด๋ฌํ ํ๊ฒฝ์ ์๋ก ์ต์ ์ํ๋ก ์ ์งํ๋ ๊ฒ์ ๋์ฑ ์ด๋ ค์์ง๋๋ค. ๋ฐ๋ณต ๊ฐ๋ฅํ ์์ ์ ์ธํ๋ผ ๋ชจ๋(๊ธฐ์กด ๋ชจ๋ ๋๋ ๋ด๋ถ ๋ชจ๋) ์ฌ์ฉ์ ๊ณ ๋ คํด ๋ณด์ธ์.
์์ฃผ ๋ฌป๋ ํ ๋ผํผ์ ๊ดํ ์ง๋ฌธ
- ์ค์ผ์คํธ๋ ์ด์ ๋๊ตฌ
- ์ฝ๋ ๋ฆฐํฐ
- ๋ฒ์ ๊ด๋ฆฌ์
- ํ ๋ฆฌํ์คํธ ์๋ํ
- pre-commit ํ๋ ์์ํฌ์ ํจ๊ป ์ฌ์ฉํ๋ Terraform์ฉ git ํํฌ ๋ชจ์
- ํ ์์ฒญ์์ Terraform์ ๋ํ ํด๋ผ์ฐ๋ ๋น์ฉ ์ถ์ . Terragrunt, Atlantis ๋ฐ pre-commit ํ ๋ผํผ์์๋ ์ฌ์ฉ ๊ฐ๋ฅํฉ๋๋ค.
๋ฆฌ์์ค ๋ฐ ์ธํ๋ผ ๋ชจ๋์ ๋ฒ์ ์ ์ง์ ํด์ผ ํฉ๋๋ค. ํ๋ก๋ฐ์ด๋๋ ๋ชจ๋ ์ธ๋ถ์์, ํ์ง๋ง ๊ตฌ์ฑ(composition) ๋ด์์๋ง ๊ตฌ์ฑ๋์ด์ผ(configure) ํฉ๋๋ค. ํ๋ก๋ฐ์ด๋ ๋ฐ Terraform ๋ฒ์ ๋ ์ ๊ธ ์ ์์ต๋๋ค.
๋ง์คํฐ ์์กด์ฑ ๊ด๋ฆฌ ๋๊ตฌ๋ ์์ง๋ง ์์กด์ฑ ์ฌ์๊ณผ ๊ด๋ จ๋ ๋ฌธ์ ๋ฅผ ์ค์ด๋ ๋ช ๊ฐ์ง ํ์ด ์์ต๋๋ค. ์๋ฅผ ๋ค์ด, ์ ์ฌ์ฉํ์ฌ ์์กด์ฑ ์ ๋ฐ์ดํธ๋ฅผ ์๋ํํ ์ ์์ต๋๋ค. Dependabot์ ์์กด์ฑ์ ์์ ํ๊ฒ ์ต์ ์ํ๋ก ์ ์งํ๊ธฐ ์ํด ํ ๋ฆฌํ์คํธ๋ฅผ ์์ฑํฉ๋๋ค. Dependabot์ Terraform ๊ตฌ์ฑ(configurations)์ ์ง์ํฉ๋๋ค.
Compliance.tf โ Terraform Compliance Simplified. Make your Terraform modules compliance-ready.
โ
(์ฌ์ ์ปค๋ฐ)์ ๋ค์ค ์ธ์ด ์ฌ์ ์ปค๋ฐ ํํฌ๋ฅผ ๊ด๋ฆฌํ๊ณ ์ ์งํ๊ธฐ ์ํ ํ๋ ์์ํฌ์ ๋๋ค. Python์ผ๋ก ์์ฑ๋์์ผ๋ฉฐ ์ฝ๋๊ฐ git ์ ์ฅ์์ ์ปค๋ฐ๋๊ธฐ์ ์์ ๊ฐ๋ฐ์์ ์ปดํจํฐ์์ ์๋์ผ๋ก ์์ ์ ์ํํ๋ ๊ฐ๋ ฅํ ๋๊ตฌ์ ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ๋ฆฐํฐ๋ฅผ ์คํํ๊ณ ์ฝ๋ ํ์์ ์ง์ ํ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค(์ฐธ์กฐ).
Terraform ๊ตฌ์ฑ(configurations)์ ์ฌ์ฉํ๋ฉด pre-commit(์ฌ์ ์ปค๋ฐ)์ ์ฌ์ฉํ์ฌ ์ฝ๋ ํ์์ ์ง์ ํ๊ณ ์ ํจ์ฑ์ ๊ฒ์ฌํ ์ ์์ ๋ฟ๋ง ์๋๋ผ ๋ฌธ์๋ฅผ ์
๋ฐ์ดํธํ ์ ์์ต๋๋ค.
์ฌ์ ์ปค๋ฐ์ด ์ต์ํด์ง๋๋ก ๋ฅผ ํ์ธํด๋ณด์ธ์. ๊ทธ๋ฆฌ๊ณ ์ด ์ ์ฅ์๊ฐ ์ด๋ฏธ ์ฌ์ฉ๋๊ณ ์๋ ๊ธฐ์กด ์ ์ฅ์(์: )๋ ํ์ธํด ๋ณด์ธ์.
(ํ ๋ผํผ ๋ ์ค)๋ Terraform ๋ชจ๋์์ ๋ค์ํ ์ถ๋ ฅ ํ์์ผ๋ก ๋ฌธ์๋ฅผ ์์ฑํ๋ ๋๊ตฌ์ ๋๋ค. ์ฌ์ ์ปค๋ฐ ํํฌ ์์ด ์๋์ผ๋ก ์คํํ๊ฑฐ๋, (์ฌ์ ์ปค๋ฐ Terraform ํํฌ)๋ฅผ ์ฌ์ฉํ์ฌ ๋ฌธ์๋ฅผ ์๋์ผ๋ก ์ ๋ฐ์ดํธํ ์ ์์ต๋๋ค.
@todo: Document module versions, release, GH actions
๋ธ๋ก๊ทธ ๊ธ:

๋ฆฌ์์ค ์ด๋ฆ, ๋ฐ์ดํฐ ์์ค ์ด๋ฆ, ๋ณ์ ์ด๋ฆ, ์ถ๋ ฅ ๋ฑ ๋ชจ๋ ๊ณณ์์ -(๋์, dash) ๋์ _(๋ฐ์ค)์ ์ฌ์ฉํฉ๋๋ค.
(UTF-8์ด ์ง์๋๋๋ผ๋) ์๋ฌธ์์ ์ซ์๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
(์ด๋ฆ ์ผ๋ถ ๋๋ ์ ์ฒด๋ฅผ ํฌํจํด) ๋ฆฌ์์ค ์ด๋ฆ์ ๋ฆฌ์์ค ์ ํ์ ๋ฐ๋ณตํ์ง ๋ง์ธ์.
`resource "aws_route_table" "public" {}``resource "aws_route_table" "public_route_table" {}``resource "aws_route_table" "public_aws_route_table" {}`๋ณด๋ค ๋ ์ค๋ช
์ ์ด๊ณ ์ผ๋ฐ์ ์ธ ์ด๋ฆ์ ์ฌ์ฉํ ์ ์๊ฑฐ๋ ๋ฆฌ์์ค ๋ชจ๋์ด ํด๋น ์ ํ์ ๋ํด ๋จ ํ ๊ฐ์ ๋ฆฌ์์ค๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ(์: AWS VPC module์๋ aws_nat_gateway ์ ํ์ ๋ฆฌ์์ค ํ ๊ฐ์ aws_route_table ์ ํ์ ๋ฆฌ์์ค๊ฐ ์ฌ๋ฌ ๊ฐ ์๋ ๊ฒฝ์ฐ์ aws_nat_gateway๋ this๋ก, aws_route_table์ private, public, database์ ๊ฐ์ด ๋ ์ค๋ช
์ ์ธ ์ด๋ฆ์ ์ง์ด์ค์ผ ํฉ๋๋ค.
์ด๋ฆ์๋ ํญ์ ๋จ์ ๋ช ์ฌ๋ฅผ ์ฌ์ฉํ์ธ์.
์ธ์ ๊ฐ ๋ด๋ถ์ ๊ฐ์ด ์ฌ๋์๊ฒ ๋
ธ์ถ๋๋ ๊ณณ(์: RDS ์ธ์คํด์ค์ DNS ์ด๋ฆ ๋ด๋ถ)์๋ -๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ฆฌ์์ค ๋๋ ๋ฐ์ดํฐ ์์ค ๋ธ๋ก ๋ด๋ถ์ ์ธ์ count / for_each๋ฅผ ๋งจ ์์ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ํฌํจํ๊ณ ๊ทธ ๋ค๋ ์ค๋ฐ๊ฟ์ผ๋ก ๊ตฌ๋ถํฉ๋๋ค.
๋ฆฌ์์ค์์ ์ง์ํ๋ ๊ฒฝ์ฐ ์ธ์ tags๋ฅผ ๋ง์ง๋ง ์ค์ ์ธ์๋ก ํฌํจํ๊ณ ํ์ํ ๊ฒฝ์ฐ depends_on ๋ฐ lifecycle์ ํฌํจํฉ๋๋ค. ์ด๋ค ๋ชจ๋๋ ํ๋์ ๋น ์ค๋ก ๊ตฌ๋ถ๋์ด์ผ ํฉ๋๋ค.
์ธ์ count / for_each์ ์กฐ๊ฑด์ ์ฌ์ฉํ ๋๋ length๋ ๋ค๋ฅธ ํํ์์ ์ฌ์ฉํ๋ ๋์ ๋ถ(bool) ๊ฐ์ ์ฐ๋ ๊ฒ์ด ์ข์ต๋๋ค.
resource ์ฝ๋ ์์ count / for_each์ ์ฌ์ฉresource "aws_route_table" "public" {
count = 2
vpc_id = "vpc-12345678"
# ... remaining arguments omitted
}
resource "aws_route_table" "private" {
for_each = toset(["one", "two"])
vpc_id = "vpc-12345678"
# ... remaining arguments omitted
}resource "aws_route_table" "public" {
vpc_id = "vpc-12345678"
count = 2
# ... remaining arguments omitted
}tags์ ๋ฐฐ์นresource "aws_nat_gateway" "this" {
count = 2
allocation_id = "..."
subnet_id = "..."
tags = {
Name = "..."
}
depends_on = [aws_internet_gateway.this]
lifecycle {
create_before_destroy = true
}
} resource "aws_nat_gateway" "this" {
count = 2
tags = "..."
depends_on = [aws_internet_gateway.this]
lifecycle {
create_before_destroy = true
}
allocation_id = "..."
subnet_id = "..."
}count์ ์กฐ๊ฑดresource "aws_nat_gateway" "that" { # Best
count = var.create_public_subnets ? 1 : 0
}
resource "aws_nat_gateway" "this" { # Good
count = length(var.public_subnets) > 0 ? 1 : 0
}๋ฆฌ์์ค ๋ชจ๋์ ๋ฐํด๋ฅผ ๋ค์ ๋ง๋ค์ง ๋ง์ธ์(์ญ์ฃผ: Don't reinvent the wheel! ์ด๋ฏธ ๋ง๋ค์ด์ ธ์ ์ ์ฐ์ด๊ณ ์๋ ๊ฒ์ ๋๊ณ ๊ตณ์ด ๋น์ทํ ์์ค์ ๊ฒ์ ์๋ก ๋ง๋๋ ๋ฐ ์๋์ง๋ฅผ ์๋ ๊ฒ์ ํผํ๋ผ๋ ๋ง). ์์
์ค์ธ ๋ฆฌ์์ค์ ๋ํ "์ธ์ ์ฐธ์กฐ" ์น์
์ ์ ์๋ ๋๋ก ๋ณ์์ ๋ํ name, description, ๋ฐ default๊ฐ์ ์ฌ์ฉํ์ธ์.
๋ณ์์ ์ ํจ์ฑ ๊ฒ์ฌ์ ๋ํ ์ง์์ ๋ค์ ์ ํ์ ์ ๋๋ค(์: ๋ค๋ฅธ ๋ณ์์ ์ก์ธ์คํ๊ฑฐ๋ ์กฐํ๋ฅผ ์ํํ ์ ์์). ๋๋ถ๋ถ์ ๊ฒฝ์ฐ ์ด ๊ธฐ๋ฅ์ ์ธ๋ชจ๊ฐ ์์ผ๋ฏ๋ก ์ํฉ์ ๋ง์ถฐ ๊ณํํ์ธ์.
์ ํ์ด list(...) ๋๋ map(...)์ธ ๊ฒฝ์ฐ ๋ณ์ ์ด๋ฆ์ ๋ณต์ํ์ ์ฌ์ฉํฉ๋๋ค.
๋ณ์ ๋ธ๋ก์ ํค ์์๋ฅผ ๋ค์๊ณผ ๊ฐ์ด ์ง์ ํ์ธ์: description , type, default, validation
๋ถ๋ช
ํ๋ค๊ณ ์๊ฐ๋๋๋ผ๋ ํญ์ ๋ชจ๋ ๋ณ์์ ๋ํ description(์ค๋ช
)์ ํฌํจํ์ธ์(ํฅํ ํ์ํ ๊ฒ์
๋๋ค).
๊ฐ ํค์ ์๊ฒฉํ ์ ์ฝ์ ์ ์ฉํ ํ์๊ฐ ์๋ ํ object()์ ๊ฐ์ ํน์ ์ ํ๋ณด๋ค๋ ๊ฐ๋จํ ์ ํ (number, string, list(...), map(...), any)์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
์ง๋์ ๋ชจ๋ ์์๊ฐ ๋์ผํ ์ ํ(์: string๋ฌธ์์ด)์ด๊ฑฐ๋ ํด๋น ์ ํ์ผ๋ก ๋ณํ๋ ์ ์๋ ๊ฒฝ์ฐ(์: number ์ซ์ ์ ํ์ string ๋ฌธ์์ด๋ก ๋ณํํ ์ ์๋ ๊ฒฝ์ฐ) map(map(string))๊ณผ ๊ฐ์ ํน์ ์ ํ์ ์ฌ์ฉํฉ๋๋ค.
ํน์ ๊น์ด์์ ์์ํ๊ฑฐ๋ ์ฌ๋ฌ ์ ํ์ ์ง์ํด์ผ ํ๋ ๊ฒฝ์ฐ์ ์ ํ ์ ํจ์ฑ ๊ฒ์ฌ๋ฅผ ๋นํ์ฑํํ๋ ค๋ฉด any ์ ํ์ ์ฌ์ฉํ์ธ์.
๊ฐ {}์ ์ง๋์ผ ๋๋ ์๊ณ ๊ฐ์ฒด์ผ ๋๋ ์์ต๋๋ค. ๊ฐ์ฒด๋ฅผ ๋ง๋ค ์ ์๋ ๋ฐฉ๋ฒ์ด ์๊ธฐ ๋๋ฌธ์ ์ง๋๋ฅผ ๋ง๋ค๋ ค๋ฉด tomap(...)์ ์ฌ์ฉํ์ธ์.
๋ชจ๋์ ๋ฒ์ ๋ฐ์์๋ ์ถ๋ ฅ์ ์ผ๊ด๋๊ณ ์ดํดํ๊ธฐ ์ฝ๊ฒ ๋ง๋์ธ์(์ฌ์ฉ์๊ฐ ๋ชจ๋์ ์ฌ์ฉํ ๋ ๋ฐํ๋๋ ๊ฐ์ ์ ํ๊ณผ ์์ฑ์ด ๋ฌด์์ธ์ง ๋ช ํํด์ผ ํฉ๋๋ค).
์ถ๋ ฅ ์ด๋ฆ์ ์์ ์ด ํฌํจํ๋ ์์ฑ์ ์ค๋ช ํด์ผ ํ๋ฉฐ ์ผ๋ฐ์ ์ผ๋ก ์ฐ๋ฆฌ๊ฐ์ํ๋ ๊ฒ๋ณด๋ค๋ ํ์์ด ๋ ์์ ๋กญ์ต๋๋ค.
์ถ๋ ฅ ์ด๋ฆ์ ์ ํฉํ ๊ตฌ์กฐ๋ {name}_{type}_{attribute}์ด๋ฉฐ ๋ค์์ ์ฐธ๊ณ ํ์ธ์.
{name}์ ํ๋ก๋ฐ์ด๋ ์ ๋์ฌ๊ฐ ์๋ ๋ฆฌ์์ค ๋๋ ๋ฐ์ดํฐ ์์ค ์ด๋ฆ์
๋๋ค. aws_subnet์ {name}์ subnet์ด๊ณ , aws_vpc์ ๊ฒฝ์ฐ vpc์
๋๋ค.
{type}์ ๋ฆฌ์์ค ์์ค์ ์ ํ์
๋๋ค.
{attribute}๋ ์ถ๋ ฅ์ด ๋ฐํํ๋ ์์ฑ์
๋๋ค.
์ถ๋ ฅ์ด ๋ณด๊ฐ ํจ์ ๋ฐ ์ฌ๋ฌ ๋ฆฌ์์ค๊ฐ ํฌํจ๋ ๊ฐ์ ๋ฐํํ๋ ๊ฒฝ์ฐ {name} ๋ฐ {type}์ ๊ฐ๋ฅํ ํ ์ผ๋ฐ์ ์ด์ด์ผ ํฉ๋๋ค(์ ๋์ฌ๋ก this๋ ์๋ตํด์ผ ํจ). ์๋ฅผ ์ฐธ์กฐํ์ธ์.
๋ฐํ๋ ๊ฐ์ด ๋ฆฌ์คํธ์ธ ๊ฒฝ์ฐ ๋ณต์ํ ์ด๋ฆ์ ๊ฐ์ ธ์ผ ํฉ๋๋ค. ์๋ฅผ ์ฐธ์กฐํ์ธ์.
๋ถ๋ช
ํ๋ค๊ณ ์๊ฐ๋๋๋ผ๋ ํญ์ ๋ชจ๋ ๋ณ์์ ๋ํ description(์ค๋ช
)์ ํฌํจํ์ธ์.
๋ชจ๋ ๋ชจ๋์ ๋ชจ๋ ์์น์์ ์ด ์ถ๋ ฅ์ ์ฌ์ฉ์ ์์ ํ ์ ์ดํ ์ ์๋ ๊ฒ ์๋๋ผ๋ฉด sensitive ์ธ์๋ฅผ ์ค์ ํ์ง ๋ง์ธ์.
element(concat(...))(0.13 ์ด์ ๋ฒ์ ์ ๋ ๊ฑฐ์ ์ ๊ทผ ๋ฐฉ์)๋ณด๋ค try()(Terraform 0.13๋ถํฐ ์ฌ์ฉ ๊ฐ๋ฅ)๋ฅผ ์ฐ๋ ๊ฒ์ด ์ข์ต๋๋ค.
output ์ฝ๋ ์์ ๋ณด์ ๊ทธ๋ฃน์ ID๋ฅผ ์ต๋ 1๊ฐ ๋ฐํํฉ๋๋ค
output "security_group_id" {
description = "The ID of the security group"
value = try(aws_security_group.this[0].id, aws_security_group.name_prefix[0].id, "")
}๋์ผํ ์ ํ์ ๋ฆฌ์์ค๊ฐ ์ฌ๋ฌ ๊ฐ ์๋ ๊ฒฝ์ฐ ์ถ๋ ฅ ์ด๋ฆ์์ this๋ฅผ ์๋ตํด์ผ ํฉ๋๋ค.
output "this_security_group_id" {
description = "The ID of the security group"
value = element(concat(coalescelist(aws_security_group.this.*.id, aws_security_group.web.*.id), [""]), 0)
}output "rds_cluster_instance_endpoints" {
description = "A list of all cluster instance endpoints"
value = aws_rds_cluster_instance.this.*.endpoint
}https://twitter.com/antonbabenko/lists/terraform-experts - ๋งค์ฐ ์ ๊ทน์ ์ผ๋ก Terraform์ ์ฌ์ฉํด ์ผ์ ํ๊ณ (๋ฌผ์ด๋ณด๋ฉด) ๋ง์ ๊ฒ์ ์๋ ค์ค ์ ์๋ ์ฌ๋๋ค์ ๋ชฉ๋ก
https://github.com/shuaibiyy/awesome-terraform - HashiCorp์ Terraform์ ๋ํ ์ ๋ณ๋ ๋ฆฌ์์ค ๋ชฉ๋ก
http://bit.ly/terraform-youtube - ์๋ ๋ฐ๋ฒค์ฝ์ "๋น์ ์ ์ํ Terraform ์ฃผ๊ฐ ๋ณต์ฉ๋" YouTube ์ฑ๋. ๋ฆฌ๋ทฐ, ์ธํฐ๋ทฐ, Q&A, ๋ผ์ด๋ธ ์ฝ๋ฉ ๋ฐ Terraform ๊ฟํ์ ์๋ ค์ฃผ๋ ๋ผ์ด๋ธ ์คํธ๋ฆฌ๋ฐ
https://weekly.tf - Terraform ์ฃผ๊ฐ ๋ด์ค๋ ํฐ. ์๋ ๋ฐ๋ฒค์ฝ๊ฐ ์ ๊ณตํ๋ Terraform ์ธ๊ณ์ ๋ค์ํ ๋ด์ค(ํ๋ก์ ํธ, ๊ณต์ง, ํ ๋ก )