Terraform 프로젝트에서 다양한 환경을 배포하는 방법

作者는 Free and Open Source FundWrite for DOnations 프로그램 一部로 기부를 받을 것이라고 선택했습니다.

소개

Terraform은 프로젝트가 사IZE나 複雑도가 커지면서 점점 더 유용해지는 고급 기능을 제공합니다. 다양한 환경에서 複雑한 인프라 정의의 관리 비용을 감소시키는 것이 가능하며, 코드를 중복 최소化을 위한 구조를 설정하고, testing과 deployment을 더 쉽게 하기 위한 도구 assissted workflows를 도입할 수 있습니다.

Terraform은 하나의 state를 백エン드에 연결합니다. 이렇게 State가 어디에 보관되고 어떻게 가져와지는지 결정합니다. 모든 State는 하나의 백エン드와 결합되며, 인프라 구성과 연결됩니다. 예를 들어 local 또는 s3과 같은 certain backends는 여러 states를 가질 수 있습니다. 그 경우, state와 인프라, 백エン드에 대한 配对은 workspace를 描述합니다. Workspaces는 동일한 인프라 구성의 여러 distinct 인스턴스를 배치하는 것이 가능하며, separate backends에 저장하지 않습니다.

이 튜토리얼에서는 먼저 다른 작업 공간을 사용하여 여러 인프라 인스턴스를 배포하겠습니다. 그런 다음, 이 튜토리얼에서는 DigitalOcean Volume로서 상태를 유지하는 자원을 배포하겠습니다. 마지막으로, Terraform Registry에서 사전 제작된 모듈을 참조하여 자신의 것을 보완할 수 있습니다.

필수 조건

이 튜토리얼을 완료하려면 다음이 필요합니다:

  • DigitalOcean 개인 액세스 토큰, DigitalOcean 컨트롤 패널을 통해 생성할 수 있습니다. DigitalOcean 제품 문서의 개인 액세스 토큰 생성 방법에서 지침을 찾을 수 있습니다.
  • 로컬 머신에 설치된 Terraform과 DO 제공자로 프로젝트를 설정한 것이 필요합니다. 스텝 1스텝 2을 완료한 DigitalOcean에서 Terraform 사용 방법 튜토리얼을 따라 프로젝트 폴더를 loadbalance 대신 terraform-advanced으로 이름지어 주십시오. 스텝 2에서 pvt_key 변수와 SSH 키 자원을 포함하지 마십시오.

참고: 이 튜토리얼은 Terraform 1.0.2에서 특정으로 테스트되었습니다.

작업공간을 사용하여 다중 인프라 인스턴스 배포

작업공간이 유용한 경우는, 주요 인프라를 수정한 버전을 배포하거나 테스트하고자 하는 경우이며, 따로 프로젝트를 생성하고 인증 키를 다시 설정하지 않고서 이를 실행할 수 있습니다. 분리된 상태로 개발하고 테스트하고자 하면, 이 상태를 주요 작업공간에 통합하고, 추가적인 상태를 삭제할 수 있습니다. Terraform 프로젝트를 init 하는 것과 관련없이, 백エン드에 상관없이 Terraform은 default라는 이름의 작업공간을 생성합니다. 이 작업공간은 항상 存在하며, 삭제할 수 없습니다.

그러나, 다중 작업공간은 스테이지링과 생산 등 여러 환경을 생성하는 것에 적절하지는 않습니다. 따라서, 상태를 추적하는 것만을 하는 작업공간은 코드나 수정사항을 저장하지 않습니다.

작업 공간이 실제 코드를 추적하지 않기 때문에, 여러 작업 공간 간의 코드 분리를 버전 관리 시스템(VCS) 수준에서 관리해야 합니다. 이를 위해 그들의 인프라 변형에 매칭시켜야 합니다. 이를 어떻게 달성할 수 있는지는 VCS 도구 자체에 의존합니다; 예를 들어, Git 분기가 적절한 추상화일 수 있습니다. 여러 환경에 대한 코드 관리를 쉽게 하기 위해, 재사용 가능한 모듈로 나눌 수 있으며, 이를 통해 각 환경마다 유사한 코드를 반복하지 않도록 할 수 있습니다.

