Lim Seunghyun Space

[T102] Terraform 설치 및 튜토리얼 본문

IaC/Terraform

[T102] Terraform 설치 및 튜토리얼

Lim Seung Hyun 2023. 7. 9. 00:14

Terraform 설치하기 (On MacOS)

Homebrew를 이용한 설치

⚠️ 사전에 HomeBrew를 설치가 필요

brew tap hashicorp/tap
brew install hashicorp/tap/terraform

Binary (From Terraform download)

Terraform Install

1. Path 설정 추가

# Terraofrm 설치 위치 확인
which Terraform

# PATH 추가
export PATH=$PATH:<which Terraform dir path>

2. 설치 확인

terraform
'''
Usage: terraform [global options] <subcommand> [args]

The available commands for execution are listed below.
The primary workflow commands are given first, followed by
less common or more advanced commands.

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
'''

terraform version
''' 예시
Terraform v1.5.1
on darwin_arm64
'''

 

tfvenv

  • Terraform의 버전 관리 도구로 필요에 따라 여러 버전의 Terraform을 환경을 구성하고 원하는 버전을 선택해서 사용할 수 있는 도구
# tfenv 설치 (Homebrew)
brew install tfenv

# 설치 확인
tfenv 
'''
tfenv 3.0.0
Usage: tfenv <command> [<options>]

Commands:
   install       Install a specific version of Terraform
   use           Switch a version to use
   uninstall     Uninstall a specific version of Terraform
   list          List all installed versions
   list-remote   List all installable versions
   version-name  Print current version
   init          Update environment to use tfenv correctly.
   pin           Write the current active version to ./.terraform-version

'''

# 설치 가능한 terraform 버전 리스트
tfenv list-remote
'''
1.5.2
1.5.1
1.5.0
1.5.0-rc2
1.5.0-rc1
'''

# 특정 terraform 버전 설치
tfenv install <terraform 버전>
'''
Installing Terraform v1.5.1
Downloading release tarball from https://releases.hashicorp.com/terraform/1.5.1/terraform_1.5.1_darwin_arm64.zip
...
'''

# tfenv로 설치한 terraform 버전 확인
tfenv list
'''
  1.5.1
* 1.4.6 (set by /opt/homebrew/Cellar/tfenv/3.0.0/version)
'''

# 특정 terraform 버전 사용 설정
tfenv use <terraform 버전>
'''
Switching default version to v1.5.1
Default version (when not overridden by .terraform-version or TFENV_TERRAFORM_VERSION) is now: 1.5.1
'''

# terraform 버전 확인
terraform version
'''
Terraform v1.5.1
on darwin_arm64
'''

 

Terraform 명령어

help: 보조 명령에서 사용 가능한 옵션과 설명을 확인

terraform
'''
Usage: terraform [-version] [-help] <command> [args]
'''

# terraform <command> -help
terraform init -help
'''
Usage: terraform [global options] init [options]

  Initialize a new or existing Terraform working directory by creating
  initial files, loading any remote state, downloading modules, etc.

  This is the first command that should be run for any new or existing
  Terraform configuration per machine. This sets up all the local data
  necessary to run Terraform that is typically not committed to version
  control.

  This command is always safe to run multiple times. Though subsequent runs
  may give errors, this command will never delete your configuration or
  state. Even so, if you have important information, please back it up prior
  to running this command, just in case.

Options:

  -backend=false          Disable backend or Terraform Cloud initialization
                          for this configuration and use what was previously
                          initialized instead.
...
'''

init: Terraform 구성 파일이 있는 작업 디렉터리를 초기화

  • 루트 모듈: init을 실행하는 디렉터리
  • 초기화를 통해 프로바이더, 모듈 등의 지정된 버전에 맞춰 루트 모듈을 구성하는 역할을 수행
# Workspace/main.tf
resource "local_file" "abc" {
  content  = "abc!"
  filename = "${path.module}/abc.txt"
}

# init시
terrafrom init
'''
Initializing the backend...

Initializing provider plugins...
- Finding latest version of hashicorp/local...
- Installing hashicorp/local v2.4.0...
- Installed hashicorp/local v2.4.0 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

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.
'''

init -upgrade: 의도적으로 버전을 변경하거나 코드에 명시한 다른 버전으로 변경 시 사용

  • 0.14 버전 이후에는 종속성을 고정시키는 .terraform.lock.hcl이 추가되었다.
  • terraform init -upgrade

validate: terraform 파일의 코드적인 유효성을 확인

  • 구성의 문법, 종속성, 속성 이름이나 연결된 값의 정확성 확인을 수행
# main.tf
resource "local_file" "abc" {
  content  = "abc!"
  # filename = "${path.module}/abc.txt" # Required 값을 의도적으로 주석처리
}

