๐Ÿ“‚ IaC/Terraform

Terraform 101 Study - 1์ฃผ์ฐจ(1) ๋‚ด์šฉ์ •๋ฆฌ

dhyuck 2023. 7. 9. 00:35
๋ฐ˜์‘ํ˜•
  • CloudNeta์˜ ๊ฐ€์‹œ๋‹ค๋‹˜์ด ์ง„ํ–‰ํ•˜์‹œ๋Š” Terraform 101 Study์— ์ฐธ๊ฐ€ํ•˜๋ฉฐ ์ž‘์„ฑํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค.
  • ์Šคํ„ฐ๋”” ๊ต์žฌ โ†’ ํ…Œ๋ผํผ์œผ๋กœ ์‹œ์ž‘ํ•˜๋Š” IaC

CH1. IaC์™€ ํ…Œ๋ผํผ


  • ์ฝ”๋“œ๋กœ ์ธํ”„๋ผ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค๋Š” ๊ฒƒ
    โ†’ โ€˜์ž์œ ๋กญ๊ฒŒ ๋ณ€๊ฒฝโ€™ํ•˜๊ณ , โ€˜ํ™˜๊ฒฝ์„ ์ดํ•ดโ€™ํ•˜๊ณ , โ€˜๋ฐ˜๋ณต์ ์œผ๋กœ ๋™์ผํ•œ ์ƒํƒœโ€™๋ฅผ ๋งŒ๋“ค์ˆ˜ ์žˆ๋‹ค๋Š” ์˜๋ฏธ
    โ†’ ๋ช…์„ธ๋ฅผ ๋ณ„๋„์˜ ๋ฌธ์„œ๋กœ ์ •๋ฆฌํ•˜์ง€ ์•Š์•„๋„ ์ธํ”„๋ผ๊ฐ€ ๋ช…ํ™•ํ•˜๊ฒŒ ์ •์˜๋˜์–ด ๋‚จ๋Š”๋‹ค๋Š” ์˜๋ฏธ

  • IaC๋Š” ์ปดํ“จํ„ฐ์—์„œ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ์˜ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ด ์ธํ”„๋ผ๋‚˜ ์„œ๋น„์Šค๋ฅผ ํ”„๋กœ๋น„์ €๋‹ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค

  • terraform์€ ํ•˜์‹œ์ฝ”ํ”„์—์„œ ๊ณต๊ฐœํ•œ IaC ๋„๊ตฌ

  • Terraform์€ Provider๋ผ๊ณ  ํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ํ†ตํ•ด ํด๋ผ์šฐ๋“œ ์ œ๊ณต์ž(AWS, GCP, โ€ฆ)๋‚˜ ๊ธฐํƒ€ ์„œ๋น„์Šค์™€ ์ƒํ˜ธ ์ž‘์šฉํ•ฉ๋‹ˆ๋‹ค.

  • ํ…Œ๋ผํผ ์ œ๊ณต ์œ ํ˜• 3๊ฐ€์ง€

    • On-Premise(์˜คํ”ˆ์†Œ์Šค ์‚ฌ์šฉ) โ†’ ๋ณ„๋„๋กœ ํ…Œ๋ผํผ ์‹คํ–‰ํ™˜๊ฒฝ๊ณผ state ๊ด€๋ฆฌ ๋ฐฉ๋ฒ•์„ ๋งˆ๋ จํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค
    • Terraform Cloud(SaaS) โ†’ ํ…Œ๋ผํผ ์‹คํ–‰ํ™˜๊ฒฝ๊ณผ state๊ด€๋ฆฌ๋ฅผ ์ง€์›
    • Terraform Enterprise(Private Install) โ†’ ์‚ฌ๋‚ด ์ปดํ“จํŒ… ์ž์›์— ์„ค์น˜
  • Immutable๊ณผ Mutable

    • Immutable Infrastructure๋Š” originally provisioned๋œ ์ดํ›„๋กœ ์ˆ˜์ •ํ•  ์ˆ˜ ์—†๋Š” ์ธํ”„๋ผ ์ŠคํŠธ๋Ÿญ์ณ์ž…๋‹ˆ๋‹ค.
    • Mutable infrastructure๋Š” originally provisioned ๋œ ์ดํ›„๋กœ ์ˆ˜์ •๋˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๋Š” ์ธํ”„๋ผ ์ŠคํŠธ๋Ÿญ์ณ์ž…๋‹ˆ๋‹ค.
    • Immutable์€ ์ˆ˜์ •์ด๋‚˜ ์—…๋ฐ์ดํŠธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์ƒˆ๋กœ์šด ์ธํ”„๋ผ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์ด์ „ ์ƒํƒœ์˜ ์ธํ”„๋ผ๋ฅผ ๊ต์ฒดํ•˜๋Š” ๋ฐฉ์‹
    • Immutable Infrastructure๋Š” ์ธํ”„๋ผ๋ฅผ ๋ฒ„์ „์œผ๋กœ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ธํ”„๋ผ๋ฅผ ๋กค๋ฐฑํ•˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด์ค๋‹ˆ๋‹ค.
    • ํ…Œ๋ผํผ์€ immutableํ•˜๊ฒŒ ์ธํ”„๋ผ๋ฅผ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
    • ํ…Œ๋ผํผ์œผ๋กœ ๊ตฌ์„ฑํ•œ ์ธํ”„๋ผ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธ ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๋Š” IaC์˜ ์ด์ ์ธ ์ธํ”„๋ผ ์ผ๊ด€์„ฑ์„ ์•ฝํ™”์‹œํ‚ต๋‹ˆ๋‹ค.

