본문 바로가기
Cloud/Terraform

Terraform이란?

by wrynn 2022. 11. 24.

 Terraform은 HashiCorp에서 만든 코드형 인프라(IaC) 관리 도구입니다.[1] 코드로 프로비저닝할 인프라를 정의하고, 작성한 코드를 Terraform으로 실행하면 내부적으로 API 호출을 통해 인프라를 생성합니다. 본문에서는 Terraform에 대해 알아보고, 간단한 실습을 통해 사용 방법을 익혀보겠습니다.

Terraform을 사용하는 이유

 클라우드 환경에서 인프라 프로비저닝은 다양한 리소스의 생성을 필요로 합니다. 예를 들어, AWS를 사용한다면 가상 네트워크인 VPC와 Subnet을 만들어주고, Routing Table을 설정해주어야 합니다. 이와 더불어 EC2와 Load Balancer를 생성하고 Target Group을 정의해 주어야 합니다. 이처럼 클라우드를 사용하면 각각의 리소스를 올바르게 구성하고 연결하는 작업이 필요한데, Terraform과 같은 IaC 도구를 활용하면 이를 훨씬 수월하게 할 수 있습니다. Terraform을 사용하는 경우 몇 가지 장점은 다음과 같습니다.

  • 동일한 인프라를 새로 구성하는 경우 속도 향상
  • 인프라 프로비저닝 프로세스를 자동화하여 안정성 향상 
  • 코드로 관리하여 변경 이력 관리 및 롤백에 용이
  • 멀티 클라우드 환경을 하나의 도구로 관리 가능

Terraform 동작 흐름

 인프라를 Terraform을 사용하여 프로비저닝할 때에는 아래의 다섯 단계를 거칩니다. 프로젝트에 필요한 인프라를 식별하는 Scope 단계와 코드를 작성하는 Author 단계는 사람이 직접 수행하며 나머지 Initialize, Plan, Apply 단계는 Terraform으로 자동화하여 수행합니다.

Terraform deployment workflow [2]

  1. Scope - 프로젝트에 필요한 인프라를 식별
  2. Author - 인프라를 코드로 작성
  3. Initialize - 인프라 관리에 필요한 Terraform 플러그인 설치
  4. Plan - 코드에 의해 변경될 인프라 확인 
  5. Apply - 인프라 변경 적용

Terraform 설치

설치 방법은 OS에 따라 달라집니다. 본문의 실습 환경은 AWS EC2 인스턴스에서 진행되며, 운영체제는 Amazon Linux를 사용하였습니다. 다른 OS의 경우 HashiCorp 공식 홈페이지의 Terraform Install을 참고합니다. 

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

 다음 명령으로 정상적으로 설치가 되었는지 확인합니다.  정상적으로 설치가 되었다면 다음과 같은 내용이 출력됩니다.

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

