본문 바로가기

AWS

Terraform - 선언 블록

HCL(Hashicorp Comfiguration Language)

테라폼에서 사용하는 설정 언어

확장자 .tf

 

선언 블록

 

- provider

클라우드 서비스 또는 인프라 스트럭처를 제공하는 공급자를 정의

테라폼과 외부 서비스를 연결해주는 기능을 하는 모듈

ex) AWS, Google Cloud Platform, Microsoft Azure - 범용 클라우드 서비스

      GitHub, DataDog, DNSimple - 특정 기능을 제공하는 서비스

      MySQL, RabbitMQ, Docker - 로컬 서비스

 

- resource

provider가 제공하는 실제 자원을 정의

 

- variable

 변수를 정의 (외부에서 입력 받음)

 

- local

지역 변수를 정의 (해당 파일 안에 정의되어있음)

 

- output

결과를 출력

 

- data 

 provider가 제공해주는 리소스의 정보 

 

- terraform

테라폼 구성을 정의

 


# provider

provider version

테라폼 v0.13 이전 테라폼 v0.13 이후
provider 블록에 프로바이더 버전을 명시 terraform 블록안에 required_providers에 정의
provider "aws" {
  version = "~> 4.2.0"
  region  = "ap-northeast-2"
}

terraform {
  required_version = ">= 1.0.0"
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.2.0"
    }
  }
}

 

# resource

리소스 선언

resource "<프로바이더 이름>_<프로바이더가 제공하는 리소스 유형>" "<이름>" {

   <인수> = <값>

}

terraform {
  required_version = ">= 1.0.0"
}


resource "local_file" "abc" {
  content  = "abc"
  filename = "${path.module}/abc.txt"
}


resource "local_file" "def" {
  content  = "def"
  filename = "${path.module}/def.txt"
}
C:\aws> terraform init -reconfigure

Initializing the backend...

Initializing provider plugins...
- Reusing previous version of hashicorp/local from the dependency lock file
- Using previously-installed hashicorp/local v2.4.0

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
C:\aws> terraform init -migrate-state

Initializing the backend...
Terraform has detected you're unconfiguring your previously set "local" backend.
Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "local" backend to the
  newly configured "local" backend. No existing state was found in the newly
  configured "local" backend. Do you want to copy this state to the new "local"
  backend? Enter "yes" to copy and "no" to start with an empty state.

  Enter a value: yes
  ...
C:\aws> terraform apply
local_file.test: Refreshing state... [id=1eebdf4fdc9fc7bf283031b93f9aef3338de9052]

Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
  + create
  - destroy

Terraform will perform the following actions:

...

local_file.test: Destroying... [id=1eebdf4fdc9fc7bf283031b93f9aef3338de9052]
local_file.test: Destruction complete after 0s
local_file.abc: Creating...				 의존 관계가 없는 경우 테라폼은 병렬 실행 방식으로 동작
local_file.def: Creating...
local_file.def: Creation complete after 0s [id=589c22335a381f122d129225f5c0ba3056ed5811]
local_file.abc: Creation complete after 0s [id=a9993e364706816aba3e25717850c26c9cd0d89d]

Apply complete! Resources: 2 added, 0 changed, 1 destroyed.

 

#1 의존관계

terraform {
  required_version = ">= 1.0.0"
}


resource "local_file" "abc" {
  content  = "abc"
  filename = "${path.module}/abc.txt"
}


resource "local_file" "def" {
  content  = local_file.abc.content			# <<< local_file def가 abc에 의존하도록 수정
  filename = "${path.module}/def.txt"
}
C:\aws> terraform destroy
C:\aws> terraform apply
		:
local_file.abc: Creating...
local_file.abc: Creation complete after 0s [id=a9993e364706816aba3e25717850c26c9cd0d89d]
local_file.def: Creating...
local_file.def: Creation complete after 0s [id=a9993e364706816aba3e25717850c26c9cd0d89d]

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

 

- terraform graph

