blog post

Terraform 從零開始 (4) — GCP 無伺服器服務 — 使用Terraform創建Cloud Function

GCP 無伺服器服務 — 使用Terraform創建Cloud Function
GCP 無伺服器服務 — 使用Terraform創建Cloud Function

訂閱 Terraform 從零開始 — 10+實戰Lab打造GCP雲端自動化架構課程

1. 無伺服器服務 — Cloud Function的主要功能和用途

無伺服器運算(Serverless Computing)是一種雲端運算模型,可以執行程式碼,而無需直接管理伺服器或基礎架構。Google Cloud Platform(GCP)中的無伺服器服務之一就是「Cloud Functions」,以下是它的主要功能和用途:

  1. 事件驅動的計算平台:Cloud Function是一個事件驅動的計算平台,可以讓您撰寫並執行程式碼片段,而不需要管理伺服器或基礎架構。
  2. 專注於編寫程式碼:Cloud Function會自動處理程式碼的部署、維護和擴展。
  3. 作為部分應用程式邏輯:自動化任務、處理數據、作為應用程式的一部分處理應用程式邏輯。
  4. 搭配其他GCP服務:例如Pub/Sub、Cloud Storage、Cloud Firestore等。
    支援多種程式語言:例如Node.js、Python、Go等。

2. 無伺服器服務 — Cloud Function的使用情境

Google Cloud Platform 的 Cloud Function可在多種場景下使用,以下是一些常見的使用情境:

  1. 自動化任務:您可以使用Cloud Function自動化許多日常任務,例如定期備份資料、處理郵件、擷取資料等。這些任務可以通過觸發器(trigger)自動啟動,並且可以搭配其他GCP服務(例如Pub/Sub、Cloud Storage、Cloud Firestore等)實現更高級的自動化流程。
  2. 數據處理:Cloud Function可以處理大量的數據並將其轉換成所需的格式。例如,您可以使用Cloud Function來轉換CSV檔案到JSON格式,或從訂閱的消息中提取特定的資訊。
  3. 應用程式邏輯:Cloud Function可以作為應用程式的一部分,處理應用程式邏輯。例如,當使用者上傳檔案到您的應用程式時,您可以使用Cloud Function來驗證和處理上傳的檔案。

3. GCP 無伺服器服務 — 使用Terraform創建Cloud Function

在這個章節中,我們將深入探討如何使用Terraform在Google Cloud Platform上創建Cloud Function。我們將依次進行以下步驟:

  1. 使用已經好的創建hello world程式碼 (python):我們首先使用一個簡單的 “Hello World” 程式碼,以便在 Cloud Function 中執行。
  2. 允許公開的http存取,提供測試:為了能夠透過 HTTP 存取測試我們的 Cloud Function,我們需要確保它可以公開訪問。這可以通過設定 Cloud Function 的存取權限和網路配置來實現。
  3. 創建cloud function並上傳程式碼進行測試:使用 Terraform 來自動化地創建 Cloud Function,我們會創建一個GCS作為程式碼上傳與部署的遠端位置。

4. Terraform Cloud Function 連結:可以到github參考對應的Terraform程式碼。

創建hello world程式碼 (python):

首先創建 src 資料夾後,再創建main.py,並且複製對應的程式碼到main.py中,提供後續部署使用。

main.py

from flask import make_response, request

def handler(request):
    headers = {
        'Content-Type': 'text/plain'
    }
    response = make_response('Hello, World!', 200, headers)
    return response
hello world程式碼 (python)

創建terraform檔案

首先創建三個檔案,分別是 0-provider.tf, 1-variables.tf, 2-main.tf, 3-output.tf

0-provider.tf

##################################################################################
# CONFIGURATION
##################################################################################
terraform {
  required_version = ">=1.0"
  required_providers {
    google = {
      source  = "hashicorp/google"
      version = ">= 4.40.0"
    }
  }
}

provider "google" {
  project = var.GCP_PROJECT
  # region  = var.GCP_REGION
  # zone        = var.zone
}

這個檔案主要用於配置 Terraform 的提供者(provider),以確保 Terraform 可以正確地與 Google Cloud Platform(GCP)進行交互。

  • terraform :這個區塊設定了 Terraform 的版本要求,確保使用的版本符合最低要求大於4.40.0版本。同時,它也定義了所需的提供者和版本。
  • provider "google" :這個區塊指定了要使用的 GCP 提供,指定了 GCP 專案 ID(由 var.GCP_PROJECT 變數提供)。

