본문 바로가기
Terraform/Terraform 101 Study

3주차 2편 테라폼 기초 - 기본 사용 3/3

by 개발자 영만 2024. 6. 30.

3.12 프로비저너

  • 프로비저너는 테라폼에서 리소스를 생성하고 관리하는 동안 추가적인 설정이나 작업을 수행하는 도구입니다.
  • 프로비저너는 특정 리소스가 생성된 후에 실행되며, 주로 초기화 스크립트 실행, 설정 파일 복사, 배포용 스크립트 실행 등의 작업을 수행합니다.
  • 프로비저너로 실행된 작업들은 테라폼 상태 파일과 동기화되지 않습니다. 따라서 프로비저너로 수행된 변경 사항은 테라폼이 추적하는 인프라 상태에 포함되지 않습니다.
  • 이는 프로비저닝 작업의 결과가 항상 일관되게 보장되지 않는다는 의미이며, 이러한 측면에서 프로비저너는 "선언적 보장이 안되는" 접근 방식을 가집니다.
  • 프로비저너는 특정 상황에서 유용하지만, 테라폼의 선언적 구성 방식을 유지하고자 할 때는 최소화하는 것이 좋습니다.
  • 프로비저너의 주된 종류로는 다음과 같은 것들이 있습니다:
    • file: 파일을 복사하거나 생성하는 작업을 수행합니다.
    • local-exec: 로컬 머신에서 명령어를 실행하여 리소스를 프로비저닝합니다.
    • remote-exec: 원격 머신에서 SSH나 WinRM을 통해 명령어를 실행하여 리소스를 프로비저닝합니다.
  • 예를 들어 AWS EC2 인스턴스를 생성한 후에 특정 패키지를 설치하거나 파일을 생성하는 경우, 이 작업들은 테라폼의 구성과는 별개로 동작해야 합니다. 이를 위해 테라폼에서는 프로비저너를 사용할 수 있지만, 이는 특히 필요한 경우에만 사용해야 합니다.
  • 실습을 위해 main.tf 파일 생성
variable "sensitive_content" {
  default   = "secret"
  #sensitive = true
}

resource "local_file" "foo" {
  content  = upper(var.sensitive_content)
  filename = "${path.module}/foo.bar"

  provisioner "local-exec" {
    command = "echo The content is ${self.content}"
  }

  provisioner "local-exec" {
    command    = "abc"
    on_failure = continue
  }

  provisioner "local-exec" {
    when    = destroy
    command = "echo The deleting filename is ${self.filename}"
  }
}
  • 실행 및 확인
# Terraform 초기화, 계획 및 적용
terraform init && terraform plan
terraform apply -auto-approve

# 상태 목록 및 상태 조회
# 상태에 프로비저너 정보(실행 및 결과)가 없다
terraform state list
terraform state show local_file.foo
cat foo.bar ; echo
cat terraform.tfstate | jq

# graph 확인 : 프로비저너 정보(의존성)이 없다
terraform graph > graph.dot

# Terraform 삭제
terraform destroy -auto-approve

  • main.tf 파일 내용 수정
variable "sensitive_content" {
  default   = "secret"
  sensitive = true
}

resource "local_file" "foo" {
  content  = upper(var.sensitive_content)
  filename = "${path.module}/foo.bar"

  provisioner "local-exec" {
    command = "echo The content is ${self.content}"
  }

  provisioner "local-exec" {
    command    = "abc"
    #on_failure = continue
  }

  provisioner "local-exec" {
    when    = destroy
    command = "echo The deleting filename is ${self.filename}"
  }
}
  • 실행 및 확인
# Terraform 적용
# 민감 정보 참조 부분의 실행 및 결과 내용은 출력 안됨
# 명령어 'abc'를 실행할 수 없어 에러가 발생
terraform apply -auto-approve

local-exec 프로비저너

  • 리눅스나 윈도우 등 각 환경에 맞게 명령어를 정의합니다.
    • command (필수) : 실행할 명령어를 입력합니다. <<EOT를 사용하여 여러 줄의 명령어를 입력할 수 있습니다.
    • working_dir (선택) : 명령어를 실행할 디렉터리를 지정합니다. 상대 경로나 절대 경로를 사용할 수 있습니다.
    • interpreter (선택) : 명령어를 실행하는 데 필요한 인터프리터를 지정합니다. 첫 번째 인수는 인터프리터의 이름이며, 두 번째 인수부터는 인터프리터에 전달할 인수 값들입니다.
    • environment (선택) : 실행할 때 사용할 환경 변수를 설정합니다. 기존 실행 환경의 값을 상속받으면서, 추가적으로 환경 변수를 설정하거나 재할당할 수 있습니다.
  • 예시 코드

 