CH3. ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ• - 1


3-1. ์ฃผ์š” ์ปค๋งจ๋“œ


terraform init

  • ํ…Œ๋ผํผ configuration ํŒŒ์ผ์ด ์žˆ๋Š” ์ž‘์—… ๋””๋ ‰์ฒ˜๋ฆฌ๋ฅผ ์ดˆ๊ธฐํ™”
  • init์„ ์‹คํ–‰ํ•˜๋Š” ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ ๋ฃจํŠธ๋ชจ๋“ˆ์ด๋ผ๊ณ  ํ•œ๋‹ค.
  • ํ…Œ๋ผํผ์—์„œ ์‚ฌ์šฉ๋˜๋Š” ํ”„๋กœ๋ฐ”์ด๋”, ๋ชจ๋“ˆ ๋“ฑ์˜ ์ง€์ •๋œ ๋ฒ„์ „์— ๋งž์ถฐ ๋ฃจํŠธ๋ชจ๋“ˆ์„ ๊ตฌ์„ฑํ•˜๋Š” ์—ญํ• 
  • -upgrade
    • ๋ชจ๋“  provider๋ฅผ configuration์— ์ง€์ •๋œ ๋ฒ„์ „ ์ œ์•ฝ ์กฐ๊ฑด ๋‚ด์—์„œ(the version constraints sepcified within) ์ตœ์‹  ๋ฒ„์ „์œผ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•ฉ๋‹ˆ๋‹ค.
    • ๊ตฌ์„ฑ ๋‚ด์— ๋ฒ„์ „ ์ œ์•ฝ ์กฐ๊ฑด์ด ํ˜„์žฌ ๊ณต๊ธ‰์ž ๋ฒ„์ „๋ณด๋‹ค ๋” ๋‚ฎ์€ ๋ฒ„์ „์ธ ๊ฒฝ์šฐ ๋‹ค์šด๊ทธ๋ ˆ์ด๋“œ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

terraform validate

  • ํ…Œ๋ผํผ configuration ํŒŒ์ผ์˜ ์œ ํšจ์„ฑ์„ ํ™•์ธํ•˜๋Š” ์—ญํ•  โ†’ ์ฝ”๋“œ์ ์ธ ์œ ํšจ์„ฑ๋งŒ์„ ๊ฒ€ํ† 