terraform validate
# 에러가 있을시, 아래처럼 코드 내 에러를 발견해준다.
'''
╷
│ Error: Missing required argument
│ 
│   on main.tf line 1, in resource "local_file" "abc":
│    1: resource "local_file" "abc" {
│ 
│ The argument "filename" is required, but no definition was found.
'''
# 에러가 없는 경우
'''
Success! The configuration is valid.
'''

# 결과를 json 형태로 확인할 수 있다.
terraform validate -json
'''
{
  "format_version": "1.0",
  "valid": true,
  "error_count": 0,
  "warning_count": 0,
  "diagnostics": []
}
'''

plan: 테라폼으로 적용할 인프라의 변경 사항에 관한 실행 계획을 생성

  • 어떤 변경 사항이 있는지 실제 적용하지 않고 확인할 수 있다.
  • 코드를 적용하기 전에 예상한 구성이 맞는지 주로 이용한다.
  • -replace <Resource> 옵션은 resource를 destory하고 create 하는 plan을 보여준다.
# main.tf
resource "local_file" "abc" {
  content  = "abc!"
  filename = "${path.module}/abc.txt"
}

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:

  # local_file.abc will be created
  + resource "local_file" "abc" {
      + content              = "abc!"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./abc.txt"
      + id                   = (known after apply)
    }