Unix/Linux/macOS Windows
resource "null_resource" "example1" {

  provisioner "local-exec" {
    command = <<EOF
      echo Hello!! > file.txt
      echo $ENV >> file.txt
    EOF

    interpreter
= [ "bash" , "-c" ]

    working_dir
= "/tmp"

    environment
= {
      ENV = "world!!"
    }

  }
}
resource "null_resource" "example1" {

  provisioner "local-exec" {
    command = <<EOF
      Hello!! > file.txt
      Get-ChildItem Env:ENV >> file.txt
      EOF

    interpreter = [ "PowerShell" , "-Command" ]

    working_dir = "C:\\windows\temp"

    environment = {
      ENV = "world!!"
    }

  }
}

 

  • main.tf 파일 내용 수정 - macOS/Linux 경우
resource "null_resource" "example1" {
  
  provisioner "local-exec" {
    command = <<EOF
      echo Hello!! > file.txt
      echo $ENV >> file.txt
      EOF
    
    interpreter = [ "bash" , "-c" ]

    working_dir = "/tmp"

    environment = {
      ENV = "world!!"
    }

  }
}
  • 실행 및 확인
# Terraform 초기화, 계획 및 적용
terraform init -upgrade
terraform plan && terraform apply -auto-approve

# 상태 목록 및 특정 상태 조회
terraform state list
terraform state show null_resource.example1

# 파일 확인
cat /tmp/file.txt

원격지 연결

  • remote-exec 및 file 프로비저너를 사용하기 위해 SSH 또는 WinRM 연결을 정의해야 합니다.
  • Connection 블록은 Terraform 리소스에서 원격 연결을 설정합니다. SSH 또는 WinRM과 같은 연결 유형을 지정하고, 해당 연결에 필요한 인증 정보를 제공합니다.
  • 리소스 내에 정의되는 경우 모든 프로비저너에 공통으로 적되고 프로비저너 내에 정의되는 경우 해당 프로비저너에만 적용됩니다.
# connection 블록을 사용하여 원격지 연결 정의
resource "null_resource" "example1" {
  
  connection {
    type     = "ssh"
    user     = "root"
    password = var.root_password
    host     = var.host
  }

  provisioner "file" {
    source      = "conf/myapp.conf"
    destination = "/etc/myapp.conf"
  }

  provisioner "file" {
    source      = "conf/myapp.conf"
    destination = "C:/App/myapp.conf"

    connection {
        type     = "winrm"
        user     = "Administrator"
        password = var.admin_password
        host     = var.host
    }
  }
}
  • connection 블록을 사용하여 리소스에 대한 원격 연결을 설정할 때 사용되는 주요 인수들과 각각의 설명은 다음과 같습니다

테라폼으로 시작하는 IaC

  • bastion host를 통해 원격 시스템에 연결하는 경우에는 connection 블록에서 관련된 인수들을 사용하여 설정할 수 있습니다.

테라폼으로 시작하는 IaC

file 프로비저너

  • 로컬 시스템의 파일이나 디렉터리를 원격 시스템에 복사하거나 업로드하는 데 사용됩니다.
  • 사용되는 인수들
    • source : 복사할 소스 파일이나 디렉터리의 경로입니다. 현재 작업 중인 디렉터리에서 상대 경로 또는 절대 경로로 지정할 수 있습니다. content와 함께 사용할 수 없습니다.
    • content : 복사할 내용을 직접 정의합니다. 대상이 디렉터리인 경우 tf-file-content 파일이 생성되며, 파일인 경우 해당 파일에 내용이 기록됩니다. source와 함께 사용할 수 없습니다.
    • destination : 복사한 파일 또는 디렉터리가 저장될 절대 경로입니다. 파일 또는 디렉터리 모두 가능합니다.
  • ssh 연결 시 destination 디렉터리가 존재해야 합니다. 디렉터리가 없는 경우 수동으로 생성해야 합니다.
  • 디렉터리를 대상으로 할 때 source 경로의 형태에 따라 동작에 차이가 있습니다
  • 마지막에 /가 없는 경우
    • source = "/foo", destination = "/tmp" 인 경우 /tmp/foo 디렉터리에 /foo 디렉터리의 모든 파일과 디렉터리가 복사됩니다.
  • 마지막에 /가 포함된 경우
    • source = "/foo/", destination = "/tmp" 인 경우 /tmp 디렉터리에 /foo 디렉터리의 모든 파일과 디렉터리가 복사됩니다.
  • file 프로비저너 구성 예