The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you`re just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.

 자동완성을 사용하기 위해서는 autocomplete 패키지를 별도로 설치해주어야 합니다.

$ touch ~/.bashrc
$ terraform -install-autocomplete

AWS CLI 설치

 Terraform은 설치가 완료되었지만, AWS 리소스를 생성하기 위해서는 AWS CLI 도구가 추가로 설치되어 있어야 합니다. Amazon Linux 운영체제에는 기본적으로 설치되어 있으며, 다른 OS에서의 설치방법은 AWS 공식 홈페이지의 Installing or updating the latest version of the AWS CLI를 참고합니다.

AWS 인증 정보(credentials) 설정

 EC2 인스턴스에서 AWS 리소스 생성을 요청하려면 적절한 사용자 인증 정보가 있어야 합니다. 아래 명령으로 설정을 진행합니다.

$ aws configure

 명령을 실행하면 아래와 같이 사용자 인증 정보를 요구합니다. 이 중 Access Key ID와 Secret Access Key는 예시로 적힌 값 대신 각자 본인이 가지고 있는 AWS 계정의 정보를 사용합니다.

* 액세스 키를 얻는 방법은 AWS Account and Access Keys를 참고합니다.

AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE   # 개인 Access Key로 변경
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY   # 개인 Secret Access Key로 변경
Default region name [None]: ap-northeast-2
Default output format [None]: json

Terraform 사용

 이제 준비가 완료되었으니 Terraform 동작 흐름에 따라 직접 Terraform을 사용하여 간단한 실습을 진행해보겠습니다.

1. Scope

 프로젝트에 필요한 인프라를 식별하는 Scope 단계에서는 EC2 인스턴스 하나가 필요하다고 가정해 보겠습니다.

2. Author

 디렉토리를 하나 만들고 그 안에 파일을 생성하여 Terraform 문법에 맞게 코드를 작성합니다. Terraform에서는 이러한 파일을 구성 파일(Configuration file)이라고 합니다.

$ mkdir learn-terraform-aws-instance
$ cd learn-terraform-aws-instance
$ vi main.tf

  main.tf 파일 내용을 다음과 같이 수정합니다. Terraform 코드는 HCL(HashiCorp Configuration Language)이라는 언어로 작성됩니다. 아래는 ap-northeast-2 리전에 AWS EC2 인스턴스를 하나 생성하는 코드입니다. VPC와 Subnet은 모두 default를 사용합니다.

* 만일 다른 리전에서 테스트를 수행하실 분들께서는 provider의 region과 resource의 ami 값 두가지를 변경해주어야 합니다. (같은 EC2 인스턴스 타입을 사용하더라도 리전에 따라 AMI가 다릅니다.)

# main.tf
terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 4.16"
    }
  }

  required_version = ">= 1.2.0"
}

provider "aws" {
  region  = "ap-northeast-2"
}

resource "aws_instance" "app_server" {
  ami           = "ami-072bfb8ae2c884cc4"
  instance_type = "t2.micro"

  tags = {
    Name = "ExampleAppServerInstance"
  }
}

3. Initialize

 terraform init으로 디렉터리를 초기화하면 Terraform 코드 파일(main.tf)에 정의된 provider 플러그인을 다운로드하고 설치합니다. 예제의 경우 AWS provider 플러그인을 설치하게 됩니다.

$ terraform init 

Initializing the backend...

Initializing provider plugins...
... (생략) ...

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.

 

4. Plan

 데이터베이스에서 쿼리문의 실행 계획을 보는 것과 유사하게 terraform plan 명령은 해당 코드를 실행했을 때, 변경되는 사항을 보여줍니다. 하지만 실제로 리소스를 변경하지는 않고 변경될 내용을 확인하는 데 사용합니다. 따라서 이 단계를 생략하고 바로 다음 단계로 넘어가도 되지만, 비즈니스 환경에서는 실제 리소스가 생성되기 전에 반드시 변경사항을 확인하는 것이 좋습니다.

$ 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_instance.app_server will be created
  + resource "aws_instance" "app_server" {
      + ami                                  = "ami-072bfb8ae2c884cc4"
      + arn                                  = (known after apply)
      ... (생략) ...
    }

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

────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take exactly these actions if you run "terraform apply" now.

5. Apply

 terraform apply는 변경사항을 적용시키는 명령입니다. 실제 인프라에 변경이 일어나기 때문에 정말로 반영할 것인지 확인하는 절차가 포함되어 있습니다. yes 를 입력하여 계속 진행합니다.

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

 정상적으로 실행된다면 콘솔 창에 생성된 EC2 인스턴스의 id값이 출력됩니다.

aws_instance.app_server: Creating...
aws_instance.app_server: Still creating... [10s elapsed]
aws_instance.app_server: Still creating... [20s elapsed]
aws_instance.app_server: Creation complete after 22s [id=i-05fea222173075842]

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

 웹 콘솔을 통해 확인해보면 ExampleAppServerInstance라는 이름의 인스턴스 하나가 실행된 것을 확인할 수 있습니다. 이것은 main.tf에서 resource 항목의 Name 태그에 정의해 둔 값과 동일한 값입니다.


실습용 리소스 제거

 실습용으로 생성한 EC2 인스턴스를 종료시키기 위해 웹 콘솔에서 EC2를 종료시킬 수도 있습니다. 하지만 프로젝트에 포함된 리소스가 많다면 각각의 리소스 일일이 제거하는 것은 번거롭기도 하고 실수할 여지가 있습니다. Terraform을 사용하면 생성과 마찬가지로 리소스 삭제도 쉽게 할 수 있습니다. 

destroy

 terraform destroy 명령으로 코드로 정의한 인프라를 삭제할 수 있습니다. apply 명령과 마찬가지로 정말로 삭제할 것인지 물어보는 단계가 포함되어 있습니다. yes를 입력하여 삭제를 진행합니다.

$ terraform destroy 
aws_instance.app_server: Refreshing state... [id=i-05fea222173075842]

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:

  # aws_instance.app_server will be destroyed
  - resource "aws_instance" "app_server" {
      - ami                                  = "ami-0eddbd81024d3fbdd" -> null
      - arn        
      ... (생략) ...
    }

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

 정상적으로 삭제가 완료되었다는 내용의 터미널 출력을 확인할 수 있습니다.

aws_instance.app_server: Destroying... [id=i-05fea222173075842]
aws_instance.app_server: Still destroying... [id=i-05fea222173075842, 10s elapsed]
aws_instance.app_server: Still destroying... [id=i-05fea222173075842, 20s elapsed]
aws_instance.app_server: Still destroying... [id=i-05fea222173075842, 30s elapsed]
aws_instance.app_server: Destruction complete after 40s

Destroy complete! Resources: 1 destroyed.

 웹 콘솔에서도 해당 인스턴스가 정상적으로 종료된 것을 확인할 수 있습니다.


참고자료

[1] https://www.ibm.com/kr-ko/cloud/learn/terraform 

[2] https://developer.hashicorp.com/terraform/tutorials/aws-get-started/infrastructure-as-code

댓글