C:\aws> terraform graph
digraph {
        compound = "true"
        newrank = "true"
        subgraph "root" {
                "[root] local_file.abc (expand)" [label = "local_file.abc", shape = "box"]
                "[root] local_file.def (expand)" [label = "local_file.def", shape = "box"]
                "[root] provider[\"registry.terraform.io/hashicorp/local\"]" [label = "provider[\"registry.terraform.io/hashicorp/local\"]", shape = "diamond"]
                "[root] local_file.abc (expand)" -> "[root] provider[\"registry.terraform.io/hashicorp/local\"]"
                "[root] local_file.def (expand)" -> "[root] local_file.abc (expand)"
                "[root] provider[\"registry.terraform.io/hashicorp/local\"] (close)" -> "[root] local_file.def (expand)"
                "[root] root" -> "[root] provider[\"registry.terraform.io/hashicorp/local\"] (close)"
        }
}

 

- https://dreampuf.github.io/GraphvizOnline

 

#2 확실하게 의존관계를 명시하고 싶을 경우

terraform {
  required_version = ">= 1.0.0"
}


resource "local_file" "abc" {
  content  = "abc"
  filename = "${path.module}/abc.txt"
}


resource "local_file" "def" {

<======================================================
  depends_on = [ local_file.abc ]         # 명시적으로 의존 관계(=종속성)를 정의
======================================================>

  content  = "def"
  filename = "${path.module}/def.txt"
}
C:\aws> terraform destroy
C:\aws> terraform apply
		:
local_file.abc: Creating...
local_file.abc: Creation complete after 0s [id=a9993e364706816aba3e25717850c26c9cd0d89d]
local_file.def: Creating...
local_file.def: Creation complete after 0s [id=589c22335a381f122d129225f5c0ba3056ed5811]

 

#3 리소스 구성에서 인수와 속성을 참조할 수 있음

 

인수 : 리소스 생성 시 사용자가 선언하는 값

속성 : 사용자가 설정하는 것은 불가능하지만 리솟스 생성 이후 획득 가능한 리소스 고유값

 

- 리소스 참조

<프로바이더 이름>_<프로바이더가 제공하는 리소스 유형>.<이름>.<인수>

<프로바이더 이름>_<프로바이더가 제공하는 리소스 유형>.<이름>.<속성>

 

# 생명주기 메타인자(The lifecycle Meta-Argument)

기본 생명주기를 의도적으로 변경할 때 사용

  • create_before_destroy (bool): 리소스 수정 시 신규 리소스를 우선 생성하고 기존 리소스를 삭제
  • prevent_destroy (bool): 해당 리소스를 삭제하려 할 때 명시적으로 거부
  • ignore_changes (list): 리소스 요소에 선언된 인수의 변경 사항을 테라폼 실행 시 무시 
  • precondition: 리스트 요소에 선언된 인수의 조건을 검증 
  • postcondition: plan과 applay 이후의 결과를 속성 값으로 검증

# 입력 변수

선언

variable "<이름>" {

  <인수> = <값>

}

variable "string" {
  type = string
  description = "string 변수"
  default = "mystring"
}

output "string" {
  value = var.string
}

variable "number" {
  type = number
  default = 1234  
}

output "number" {
  value = var.number
}

variable "boolean" {
  type = bool
  default = true
}

output "boolean" {
  value = var.boolean
}

variable "list" {
  type = list
  default = ["aaa", "bbb", "ccc", "ddd"]
}

output "list_index_0" {
  value = var.list.0
}

output "list_all" {
  value = var.list
}

output "list_all_upper" {
  value = [
    for v in var.list:
      upper(v)
  ]
}

variable "map" {
  type = map
  default = {
    aws = "amazon",
    azure = "microsoft",
    gcp = "google"
  }  
}

output "map_all" {
  value = var.map
}

output "map_all_upper" {
  value = [
    for k in var.map:
      upper(k)
  ]
}

 

#1 민감한 변수 취급

variable "password" {
  sensitive = true
}

resource "local_file" "abc" {
  content = var.password
  filename = "${path.module}/abc.txt"
}
C:\aws> terraform apply
var.password
  Enter a value:				⇐ 입력하는 내용이 표시되지 않음

local_file.abc: Refreshing state... [id=57b2ad99044d337197c0c39fd3823568ff81e48a]

Terraform used the selected providers to generate the following execution plan.
Resource actions are indicated with the following symbols:
-/+ destroy and then create replacement

Terraform will perform the following actions:

  # local_file.abc must be replaced
