《Terraform 101 從入門到實踐》 Terraform在公有云GCP上的應用

南瓜慢說發表於2023-02-19
《Terraform 101 從入門到實踐》這本小冊在南瓜慢說官方網站GitHub兩個地方同步更新,書中的示例程式碼也是放在GitHub上,方便大家參考檢視。

Terraform支援的公有云有很多,如AWS、Azure、Google、Alibaba等。將Terraform應用於公有云,才最能發揮其強大的功能。

初始化GCP專案

建立一個新專案

首先我們需要初始化一個GCP專案。GCP給開發者提供了免費試用的服務,我們可以在不花錢的情況下學習GCP的功能。

要使用GCP,我們需要建立一個專案,它所有的資源都是在專案之下管理的:

建立Service Account

在實際開發中,我們不能使用自己的賬號在做操作,最好的方式是建立一個服務賬號(Service Account),這應該也是所有云平臺都推薦的方式。建立位置如下:

輸入賬號名字:

選擇角色,為了方便,我直接選擇Owner,會擁有所有許可權,但實際應用肯定不能這樣,要做好隔離:

建立金鑰檔案

對於Service Account,不是透過使用者名稱密碼來授權的,而是透過金鑰檔案,建立如下:

選擇新建一個金鑰,並格式為json。建立後,會自動下載key檔案。

設定gcloud SDK

Key檔案拿到後,我們可以設定環境變數:GOOGLE_APPLICATION_CREDENTIALS

$ export GOOGLE_APPLICATION_CREDENTIALS=/Users/larry/Software/google-cloud-sdk/pkslow-admin-for-all.json

啟用Service Account:

$ gcloud auth activate-service-account admin-for-all@pkslow.iam.gserviceaccount.com --key-file=${GOOGLE_APPLICATION_CREDENTIALS}

設定SDK的專案ID:

$ gcloud config set project pkslow

檢查一下設定是否正確:

$ gcloud auth list
               Credentialed Accounts
ACTIVE  ACCOUNT
*       admin-for-all@pkslow.iam.gserviceaccount.com

To set the active account, run:
    $ gcloud config set account `ACCOUNT`


$ gcloud config list
[core]
account = admin-for-all@pkslow.iam.gserviceaccount.com
disable_usage_reporting = True
project = pkslow

Your active configuration is: [default]

使用gcloud建立Pub/Sub

SDK設定好後,就可以使用了,我們使用它來建立Pub/Sub試試。建立主題和訂閱:

$ gcloud pubsub topics create pkslow-test
Created topic [projects/pkslow/topics/pkslow-test].

$ gcloud pubsub subscriptions create pkslow-sub --topic=pkslow-test
Created subscription [projects/pkslow/subscriptions/pkslow-sub].

檢查是否建立成功:

$ gcloud pubsub topics list
---
name: projects/pkslow/topics/pkslow-test


$ gcloud pubsub subscriptions list
---
ackDeadlineSeconds: 10
expirationPolicy:
  ttl: 2678400s
messageRetentionDuration: 604800s
name: projects/pkslow/subscriptions/pkslow-sub
pushConfig: {}
topic: projects/pkslow/topics/pkslow-test

在瀏覽器檢視,發現已經成功建立了:


Terraform建立Pub/Sub

下載Terraform外掛

我們需要安裝GCP的Terraform外掛來管理GCP資源:

# 設定外掛目錄
$ export TERRAFORM_PLUGIN=/Users/larry/Software/terraform/plugins
# 建立目錄
$ mkdir -p ${TERRAFORM_PLUGIN}/registry.terraform.io/hashicorp/google/4.0.0/darwin_amd64
$ cd ${TERRAFORM_PLUGIN}/registry.terraform.io/hashicorp/google/4.0.0/darwin_amd64
# 下載
$ wget https://releases.hashicorp.com/terraform-provider-google/4.0.0/terraform-provider-google_4.0.0_darwin_amd64.zip
# 解壓
$ unzip terraform-provider-google_4.0.0_darwin_amd64.zip

準備Terraform程式碼

需要提供Terraform程式碼理管理Pub/Sub,更多細節請參考: Terrafrom GCP.