resource "null_resource" "foo" {
  
  # myapp.conf 파일이 /etc/myapp.conf 로 업로드
  provisioner "file" {
    source      = "conf/myapp.conf"
    destination = "/etc/myapp.conf"
  }
  
  # content의 내용이 /tmp/file.log 파일로 생성
  provisioner "file" {
    content     = "ami used: ${self.ami}"
    destination = "/tmp/file.log"
  }
  
  # configs.d 디렉터리가 /etc/configs.d 로 업로드
  provisioner "file" {
    source      = "conf/configs.d"
    destination = "/etc"
  }
  
  # apps/app1 디렉터리 내의 파일들만 D:/IIS/webapp1 디렉터리 내에 업로드
  provisioner "file" {
    source      = "apps/app1/"
    destination = "D:/IIS/webapp1"
  }

}

 

remote-exec 프로비저너

  • remote-exec 프로비저너는 원격지 환경(예: AWS EC2 인스턴스)에서 명령을 실행하거나 패키지를 설치하는 등의 작업을 자동화하는 데 사용됩니다.
  • remote-exec 프로비저너에서 사용하는 주요 인수는 다음과 같으며, 이 인수들은 서로 배타적으로 사용됩니다
    • inline : 명령어 목록을 정의합니다. 목록은 대괄호 [ ] 블록 내에 작성하며, 각 명령어는 큰따옴표 " "로 묶고 쉼표 ,로 구분합니다.
    • script : 로컬 시스템의 스크립트 경로를 지정하여 원격 시스템에 복사한 후 실행합니다.
    • scripts : 로컬 시스템의 여러 스크립트 경로를 목록으로 지정하여, 원격 시스템에 순차적으로 복사하고 실행합니다. 목록은 대괄호 [ ] 블록 내에 작성하며, 각 스크립트 경로는 큰따옴표 " "로 묶고 쉼표 ,로 구분합니다.
  • script 또는 scripts 인수로 지정된 스크립트는 해당 스크립트 실행에 필요한 인수를 직접 설정할 수 없습니다. 인수가 필요한 경우 file 프로비저너를 사용하여 로컬 스크립트를 원격 시스템에 업로드하고 inline 인수를 사용하여 업로드된 스크립트에 필요한 인수를 전달하며 실행합니다.
  • remote-exec 프로비저너 구성 예
resource "aws_instance" "web" {
  # ...

  # Establishes connection to be used by all
  # generic remote provisioners (i.e. file/remote-exec)
  connection {
    type     = "ssh"
    user     = "root"
    password = var.root_password
    host     = self.public_ip
  }

  provisioner "file" {
    source      = "script.sh"
    destination = "/tmp/script.sh"
  }

  provisioner "remote-exec" {
    inline = [
      "chmod +x /tmp/script.sh",
      "/tmp/script.sh args",
    ]
  }
}

 

3.13 null_resource와 terraform_data

  • 테라폼 1.4 버전에서는 기존의 null_resource 리소스를 대체할 수 있는 terraform_data 리소스가 추가되었습니다.

null_resource

  • 테라폼에서 null_resource는 아무 작업도 수행하지 않는 리소스를 구현하는 데 사용됩니다.
  • 이 리소스가 필요한 이유는 테라폼 프로비저닝 동작을 설계하면서 사용자가 의도적으로 프로비저닝하는 동작을 조율해야 하는 상황이 발생하기 때문입니다. 프로바이더가 제공하는 리소스 수명주기 관리만으로는 이를 해결하기 어려울 수 있습니다.
  • 주로 사용되는 시나리오
    • 프로비저닝 수행 과정에서 명령어 실행
    • 프로비저너와 함께 사용
    • 모듈, 반복문, 데이터 소스, 로컬 변수와 함께 사용
    • 출력을 위한 데이터 가공
  • 사용 예제
    • AWS EC2 인스턴스를 프로비저닝하면서 웹서비스를 실행시키고 싶다고 가정
    • 웹서비스 설정에는 고정된 외부 IP가 필요하므로 aws_eip 리소스를 생성해야 합니다.
  • main.tf 파일 생성
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_security_group" "instance" {
  name = "t101sg"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

}