작업 공간에서 자원 배포

이제 여러 작업 공간에서 적용할 Droplet을 배포하는 프로젝트를 생성하겠습니다.

Droplet 정의를 droplets.tf라는 파일에 저장하겠습니다.

terraform-advanced 디렉토리에 있다고 가정하고, 다음 명령으로 파일을 생성하고 편집하겠습니다:

  1. nano droplets.tf

다음 줄들을 추가하십시오:

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-18-04-x64"
  name   = "web-${terraform.workspace}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

이 정의는 fra1 지역에서 Ubuntu 18.04를 실행하는 Droplet을 하나의 CPU 코어와 1 GB RAM으로 생성합니다. 그 이름은 배포된 현재 작업 공간의 이름을 포함할 것입니다. 작업이 끝나면, 파일을 저장하고 닫으십시오.

Terraform 프로젝트를 사용하여 그 동작을 실행하기 위해서는

  1. terraform apply -var "do_token=${DO_PAT}"

이 생성되어야 합니다. 실행 결과는 다음과 유사하게 보일 수 있습니다.

Output
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: # digitalocean_droplet.web이 생성되将被 + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-default" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ...

Droplet을 배포하기 전에 지정되는 default 작업공간에 대해 yes를 Enter하십시오.

Droplet의 이름은 web-default가 됩니다. 이 이유는 시작하는 작업공간의 이름이 default입니다. 작업공간 목록을 보여 이것이 유일하게 사용 가능한 것을 확인할 수 있습니다.

  1. terraform workspace list

실행 결과는 다음과 유사하게 보일 수 있습니다.

Output
* default

*(加点)는 현재 해당 작업공간을 사용하고 있음을 의미합니다.

다른 Droplet을 배포하기 위해서는 testing라고 이름지정한 새 작업공간을 생성하고 이를 사용하기 위해 workspace new를 실행하십시오.

  1. terraform workspace new testing

실행 결과는 다음과 유사하게 보일 수 있습니다.

Output
Created and switched to workspace "testing"! You're now on a new, empty workspace. Workspaces isolate their state, so if you run "terraform plan" Terraform will not see any existing state for this configuration.

Droplet의 배포를 다시 계획하기 위해서는 다음과 같이 실행합니다.

  1. terraform plan -var "do_token=${DO_PAT}"

이전과 유사한 실행 결과가 나타나ます。

Output
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: # digitalocean_droplet.web이 생성되将被 + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-testing" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } Plan: 1 to add, 0 to change, 0 to destroy. ...

Terraform이 web-testing라는 Droplet을 배포하는 것을 예정하고 이를 web-default와 다르게 명명하였음을 주의하십시오. 이 이유는 defaulttesting 작업공간은 분리된 상태로 존재하며 서로의 자원에 대한 지식이 없기 때문입니다. 그러나 같은 코드로 생성되었습니다.

현재 testing 작업공간에 있는지 확인하기 위해 workspace show를 실행하면 다음과 같은 결과가 나타납니다.

  1. terraform workspace show

실행 결과는 현재 사용하고 있는 작업공간의 이름입니다.

Output
testing

작업스 pace를 삭제하려면 먼저 모두 배포 된 자원을 파괴해야 합니다. 그러나 활성화 되어 있으면 workspace select 를 사용하여 다른 것으로 전환해야 합니다. 지금 testing 작업 스 pace는 비어 있으므로 立即可에 default 로 전환 할 수 있습니다.

  1. terraform workspace select default

Terraform의 전환을 확인하는 输出行이 보입니다.

Output
Switched to workspace "default".

그러나 이를 삭제하기 위해 workspace delete 를 실행하면 됩니다.

  1. terraform workspace delete testing

Terraform은 그 다음 삭제를 실행합니다.

Output
Deleted workspace "testing"!

또한 default 작업 스 pace에 배포 한 Droplet을 다음과 같이 삭제할 수 있습니다.

  1. terraform destroy -var "do_token=${DO_PAT}"

대기 중에 yes 를 입력하여 프로세스를 완료하십시오.