terraform plan

  • ์ธํ”„๋ผ๋ฅผ ๋ณ€๊ฒฝํ•˜๊ธฐ ์œ„ํ•œ ์‹คํ–‰ ๊ณ„ํš์„ ์ƒ์„ฑํ•˜๋Š” ์—ญํ•  โ†’ ๋ณ€๊ฒฝ์‚ฌํ•ญ์„ ์‹ค์ œ ์ ์šฉํ•˜์ง€๋Š” ์•Š๋Š”๋‹ค.
  • apply ์ „์— ์˜๋„ํ•œ๋Œ€๋กœ ์ธํ”„๋ผ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š”์ง€ ๊ฒ€ํ† ํ•˜๋Š”๋ฐ ์ด์šฉ
  • (+)๋Š” create, (-)๋Š” delete, (~)๋Š” update, (-)(+)๋Š” replace๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.
  • -detailed-exitcode
    • plan์˜ ๊ฒฐ๊ณผ๋ฅผ ์ข…๋ฃŒ ์ฝ”๋“œ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ์˜ต์…˜ โ†’ ํŒŒ์ดํ”„๋ผ์ธ ์„ค๊ณ„์—์„œ ํ™œ์šฉ ๊ฐ€๋Šฅ
    • 0: ๋ณ€๊ฒฝ ์—†์ด ์„ฑ๊ณต(Succeeded with empty diff) / 1: ์˜ค๋ฅ˜ / 2: ๋ณ€๊ฒฝ ์žˆ๋Š” ์„ฑ๊ณต(Succeeded with non-empty diff)

terraform apply

  • ์ธํ”„๋ผ์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ ์šฉํ•˜๋Š” ์—ญํ• 
  • apply๋Š” plan์œผ๋กœ ์ƒ์„ฑ๋˜๋Š” ์‹คํ–‰ ๊ณ„ํš์ด ํ•„์š”ํ•˜์ง€๋งŒ, ์‹คํ–‰ ๊ณ„ํš์ด ์—†๋‹ค๋ฉด ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•˜๊ณ  ์Šน์ธํ•  ๊ฒƒ์ธ์ง€ ๋ฌป๋Š” ๋ฉ”์„ธ์ง€๊ฐ€ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.
  • -replace
    • configuration์„ ํŽธ์ง‘ํ•˜์ง€ ์•Š๊ณ  ์ง€์ •ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ recreateํ•˜๋Š”๋ฐ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
    • plan๊ณผ apply์— ๋ชจ๋‘ ์ ์šฉ ๊ฐ€๋Šฅ
  • -auto-approve
    • ์‹คํ–‰ ๊ณ„ํš์„ ์ž๋™ ์Šน์ธํ•˜๋Š” ์˜ต์…˜์ž…๋‹ˆ๋‹ค.
    • apply์™€ destroy์— ๋ชจ๋‘ ์ ์šฉ ๊ฐ€๋Šฅ

terraform destroy

  • ํ…Œ๋ผํผ์œผ๋กœ ๊ด€๋ฆฌํ•˜๋Š” ๋ชจ๋“  ๋ฆฌ์†Œ์Šค๋ฅผ ์‚ญ์ œํ•˜๋ฉฐ ํ…Œ๋ผํผ์œผ๋กœ ๊ด€๋ฆฌํ•˜์ง€ ์•Š๋Š” ๋ฆฌ์†Œ์Šค๋Š” ์‚ญ์ œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

terraform fmt

  • configuration ํŒŒ์ผ์— ํ…Œ๋ผํผ ์ปจ๋ฒค์…˜๊ณผ ์Šคํƒ€์ผ์„ ์ ์šฉํ•˜๋Š”๋ฐ ์‚ฌ์šฉ โ†’ ์ฃผ๋กœ ์ฝ”๋“œ์˜ ๊ฐ€๋…์„ฑ์„ ๋†’์ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ
  • ์ฝ”๋”ฉ ์Šคํƒ€์ผ(๋นˆ์นธ, ์ •๋ ฌ ๋“ฑ)์— ์˜ํ•œ ์ปค๋ฐ‹์„ ์ค„์ด๊ณ  ์—…๋ฐ์ดํŠธ๋ฅผ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