版本檔案version.tf:

terraform {
  required_version = "= 1.0.11"
  required_providers {

    google = {
      source  = "hashicorp/google"
      version = "= 4.0.0"
    }
  }
}

主檔案main.tf:

provider "google" {
  project     = "pkslow"
}

resource "google_pubsub_topic" "pkslow-poc" {
  name = "pkslow-poc"
}

resource "google_pubsub_subscription" "pkslow-poc" {
  name  = "pkslow-poc"
  topic = google_pubsub_topic.pkslow-poc.name

  labels = {
    foo = "bar"
  }

  # 20 minutes
  message_retention_duration = "1200s"
  retain_acked_messages      = true

  ack_deadline_seconds = 20

  expiration_policy {
    ttl = "300000.5s"
  }
  retry_policy {
    minimum_backoff = "10s"
  }

  enable_message_ordering    = true
}

初始化和變更

指定外掛目錄初始化:

$ terraform init -plugin-dir=${TERRAFORM_PLUGIN}

使變更生效,就會在GCP上建立對應的資源:

$ terraform apply -auto-approve

如果沒有發生錯誤,則意味著建立成功,我們檢查一下:

$ gcloud pubsub topics list
---
name: projects/pkslow/topics/pkslow-poc

$ gcloud pubsub subscriptions list
---
ackDeadlineSeconds: 20
enableMessageOrdering: true
expirationPolicy:
  ttl: 300000.500s
labels:
  foo: bar
messageRetentionDuration: 1200s
name: projects/pkslow/subscriptions/pkslow-poc
pushConfig: {}
retainAckedMessages: true
retryPolicy:
  maximumBackoff: 600s
  minimumBackoff: 10s
topic: projects/pkslow/topics/pkslow-poc

注意:我們並沒有提供任何密碼或金鑰,那Terraform怎麼可以直接操作我的GCP資源呢?因為它會根據環境變數GOOGLE_APPLICATION_CREDENTIALS來獲取。

傳送和接收訊息

我們透過gcloud來傳送訊息到Pub/Sub上:

$ gcloud pubsub topics publish pkslow-poc --message="www.pkslow.com"
messageIds:
- '3491736520339885'

$ gcloud pubsub topics publish pkslow-poc --message="Larry Deng"
messageIds:
- '3491738650256958'

$ gcloud pubsub topics publish pkslow-poc --message="Hi, pkslower"
messageIds:
- '3491739306095970'

從Pub/Sub拉取訊息:

$ gcloud pubsub subscriptions pull pkslow-poc --auto-ack

我們還能在GCP介面上監控對應的佇列,十分方便:


透過Google Cloud Storage(GCS)管理Terraform的狀態State

管理Terraform狀態檔案的最佳方式是透過雲端的統一的儲存,如谷歌雲就用GCS。

首先要建立一個Bucket:

$ gsutil mb -p pkslow -l us-west1 -b on gs://pkslow-terraform
Creating gs://pkslow-terraform/...

$ gsutil ls gs://
gs://pkslow-terraform/

然後在Terraform檔案中配置對應的資訊:

terraform {
  backend "gcs" {
    bucket  = "pkslow-terraform"
    prefix  = "state/gcp/pubsub"
  }
}

初始化後,就會在Bucket上建立對應的目錄:

$ terraform init -plugin-dir=${TERRAFORM_PLUGIN}

變更生效:

$ terraform apply -auto-approve

我們在瀏覽器檢視一下,發現已經成功狀態了對應的狀態檔案:

透過遠端的雲端,不僅可以存入狀態檔案,也可以從狀態檔案讀取資料,如一些輸出變數。比如模組A建立了一個VM,而我們可能透過這種方式獲取它的IP,以便在其它模組使用。大致的配置如下:

data "terraform_remote_state" "foo" {
  backend = "gcs"
  config = {
    bucket  = "terraform-state"
    prefix  = "prod"
  }
}

resource "template_file" "bar" {
  template = "${greeting}"

  vars {
    greeting = "${data.terraform_remote_state.foo.greeting}"
  }
}

相關文章