Plan: 1 to add, 0 to change, 0 to destroy.
'''

# terraform plan 결과를 시스템 코드로 확인할 수 있다.
terraform plan -detailed-exitcode
'''
시스템 코드는
echo %errorlevel% 혹은 echo $? 으로 확인한다.
0: 변경 사항이 없으며 오류가 없음
1: 오류가 있음
2: 변경 사항이 있지만 오류가 없음
'''

apply: 작성한 코드를 실제로 반영한다.

  • 구성 계획을 미리 보여주고 수행 여부를 물어본다.
    • -auto-approve 옵션을 통해 수행 여부와 관계없이 반영할 수 있다.
    • terraform apply -auto-approve
  • terraform은 선언적 구성 관리를 제공하는 언어로 멱등성 보장하면서 상태를 관리하기 때문에 동일한 구성에 대해서는 다시 실행하거나 변경하는 작업을 수행하지 않는다.
  • -replace <Resource> 옵션은 resource를 destory하고 create 한다.
# main.tf
resource "local_file" "abc" {
  content  = "abc!"
  filename = "${path.module}/abc.txt"
}

terraform apply
'''
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:

  # local_file.abc will be created
  + resource "local_file" "abc" {
      + content              = "abc!"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./abc.txt"
      + id                   = (known after apply)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

local_file.abc: Creating...
local_file.abc: Creation complete after 0s [id=5678fb68a642f3c6c8004c1bdc21e7142087287b]
'''

# apply한 리소스 확인
terraform state list
'''
local_file.abc
'''


# main.tf 을 수정
resource "local_file" "abc" {
  content  = "abc!"
  filename = "${path.module}/abcd.txt"
}

resource "local_file" "dev" {
  content  = "def!"
  filename = "${path.module}/def.txt"
}


terraform apply
# 기존에 apply된 내용에서 추가된 내용만 생성한다.
# 추가로 main.tf에서 변경된 사항이 있다면 이전과 비교해서 현재의 plan에 맞게 변경해준다.
'''
local_file.abc: Refreshing state... [id=5678fb68a642f3c6c8004c1bdc21e7142087287b]

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:

  # local_file.dev will be created
  + resource "local_file" "dev" {
      + content              = "def!"
      + content_base64sha256 = (known after apply)
      + content_base64sha512 = (known after apply)
      + content_md5          = (known after apply)
      + content_sha1         = (known after apply)
      + content_sha256       = (known after apply)
      + content_sha512       = (known after apply)
      + directory_permission = "0777"
      + file_permission      = "0777"
      + filename             = "./def.txt"
      + id                   = (known after apply)
    }

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

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

local_file.dev: Creating...
local_file.dev: Creation complete after 0s [id=15f946cb27f0730866cefea4f0923248d9366cb0]
'''

terraform state list
'''
local_file.abc
local_file.dev
'''

destroy: 테라폼으로 구성하고 apply 된 모든 리소스를 제거

  • 테라폼 코드로 구성된 리소스 일부만 제거하기 위해서는 테라폼의 선언적 특성에 따라 삭제하려는 항목을 코드에서 제거하고, 다시 apply 해야 한다.
# main.tf
resource "local_file" "abc" {
  content  = "abc!"
  filename = "${path.module}/abc.txt"
}


terraform destroy
'''
ocal_file.abc: Refreshing state... [id=5678fb68a642f3c6c8004c1bdc21e7142087287b]

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

Terraform will perform the following actions:

  # local_file.abc will be destroyed
  - resource "local_file" "abc" {
      - content              = "abc!" -> null
      - content_base64sha256 = "U+Dv8yBGJvPiVspjZXLXzN+OtaGQyd76P6VnvGOGa3Y=" -> null
      - content_base64sha512 = "J873Ugx5HyDEnYsjdX8iMBjn4I3gft82udsl3lNeWEoqwmNE3mvUZNNz4QRqQ3iaT5SW1y9p3e1Xn2txEBapKg==" -> null
      - content_md5          = "4edb03f55c86d5e0a76f5627fa506bbf" -> null
      - content_sha1         = "5678fb68a642f3c6c8004c1bdc21e7142087287b" -> null
      - content_sha256       = "53e0eff3204626f3e256ca636572d7ccdf8eb5a190c9defa3fa567bc63866b76" -> null
      - content_sha512       = "27cef7520c791f20c49d8b23757f223018e7e08de07edf36b9db25de535e584a2ac26344de6bd464d373e1046a43789a4f9496d72f69dded579f6b711016a92a" -> null
      - directory_permission = "0777" -> null
      - file_permission      = "0777" -> null
      - filename             = "./abc.txt" -> null
      - id                   = "5678fb68a642f3c6c8004c1bdc21e7142087287b" -> null
    }

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

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

local_file.abc: Destroying... [id=5678fb68a642f3c6c8004c1bdc21e7142087287b]
local_file.abc: Destruction complete after 0s

Destroy complete! Resources: 1 destroyed.
'''

# 리소스 확인시 아무것도 출력되지 않는다.
terraform destroy

fmt: Terraform 구성 파일을 표준 형식과 표준 스타일로 적용

terraform fmt

 

HCL(HashiCorp Configuration Language)

  • IaC와 구성 정보를 명시하기 위해 개발된 오픈소스 도구
  • 표현식
// 한줄 주석 방법1
# 한줄 주석 방법2

/*
라인
주석
*/

locals {
  key1     = "value1"     # = 를 기준으로 키와 값이 구분되며
  myStr    = "TF ♡ UTF-8" # UTF-8 문자를 지원한다.
  multiStr = <<EOF
  Multi
  Line
  String
  with anytext
EOF

  boolean1    = true   # boolean true
  boolean2    = false  # boolean false를 지원한다.
  deciaml     = 123    # 기본적으로 숫자는 10진수,
  octal       = 0123   # 0으로 시작하는 숫자는 8진수,
  hexadecimal = "0xD5" # 0x 값을 포함하는 스트링은 16진수,
  scientific  = 1e10   # 과학표기 법도 지원한다.

  # funtion 호출 예
  myprojectname = format("%s is myproject name", var.project)
  # function ref: https://developer.hashicorp.com/terraform/language/functions

  # 3항 연산자 조건문을 지원한다.
  credentials = var.credentials == "" ? file(var.credentials_file) : var.credentials
}

# 인프라를 구성하기 위한 선언 블록도 존재
- terraform, resource, data, variable, local, output

 

Terraform Block

 

  • Terraform 구성을 명시하는데 사용
    • 테라폼 버전이나 프로바이더 버전과 같은 값들은 자동으로 설정되지만 직접 버전을 명시적으로 선언하고 필요한 조건만 입력해 실행 오류를 최소화 할 것을 권장
  • 각 provider별 예제 Link
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"
  }
}

 

실습해보기

AWS CLI  구성 (on Mac OS)

# install
brew intsall awscli

# 설치 확인
aws --version

# AWS 자격증명 등록
aws configure
'''
AWS Access Key ID [****************A6V6]: <Your Key>
AWS Secret Access Key [****************bUrU]: <Your Access Key>
Default region name [ap-northeast-2]: <Your Region>
Default output format [json]: JSON
'''

# Default로 설정한 Region의 default VPC 확인
aws ec2 describe-vpcs --filter 'Name=isDefault,Values=true'
'''
{
    "Vpcs": [
        {
            ...,
            "IsDefault": true
        }
    ]
}
'''

Terraform을 통해 EC2 생성하기

# 작업 공간 생성
mkdir ~/create-ec2-terraform
cd ~/create-ec2-terraform

# 테라폼 코드 생성
touch main.tf
# Terraform 코드
provider "aws" {
  region = "ap-northeast-2"
}

resource "aws_instance" "example" {
  ami           = "ami-0a0064415cdedc552"
  instance_type = "t2.micro"
  
  tags = {
    Name = "test-study"
  }
}
# 작업 공간 초기화
terraform init

# terraform 실행 계획 확인
terraform plan

# terraform 실행 및 인프라 생성
terraform apply -auto-approve

# cli로 생성 확인하기
aws ec2 describe-instances --output table

EC2 생성 완료!

# 인프라 삭제
terraform destroy -auto-approve

EC2 종료 완료!

728x90

'IaC > Terraform' 카테고리의 다른 글

[T102] 반복문  (0) 2023.07.16
[T102] Output  (0) 2023.07.16
[T102] Local  (0) 2023.07.16
[T102] Variable  (0) 2023.07.16
[T102] Data Source  (0) 2023.07.15