-/+ resource "local_file" "abc" {
      ~ content              = (sensitive value) # forces replacement ⇐ 입력하는 내용이 표시되지 않음
      ~ content_base64sha256 = "oHXRfz1FMHOFP4E4OMFbgCO4xIcDhDY1T+WZw5QuH5U=" -> (known after apply)
      ~ content_base64sha512 = 
...

 

# 데이터 소스

테라폼으로 정의되지 않는 외부 리소스 또는 저장된 정보를 테라폼 내에서 참조할 때 사용

 

데이터 소스 정의

data "<프로바이더>_<리소스 유형>" "<이름>" {

   <인수> = <값>

}

 

데이터 소스 참조

terraform {
  required_version = ">= 1.0.0"
}


resource "local_file" "abc" {
  content  = "abc"
  filename = "${path.module}/abc.txt"
}


data "local_file" "abc" {
  filename = local_file.abc.filename
}


resource "local_file" "def" {
  content  = data.local_file.abc.content
  filename = "${path.module}/def.txt"
}

 

# local

variable "prefix" {
  default = "hello"
}

locals {
  name    = "terraform"
  content = "${var.prefix} ${local.name}"
}

resource "local_file" "abc" {
  content  = local.content
  filename = "${path.module}/abc.txt"
}

 

# terraform

-semantic versioning

  version = major.minor.patch
  --major 내부 동작의 API가 변경 또는 삭제되거나 하위 호환이 되지 않는 버전
  --minor 신규 기능이 추가되거나 개선되고 하위 호환이 가능한 버전
  --patch 버그 수정 또는 일부 기능이 개선된 하위 호환이 가능한 버전

  버전 제약 구문

  -- = 또는 연산자 없음 : 지정된 버전만 허용

   -- != : 지정된 버전을 제외

   -- >, >=, <, <= : 지정한 버전과 비교해서 조건에 맞는 경우 허용

   -- ~> : 지정한 버전에서 가장 자리수가 낮은 구성요소만 증가하는 것을 허용

       --- ~> x.y → x.y ~ x.y+n

       --- ~> x.y.z → x.y.z ~ x.y.z+n

 

#1 테라폼 버전 확인

C:\aws> terraform version
Terraform v1.6.4
on windows_386
+ provider registry.terraform.io/hashicorp/aws v5.26.0

 

#2 main.tf 파일에 terraform 블록 추가

terraform {
  required_version = "< 1.0.0"
}

 

#3 terraform init

C:\aws> terraform init

Initializing the backend...
╷
│ Error: Unsupported Terraform Core version
│
│   on main.tf line 2, in terraform:
│    2:   required_version = "< 1.0.0"
│
│ This configuration does not support Terraform version 1.6.4. To proceed, either choose another supported
│ Terraform version or update this version constraint. Version constraints are normally set for good reason,
│ so updating the constraint may lead to other errors or unexpected behavior.

 

#4 실행 환경에 맞게 버전 조건을 수정한 후 terraform init 실행

terraform {
  required_version = ">= 1.0.0"
}

 

C:\aws> terraform init

Initializing the backend...
Initializing provider plugins...

...

 

# 백엔드 블록

테라폼 실행 시 저장된 상태 파일(State)의 저장 위치를 선언

-- 상태파일 : 코드로 관리되는 리소스 정보 -> 리소스 탐색 및 추적에 사용

작업자들이 테라폼 상태 파일을 공유하기 위해서는 외부 백엔드 저장소가 필요

민감한 데이터가 포함될 수 있으므로 접근 제어가 필요

기본적으로 활성화되는 백엔드는 local ⇒ 작업자의 로컬 환경에 저장하고 관리 

테라폼이 실행되는 동안 .terraform.tfstate.lock.info 파일이 생성되면서 해당 상태를 동시에 사용하지 못하도록 잠금 처리

### .terraform.tfstate.lock.info ###
{
"ID":"d30715d2-3b6f-0247-8075-f11fb6e09ac9",
"Operation":"OperationTypeApply",
"Info":"",
"Who":"DESKTOP-O0MUMK8\\myanj@DESKTOP-O0MUMK8",
"Version":"1.6.4",
"Created":"2023-11-21T05:18:38.478762Z",
"Path":"terraform.tfstate"
}

 

#1 main.tf 수정

terraform {
  required_version = ">= 1.0.0"
}


# https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file
resource "local_file" "test" {
  content  = "test content"
  filename = "${path.module}/test.txt"
}

 

#2  C:\aws> terraform init

 

-lock=false 옵션을 추가하면 잠금을 무시할 수 있음

 

#3 백엔드 설정 변경

### main.tf ###

terraform {
  required_version = ">= 1.0.0"

<=========================================
  backend "local" {					
    path = "state/myterraform.tfstate"    		
  }
=========================================>  
}


# https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file
resource "local_file" "test" {
  content  = "test content"
  filename = "${path.module}/test.txt"
}
C:\aws> terraform apply

 

 

 

 

 

 

 

 

 

 

 

 

 

=> state 폴더

     myterraform.tfstate 파일이 생성

 

 

#4 새로운 백엔드로의 전환을 위한 조건(옵션)

terraform {
  required_version = ">= 1.0.0"


  backend "local" {
    path = "state/myterraform.tfstate.v2"    
  }
}


# https://registry.terraform.io/providers/hashicorp/local/latest/docs/resources/file
resource "local_file" "test" {
  content  = "test content"
  filename = "${path.module}/test.txt"
}
C:\aws> terraform init -migrate-state

Initializing the backend...
Backend configuration changed!

Terraform has detected that the configuration specified for the backend
has changed. Terraform will now check for existing state in the backends.

Do you want to copy existing state to the new backend?
  Pre-existing state was found while migrating the previous "local" backend to the
  newly configured "local" backend. No existing state was found in the newly
  configured "local" backend. Do you want to copy this state to the new "local"
  backend? Enter "yes" to copy and "no" to start with an empty state.

  Enter a value: yes

...

 

 

 

 

 

 

 

 

 

=> state 폴더

     myterraform.tfstate.v2 파일이 생성

 

 

C:\aws> terraform init -reconfigure

Initializing the backend...

Successfully configured the backend "local"! Terraform will automatically
use this backend unless the backend configuration changes.

Initializing provider plugins...
- Reusing previous version of hashicorp/local from the dependency lock file
- Using previously-installed hashicorp/local v2.4.0

...

⇒ myterraform.tfstate.v3 파일이 생성되지 않음

⇒ terraform apply 명령을 실행하면 myterraform.tfstate.v3 파일이 생성됨

 

#반복문

- count

resource "local_file" "abc" {
  count    = 5
  content  = "abc"
  filename = "${path.module}/abc${count.index}.txt"
}
variable "names" {
  type    = list(string)
  default = ["aaa", "bbb", "ccc"]
}


resource "local_file" "abc" {
  count    = length(var.names)
  content  = var.names[count.index]
  filename = "${path.module}/file-${var.names[count.index]}-${count.index}.txt"
}

 

- for_each

variable "venders" {
  type    = map
  default = {
    aws = "amazon",
    azure = "microsoft",
    gcp = "google"
  }
}


resource "local_file" "abc" {
  for_each = var.venders
  content  = each.value
  filename = "${path.module}/file-${each.key}.txt"
}

 

-for  

 복합 형식 값의 형태를 반환

 -- list : 값 또는 인덱스와 값을 반환

 -- map : key 또는 key와 value를 반환

 -- set : key 값에 대해 반환

variable "venders" {
  type    = map
  default = {
    aws = "amazon",
    azure = "microsoft",
    gcp = "google"
  }
}

locals {
  products = [ for k, v in var.venders: "${upper(k)}" ]
  venders = [ for k, v in var.venders: "${upper(v)}" ]
  products-venders = [ for k, v in var.venders: "${upper(k)} - ${upper(v)}" ]
}

output "products" {
  value = local.products
}

output "venders" {
  value = local.venders
}

output "products-venders" {
  value = local.products-venders  
}
728x90

'AWS' 카테고리의 다른 글

AWS - Flask / MySQL / react 배포  (2) 2023.11.24
AWS - EKS  (0) 2023.11.22
AWS - Terraform (ASG , LB)  (1) 2023.11.21
AWS - 웹 서비스 환경 구성 실습  (0) 2023.11.20
AWS - Terraform  (1) 2023.11.20