將 Google Cloud 資源匯入 Terraform 狀態

Terraform 可以匯入現有基礎架構。這樣一來,您就能將透過其他方式建立的資源納入 Terraform 管理。

您可以匯入任何 Google Cloud 資源的狀態。

Terraform 支援多種資源匯入方式:

一次匯入一項資源

import 指令會採用兩個引數:資源位址和 ID。 資源位址是識別碼,指向設定中的資源執行個體。這個 ID 是用來識別要匯入的資源。 Google CloudID 格式會因資源類型而異,且已記錄供應商支援的各項資源。建議使用完整 ID,包括專案 ID (如支援)。

  • 找出要匯入的資源地址。

    resource "google_storage_bucket" "sample" {
     name          = "my-bucket"
     project       = "sample-project"
     location      = "US"
     force_destroy = true
    }
    

    以先前定義的 Cloud Storage 值區等範例資源來說,這就是 google_storage_bucket.sample

  • 如要瞭解資源 ID 格式,請參閱 google_storage_bucket 資源的供應商匯入文件。在本例中,資源 ID 的形式為 project/name,因此上述範例的資源 ID 為 sample-project/my-bucket

  • 使用資源位址和 ID 建構 import 陳述式,如下所示:

    terraform import google_storage_bucket.sample sample-project/my-bucket
    

    輸出:

    terraform import google_storage_bucket.sample sample-project/my-bucket
    google_storage_bucket.sample: Importing from ID "sample-project/my-bucket"...
    google_storage_bucket.sample: Import prepared!
    Prepared google_storage_bucket for import
    google_storage_bucket.sample: Refreshing state... [id=sample-project/my-bucket]
    Import successful!
    The resources that were imported are shown above. These resources are now in
    your Terraform state and will henceforth be managed by Terraform.
    

匯入模組中的資源

模組會在 Terraform 設定中封裝一或多個資源。由於匯入需要資源位址,因此模組中的每個資源都必須個別匯入。

  • 找出要匯入的模組資源。

    module "gcs_bucket" {
     source  = "terraform-google-modules/cloud-storage/google//modules/simple_bucket"
     version = "~> 3.4"
    
     name       = "my-bucket"
     project_id = "sample-project"
     location   = "us-east1"
    }
    

    如要找出資源位址,可以檢查模組內容。 或者,您也可以套用設定,並使用供應商顯示的錯誤。例如:

    terraform apply
    module.gcs_bucket.google_storage_bucket.bucket: Creating...
    ╷
    │ Error: googleapi: Error 409: Your previous request to create the named bucket succeeded and you already own it., conflict
    │
    │   with module.gcs_bucket.google_storage_bucket.bucket,
    

    使用上述記錄,您可以找出需要匯入為 module.gcs_bucket.google_storage_bucket.bucket 的資源位址。

  • 如要瞭解資源 ID 格式,請參閱 google_storage_bucket 資源的供應商匯入文件。在本例中,格式為 project/name。您可以從方案輸出內容中找出名稱。

    輸出:

    module.gcs_bucket.google_storage_bucket.bucket will be created
    + resource "google_storage_bucket" "bucket" {
        + name                        = "my-bucket"
        + project                     = "sample-project"
        ...
      }
    

    在上述範例中,資源 ID 為 sample-project/my-bucket

  • 使用資源位址和 ID 建構 import 陳述式,如下所示:

    terraform import module.gcs_bucket.google_storage_bucket.bucket sample-project/my-bucket
    

    輸出:

    terraform import module.gcs_bucket.google_storage_bucket.bucket sample-project/my-bucket
    module.gcs_bucket.google_storage_bucket.bucket: Importing from ID "sample-project/my-bucket"...
    module.gcs_bucket.google_storage_bucket.bucket: Import prepared!
    Prepared google_storage_bucket for import
    module.gcs_bucket.google_storage_bucket.bucket: Refreshing state... [id=sample-project/my-bucket]
    Import successful!
    The resources that were imported are shown above. These resources are now in
    your Terraform state and will henceforth be managed by Terraform.
    

使用設定導向的 import 區塊大量匯入資源

在 Terraform 1.5 版中,您可以在 Terraform 設定中新增 import 區塊。這樣一來,您就能在 plan 作業期間預覽匯入作業,並使用 apply 作業執行匯入作業。

您也可以為匯入的資源自動產生程式碼,不必手動編寫程式碼。

import 區塊會採用兩個參數:

  • id:要匯入的雲端資源供應商定義資源 ID。

    如要瞭解可接受的供應商定義資源 ID,請參閱 Hashicorp 的 Google 供應商說明文件中,資源的「匯入」部分。舉例來說,projects/{project}/global/networks/{name} 是虛擬私有雲網路的資源 ID,如google_compute_network參考頁面所示。

  • to:要建立的 Terraform 資源位址。通常為 RESOURCE TYPE.NAME