이 섹션에서는 여러 개의 Terraform 작업 스 pace에서 작업하였습니다. 다음 섹션에서는 상태를 유지하는 자원을 배포하게 됩니다.

상태를 유지하는 자원 배포

상태 less한 자원은 데이터를 보관하지 않으므로 unique하지 않은 이유로 빠르게 생성하고 替わrizability가 좋습니다. 반면에 상태 full한 자원은 유일하거나 재생하기 어렵게 되는 데이터를 포함하므로 지속적인 데이터 저장소가 필요합니다.

이러한 자원을 파괴하거나 다양한 자원에서 그들의 데이터를 사용하기 때문에 별도의 엔티티로 저장하는 것이 좋습니다. 예를 들어 DigitalOcean Volumes 과 같은 것입니다.

볼렘은 extra storage space를 제공합니다. 볼렘은 드랍렘(서버)에 附加される 수 있지만, 그들과 분리되어 있습니다. 이 단계에서, 드랍렘을 연결하기 위해 droplets.tf에 볼렘을 정의하고 연결하는 것을 배울 것입니다.

다음과 같이 编辑 할 수 있도록 열기:

  1. nano droplets.tf

다음과 같은 行을 추가하세요:

resource "digitalocean_droplet" "web" {
  image  = "ubuntu-18-04-x64"
  name   = "web-${terraform.workspace}"
  region = "fra1"
  size   = "s-1vcpu-1gb"
}

resource "digitalocean_volume" "volume" {
  region                  = "fra1"
  name                    = "new-volume"
  size                    = 10
  initial_filesystem_type = "ext4"
  description             = "New Volume for Droplet"
}

resource "digitalocean_volume_attachment" "volume_attachment" {
  droplet_id = digitalocean_droplet.web.id
  volume_id  = digitalocean_volume.volume.id
}

여기에 볼렘과 볼렘 연결을 정의하는 새로운 자원 두 개를 정의합니다. 볼렘은 10GB로 지정되며 ext4로 포맷되며 new-volume라는 이름을 가지며, 드랍렘과 같은 région에 위치합니다. 볼렘과 드랍렘이 분리되어 있으므로, 그들을 연결하기 위한 볼렘 연결 오브젝트를 정의해야 합니다. volume_attachment는 드랍렘과 볼렘 ID를 읽어 디지털 오cean 클라우드에게 볼렘을 드랍렘의 디스크 장치로 사용할 수 있게 하는 명령을 실행합니다.

다 结束后, 文件을 저장하고 닫으세요.

다음과 같은 구성을 시행하기 위해 실행하세요:

  1. terraform plan -var "do_token=${DO_PAT}"

Terraform이 계획 할 것은 다음과 같습니다:

Output
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: # digitalocean_droplet.web이(가) 생성되고 + resource "digitalocean_droplet" "web" { + backups = false + created_at = (known after apply) + disk = (known after apply) + id = (known after apply) + image = "ubuntu-18-04-x64" + ipv4_address = (known after apply) + ipv4_address_private = (known after apply) + ipv6 = false + ipv6_address = (known after apply) + ipv6_address_private = (known after apply) + locked = (known after apply) + memory = (known after apply) + monitoring = false + name = "web-default" + price_hourly = (known after apply) + price_monthly = (known after apply) + private_networking = (known after apply) + region = "fra1" + resize_disk = true + size = "s-1vcpu-1gb" + status = (known after apply) + urn = (known after apply) + vcpus = (known after apply) + volume_ids = (known after apply) + vpc_uuid = (known after apply) } # digitalocean_volume.volume가 생성되고 + resource "digitalocean_volume" "volume" { + description = "New Volume for Droplet" + droplet_ids = (known after apply) + filesystem_label = (known after apply) + filesystem_type = (known after apply) + id = (known after apply) + initial_filesystem_type = "ext4" + name = "new-volume" + region = "fra1" + size = 10 + urn = (known after apply) } # digitalocean_volume_attachment.volume_attachment가 생성되고 + resource "digitalocean_volume_attachment" "volume_attachment" { + droplet_id = (known after apply) + id = (known after apply) + volume_id = (known after apply) } Plan: 3 to add, 0 to change, 0 to destroy. ...