resource "aws_instance" "example" {
  ami                    = "ami-0c9c942bd7bf113a2"
  instance_type          = "t2.micro"
  subnet_id              = "subnet-xxxx"
  private_ip             = "172.31.1.100"
  vpc_security_group_ids = [aws_security_group.instance.id]

  user_data = <<-EOF
              #!/bin/bash
              echo "Hello, T101 Study" > index.html
              nohup busybox httpd -f -p 80 &
              EOF

  tags = {
    Name = "Single-WebSrv"
  }

  provisioner "remote-exec" {
    inline = [
      "echo ${aws_eip.myeip.public_ip}"
     ]
  }
}

resource "aws_eip" "myeip" {
  #vpc = true
  instance = aws_instance.example.id
  associate_with_private_ip = "172.31.1.100"
}

output "public_ip" {
  value       = aws_instance.example.public_ip
  description = "The public IP of the Instance"
}
  • aws_eip는 생성 시 aws_instance의 id가 필요합니다.
  • aws_instance의 프로비저너는 동작 시 aws_eip의 public_ip가 필요합니다.
  • 실행 - aws_instance와 aws_eip 간 상호 참조 문제가 발생
# 두 리소스의 종속성이 상호 참조되어 발생하는 에러
terraform init && terraform plan

  • main.tf 파일 수정 - 두 리소스 중 하나의 실행 시점을 한 단계 뒤로 미뤄야 하고, 이를 위해 간격을 추가하여 실제 리소스와는 무관한 동작을 수행하려면 null_resource를 활용할 수 있습니다.
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_security_group" "instance" {
  name = "t101sg"

  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

}

resource "aws_instance" "example" {
  ami                    = "ami-0c9c942bd7bf113a2"
  instance_type          = "t2.micro"
  subnet_id              = "subnet-xxxx"
  private_ip             = "172.31.0.100"
  key_name               = "kp-xxxx" # 각자 자신의 EC2 SSH Keypair 이름 지정
  vpc_security_group_ids = [aws_security_group.instance.id]

  user_data = <<-EOF
              #!/bin/bash
              echo "Hello, T101 Study" > index.html
              nohup busybox httpd -f -p 80 &
              EOF

  tags = {
    Name = "Single-WebSrv"
  }

}

resource "aws_eip" "myeip" {
  #vpc = true
  instance = aws_instance.example.id
  associate_with_private_ip = "172.31.0.100"
}

resource "null_resource" "echomyeip" {
  provisioner "remote-exec" {
    connection {
      host = aws_eip.myeip.public_ip
      type = "ssh"
      user = "ubuntu"
      private_key =  file("/Users/xxxx/.ssh/kp-xxxx.pem") # 각자 자신의 EC2 SSH Keypair 파일 위치 지정
      #password = "qwe123"
    }
    inline = [
      "echo ${aws_eip.myeip.public_ip}"
      ]
  }
}

output "public_ip" {
  value       = aws_instance.example.public_ip
  description = "The public IP of the Instance"
}

output "eip" {
  value       = aws_eip.myeip.public_ip
  description = "The EIP of the Instance"
}
  • 실행 및 확인
# 프로비저너 설치 필요
terraform plan
terraform init -upgrade

# Terraform 계획 및 적용
# AWS EIP를 할당하기 전에 임시로 유동 공인 IP를 출력
terraform plan
terraform apply -auto-approve

# Terraform 상태 조회
terraform state list
terraform state show aws_eip.myeip
terraform state show aws_instance.example
terraform state show null_resource.echomyeip

# graph 확인 > graph.dot 파일 선택 후 오른쪽 상단 DOT 클릭
terraform graph > graph.dot

# 데이터소스 값 확인
echo "aws_instance.example.public_ip" | terraform console
echo "aws_eip.myeip.public_ip" | terraform console

# 출력된 EC2 퍼블릭IP로 curl 접속 확인
MYIP=$(terraform output -raw eip)
while true; do curl --connect-timeout 1  http://$MYIP/ ; echo "------------------------------"; date; sleep 1; done

  • null_resource는 자체적으로 상태를 관리하지 않고, 정의된 id 속성 외에는 다른 상태 속성을 가지지 않습니다. 따라서 해당 리소스의 내용이 변경되어도 Terraform은 새로운 실행 계획에서 이를 감지하지 못합니다.
  • 이러한 경우를 대비해 trigger를 사용하여 명시적으로 리소스를 갱신하거나 재실행할 수 있습니다.
  • trigger 정의와 동작 예제
