테라폼(Terraform, https://www.terraform.io)은 클라우드(Cloud) 인프라스트럭처(Infrastructure)를 소스 코드로 관리할 수 있도록 하시코프(HashiCorp)에서 만든 도구이며, 이러한 개념을 인프라스트럭처 애즈 코드(Infrastructure as Code, IaC)라고 부른다. 테라폼이라는 단어는 지구와 비슷한 행성을 사람이 살 수 있는 환경으로 만든다는 뜻을 가지고 있는데, 하시코프 창업자가 새로운 IaC 프로젝트의 이름을 고민하던 중 인프라스트럭처를 구축한다는 점이 비슷하다고 생각해서 이름을 지었다고 한다. 1 2
보통 인프라스트럭처라고 부르는 것에는 부하 분산기(Load Balancer), 데이터베이스(Database), 방화벽(Security Firewall), 저장소(Storage), 도메인 시스템(DNS) 등이 포함된다. 서비스(Application/Service)를 구동하기 위한 기반시설 같은 것이다. IDC 또는 On-premises 환경에서는 전문가들이 직접 설치를 해주었고 고도의 기술과 많은 시간이 필요했다. 그런데 클라우드 환경에서는 이러한 인프라스트럭처들을 모두 API로 관리할 수 있게 되었고, 이 것을 고도화하여 스트립트나 코드(Script/Code)로 인프라스트럭처를 다룰 수 있도록 발전했다. 클라우드 포메이션이나 테라폼은 그렇게 탄생했다. 테라폼을 이용하면 클라우드 제공업체(Cloud Provider)가 제공하는 여러 인프라스트럭처를 편리하게 생성, 삭제, 변경할 수 있다. 3
Terraform Life-cycle
- Setup backend
- Edit terraform files
- Initialize (terraform init)
- Plan (terraform plan)
- Apply (terraform apply)
- List (terraform state list)
- Destroy (terraform destroy)
Terraform Workflow
- Edit terraform files
- Plan
- Review report from plan
- Apply (Build Infrastructure)
- Review terraform state
- If you need, repeat whole cycle from STEP 1
Example
다음은 GCP(Google Cloud Platform)에서 VPC(Virtual Private Cloud)를 만드는 예제를 보여준다. VPC 모듈(Terraform Module) 안에서 VPC와 퍼블릭,프라이빗 서브 네트워크(Public/Private Subnetwork)를 만든다. 바로 아래는 모듈을 사용하는 쪽이고 그 아래는 모듈을 정의한 부분이다.
terraform {
required_version = ">= 0.11"
}
provider "google" {
region = "us-central1"
project = "${var.your_proj}"
credentials = "${file("key.json")}"
}
module "vpc" {
source = "${var.module_url}"
vpc_name = "test_vpc_gcp"
regions = "list("us-central1", "asia-south1")"
private_subnets = "list("10.255.233.0/24", "10.255.243.0/24")"
public_subnets = "list("10.255.123.0/24", "10.255.124.0/24")"
}
VPC 모듈에서는 한 개의 VPC를 만들고 그 안에 여러 개의 서브넷을 구성하도록 설계했다. 각 서브넷은 크게 퍼블릭 프라이빗으로 나누었다. 그리고 각 서브넷은 리전(Region) 마다 한 개씩 만들도록 했다. 다시 말해서 각 리전마다 퍼블릭 서브넷 한 개 프라이빗 서브넷 한 개를 만드는 것이다. Google의 자원을 정의할 때 퍼블릭 서브넷의 개수와 리전의 개수가 같지 않으면 아무것도 만들 지 않도록 조건을 설정했다. 아래 예제에서 count 변수의 값을 계산하는 부분을 보면 자세한 조건을 알 수 있다. 다시 말해서, 입력값으로 받은 리전과 서브넷의 수가 같지 않으면 자원의 총 합은 0이 되므로 아무 서브넷도 만들지 않는다.
locals {
private_subnets_count = "${length(var.private_subnets)}"
public_subnets_count = "${length(var.public_subnets)}"
regions_count = "${length(var.regions)}"
}
resource "google_compute_network" "vpc" {
name = "${var.vpc_name}"
description = "${var.vpc_desc}"
auto_create_subnetworks = "${var.automode}"
}
resource "google_compute_subnetwork" "private" {
count = "${local.private_subnets_count != local.regions_count ? 0 : local.regions_count}"
name = "${format("%s-private-%s", var.vpc_name, element(var.regions, count.index))}"
network = "${google_compute_network.vpc.self_link}"
region = "${element(var.regions, count.index)}"
ip_cidr_range = "${element(var.private_subnets, count.index)}"
}
resource "google_compute_subnetwork" "public" {
count = "${local.public_subnets_count != local.regions_count ? 0 : local.regions_count}"
name = "${format("%s-public-%s", var.vpc_name, element(var.regions, count.index))}"
network = "${google_compute_network.vpc.self_link}"
region = "${element(var.regions, count.index)}"
ip_cidr_range = "${element(var.public_subnets, count.index)}"
}
테라폼 파일(File)을 만들었으면 그 안에서 어떤 자원을 만들 수 있는 지 먼저 점검해 볼 수 있다.
$ terraform plan
실행 계획을 확인하면 테라폼으로 만들거나 변경하거나 삭제할 자원을 볼 수 있다. 대부분은 실행계획 그대로 실제 자원을 만들거나 변경하는데, 가끔은 실패하는 경우가 있다. 실행 계획은 테라폼 파일이 동작할 상황을 가정해서 보여주는 것으로 실제 프로바이더(Provider)에 적용한 결과를 보여주지 않기 때문이다. 그래서 실행계획에서는 잘 만들어질 것 같던 자원이라도 테라폼 어플라이(Apply) 명령으로 실제 반영하려고 할 때 각 프로파이더의 제약사항에 따라 자원생성에 실패하기도 한다. 실행 계획을 확인했으면, 'terraform apply' 명령을 실행해서 설계한 자원을 만들거나 변경할 수 있다.
$ terraform apply
테라폼을 자주 사용하다보면 자연스럽게 모듈(Module)을 사용하게 된다. 위의 예제처럼 반복적으로 사용할 수 있는 부분들을 모듈로 만들어 두고 여러 곳에서 공통으로 활용하기 좋기 때문이다. 모듈은 직접 만들어서 사용해도 좋고 다른 사람이 만들어 놓은 것을 가져다 사용해도 좋다. 4
테라폼을 이용해서 자원을 관리하다보면 만들어 놓은 자원을 삭제 해야할 경우가 있다. 이 때는 'terraform destroy' 명령을 활용하면 되는데, 명령을 이용하면 같은 공간의 모든 자원을 한 번에 다 삭제할 수도 있고 특정 자원만 골라서 삭제할 수도 있다. 특히 특정 자원만 골라서 삭제하는 기능은 종종 유용하다. 모듈을 조합해서 하나의 커다란 자원을 만들었는데, 그 중 일부만 변경하거나 제거하고 싶을 경우 이 기능을 활용하면 편하다.
$ terraform destroy -target module.testlb -target module.servergroup
Enter Value: yes
module.testlb.aws_lb.lb: Destroying... (ID: arn:aws:elasticloadbalancing:us-east-1:...r/net/testlb-test-ue1/0b6655e59805dc44)
module.testlb.aws_lb.lb: Still destroying... (ID: arn:aws:elasticloadbalancing:us-east-1:...r/net/testlb-test-ue1/0b6655e59805dc44, 10s elapsed)
module.testlb.aws_lb.lb: Still destroying... (ID: arn:aws:elasticloadbalancing:us-east-1:...r/net/testlb-test-ue1/0b6655e59805dc44, 20s elapsed)
module.testlb.aws_lb.lb: Destruction complete after 22s
module.testlb.aws_security_group.lb: Destroying... (ID: sg-e5e2e391)
module.testlb.aws_security_group.lb: Destruction complete after 1s
Destroy complete! Resources: 5 destroyed.
만약 지정한 자원만 삭제하는 기능을 사용하지 않고 특정 자원만 없애고 싶다면, 테라폼 파일에서 해당 자원을 주석 처리하고 'apply' 명령을 실행하여 삭제할 수 있다. 그렇게 하면 현재 프로바이더에 만들어진 자원과 테라폼 파일에 정의한 자원목록을 비교하게 되고 테라폼 파일에 없는 자원은 삭제하기 때문이다.
- IaC(Infrastructure as Code)를 이야기한다면 대부분 테라폼을 떠올릴 정도로 대표적이다. 하지만 테라폼 이전부터 AWS(Amazon Web Services)에서는 자신들의 자원(Resources)들을 관리하기 위하여 AWS 클라우드 포메이션(CloudFormation)이라는 비슷한 서비스를 제공했다. [본문으로]
- 지형(Terrain)과 변환(Transform)이라는 단어를 이미 알고 있다면 테라폼이라는 단어가 어떤 것을 가리키는 지 더 쉽게 유추할 수 있을 것이다. [본문으로]
- 대표적으로 AWS(Amazon Web Services), GCP(Google Cloud Platform)가 있다. [본문으로]
- Jikji Code [본문으로]
'Sorry Architecture' 카테고리의 다른 글
Security as Code (0) | 2019.03.03 |
---|---|
Polymorphism (0) | 2019.02.21 |
Immutable Infrastructure (0) | 2019.02.21 |
CI/CD Pipeline (0) | 2019.02.21 |
Circuit Breaker (0) | 2019.02.21 |