Terraform이 생성하고자 하는 결과는 Droplet, Volume, 및 Volume attachment로 이루어진 것입니다. 이를 통해 Volume를 Droplet과 연결시킵니다.

이제 Volume(stateful resource)를 Droplet에 연결하고 있습니다. 다음 섹션에서는 项目中에 삽입 할 수 있는 공개된, 미리 만들어진 Terraform 모듈을 살펴봅니다.

사전 제작된 모듈 참조

프로젝트에 맞춤형 모듈을 직접 만드는 것 외에도, 다른 개발자들이 공개적으로 제공하는 사전 제작된 모듈과 제공자를 사용할 수 있습니다. 이 모듈들은 Terraform Registry에서 확인할 수 있습니다.

모듈 섹션에서 사용 가능한 모듈 데이터베이스를 검색하고 제공자를 기준으로 정렬하여 필요한 기능을 가진 모듈을 찾을 수 있습니다. 모듈을 찾으면, 해당 모듈의 설명을 읽을 수 있으며, 모듈이 제공하는 입력과 출력 및 외부 모듈 및 제공자 의존성들이 나열되어 있습니다.

이제 DigitalOcean SSH 키 모듈을 프로젝트에 추가하겠습니다. 기존 정의와 별도로 코드를 저장하기 위해 ssh-key.tf라는 파일을 생성하고 편집할 수 있습니다. 다음 명령어를 실행하여 생성하고 편집하십시오:

  1. nano ssh-key.tf

다음 줄들을 추가하십시오:

module "ssh-key" {
  source         = "clouddrove/ssh-key/digitalocean"
  key_path       = "~/.ssh/id_rsa.pub"
  key_name       = "new-ssh-key"
  enable_ssh_key = true
}

이 코드는 clouddrove/droplet/digitalocean 모듈의 인스턴스를 레지스트리를 통해 정의하고 해당 모듈이 제공하는 일부 매개 변수를 설정합니다. 이 코드를 사용하여 ~/.ssh/id_rsa.pub から 公開 SSH キー를 읽어 계정에 추가하면 좋습니다.

작업을 마치고 afterward, the file should be saved and closed.

Before you plan this code, you must download the referenced module by running:

  1. terraform init

You’ll receive output similar to the following:

Output
Initializing modules... Downloading clouddrove/ssh-key/digitalocean 0.13.0 for ssh-key... - ssh-key in .terraform/modules/ssh-key Initializing the backend... Initializing provider plugins... - Reusing previous version of digitalocean/digitalocean from the dependency lock file - Using previously-installed digitalocean/digitalocean v2.10.1 Terraform has been successfully initialized! ...

You can now plan the code for the changes:

  1. terraform plan -var "do_token=${DO_PAT}"

You’ll receive output similar to this:

Output
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: ... # module.ssh-key.digitalocean_ssh_key.default[0] will be created + resource "digitalocean_ssh_key" "default" { + fingerprint = (known after apply) + id = (known after apply) + name = "devops" + public_key = "ssh-rsa ... demo@clouddrove" } Plan: 4 to add, 0 to change, 0 to destroy. ...

The output shows that you would create the SSH key resource, which means that you downloaded and invoked the module from your code.

Conclusion

Larger projects can make use of some advanced features Terraform offers to help reduce complexity and make maintenance easier. Workspaces allow you to test new additions to your code without touching the stable main deployments. You can also couple workspaces with a version control system to track code changes. Using pre-made modules can also shorten development time, but may incur additional expenses or time in the future if the module becomes obsolete.

이 튜토리얼은 Terraform으로 인fra를 관리하는 방법 시리즈의 일부입니다. 이 시리즈는 Terraform에 대한 다양한 주제를 涵蓋하며, Terraform을 처음 安装하는 것부터 複雑한 프로젝트를 관리하는 것까지입니다.

Source:
https://www.digitalocean.com/community/tutorials/how-to-deploy-multiple-environments-with-workspaces-in-your-terraform-project