컬쥐네 다락방

Terraform | 테라폼 기초 지식 (구성 파일, 변수) 본문

클라우드/Terraform

Terraform | 테라폼 기초 지식 (구성 파일, 변수)

코딩하는 갱얼쥐 2022. 4. 21. 17:22

Terraform

HCL: Hashicorp Configuration Language

DSL: Domain Specific Language

Workflow

  • 코드 작성(Write)
  • 계획(Plan)
  • 적용(Apply)

프로바이더
https://registry.terraform.io/browse/providers

설치

terraform 설치
https://www.terraform.io/downloads

sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://rpm.releases.hashicorp.com/RHEL/hashicorp.repo
sudo yum -y install terraform

terraform --version

aws-cli 설치
https://docs.aws.amazon.com/ko_kr/cli/latest/userguide/getting-started-install.html

cd ~
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" 
sudo yum install -y unzip
unzip awscliv2.zip 
sudo ./aws/install

aws --version

aws configure
aws sts get-caller-identity

시간 설정

$ sudo vi /etc/chrony.conf
$ sudo systemctl restart chronyd
$ timedatectl set-ntp true
$ sudo timedatectl set-timezone Asia/Seoul
$ chronyc sources -v

구성파일

Terraform Configure File

  • .tf
  • .tf.json: Json 형식

인코딩
Unicode

디렉토리
현재 작업 디렉토리 위치에 따라서 해당 디렉토리의 .tf, .tf.json 모두 읽어서 실행

구성 파일

<BLOCK TYPE> <BLOCK LABEL> ... {
    ARGUMENT
    KEY = VALUE
}

{ } 블록

테라폼 블록

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}
  • aws: 프로바이더의 이름
  • source: 프로바이더의 종류
  • version: 프로바이더의 버전
    • 4.10: 특정 버전
    • ~> 3.12: 특정 버전 이상
      • 3.12: 최소 버전

프로바이더 블록(필수)

provider "aws" {
  profile = "default"
  region  = "us-west-2"
}
  • provider "aws": terraform 블록 이름 매칭
    • profile: aws 자격증명 파일의 프로필
    • region

참고
테라폼 리소스 = 앤서블 모듈
테라폼 모듈 = 앤서블 역할

리소스 블록

resource "RESOURCE_TYPE" "NAME" {
  ARGUMENT = VALUE
}
  • RESOURCE_TYPE: 리소스 종료
  • NAME: 리소스 이름(테라폼에서 구분 하기 위한 이름)
  • ARGUMENT: 인자/속성

실행 순서

초기화

terraform init

프로바이더 플러그인 설치

언제?

  • 최초로 프로바이더 설치
  • 프로바이터 버전 업데이트

포멧팅

terraform fmt

언제?

  • 새로운 파일 작성
  • 기존 파일 변경

유효성 검증

terraform validate

테라폼 파일의 유효성 검증을 진행해 간단하게 오류를 검사할 수 있다.

계획

terraform plan

테라폼을 실행했을 때를 가정하여 그 계획을 보여준다. 무엇이 바뀌는지, 어떤 내용이 적용되는지 확인할 수 있다.

[vagrant@controller 01]$ terraform plan

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

