將 Google Cloud 資源匯入 Terraform 狀態

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

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

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

一次匯入一項資源

import 指令會使用兩個引數:資源地址和 ID。資源地址是指向設定中資源執行個體的 ID。ID 是識別要匯入的 Google Cloud中的資源的 ID。ID 的格式會因資源類型而異,且已在說明文件中記錄供應商支援的每項資源。建議您使用完整 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 資源的供應器匯入文件說明。在本例中,其形式為 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 版中,您可以將 import 區塊新增至 Terraform 設定。這樣一來,您就能在 plan 作業期間預覽匯入作業,並使用 apply 作業執行作業。

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

import 區塊有兩個參數:

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

    如要瞭解供應商定義的資源 ID 可接受的值,請參閱 Hashicorp 的 Google 供應商說明文件中,該資源的「Import」匯入一節。舉例來說,projects/{project}/global/networks/{name} 是 VPC 網路的資源 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 狀態。

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

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

事前準備

  • 準備 Cloud Shell。

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

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

    export GOOGLE_CLOUD_PROJECT=PROJECT_ID

    如果您在 Terraform 設定檔中設定明確的值,系統會覆寫環境變數。

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

    gcloud components install config-connector
    

    設定連接器可讓您使用 Google Cloud的 Terraform 大量匯出工具。

    如果看到 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.
    

後續步驟