resource "null_resource" "foo" {
  triggers = {
    ec2_id = aws_instance.bar.id # instance의 id가 변경되는 경우 재실행
  }
  ...생략...
}

resource "null_resource" "bar" {
  triggers = {
    ec2_id = time() # 테라폼으로 실행 계획을 생성할 떄마다 재실행
  }
  ...생략...
}

terraform_data

  • terraform_data 리소스는 자체적으로 아무것도 수행하지 않지만, null_resource와는 다르게 별도의 프로바이더 구성이 필요하지 않습니다.
  • 테라폼 자체에 포함된 기본 수명주기 관리자를 제공하여 이를 통해 별도 프로바이더 설정 없이 사용할 수 있다는 장점이 있습니다.
  • 기본적으로 null_resource와 동일한 용도로 사용되며, 강제 재실행을 위한 trigger_replace와 상태 저장을 위한 input 인수, 그리고 input에 저장된 값을 출력하는 output 속성을 제공합니다.
  • triggers_replace 에 정의되 값이 기존 map 형태에서 tuple로 변경되어 사용이 더 간단해졌습니다.
  • terraform_data 리소스의 trigger_replace 정의와 동작 예제
resource "aws_instance" "web" {
  # ...
}

resource "aws_instance" "database" {
  # ...
}

# A use-case for terraform_data is as a do-nothing container
# for arbitrary actions taken by a provisioner.
resource "terraform_data" "bootstrap" {
  triggers_replace = [
    aws_instance.web.id,
    aws_instance.database.id
  ]

  provisioner "local-exec" {
    command = "bootstrap-hosts.sh"
  }
}
resource "terraform_data" "foo" {
  triggers_replace = [
    aws_instance.foo.id,
    aws_instance.bar.id
  ]

  input = "world"
}

output "terraform_data_output" {
  value = terraform_data.foo.output  # 출력 결과는 "world"
}

 

3.14 moved 블록

moved 블록

  • Terraform 1.1 버전부터 도입된 moved 블록을 사용하면 기존 리소스의 주소를 변경하면서도 기존 인프라를 그대로 유지할 수 있습니다.
  • 이는 리소스의 이름 변경, count에서 for_each로의 변경, 또는 리소스를 모듈로 이동하는 경우에 매우 유용합니다.
  • 이전에는 terraform state mv 명령을 사용하여 State를 수정해야 했습니다.
  • moved 블록을 사용한다면 State에 접근할 필요 없어 보안 측면에서도 유리합니다.
  • 실습을 위해 main.tf 파일 생성
resource "local_file" "a" {
  content  = "foo!"
  filename = "${path.module}/foo.bar"
}

output "file_content" {
  value = local_file.a.content
}
  • 실행 및 확인
# Terraform 초기화 및 적용
terraform init && terraform plan && terraform apply -auto-approve

# 로컬 파일 확인
cat foo.bar ; echo

# Terraform 상태 목록 확인
terraform state list

# Terraform 콘솔을 사용하여 특정 리소스의 속성을 확인
echo "local_file.a" | terraform console
echo "local_file.a.id" | terraform console

  • main.tf 파일 수정 - local_file 의 이름을 a → b로 변경
resource "local_file" "b" {
  content  = "foo!"
  filename = "${path.module}/foo.bar"
}

output "file_content" {
  value = local_file.b.content
}
  • 실행 - 기존 리소스를 제거하고 새로운 리소스를 생성
# Terraform 계획
terraform plan

  • main.tf 파일 수정 - local_file.a 의 프로비저닝 결과를 유지한 채 이름을 변경하기 위해 moved 블록을 사용
resource "local_file" "b" {
  content  = "foo!"
  filename = "${path.module}/foo.bar"
}

moved {
  from = local_file.a
  to   = local_file.b
}

output "file_content" {
  value = local_file.b.content
}
  • 실행 - 변화 없음
# Terraform 계획
terraform plan

# Terraform 적용 및 상태 목록 확인
terraform apply -auto-approve
terraform state list

# Terraform 콘솔을 사용하여 특정 리소스의 속성을 확인
echo "local_file.b" | terraform console
echo "local_file.b.id" | terraform console

  • main.tf 파일 수정 - moved 블록을 삭제하여 리팩터링 완료