1-variables.tf

variable "GCP_PROJECT" {
  description = "GCP Project ID"
  type        = string
  default     = "terraform101-384507"
}

variable "GCP_REGION" {
  type    = string
  default = "asia-east1"
}

variable "func_name" {
  type    = string
  default = "cloud-function-tf-ch4-5-3"
}

這個檔案用於定義 Terraform 使用的變數,以實現更高度的可配置性和重用性。

  • variable "GCP_PROJECT":這是 GCP 專案 ID 的變數,它描述了 GCP 專案的 ID。它的預設值是 “terraform101-384507″,但可以在使用時指定不同的值。
  • variable "GCP_REGION":這是定義網路服務所在位置(地區)的變數。
  • variable "func_name":這是用於定義 Google Cloud Function 名稱的變數。

2-main.tf

##################################################################################
# RESOURCE
##################################################################################
# 使用random產生亂數
resource "random_id" "bucket_prefix" {
  byte_length = 8
}

# 產生存放程式碼的GCS
resource "google_storage_bucket" "cloud_function_bucket" {
  name                        = "${var.func_name}-bucket-${random_id.bucket_prefix.hex}"
  location                    = "ASIA"
  uniform_bucket_level_access = true
}

# 將特定路徑壓縮成zip檔案
data "archive_file" "src" {
  type        = "zip"
  source_dir  = "${path.root}/src/" # Directory where your Python source code is
  output_path = "${path.root}/generated/${var.func_name}.zip"
}

# 將zip上傳到GCP上,提供cloud function部署
resource "google_storage_bucket_object" "archive" {
  name   = "${data.archive_file.src.output_md5}.zip"
  bucket = google_storage_bucket.cloud_function_bucket.name
  source = data.archive_file.src.output_path

  metadata = {
    ManagedBy = "Terraform"
  }
}

# cloud function 程式碼
resource "google_cloudfunctions_function" "hello_function" {
  name                = var.func_name
  description         = "An hello Cloud Function"
  runtime             = "python39"
  available_memory_mb = 256
  timeout             = 60

  source_archive_bucket = google_storage_bucket.cloud_function_bucket.name
  source_archive_object = google_storage_bucket_object.archive.name

  trigger_http = true
  entry_point  = "handler"

  environment_variables = {
    FOO = "bar"
  }

  labels = {
    env = "dev"
  }
  depends_on = [
    google_storage_bucket.cloud_function_bucket,
    google_storage_bucket_object.archive
  ]
}

# IAM 所有人都可以去access
resource "google_cloudfunctions_function_iam_member" "invoker" {
  project        = google_cloudfunctions_function.hello_function.project
  region         = google_cloudfunctions_function.hello_function.region
  cloud_function = google_cloudfunctions_function.hello_function.name

  role   = "roles/cloudfunctions.invoker"
  member = "allUsers"
}

這段 Terraform 程式碼的目的是使用 Terraform 工具自動化地在 Google Cloud Platform 上創建一個 Cloud Function,並將相關的資源設定和配置進行定義。:

1. random_id 資源: 這個資源使用 random_id 來產生一個隨機的 ID,用於標識後續創建的儲存桶(Bucket)。這有助於確保每次運行 Terraform 時都能創建一個新的儲存桶。

2. google_storage_bucket 資源: 這個資源用於創建 Google Cloud Storage 儲存桶,用於存放 Cloud Function 的程式碼。儲存桶的名稱是根據一些變數和隨機 ID 動態生成的。

3. data "archive_file" "src" 資源: 這個資源使用 archive_file 來將指定路徑的程式碼目錄壓縮成 ZIP 檔案。這樣的壓縮檔案將用於上傳到儲存桶,以供 Cloud Function 部署使用。

4. google_storage_bucket_object 資源: 這個資源使用剛剛壓縮的 ZIP 檔案,將它上傳到剛剛創建的 Google Cloud Storage 儲存桶。這個壓縮檔案將在 Cloud Function 的部署過程中被使用。

5. google_cloudfunctions_function 資源: 這個資源創建實際的 Cloud Function。它設定了 Cloud Function 的名稱、描述、執行環境(Python 3.9)、可用內存、超時時間、HTTP 觸發、入口函數等設定。同時,它也引用了剛剛儲存桶上傳的 ZIP 檔案作為程式碼來源。