Terraform will perform the following actions:

  # aws_eip.app_server will be created
  + resource "aws_eip" "app_server" {
      + allocation_id        = (known after apply)
      + association_id       = (known after apply)
      + carrier_ip           = (known after apply)
      + customer_owned_ip    = (known after apply)
      + domain               = (known after apply)
      + id                   = (known after apply)
      + instance             = (known after apply)
      + network_border_group = (known after apply)
      + network_interface    = (known after apply)
      + private_dns          = (known after apply)
      + private_ip           = (known after apply)
      + public_dns           = (known after apply)
      + public_ip            = (known after apply)
      + public_ipv4_pool     = (known after apply)
      + tags_all             = (known after apply)
      + vpc                  = true
    }

  # aws_instance.app_server will be created
  + resource "aws_instance" "app_server" {
      + ami                                  = "ami-0454bb2fefc7de534"
      + arn                                  = (known after apply)
      + associate_public_ip_address          = (known after apply)
      + availability_zone                    = (known after apply)
      + cpu_core_count                       = (known after apply)
      + cpu_threads_per_core                 = (known after apply)
      + disable_api_termination              = (known after apply)
      + ebs_optimized                        = (known after apply)
      + get_password_data                    = false
      + host_id                              = (known after apply)
      + id                                   = (known after apply)
      + instance_initiated_shutdown_behavior = (known after apply)
      + instance_state                       = (known after apply)
      + instance_type                        = "t2.micro"
      + ipv6_address_count                   = (known after apply)
      + ipv6_addresses                       = (known after apply)
      + key_name                             = (known after apply)
      + monitoring                           = (known after apply)
      + outpost_arn                          = (known after apply)
      + password_data                        = (known after apply)
      + placement_group                      = (known after apply)
      + placement_partition_number           = (known after apply)
      + primary_network_interface_id         = (known after apply)
      + private_dns                          = (known after apply)
      + private_ip                           = (known after apply)
      + public_dns                           = (known after apply)
      + public_ip                            = (known after apply)
      + secondary_private_ips                = (known after apply)
      + security_groups                      = (known after apply)
      + source_dest_check                    = true
      + subnet_id                            = (known after apply)
      + tags                                 = {
          + "Environment" = "Terraform"
          + "Name"        = "App Instance"
        }
      + tags_all                             = {
          + "Environment" = "Terraform"
          + "Name"        = "App Instance"
        }
      + tenancy                              = (known after apply)
      + user_data                            = (known after apply)
      + user_data_base64                     = (known after apply)
      + vpc_security_group_ids               = (known after apply)

      + capacity_reservation_specification {
          + capacity_reservation_preference = (known after apply)

          + capacity_reservation_target {
              + capacity_reservation_id = (known after apply)
            }
        }

      + ebs_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + snapshot_id           = (known after apply)
          + tags                  = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }

      + enclave_options {
          + enabled = (known after apply)
        }

      + ephemeral_block_device {
          + device_name  = (known after apply)
          + no_device    = (known after apply)
          + virtual_name = (known after apply)
        }

      + metadata_options {
          + http_endpoint               = (known after apply)
          + http_put_response_hop_limit = (known after apply)
          + http_tokens                 = (known after apply)
          + instance_metadata_tags      = (known after apply)
        }

      + network_interface {
          + delete_on_termination = (known after apply)
          + device_index          = (known after apply)
          + network_interface_id  = (known after apply)
        }

      + root_block_device {
          + delete_on_termination = (known after apply)
          + device_name           = (known after apply)
          + encrypted             = (known after apply)
          + iops                  = (known after apply)
          + kms_key_id            = (known after apply)
          + tags                  = (known after apply)
          + throughput            = (known after apply)
          + volume_id             = (known after apply)
          + volume_size           = (known after apply)
          + volume_type           = (known after apply)
        }
    }

  # aws_s3_bucket.app_server will be created
  + resource "aws_s3_bucket" "app_server" {
      + acceleration_status         = (known after apply)
      + acl                         = "private"
      + arn                         = (known after apply)
      + bucket                      = "encore-test220421"
      + bucket_domain_name          = (known after apply)
      + bucket_regional_domain_name = (known after apply)
      + force_destroy               = false
      + hosted_zone_id              = (known after apply)
      + id                          = (known after apply)
      + object_lock_enabled         = (known after apply)
      + region                      = (known after apply)
      + request_payer               = (known after apply)
      + tags_all                    = (known after apply)
      + website_domain              = (known after apply)
      + website_endpoint            = (known after apply)

      + object_lock_configuration {
          + object_lock_enabled = (known after apply)

          + rule {
              + default_retention {
                  + days  = (known after apply)
                  + mode  = (known after apply)
                  + years = (known after apply)
                }
            }
        }

      + versioning {
          + enabled    = (known after apply)
          + mfa_delete = (known after apply)
        }
    }

Plan: 3 to add, 0 to change, 0 to destroy.

적용

terraform apply

테라폼 설정을 적용한다. 실제 실행을 통해 EC2 인스턴스가 생성되게 된다.

제거

terraform destroy

진행 상황 자동 동의

테라폼의 적용이나 제거를 하다보면 진행 여부에 관해 계속해서 물어보게 되는데, 이를 간단하게 모두 동의하려면 --auto-approve 옵션을 추가해주면 된다.

[vagrant@controller 01]$ terraform apply --auto-approve

상태 확인

  • terraform.tfstate: 현재상태

  • terraform.tfstate.backup: 직전 상태

    terraform show
    terraform state list
    terraform state show aws_instance.app_server

상태 재 동기화

terraform refresh

EC2의 설정을 바꿨을 경우 재동기화를 해줘야 terraform show에서 상태가 변경되어 적용된 것을 확인 가능.

리소스 생성 순서

  • 의존 관계가 없는 리소스는 병렬로 실행
  • 의존 관계가 있는 경우 의존 관계에 따라서 순서가 정해지게 됨

명시적 의존성

resource "aws_instance" "app_server" {

  depends_on = [
    aws_s3_bucket.app_bucket
  ]
}

https://www.terraform.io/language/meta-arguments/depends_on

입력 변수(Input Variable)

https://www.terraform.io/language/values/variables

variable "image_id" {
  type = string
}

variable "availability_zone_names" {
  type    = list(string)
  default = ["us-west-1a"]
}
  • type:
    • 일반 타입
      • string
        • "app_server"
      • number
        • 1
        • 1.0
      • bool
        • true
        • false
    • 복합 타입
      • list / tuple
        • [a, b, c]
      • map / object
        • `{a = abc, b = xyz}
  • default: 기본 값
  • description: 설명
variables abc {
  type = list(string)
  # ["a", "b"]
  type = list(number)
  # [1, 2]
}

변수 값 할당

-var 옵션

테라폼을 실행할 때 옵션을 추가하면 가장 높은 우선순위를 가지는 변수 값을 할당 가능.

terraform plan -var "instance_name=xyz"

terraform.tfvars 파일

별도의 파일을 만들어서 변수를 할당하여 테라폼을 진행할 수도 있다 이때 파일명을 꼭 확인해줘야 테라폼이 자동으로 찾아서 설정이 가능하다.
terraform.tfvars

instance_name = "xyz"