resource "local_file" "b" {
  content  = "foo!"
  filename = "${path.module}/foo.bar"
}

# moved {
#   from = local_file.a
#   to   = local_file.b
# }

output "file_content" {
  value = local_file.b.content
}

 

3.15 CLI를 위한 시스템 환경 변수

  • 테라폼은 환경 변수를 통해 실행 방식과 출력 내용에 대한 옵션을 조절할 수 있습니다.
  • 시스템 환경 변수를 설정하면, 영구적으로 로컬 환경에 적용되는 옵션이나 별도 서버 환경에서 실행하기 위한 옵션을 부여할 수 있습니다.
  • 이를 통해 로컬 작업 환경과 다른 환경 구성에서만 사용될 특정 옵션을 적용할 수 있습니다.
Mac/리눅스/유닉스 : export <환경 변수 이름>=<값>
Windows CMD : set <환경 변수 이름>=<값>
Windows PowerShell : $Env:<환경 변수 이름>='<값>'

TF_LOG

  • 테라폼의 stderr 로그에 대한 레벨을 정의합니다.
  • 설정할 수 있는 값은 trace, debug, info, warn, error, off입니다. 관련 환경 변수가 없는 경우 off와 동일하게 동작합니다.
  • 디버깅을 위한 로그 관련 환경 변수 설명은 다음과 같습니다
    • TF_LOG: 로깅 레벨 지정 또는 해제
    • TF_LOG_PATH: 로그 출력 파일 위치 지정
    • TF_LOG_CORE: TF_LOG와 별도로 테라폼 자체 코어에 대한 로깅 레벨 지정 또는 해제
    • TF_LOG_PROVIDER: TF_LOG와 별도로 테라폼에서 사용하는 프로바이더에 대한 로깅 레벨 지정 또는 해제
  • 환경에 맞게 TF_LOG를 info로 설정하고 terraform plan 동작을 실행하면 테라폼 출력에 관련 로그가 출력됩니다
TF_LOG=info terraform plan
...

TF_INPUT

  • 값을 false 또는 0으로 설정하면 테라폼 실행 시 인수에 -input=false를 추가한 것과 동일한 수행 결과를 확인할 수 있습니다.
  • 환경에 맞게 TF_INPUT을 0으로 설정하고 terraform plan 동작을 실행하면 입력받는 동작을 수행하지 않으므로 입력 변수를 입력해야 하는 경우 에러가 출력됩니다
TF_INPUT=0 terraform plan
Error : No value for required variable

TF_VAR_name

  • TF_VAR_<변수 이름>을 사용하면 입력 시 또는 default로 선언된 변수 값을 대체할 수 있습니다.
  • 예를 들어, TF_VAR_region 환경 변수를 설정하면 region 변수의 기본값을 대체할 수 있습니다.

TF_CLI_ARGS / TF_CLI_ARGS_subcommand

  • 테라폼 실행 시 추가할 인수를 정의할 수 있습니다.
# TF_CLI_ARGS="-input=false" terraform apply -auto-approve 는 terraform apply -input=false -auto-approve 와 같다
TF_CLI_ARGS="-input=false" terraform apply -auto-approve
Error: No value for required variable

# TF_CLI_ARGS_apply로 인수를 정의하면 terraform apply 커맨드 수행 시에만 동작한다
export TF_CLI_ARGS_apply="-input=false"
terraform apply -auto-approve
Error: No value for required variable

terraform plan
<정상 계획 예측 출력>

TF_DATA_DIR

  • 이 데이터는 기본적으로 .terraform 디렉터리 위치에 기록되지만, TF_DATA_DIR에 경로가 정의되면 기본 경로를 대체하여 사용됩니다.
  • 일관된 테라폼 사용을 위해서 해당 변수는 실행 시마다 일관되게 적용될 수 있도록 설정하는 것이 중요합니다.
  • 설정 값이 이전 실행 시에만 적용되는 경우 init 명령으로 수행된 모듈, 아티팩트 등의 파일을 찾지 못합니다.
  • 이미 terraform init이 수행된 상태에서 TF_DATA_DIR로 경로를 재지정하고 실행하는 경우 플러그인 설치가 필요하다는 메시지가 출력됩니다.
TF_DATA_DIR=./.terraform_tmp terraform plan
Error: Required plugins anr not installed