6. google_cloudfunctions_function_iam_member 資源: 這個資源設定 Cloud Function 的 IAM(身份和存取管理)權限,使所有人(allUsers)都可以進行 HTTP 存取。這個設定允許任何人都能觸發這個 Cloud Function。

總之,這段 Terraform 程式碼結合了多個資源,從儲存桶的創建到 Cloud Function 的部署和 IAM 設定,實現了自動化地在 Google Cloud Platform 上創建和配置 Cloud Function。

3-output.tf

output "bucket_name" {
  value = google_storage_bucket.cloud_function_bucket.name
}

output "cloud_function_https_trigger_url" {
  value = google_cloudfunctions_function.hello_function.https_trigger_url
}

這部分是定義 Terraform 的輸出(Outputs),它們允許你在執行 Terraform 部署後,獲取一些有用的值,以便在後續操作中使用。

  1. output "bucket_name": 這個輸出將 google_storage_bucket.cloud_function_bucket 資源創建的儲存桶名稱作為輸出值。在執行 Terraform 部署後,你可以查看這個輸出,以獲取剛剛創建的儲存桶的名稱。
  2. output "cloud_function_https_trigger_url": 這個輸出將 google_cloudfunctions_function.hello_function 資源創建的 Cloud Function 的 HTTPS 觸發 URL 作為輸出值。當你的 Cloud Function 部署完成後,你可以使用這個輸出值來快速存取和測試 Cloud Function。

總之,這些輸出定義允許你在 Terraform 部署完成後,輕鬆地檢索一些重要的資訊,例如創建的儲存桶名稱和 Cloud Function 的 HTTPS 觸發 URL。

執行terraform部署

到專案目錄執行初始化計畫

terraform init 
# or
tf init

確認部署計畫內容

terraform plan -out plan.out
# or
tfp
觀看部署計畫 terraform plan -out plan.out

最後執行 terraform apply -auto-approve 來部署對應的資源到雲端架構上,就可以得到下列的結果。

terraform apply -auto-approve
# or 
tfdp
部署雲端架構 terraform apply -auto-approve
GCP 無伺服器服務 — Cloud Function

測試部署的 Cloud Function

創建完畢,並看到Cloud Function後,可以點選查看函數的詳細資料。

Cloud Function 總覽
Cloud Function 服務帳號

接下來可以嘗試觸發服務,點選觸發條件中的網址,就可以轉發到服務。離如下面的一長串網址,分別會是專案、地區與函數名稱組成的url。

Cloud Function 觸發條件 url
Cloud Function 回傳內容

也可以複製剛剛terraform部署後產生的ouput網址,貼到瀏覽器上也可以看到回傳的內容。

terraform部署後產生的ouput網址
Cloud Function 回傳內容

Terraform tip:可以利用下列的 Terraform tip,來增進部署效率。

  1. 打開終端機中的 .bashrc or .zshrc 檔案
  2. 在文件最下方加入下列指令
  3. 執行 source ~/.zshrc 或是 source ~/.bashrc 讓下面的 alias 快捷鍵生效
alias tf="terraform"
alias tfv="terraform validate"
alias tfdp="terraform apply -auto-approve plan.out"
alias tfd="terraform apply -auto-approve"
alias tfr="terraform destroy -auto-approve"
alias tfp="terraform plan -out plan.out"

課程連結

如果您覺得這篇文章對您有幫助,我誠摯地邀請您透過以下連結訂閱我的 Udemy 課程,進一步深入學習 Terraform 和 GCP 的知識:

訂閱 Terraform 從零開始 — 10+實戰Lab打造GCP雲端自動化架構課程

訂閱 Terraform 從零開始 — 10+實戰Lab打造GCP雲端自動化架構課程
https://devops-with-alex.com/go/terraform

相關連結

  1. Terraform-from-zero-to-hero-10-Lab-GCP-Infrastucture-as-Code — https://github.com/qwedsazxc78/Terraform-from-zero-to-hero-10-Lab-GCP-Infrastucture-as-Code
  2. Terraform-project-best-practice — https://github.com/qwedsazxc78/terraform-project-best-practice
  3. GCP 無伺服器服務 — Cloud Function

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *