Terraform으로 인프라를 구성하기 위한 다음과 같은 선언 블록들이 있다.
테라폼의 구성을 명시하는데 사용
terraform {
required_version = "~> 1.3.0" # 테라폼 버전
required_providers { # 프로바이더 버전을 나열
random = {
version = ">= 3.0.0, < 3.1.0"
}
aws = {
version = "4.2.0"
}
}
cloud { # Cloud/Enterprise 같은 원격 실행을 위한 정보
organization = "<MY_ORG_NAME>"
workspaces {
name = "my-first-workspace"
}
}
backend "local" { # state를 보관하는 위치를 지정
path = "relative/path/to/terraform.tfstate"
}
}
required_version
: 테라폼 버전을 지정terraform {
required_version = "~> 1.3.0" # 테라폼 버전
}
required_providers
: 프로바이더 버전을 나열terraform {
required_providers {
local = {
source = "opentofu/local"
version = "2.5.1"
}
}
}
backend
의 remoteterraform {
cloud {
hostname = "app.terraform.io"
organization = "<MY_ORG_NAME>"
workspaces {
name = "my-first-workspace"
}
}
}
.terraform.tfstate.lock.info
파일이 생성되면서-lock=false
옵션을 사용하여 잠금을 무시할 수 있다.terraform {
backend "local" {
path = "state/terraform.tfstate"
}
}
terraform init
옵션-migrate-state
: 이전 state파일을 새로운 backend로 이동-reconfigure
: 이전 state 파일을 삭제하고, state를 새로 생성선언된 항목을 생성하는 동작을 수행한다.
resourece_type
= <provider>_<resource_type>
resource_name
은 resource_type 내에서 고유해야 한다.resource "<resource_type>" "<resource_name>" {
argument1 = "<value1>"
argument2 = "<value2>"
}
depneds_on
)depends_on
: 다른 리소스에 의존성을 설정resource "local_file" "def" {
depends_on = [
local_file.abc
]
content = "456"
filename = "${path.module}/def.txt"
}
graphviz (dot) language support
확장을 설치하면, 그래프로 표현할 수 있다.terraform graph >> graph.dot
<resource_type>.<resource_name>.<attribute>
resource "local_file" "def" {
content = local_file.abc.content
filename = "${path.module}/def.txt"
}
lifecycle
)create_before_destroy
(bool): 리소스를 새로 생성한 후, 기존 리소스를 삭제prevent_destroy
(bool): 리소스 삭제를 명시적으로 거부ignore_changes
(list): 리소스 변경을 테라폼 실행 시 무시precondition
: 리소스에 선언된 인수의 조건을 검증postcondition
: plan, apply 이후 결과를 속성 값으로 검증create_before_destroy
false
resource "local_file" "abc" {
content = "lifecycle - step 2"
filename = "${path.module}/abc.txt"
lifecycle {
create_before_destroy = true
}
}
prevent_destroy
false
resource "local_file" "abc" {
content = "lifecycle - step 3"
filename = "${path.module}/abc.txt"
lifecycle {
prevent_destroy = true
}
}
ignore_changes
[]
all
사용resource "local_file" "abc" {
content = "lifecycle - step 4"
filename = "${path.module}/abc.txt"
lifecycle {
# ignore_changes = all
ignore_changes = [
content
]
}
}
precondition
variable "file_name" {
type = string
default = "step0.txt"
}
resource "local_file" "abc" {
content = "lifecycle - step 5"
filename = "${path.module}/${var.file_name}"
lifecycle {
precondition {
condition = var.file_name == "step0.txt"
error_message = "File name must be step0.txt"
}
}
}
postcondition
resource "local_file" "abc" {
content = "lifecycle - step 6"
filename = "${path.module}/abc.txt"
lifecycle {
postcondition {
condition = self.content == ""
error_message = "File content must be empty"
}
}
}
data "<resource_type>" "<data_name>" {
argument1 = "<value1>"
argument2 = "<value2>"
}
# 데이터 소스 참조
data.<resource_type>.<data_name>.<attribute>
data "aws_availablity_zones" "available" {
state = "available"
}
resource "aws_subnet" "primary" {
availability_zone = data.aws_availablity_zones.available.names[0]
}
resource "aws_subnet" "secondary" {
availability_zone = data.aws_availablity_zones.available.names[1]
}
default
: 변수의 기본값type
: 변수의 유형description
: 변수에 대한 설명validation
: 변수의 유효성 검사sensitive
: 변수의 값이 출력되지 않도록 설정nullable
: 변수의 값이 null이 될 수 있는지 설정variable "<variable_name>" {
type = type
description = "<description>"
default = "<default_value>"
validation {
condition = "<condition>"
error_message = "<error_message>"
}
sensitive = false
nullable = false
}
variable "string" {
type = string
description = "var String"
default = "default string"
}
variable "number" {
type = number
description = "var Number"
default = 123
}
variable "boolean" {
type = bool
description = "var Bool"
default = true
}
variable "list" {
default = [
"a",
"b",
"c"
]
}
output "list_index_0" {
value = var.list.0
}
output "list_all" {
value = [
for v in var.list:
upper(v)
]
}
variable "map" {
default = {
key1 = 1
key2 = 2
}
}
variable "set" {
type = set(string)
default = [
"a",
"b",
"c"
]
}
variable "object" {
type = object({name=string, age=number})
default = {
name = "John"
age = 30
}
}
variable "tuple" {
type = tuple([string, number, bool])
default = ["John", 30, false]
}
variable "ingress_rules" {
type = list(object({
port = number,
description = optional(string),
protocol = optional(string, "tcp")
}))
default = [
{
port = 80
description = "HTTP"
},
{
port = 443
description = "HTTPS"
},
{
port = 53,
protocol = "udp"
}
]
}
output "ingress_rules" {
value = var.ingress_rules
}
validation
블록을 사용하여 변수의 유효성을 검사할 수 있다.variable "image_id" {
type = string
description = "AMI ID"
validation {
condition = length(var.image_id) > 4
error_message = "Image ID must not be empty"
}
validation {
condition = can(regex("^ami-", var.image_id))
error_message = "Image ID must be in the format 'ami-...'"
}
}
variable "my_var" {
default = "value"
}
export TF_VAR_my_var="value"
terraform.tfvars
파일my_var = "value"
*.auto.tfvars
파일*.auto.tfvars.json
파일-var
, -var-file
옵션terraform apply -var=my_var=value
terraform apply -var-file=my_vars.tfvars
variable
과 달리 입력을 받을 수 없다.variable "prefix" {
default = "hello"
}
locals {
name = "terraform"
content = "${var.prefix} ${local.name}"
my_info = {
age = 20
region = "KR"
}
my_nums = [1, 2, 3, 4, 5]
}
locals {
content = "hello" # 중복 선언으로 오류 발생
}
local.<local_name>
terraform apply
실행 후, 출력된 값을 확인할 수 있다.output "instance_ip_addr" {
value = "https://${aws_instance.web.public_ip}"
}
value
: 출력 값description
: 출력 값에 대한 설명sensitive
: 민감한 출력 값임을 알리고, 출력되지 않도록 설정depends_on
: 출력 값이 의존하는 리소스precondition
: 출력 값에 대한 조건 검증variable "my_password" {
sensitive = true
}
resource "local_file" "abc" {
content = var.my_password
filename = "${path.module}/abc.txt"
}
output "file_id" {
value = local_file.abc.id
}
output "file_absolute_path" {
value = abspath(local_file.abc.filename)
}
$ terraform plan
Changes to Outputs:
+ file_absolute_path = "/Users/shinyoungkim/IdeaProjects/hello-terraform/abc.txt"
+ file_id = (known after apply)
$ terraform apply
Outputs:
file_absolute_path = "/Users/shinyoungkim/IdeaProjects/hello-terraform/abc.txt"
file_id = "40bd001563085fc35165329ea1ff5c5ecbdbbeef"
$ terrafrom output file_id
"40bd001563085fc35165329ea1ff5c5ecbdbbeef"
$ terraform output -raw file_id
40bd001563085fc35165329ea1ff5c5ecbdbbeef%