3-2. HCL(HashiCorp configuration Language)


  • ํ•˜์‹œ์ฝ”ํ”„์—์„œ ๊ฐœ๋ฐœํ•œ ์˜คํ”ˆ์†Œ์Šค ๋„๊ตฌ โ†’ ํ…Œ๋ผํผ์—์„œ๋Š” HCL์ด ์ฝ”๋“œ ์˜์—ญ์„ ๋‹ด๋‹น
  • JSON์˜ ๋‹จ์  โ†’ ๊ตฌ๋ฌธ์ด ๊ธธ์–ด์ง€๊ณ  ์ฃผ์„์ด ์ง€์›๋˜์ง€ ์•Š์Œ
  • YAML์˜ ๋‹จ์  โ†’ ๊ด€๋ฆฌ๋Œ€์ƒ์ด ๋งŽ์•„์ง€๊ณ  ๊ตฌ์„ฑ์ด ๋ณต์žกํ•ด์งˆ ๊ฒฝ์šฐ ๋ฆฌ์†Œ์Šค ๊ตฌ์„ฑ์„ ํŒŒ์•…ํ•˜๊ธฐ ์–ด๋ ค์›€
  • HCL์€ JSON์— ๋น„ํ•ด ๋™์ผํ•œ ๋‚ด์šฉ์„ 50~70% ๊ฐ„๊ฒฐํ•˜๊ฒŒ ์ž‘์„ฑ ๊ฐ€๋Šฅ
  • HCL์€ ์ฃผ์„๊ณผ ๋ณ€์ˆ˜, function๋„ ์ œ๊ณต

3-3. ํ…Œ๋ผํผ ๋ธ”๋ก


  • ํ…Œ๋ผํผ ๋ธ”๋ก์€ ํ…Œ๋ผํผ ์ž์ฒด์˜ ๊ตฌ์„ฑ(ํ…Œ๋ผํผ ๋ฒ„์ „, ํ”„๋กœ๋ฐ”์ด๋” ๋ฒ„์ „ ๋“ฑ)์„ ๋ช…์‹œํ•˜๋Š”๋ฐ ์‚ฌ์šฉ โ†’ ๋ฒ„์ „์„ ๋ช…์‹œ์ ์œผ๋กœ ์„ ์–ธํ•˜์—ฌ ์‹คํ–‰ ์˜ค๋ฅ˜๋ฅผ ์ตœ์†Œํ™”ํ•  ๊ฒƒ์„ ๊ถŒ์žฅ
  • ๋ฒ„์ „ ์ฒด๊ณ„๋Š” ์‹œ๋งจํ‹ฑ ๋ฒ„์ „ ๊ด€๋ฆฌ(Semantic Versioning)๋ฅผ ์‚ฌ์šฉ โ†’ Major.Minor.Patch
  • required_version โ†’ ํ…Œ๋ผํผ ๋ฒ„์ „ ์ง€์ •
  • required_version โ†’ ํ”„๋กœ๋ฐ”์ด๋” ๋ฒ„์ „ ์ง€์ •
terraform {
  required_version = ">= 1.0.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.2.0"
    }
  }
}
  • cloud ๋ธ”๋ก โ†’ TF Cloud ๋˜๋Š” TF Enterprise๋ฅผ ์„ ์–ธ
  • backend ๋ธ”๋ก โ†’ ํ…Œ๋ผํผ ์‹คํ–‰ ์‹œ ์ €์žฅ๋˜๋Š” State์˜ ์ €์žฅ ์œ„์น˜๋ฅผ ์„ ์–ธ
    • ํ…Œ๋ผํผ์€ State์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ๋กœ ๊ด€๋ฆฌ๋œ ๋ฆฌ์†Œ์Šค๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ์ถ”์ ํ•œ๋‹ค.
    • ํ…Œ๋ผํผ์€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ .terraform.tfstate.lock.info๋ผ๋Š” ํŒŒ์ผ๋กœ State๋ฅผ ๋™์‹œ์— ์‚ฌ์šฉํ•˜์ง€ ๋ชปํ•˜๋„๋ก ์ž ๊ธˆ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
      โ†’ -lock=false๋ผ๋Š” ์˜ต์…˜์œผ๋กœ ์ž ๊ธˆ์„ ๋ฌด์‹œํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ •์ƒ์ ์ธ ๊ฒฝ์šฐ๋ผ๋ฉด ๋‹ค๋ฅธ ์ž‘์—…์ด ์ˆ˜ํ–‰ ์ค‘์ผ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ฃผ์˜ํ•ด์•ผํ•œ๋‹ค.
  • ๋ฐฑ์—”๋“œ๋Š” ๋‹ค์ค‘์œผ๋กœ ์„ ํƒํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

3-4. ๋ฆฌ์†Œ์Šค(resource)


  • ๋ฆฌ์†Œ์Šค ๋ธ”๋ก โ†’ ์„ ์–ธ๋œ ํ•ญ๋ชฉ ์ƒ์„ฑ์„ ์ˆ˜ํ–‰ํ•˜๊ณ  resource๋กœ ์‹œ์ž‘ํ•œ๋‹ค.

    • name์€ ๋™์ผํ•œ ์œ ํ˜•์— ๋Œ€ํ•ด ์‹๋ณ„์ž ์—ญํ• ์„ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์œ ํ˜•์ด ๊ฐ™์€ ๊ฒฝ์šฐ์—๋Š” ๊ฐ™์€ ์ด๋ฆ„์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.

      resource "<provider>_<resource_type>" "<name>" {
        <์ธ์ˆ˜> = <๊ฐ’>
      }
  • ์ข…์†์„ฑ โ†’ ํ…Œ๋ผํผ์€ ์ข…์†์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ ๋ฆฌ์†Œ์Šค๋ฅผ ํ”„๋กœ๋น„์ €๋‹ํ•ฉ๋‹ˆ๋‹ค.

    • ์ข…์†์„ฑ์—๋Š” ์•”์‹œ์  ์ข…์†์„ฑ๊ณผ ๋ช…์‹œ์  ์ข…์†์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
      • ์•”์‹œ์  ์ข…์†์„ฑ์€ ํ…Œ๋ผํผ์— ์˜ํ•ด ์ž๋™์œผ๋กœ ๋ถ€์—ฌ๋ฉ๋‹ˆ๋‹ค.
      • ๋ช…์‹œ์  ์ข…์†์„ฑ์€ depends_on์œผ๋กœ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์ข…์†์„ฑ์ด ์—†๋Š” ๋™์ผ ์ˆ˜์ค€์˜ ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฒฝ์šฐ ๋ณ‘๋ ฌ์ ์œผ๋กœ ํ”„๋กœ๋น„์ €๋‹๋ฉ๋‹ˆ๋‹ค.
  • ๋ฆฌ์†Œ์Šค argument์™€ attribute

    • argument๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์ƒ์„ฑํ•  ๋•Œ ์ง€์ •ํ•˜๋Š” ๊ฐ’(์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ • ๊ฐ€๋Šฅ)

    • attribute๋Š” ์ƒ์„ฑ๋œ ๋ฆฌ์†Œ์Šค๊ฐ€ ๊ฐ€์ง„ ์†์„ฑ(์‚ฌ์šฉ์ž๊ฐ€ ์ง€์ • ๋ถˆ๊ฐ€๋Šฅ)

    • argument์™€ attribute๋Š” ์ฐธ์กฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค.

    • ์•„๋ž˜์˜ ์˜ˆ์‹œ์—์„œ ami์™€ instance_type๋Š” argument์ด๊ณ , ์ƒ์„ฑ๋œ EC2 ์ธ์Šคํ„ด์Šค์˜ arn, private ip๋Š” attribute์ด๋‹ค.

      resource "aws_instance" "example" {
        ami = "ami-01234567890abcde"
        instance_type = "t2.micro"
      }
  • lifecycle โ†’ ๋ฆฌ์†Œ์Šค์˜ ์ˆ˜๋ช…์ฃผ๊ธฐ๋ฅผ ์ปจํŠธ๋กคํ•˜๋Š” ๋ฉ”ํƒ€์ธ์ˆ˜
    • create_before_destroy โ†’ ๋ฆฌ์†Œ์Šค replaceํ•˜๋Š” ๊ฒฝ์šฐ ์ƒ์„ฑ ํ›„ ์‚ญ์ œํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ์ ์œผ๋กœ replace๋Š” ์‚ญ์ œ ํ›„ ์ƒ์„ฑ์ž…๋‹ˆ๋‹ค.
    • pervent_destroy โ†’ ๋ฆฌ์†Œ์Šค ์‚ญ์ œ(Destroy)๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ๊ฑฐ๋ถ€
    • ignore_changes โ†’ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ถ”์ ํ•˜์ง€ ์•Š๊ณ ์ž ํ•˜๋Š” ๋ฆฌ์†Œ์Šค๋ฅผ ์„ ์–ธ
    • precondition โ†’ ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ์ „ argument๋ฅผ ๊ฒ€์ฆ
    • postcondition โ†’ ๋ฆฌ์†Œ์Šค ์ƒ์„ฑ ํ›„ ๊ฒฐ๊ณผ๋ฅผ ๊ฒ€์ฆ
๋ฐ˜์‘ํ˜•