Terraform IaC Sheet: Provisioning & State Ops

πŸ’‘ Terraform IaC Sheet: Provisioning & State Ops β€” Executive Summary

Technical architectural analysis, practical configuration manifests, and deployment instructions for Terraform IaC Sheet: Provisioning & State Ops.

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
  • The state of the existing infrastructure can be added to the state of terraform, but the resource file must be written directly.
refresh
bash
# .tfνŒŒμΌμ„ ν΄λΌμš°λ“œ λ¦¬μ†ŒμŠ€μ˜ μ‹€μ œ μƒνƒœμ™€ 동기화
terraform refresh
apply vs refresh
  1. terraform apply:
    – Purpose: Apply changes in configuration files to real infrastructure.
    – Change infrastructure: Yes, we actually change infrastructure.
    – Update state file: Update the state file after changes.
    – Yes: Create a new resource or modify an existing resource.
  2. terraform refresh:
    – Purpose: Synchronize the current infrastructure state with the state file.
    – Infrastructure changes: No, it will not affect the infrastructure.
    – Update state file: Update only the state file.
    – Yes: Reflects resources that have been manually changed externally.
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
Reflecting existing resources in 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}
Scenario
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)
    }
<<<

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *