✔️ Overview
Terraform은 HashiCorp에서 제공하는 코드로서의 인프라입니다. 안전하고 반복 가능한 방식으로 인프라를 구축, 변경 및 관리하기 위한 도구입니다. 운영자 및 인프라 팀은 Terraform을 사용하여 사람이 읽을 수 있고 자동화된 배포를 위한 HCL(HashiCorp Configuration Language)이라는 구성 언어로 환경을 관리할 수 있습니다.
코드로서의 인프라는 사용자 인터페이스에서 리소스를 수동으로 구성하는 대신 파일 또는 파일에서 인프라를 관리하는 프로세스입니다. 이 인스턴스의 리소스는 가상 머신, 보안 그룹, 네트워크 인터페이스 등과 같은 주어진 환경의 모든 인프라입니다. 높은 수준에서 Terraform을 사용하면 운영자가 HCL을 사용하여 원하는 리소스의 정의가 포함된 파일을 작성할 수 있습니다. 거의 모든 제공자(AWS, Google Cloud, GitHub, Docker 등)를 지원하고 적용 시 해당 리소스 생성을 자동화합니다.
배포를 위한 간단한 워크플로는 아래 단계를 밀접하게 따릅니다.
- 범위 - 지정된 프로젝트에 대해 생성해야 하는 리소스를 확인합니다.
- 작성자 - 범위 매개변수를 기반으로 HCL에서 구성 파일을 생성합니다.
- 초기화 - 구성 파일이 있는 프로젝트 디렉토리에서 terraform init를 실행합니다. 그러면 프로젝트에 대한 올바른 공급자 플러그인이 다운로드됩니다.
- 계획 및 적용 - terraform 계획을 실행하여 생성 프로세스를 확인한 다음 terraform 적용을 실행하여 실제 리소스와 구성 파일의 향후 변경 사항을 배포 환경에 실제로 존재하는 것과 비교하는 상태 파일을 생성합니다.
✔️ 실습 목표
이 실습에서는 다음 작업을 수행하는 방법을 배웁니다.
- Terraform으로 인프라 구축, 변경 및 파괴
- Terraform으로 리소스 종속성 생성
- Terraform으로 인프라 프로비저닝
✔️ Build Infrastructure
Terraform은 Cloud Shell에 사전 설치되어 제공됩니다. Terraform이 이미 설치되어 있으면 바로 뛰어들어 일부 인프라를 만들 수 있습니다.
main.tf라는 파일에 예제 구성을 생성하여 시작합니다. Terraform은 .tf 또는 .tf.json으로 끝나는 파일을 구성 파일로 인식하고 실행 시 로드합니다.
1. main.tf 파일을 만듭니다.
touch main.tf
2. Cloud Shell 툴바에서 Open Editor 버튼을 클릭합니다. (필요에 따라 편집기 열기 및 터미널 열기 아이콘을 사용하여 Cloud Shell과 코드 편집기 간에 전환하거나 새 창에서 열기 버튼을 클릭하여 편집기를 별도의 탭에 열어둘 수 있습니다.)
3. Editor에서 main.tf 파일에 다음 내용을 추가합니다. <PROJECT_ID>를 랩의 프로젝트 ID로 바꿔야 합니다.
terraform {
required_providers {
google = {
source = "hashicorp/google"
}
}
}
provider "google" {
version = "3.5.0"
project = "<PROJECT_ID>"
region = "us-central1"
zone = "us-central1-c"
}
resource "google_compute_network" "vpc_network" {
name = "terraform-network"
}
팁: Terraform 0.12에서 이 스니펫을 사용하려면 terraform {} 블록을 제거하세요.
✔️ Terraform Block
Terraform은 Terraform Registry에서 다운로드할 공급자를 알기 위해 Terraform {} 블록이 필요합니다. 위의 구성에서 google 공급자의 소스는 registry.terraform.io/hashicorp/google의 축약형인 hashicorp/google로 정의됩니다.
또한 required_providers 블록에 정의된 각 공급자에 버전을 할당할 수 있습니다. 버전 인수는 선택 사항이지만 권장됩니다. 주요 변경 사항을 포함할 수 있는 새 공급자를 다운로드하는 것을 방지하기 위해 공급자를 특정 버전 또는 버전 범위로 제한하는 데 사용됩니다. 버전이 지정되지 않은 경우 Terraform은 초기화 중에 가장 최신 공급자를 자동으로 다운로드합니다.
자세히 알아보려면 공급자 소스 문서를 참조하십시오.
✔️ Providers
공급자 블록은 명명된 공급자를 구성하는 데 사용됩니다.(이 경우 google. 공급자는 리소스 생성 및 관리를 담당합니다.) Terraform 구성이 다른 공급자의 리소스를 관리하는 경우 여러 공급자 블록이 존재할 수 있습니다.
✔️ Initialization
새 구성을 위해 실행하거나 버전 제어에서 기존 구성을 확인한 후 실행하는 첫 번째 명령은 terraform init이며, 이는 후속 명령에서 사용할 다양한 로컬 설정과 데이터를 초기화합니다.
1. main.tf 파일과 동일한 디렉토리에서 terraform init 명령을 실행하여 새 Terraform 구성을 초기화합니다.
terraform init
✔️ Creating Resources
1. terraform apply 명령을 실행하여 지금 구성을 적용합니다.
terraform apply
출력에는 "google_compute_network" "vpc_network" 리소스 옆에 +가 표시됩니다. 이는 Terraform이 이 리소스를 생성함을 의미합니다. 그 아래에는 설정할 속성이 표시됩니다. 표시된 값이 (적용 후 알려짐)이면 리소스가 생성될 때까지 값을 알 수 없음을 의미합니다.
계획이 성공적으로 생성되면 이제 Terraform이 일시 중지되고 계속 진행하기 전에 승인을 기다립니다. 계획의 내용이 올바르지 않거나 위험해 보이는 경우 인프라를 변경하지 않고 여기에서 중단하는 것이 안전합니다.
terraform 적용이 오류로 실패한 경우 오류 메시지를 읽고 발생한 오류를 수정하십시오.
2. 계획은 여기에서 허용되는 것으로 보이므로 계속 진행하려면 확인 프롬프트에 yes를 입력하십시오.
Terraform이 네트워크가 성공적으로 생성될 때까지 기다리므로 계획을 실행하는 데 몇 분이 걸립니다.
# ...
Enter a value: yes
google_compute_network.vpc_network: Creating...
google_compute_network.vpc_network: Still creating... [10s elapsed]
google_compute_network.vpc_network: Still creating... [20s elapsed]
google_compute_network.vpc_network: Still creating... [30s elapsed]
google_compute_network.vpc_network: Still creating... [40s elapsed]
google_compute_network.vpc_network: Still creating... [50s elapsed]
google_compute_network.vpc_network: Creation complete after 58s [id=terraform-network]
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
이렇게 하면 Terraform이 모두 완료됩니다! Cloud Console로 이동하여 프로비저닝한 네트워크를 볼 수 있습니다.
3. 콘솔의 탐색 메뉴에서 VPC 네트워크로 이동합니다. Terraform-network가 프로비저닝된 것을 볼 수 있습니다.
4. Cloud Shell에서 terraform show 명령어를 실행하여 현재 상태를 검사합니다.
terraform show
이 값은 이 실습의 뒷부분에서 다룰 다른 리소스 또는 출력을 구성하는 데 참조할 수 있습니다.
✔️ Change Infrastructure
이전 섹션에서는 VPC 네트워크인 Terraform을 사용하여 기본 인프라를 생성했습니다. 이 섹션에서는 구성을 수정하고 Terraform이 변경을 처리하는 방법을 확인합니다.
인프라는 지속적으로 발전하고 있으며 Terraform은 이러한 변화를 관리하고 시행하는 데 도움이 되도록 구축되었습니다. Terraform 구성을 변경하면 Terraform은 원하는 상태에 도달하는 데 필요한 것만 수정하는 실행 계획을 구축합니다.
Terraform을 사용하여 인프라를 변경하면 구성뿐만 아니라 상태도 버전 제어할 수 있으므로 시간이 지남에 따라 인프라가 어떻게 발전하는지 확인할 수 있습니다.
✔️ Adding Resources
Terraform 구성에 추가하고 Terraform apply를 실행하여 프로비저닝하여 새 리소스를 추가할 수 있습니다.
1. 편집기에서 main.tf에 컴퓨팅 인스턴스 리소스를 추가합니다.
resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "f1-micro"
boot_disk {
initialize_params {
image = "debian-cloud/debian-9"
}
}
network_interface {
network = google_compute_network.vpc_network.name
access_config {
}
}
}
이 리소스에는 몇 가지 추가 인수가 포함되어 있습니다. 이름과 머신 유형은 단순한 문자열이지만 boot_disk 및 network_interface는 더 복잡한 블록입니다. 문서에서 사용 가능한 모든 옵션을 볼 수 있습니다.
이 예에서 컴퓨팅 인스턴스는 Debian 운영 체제를 사용하고 이전에 생성한 VPC 네트워크에 연결됩니다. 이 구성이 google_compute_network.vpc_network.name을 사용하여 네트워크의 이름 속성을 참조하는 방법에 주목하세요. -- google_compute_network.vpc_network는 ID이며 네트워크를 정의하는 블록의 값과 일치하고 name은 해당 리소스의 속성입니다.
인수가 없더라도 access_config 블록이 있으면 인터넷을 통해 인스턴스에 액세스할 수 있습니다.
2. 이제 Terraform apply를 실행하여 컴퓨팅 인스턴스를 생성합니다.
terraform apply
다시 한 번 확인 메시지에 예라고 대답합니다.
이것은 매우 간단한 변경입니다. "vm_instance"라는 이름의 "google_compute_instance" 리소스를 구성에 추가하고 Terraform이 Google Cloud에서 리소스를 생성했습니다.
✔️ Changing Resources
Terraform은 리소스 생성 외에도 이러한 리소스를 변경할 수 있습니다.
1. 다음과 같이 보이도록 "vm_instance"에 태그 인수를 추가합니다.
resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "f1-micro"
tags = ["web", "dev"]
# ...
}
2. terraform apply를 다시 실행하여 인스턴스를 업데이트하십시오.
terraform apply
3. 접두사 ~는 Terraform이 리소스를 제자리에서 업데이트함을 의미합니다. 예라고 응답하여 지금 이 변경 사항을 적용할 수 있습니다. 그러면 Terraform이 인스턴스에 태그를 추가합니다.
✔️ Destructive Resources
파괴적인 변경은 공급자가 기존 리소스를 업데이트하는 대신 교체해야 하는 변경입니다. 이는 일반적으로 클라우드 공급자가 구성에 설명된 방식으로 리소스 업데이트를 지원하지 않기 때문에 발생합니다.
인스턴스의 디스크 이미지를 변경하는 것은 파괴적인 변경의 한 예입니다.
1. 구성 파일의 vm_instance 리소스 내 boot_disk 블록을 편집하고 다음과 같이 변경합니다.
boot_disk {
initialize_params {
image = "cos-cloud/cos-stable"
}
}
2. 이제 Terraform apply를 다시 실행하여 Terraform이 기존 리소스에 이 변경 사항을 적용하는 방법을 확인합니다.
terraform apply
접두사 -/+는 Terraform이 리소스를 제자리에서 업데이트하지 않고 파괴하고 다시 생성한다는 것을 의미합니다. 일부 속성은 제자리에서 업데이트할 수 있지만(~ 접두사로 표시됨) 인스턴스의 부팅 디스크 이미지를 변경하려면 다시 생성해야 합니다. Terraform과 Google Cloud 제공업체가 이러한 세부정보를 자동으로 처리하고 실행 계획을 통해 Terraform이 수행할 작업을 명확하게 알 수 있습니다.
또한 실행 계획은 디스크 이미지 변경이 인스턴스를 교체해야 하는 이유임을 보여줍니다. 이 정보를 사용하여 일부 상황에서 허용되지 않는 업데이트를 삭제/생성하지 않도록 변경 사항을 조정할 수 있습니다.
3. 다시 한 번, Terraform은 계속하기 전에 실행 계획의 승인을 요청합니다. 계획된 단계를 실행하려면 yes로 답하세요.
실행 계획에서 알 수 있듯이 Terraform은 먼저 기존 인스턴스를 파괴한 다음 그 자리에 새 인스턴스를 생성했습니다. terraform show를 다시 사용하여 이 인스턴스와 연결된 새 값을 볼 수 있습니다.
✔️ Destory Infrastructure
인프라를 구축하고 변경하는 방법을 살펴보았습니다. 여러 리소스를 만들고 리소스 종속성을 표시하기 전에 Terraform 관리 인프라를 완전히 파괴하는 방법을 볼 수 있습니다.
인프라 파괴는 프로덕션 환경에서 드문 경우입니다. 그러나 Terraform을 사용하여 개발, 테스트 및 스테이징과 같은 여러 환경을 가동하는 경우에는 파괴가 유용한 작업인 경우가 많습니다.
리소스는 terraform apply와 유사하지만 구성에서 모든 리소스가 제거된 것처럼 작동하는 terraform destroy 명령을 사용하여 삭제할 수 있습니다.
1. Terraform 파괴 명령을 시도하십시오. 이 계획을 실행하고 인프라를 파괴하려면 예라고 대답하십시오.
terraform destroy
- 접두사는 인스턴스와 네트워크가 파괴될 것임을 나타냅니다. 적용과 마찬가지로 Terraform은 실행 계획을 표시하고 변경하기 전에 승인을 기다립니다.
Terraform 적용과 마찬가지로 Terraform은 파괴되어야 하는 순서를 결정합니다. 리소스가 아직 남아 있는 경우 GCP는 VPC 네트워크 삭제를 허용하지 않으므로 Terraform은 네트워크를 파괴하기 전에 인스턴스가 파괴될 때까지 기다립니다. 작업을 수행할 때 Terraform은 올바른 작업 순서를 결정하기 위해 종속성 그래프를 생성합니다. 여러 리소스가 있는 더 복잡한 경우 Terraform은 안전한 경우 병렬로 작업을 수행합니다.
✔️ Create Resource Dependencies
이 섹션에서는 리소스 종속성과 리소스 매개변수를 사용하여 한 리소스에 대한 정보를 다른 리소스와 공유하는 방법에 대해 자세히 알아봅니다.
실제 인프라에는 다양한 리소스와 리소스 유형이 있습니다. Terraform 구성에는 여러 리소스, 여러 리소스 유형이 포함될 수 있으며 이러한 유형은 여러 공급자에 걸쳐 있을 수도 있습니다.
이 섹션에서는 여러 리소스를 구성하는 방법과 리소스 속성을 사용하여 다른 리소스를 구성하는 방법에 대한 기본 예를 보여줍니다.
1. 네트워크와 인스턴스를 다시 만드십시오. 프롬프트에 yes로 응답하면 리소스가 생성됩니다.
terraform apply
✔️ Assigning a Static IP Address
1. 이제 main.tf의 VM 인스턴스에 고정 IP를 할당하여 구성에 추가합니다.
resource "google_compute_address" "vm_static_ip" {
name = "terraform-static-ip"
}
이것은 'google_compute_address' 리소스 유형을 생성하는 경우를 제외하고 VM 인스턴스 리소스를 추가하는 이전 예와 비슷해야 합니다. 이 리소스 유형은 예약된 IP 주소를 프로젝트에 할당합니다.
2. 다음으로 Terraform 계획을 실행합니다.
terraform plan
Terraform 계획으로 생성되는 내용을 볼 수 있습니다.
$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.
google_compute_network.vpc_network: Refreshing state... [id=terraform-network]
google_compute_instance.vm_instance: Refreshing state... [id=terraform-instance]
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
+ create
Terraform will perform the following actions:
# google_compute_address.vm_static_ip will be created
+ resource "google_compute_address" "vm_static_ip" {
+ address = (known after apply)
+ address_type = "EXTERNAL"
+ creation_timestamp = (known after apply)
+ id = (known after apply)
+ name = "terraform-static-ip"
+ network_tier = (known after apply)
+ project = (known after apply)
+ region = (known after apply)
+ self_link = (known after apply)
+ subnetwork = (known after apply)
+ users = (known after apply)
}
Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
terraform apply와 달리 plan 명령은 변경 사항만 표시하고 실제로 변경 사항을 직접 적용하지 않습니다. 지금까지 변경한 사항은 고정 IP를 추가하는 것뿐입니다. 다음으로 인스턴스에 IP 주소를 연결해야 합니다.
3. 다음과 같이 인스턴스의 network_interface 구성을 업데이트합니다.
network_interface {
network = google_compute_network.vpc_network.self_link
access_config {
nat_ip = google_compute_address.vm_static_ip.address
}
}
access_config 블록에는 몇 가지 선택적 인수가 있으며 이 경우 nat_ip를 고정 IP 주소로 설정합니다. Terraform이 이 구성을 읽을 때 다음을 수행합니다.
- vm_instance 전에 vm_static_ip가 생성되었는지 확인합니다.
- 상태에서 vm_static_ip의 속성을 저장합니다.
- nat_ip를 vm_static_ip.address 속성 값으로 설정합니다.
4. Terraform 계획을 다시 실행하지만 이번에는 계획을 저장합니다.
terraform plan -out static_ip
이 방법으로 계획을 저장하면 나중에 정확히 동일한 계획을 적용할 수 있습니다. 계획에 의해 생성된 파일을 적용하려고 하면 Terraform은 먼저 계획을 적용하기 전에 똑같은 변경 사항이 적용되는지 확인합니다.
이 경우 Terraform이 새 google_compute_address를 만들고 이를 사용하도록 기존 VM을 업데이트하는 것을 볼 수 있습니다.
5. Terraform apply "static_ip"를 실행하여 Terraform이 이 변경 사항을 적용할 계획을 확인합니다.
terraform apply "static_ip"
위와 같이 Terraform은 VM 인스턴스를 수정하기 전에 고정 IP를 생성했습니다. IP 주소를 인스턴스의 네트워크 인터페이스 구성에 전달하는 보간 표현식으로 인해 Terraform은 종속성을 유추할 수 있으며 인스턴스를 업데이트하기 전에 고정 IP를 생성해야 한다는 것을 알고 있습니다.
student_03_014d41972468@cloudshell:~ (qwiklabs-gcp-02-2876cb24e469)$ terraform plan -out static_ip
google_compute_network.vpc_network: Refreshing state... [id=projects/qwiklabs-gcp-02-2876cb24e469/global/networks/terraform-network]
google_compute_instance.vm_instance: Refreshing state... [id=projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance]
Note: Objects have changed outside of Terraform
Terraform detected the following changes made outside of Terraform since the last "terraform apply":
# google_compute_instance.vm_instance has changed
~ resource "google_compute_instance" "vm_instance" {
id = "projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance"
+ labels = {}
+ metadata = {}
name = "terraform-instance"
tags = [
"dev",
"web",
]
# (13 unchanged attributes hidden)
# (4 unchanged blocks hidden)
}
Unless you have made equivalent changes to your configuration, or ignored the relevant attributes using ignore_changes, the following plan
may include actions to undo or respond to these changes.
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
+ create
~ update in-place
Terraform will perform the following actions:
# google_compute_address.vm_static_ip will be created
+ resource "google_compute_address" "vm_static_ip" {
+ address = (known after apply)
+ address_type = "EXTERNAL"
+ creation_timestamp = (known after apply)
+ id = (known after apply)
+ name = "terraform-static-ip"
+ network_tier = (known after apply)
+ project = (known after apply)
+ purpose = (known after apply)
+ region = (known after apply)
+ self_link = (known after apply)
+ subnetwork = (known after apply)
+ users = (known after apply)
}
# google_compute_instance.vm_instance will be updated in-place
~ resource "google_compute_instance" "vm_instance" {
id = "projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance"
name = "terraform-instance"
tags = [
"dev",
"web",
]
# (15 unchanged attributes hidden)
~ network_interface {
name = "nic0"
# (4 unchanged attributes hidden)
~ access_config {
~ nat_ip = "35.202.94.255" -> (known after apply)
# (1 unchanged attribute hidden)
}
}
# (3 unchanged blocks hidden)
}
Plan: 1 to add, 1 to change, 0 to destroy.
╷
│ Warning: Version constraints inside provider configuration blocks are deprecated
│
│ on main.tf line 9, in provider "google":
│ 9: version = "3.5.0"
│
│ Terraform 0.13 and earlier allowed provider version constraints inside the provider configuration block, but that is now deprecated and
│ will be removed in a future version of Terraform. To silence this warning, move the provider version constraint into the required_providers
│ block.
╵
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Saved the plan to: static_ip
To perform exactly these actions, run the following command to apply:
terraform apply "static_ip"
student_03_014d41972468@cloudshell:~ (qwiklabs-gcp-02-2876cb24e469)$ terraform apply "static_ip"
google_compute_address.vm_static_ip: Creating...
google_compute_address.vm_static_ip: Creation complete after 3s [id=projects/qwiklabs-gcp-02-2876cb24e469/regions/us-central1/addresses/terraform-static-ip]
google_compute_instance.vm_instance: Modifying... [id=projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance]
google_compute_instance.vm_instance: Still modifying... [id=projects/qwiklabs-gcp-02-2876cb24e469/z...entral1-c/instances/terraform-instance, 10s elapsed]
google_compute_instance.vm_instance: Still modifying... [id=projects/qwiklabs-gcp-02-2876cb24e469/z...entral1-c/instances/terraform-instance, 20s elapsed]
google_compute_instance.vm_instance: Modifications complete after 29s [id=projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance]
╷
│ Warning: Version constraints inside provider configuration blocks are deprecated
│
│ on main.tf line 9, in provider "google":
│ 9: version = "3.5.0"
│
│ Terraform 0.13 and earlier allowed provider version constraints inside the provider configuration block, but that is now deprecated and
│ will be removed in a future version of Terraform. To silence this warning, move the provider version constraint into the required_providers
│ block.
╵
Apply complete! Resources: 1 added, 1 changed, 0 destroyed.
✔️ Implicit and Explicit Dependencies
보간 표현식에 사용된 리소스 속성을 연구함으로써 Terraform은 한 리소스가 다른 리소스에 종속될 때 자동으로 추론할 수 있습니다. 위의 예에서 google_compute_address.vm_static_ip.address에 대한 참조는 vm_static_ip라는 google_compute_address에 대한 암시적 종속성을 만듭니다.
Terraform은 이 종속성 정보를 사용하여 다른 리소스를 만들고 업데이트할 올바른 순서를 결정합니다. 위의 예에서 Terraform은 vm_instance가 이를 사용하도록 업데이트되기 전에 vm_static_ip가 생성되어야 한다는 것을 알고 있습니다.
보간 표현식을 통한 암시적 종속성은 이러한 관계에 대해 Terraform에 알리는 기본 방법이며 가능한 한 항상 사용해야 합니다.
때로는 Terraform에 표시되지 않는 리소스 간에 종속성이 있습니다. Depends_on 인수는 모든 리소스에 추가할 수 있으며 명시적 종속성을 생성할 리소스 목록을 허용합니다.
예를 들어, 인스턴스에서 실행할 애플리케이션은 특정 Cloud Storage 버킷을 사용할 것으로 예상하지만 해당 종속성은 애플리케이션 코드 내부에 구성되어 있으므로 Terraform에 표시되지 않습니다. 그 경우, 의존성을 명시적으로 선언하기 위해 extends_on을 사용할 수 있습니다.
1. 다음을 main.tf에 추가하여 Cloud Storage 버킷과 버킷에 대한 명시적 종속성이 있는 인스턴스를 추가합니다.
# New resource for the storage bucket our application will use.
resource "google_storage_bucket" "example_bucket" {
name = "<UNIQUE-BUCKET-NAME>"
location = "US"
website {
main_page_suffix = "index.html"
not_found_page = "404.html"
}
}
# Create a new instance that uses the bucket
resource "google_compute_instance" "another_instance" {
# Tells Terraform that this VM instance must be created only after the
# storage bucket has been created.
depends_on = [google_storage_bucket.example_bucket]
name = "terraform-instance-2"
machine_type = "f1-micro"
boot_disk {
initialize_params {
image = "cos-cloud/cos-stable"
}
}
network_interface {
network = google_compute_network.vpc_network.self_link
access_config {
}
}
}
저장소 버킷은 전역적으로 고유해야 합니다. 이 때문에 UNIQUE-BUCKET-NAME을 고유하고 유효한 버킷 이름으로 바꿔야 합니다. 이름과 날짜를 사용하면 일반적으로 고유한 버킷 이름을 추측할 수 있습니다.
구성에서 이러한 리소스가 어디로 가야 하는지 궁금할 수 있습니다. Terraform 구성 파일에서 리소스가 정의되는 순서는 Terraform이 변경 사항을 적용하는 방식에 영향을 미치지 않습니다. 귀하와 귀하의 팀에 가장 적합한 방식으로 구성 파일을 구성하십시오.
2. 이제 terraform plan을 실행하고 terraform apply를 실행하여 이러한 변경 사항이 실제로 적용되는지 확인합니다.
terraform plan
terraform apply
3. 계속 진행하기 전에 구성에서 이러한 새 리소스를 제거하고 terraform apply를 다시 한 번 실행하여 제거하십시오. 시작 안내서에서 더 이상 버킷이나 두 번째 인스턴스를 사용하지 않습니다.
✔️ Provision Infrastructure
이 시점에서 시작한 컴퓨팅 인스턴스는 제공된 Google 이미지를 기반으로 하지만 추가 소프트웨어가 설치되거나 구성이 적용되지 않았습니다.
GCP를 사용하면 고객이 자신의 커스텀 운영체제 이미지를 관리할 수 있습니다. 이것은 Terraform으로 프로비저닝하는 인스턴스가 필요에 따라 사전 구성되도록 하는 좋은 방법이 될 수 있습니다. Packer는 이를 위한 완벽한 도구이며 Google Cloud용 빌더를 포함합니다.
Terraform은 프로비저닝 도구를 사용하여 파일을 업로드하고, 셸 스크립트를 실행하거나, 구성 관리 도구와 같은 다른 소프트웨어를 설치 및 트리거합니다.
✔️ Defining a Provisioner
1. 프로비저닝 도구를 정의하려면 구성에서 첫 번째 vm_instance를 정의하는 리소스 블록을 다음과 같이 수정합니다.
resource "google_compute_instance" "vm_instance" {
name = "terraform-instance"
machine_type = "f1-micro"
tags = ["web", "dev"]
provisioner "local-exec" {
command = "echo ${google_compute_instance.vm_instance.name}: ${google_compute_instance.vm_instance.network_interface[0].access_config[0].nat_ip} >> ip_address.txt"
}
# ...
}
이렇게 하면 리소스 블록 내에 제공자 블록이 추가됩니다. 여러 프로비저닝 단계를 정의하기 위해 여러 프로비저닝 블록을 추가할 수 있습니다. Terraform은 많은 프로비저닝 도구를 지원하지만 이 예에서는 local-exec 프로비저닝 도구를 사용하고 있습니다.
local-exec 프로비저닝 도구는 VM 인스턴스 자체가 아니라 Terraform을 실행하는 시스템에서 로컬로 명령을 실행합니다. 이 프로비저닝 도구를 다른 프로비저닝 도구와 비교하여 사용 중이므로 지금 연결 정보를 지정하는 것에 대해 걱정할 필요가 없습니다.
이것은 또한 이전에 본 것보다 더 복잡한 문자열 보간 예를 보여줍니다. 각 VM 인스턴스에는 여러 네트워크 인터페이스가 있을 수 있으므로 대부분의 프로그래밍 언어와 마찬가지로 network_interface[0]가 있는 첫 번째 인스턴스를 참조하고 0부터 시작합니다. 각 네트워크 인터페이스에는 여러 access_config 블록도 있을 수 있으므로 다시 한 번 첫 번째 블록을 지정합니다.
2. 테라폼 적용을 실행합니다. 이 시점에서 출력이 처음에는 혼란스러울 수 있습니다.
terraform apply
Terraform은 할 일을 찾지 못했습니다. 확인하면 로컬 컴퓨터에 ip_address.txt 파일이 없음을 알 수 있습니다.
Terraform은 프로비저닝 도구를 다른 인수와 다르게 취급합니다. 프로비저닝 도구는 리소스가 생성될 때만 실행되지만 프로비저닝 도구를 추가해도 해당 리소스가 강제로 삭제되고 다시 생성되지는 않습니다.
3. Terraform taint를 사용하여 Terraform에 인스턴스를 다시 생성하도록 지시합니다.
terraform taint google_compute_instance.vm_instance
오염된 자원은 다음 적용 시 파괴되고 재생성됩니다.
4. 지금 Terraform 적용을 실행하십시오.
terraform apply
5. ip_address.txt 파일의 내용을 보고 모든 것이 제대로 작동하는지 확인하십시오.
귀하가 요청한 대로 IP 주소가 포함되어 있습니다.
student_03_014d41972468@cloudshell:~ (qwiklabs-gcp-02-2876cb24e469)$ terraform apply
google_compute_address.vm_static_ip: Refreshing state... [id=projects/qwiklabs-gcp-02-2876cb24e469/regions/us-central1/addresses/terraform-static-ip]
google_compute_network.vpc_network: Refreshing state... [id=projects/qwiklabs-gcp-02-2876cb24e469/global/networks/terraform-network]
google_storage_bucket.example_bucket: Refreshing state... [id=20220327ssh]
google_compute_instance.another_instance: Refreshing state... [id=projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance-2]
google_compute_instance.vm_instance: Refreshing state... [id=projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance]
Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following
symbols:
-/+ destroy and then create replacement
Terraform will perform the following actions:
# google_compute_instance.vm_instance is tainted, so must be replaced
-/+ resource "google_compute_instance" "vm_instance" {
~ cpu_platform = "Intel Haswell" -> (known after apply)
- enable_display = false -> null
~ guest_accelerator = [] -> (known after apply)
~ id = "projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance" -> (known after apply)
~ instance_id = "3394095559486576272" -> (known after apply)
~ label_fingerprint = "42WmSpB8rSM=" -> (known after apply)
- labels = {} -> null
- metadata = {} -> null
~ metadata_fingerprint = "uYMRtpe5CrQ=" -> (known after apply)
+ min_cpu_platform = (known after apply)
name = "terraform-instance"
~ project = "qwiklabs-gcp-02-2876cb24e469" -> (known after apply)
~ self_link = "https://www.googleapis.com/compute/v1/projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance" -> (known after apply)
tags = [
"dev",
"web",
]
~ tags_fingerprint = "XaeQnaHMn9Y=" -> (known after apply)
~ zone = "us-central1-c" -> (known after apply)
# (3 unchanged attributes hidden)
~ boot_disk {
~ device_name = "persistent-disk-0" -> (known after apply)
+ disk_encryption_key_sha256 = (known after apply)
+ kms_key_self_link = (known after apply)
~ source = "https://www.googleapis.com/compute/v1/projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/disks/terraform-instance" -> (known after apply)
# (2 unchanged attributes hidden)
~ initialize_params {
~ image = "https://www.googleapis.com/compute/v1/projects/cos-cloud/global/images/cos-stable-93-16623-102-34" -> "cos-cloud/cos-stable"
~ labels = {} -> (known after apply)
~ size = 10 -> (known after apply)
~ type = "pd-standard" -> (known after apply)
}
}
~ network_interface {
~ name = "nic0" -> (known after apply)
~ network_ip = "10.128.0.2" -> (known after apply)
~ subnetwork = "https://www.googleapis.com/compute/v1/projects/qwiklabs-gcp-02-2876cb24e469/regions/us-central1/subnetworks/terraform-network" -> (known after apply)
~ subnetwork_project = "qwiklabs-gcp-02-2876cb24e469" -> (known after apply)
# (1 unchanged attribute hidden)
~ access_config {
~ network_tier = "PREMIUM" -> (known after apply)
# (1 unchanged attribute hidden)
}
}
~ scheduling {
~ automatic_restart = true -> (known after apply)
~ on_host_maintenance = "MIGRATE" -> (known after apply)
~ preemptible = false -> (known after apply)
+ node_affinities {
+ key = (known after apply)
+ operator = (known after apply)
+ values = (known after apply)
}
}
- shielded_instance_config {
- enable_integrity_monitoring = true -> null
- enable_secure_boot = false -> null
- enable_vtpm = true -> null
}
}
Plan: 1 to add, 0 to change, 1 to destroy.
╷
│ Warning: Version constraints inside provider configuration blocks are deprecated
│
│ on main.tf line 9, in provider "google":
│ 9: version = "3.5.0"
│
│ Terraform 0.13 and earlier allowed provider version constraints inside the provider configuration block, but that is now
│ deprecated and will be removed in a future version of Terraform. To silence this warning, move the provider version constraint
│ into the required_providers block.
╵
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
google_compute_instance.vm_instance: Destroying... [id=projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance]
google_compute_instance.vm_instance: Still destroying... [id=projects/qwiklabs-gcp-02-2876cb24e469/z...entral1-c/instances/terraform-instance, 10s elapsed]
google_compute_instance.vm_instance: Still destroying... [id=projects/qwiklabs-gcp-02-2876cb24e469/z...entral1-c/instances/terraform-instance, 20s elapsed]
google_compute_instance.vm_instance: Destruction complete after 27s
google_compute_instance.vm_instance: Creating...
google_compute_instance.vm_instance: Still creating... [10s elapsed]
google_compute_instance.vm_instance: Provisioning with 'local-exec'...
google_compute_instance.vm_instance (local-exec): Executing: ["/bin/sh" "-c" "echo terraform-instance:34.133.105.145 >> ip_address.txt"]
google_compute_instance.vm_instance: Creation complete after 10s [id=projects/qwiklabs-gcp-02-2876cb24e469/zones/us-central1-c/instances/terraform-instance]
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
✔️ Failed Provisioners and Tainted Resources
리소스가 성공적으로 생성되었지만 프로비저닝 단계에 실패하면 Terraform은 오류를 발생시키고 리소스를 오염된 것으로 표시합니다. 오염된 리소스가 여전히 존재하지만 프로비저닝에 실패했기 때문에 사용하기에 안전한 것으로 간주되어서는 안 됩니다.
다음 실행 계획을 생성할 때 Terraform은 오염된 리소스를 모두 제거하고 새 리소스를 생성하여 생성 후 다시 프로비저닝을 시도합니다.
✔️ Destroy Provisioners
제거 작업 중에만 실행되는 제공자를 정의할 수도 있습니다. 시스템 정리, 데이터 추출 등에 유용합니다.
많은 리소스의 경우 가능하면 기본 제공 정리 메커니즘(예: init 스크립트)을 사용하는 것이 좋지만 필요한 경우 프로비저닝 도구를 사용할 수 있습니다.
이 실습에서는 파괴 프로비저닝 도구의 예를 보여주지 않습니다. 파괴 프로비져너를 사용해야 하는 경우 프로비져너 설명서를 참조하십시오.
이 실습에서는 Terraform을 사용하여 인프라를 구축, 변경 및 파괴하는 방법을 배웠습니다.
그런 다음 리소스 종속성을 생성하고 Terraform 구성 파일로 기본 인프라를 프로비저닝했습니다.
'Study > Study Jam' 카테고리의 다른 글
[Study Jam] Multiple VPC Networks - 1 (0) | 2022.03.29 |
---|---|
[Study Jam] Interact with Terraform Modules (0) | 2022.03.27 |
[Study Jam] Terraform Fundamentals (0) | 2022.03.27 |
[Study Jam] Continuous Delivery with Jenkins in Kubernetes Engine - 2 (0) | 2022.03.25 |
[Study Jam] Continuous Delivery with Jenkins in Kubernetes Engine - 1 (0) | 2022.03.25 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!