以下是虛擬私有雲網路的 import 區塊範例:

import {
  # Provider-defined resource ID of the cloud resource to be imported
  id = "projects/PROJECT_ID/global/networks/my-network"

  # Terraform resource address to be created
  to = google_compute_network.my_network
}

如果您是手動建立資源區塊,請執行 terraform plan 預覽匯入作業。

如要讓 Terraform 為您產生資源區塊,請使用 -generate-config-out 標記指定要產生設定的檔案。

例如:

 terraform plan -generate-config-out=generated_resources.tf

檢查產生的程式碼後,請執行 terraform apply 作業,將設定匯入 Terraform 狀態。

匯入大量匯出後建立的資源

大量匯出功能可讓您將資源匯出為 Terraform 設定,並匯入這些資源的 Terraform 狀態,以便在 Terraform 中管理部署作業。 Google Cloud

事前準備

  • 準備 Cloud Shell。

    啟動 Cloud Shell,並設定要為已部署資源產生 Terraform 程式碼的預設 Google Cloud 專案。

    每個專案只需要執行一次這個指令,而且可以在任何目錄中執行。

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    如果您在 Terraform 設定檔中設定明確值,環境變數就會遭到覆寫。

  • 在 Cloud Shell 中,安裝 Config Connector 的指令列介面 (CLI)。

    gcloud components install config-connector
    

    您可以使用 Config Connector 的 Terraform 大量匯出工具。 Google Cloud

    如果看到 ERROR: (gcloud.components.install) You cannot perform this action because the Google Cloud CLI component manager is disabled for this installation,請改為執行下列指令:

    sudo apt-get install google-cloud-sdk-config-connector
    
  • 啟用 Cloud Asset API。

    gcloud services enable cloudasset.googleapis.com
    

為資源產生 Terraform 程式碼

  1. 如果還沒建立目錄,請先建立要輸出專案設定的目錄。

    mkdir OUTPUT_DIRECTORY
    
  2. 執行 gcloud beta resource-config bulk-export 指令,將專案的完整設定輸出至 OUTPUT_DIRECTORY 路徑:

    gcloud beta resource-config bulk-export \
       --path=OUTPUT_DIRECTORY \
       --project=PROJECT_ID \
       --resource-format=terraform
    

從產生的程式碼建立 Terraform 模組

執行 gcloud beta resource-config terraform generate-import 指令,指向輸出目錄中的內容:

gcloud beta resource-config terraform generate-import OUTPUT_DIRECTORY

這個指令會產生 Terraform 模組和匯入指令碼:

  • gcloud-export-modules.tf 檔案。這個檔案會指向子資源中的所有模組。這個檔案的內容如下所示:

    provider "google" {
     project = "PROJECT_ID"
    }
    
    module "OUTPUT_DIRECTORY-projects-PROJECT_ID-ComputeFirewall" {
     source = "./OUTPUT_DIRECTORY/projects/PROJECT_ID/ComputeFirewall"
    }
    
    module "OUTPUT_DIRECTORY-projects-PROJECT_ID-ComputeBackendService-global" {
     source = "./OUTPUT_DIRECTORY/projects/PROJECT_ID/ComputeBackendService/global"
    }
    

    依此類推。

  • 可執行的殼層指令碼,名稱類似 terraform_import_20220331-19-12-33.sh。殼層指令碼包含 terraform import 指令清單:

    #!/bin/sh
    # Terraform Import Script generated by gcloud cli
    
    terraform import module.OUTPUT_DIRECTORY-projects-PROJECT_ID-ComputeFirewall.google_compute_firewall.allow_ssh projects/PROJECT_ID/global/firewalls/allow-ssh
    

    依此類推。

    terraform import 指令用於將 generate-import 指令建立的模組匯入 Terraform 狀態。

將模組匯入 Terraform 狀態

  1. 初始化:

    terraform init
    
  2. 執行指令碼:

    ./terraform_import_20220331-19-12-33.sh
    

    輸出:

    module.examples-projects-PROJECT_ID-ComputeInstance-us-central1-a.google_compute_instance.instance_1:
    Importing from ID
    "projects/PROJECT_ID/zones/us-central1-a/instances/instance-1"...
    module.examples-projects-PROJECT_ID-ComputeInstance-us-central1-a.google_compute_instance.instance_1:
    Import prepared!
     Prepared google_compute_instance for import
    module.examples-projects-PROJECT_ID-ComputeInstance-us-central1-a.google_compute_instance.instance_1:
    Refreshing state...
    [id=projects/PROJECT_ID/zones/us-central1-a/instances/instance-1]
    
    Import successful!
    
    The resources that were imported are shown above. These resources are now in
    your Terraform state and will henceforth be managed by Terraform.
    

後續步驟