將 Terraform 資源從 organizationSecurityPolicies 遷移至 firewallPolicies

Google 建議使用 firewallPolicies 方法設定 Cloud Next Generation Firewall 政策。本文將引導您遷移 Terraform 設定,改用 firewallPolicies 方法,而非 organizationSecurityPolicies 方法。

firewallPolicies 方法提供機構管理選項,可進行精細控管。建議您使用 Terraform 進行資源管理,方法如下:firewallPolicies本文假設您熟悉 Terraform 最佳做法和基本 Terraform 作業。

防火牆政策可讓您將多項防火牆規則組成群組,然後明確拒絕或允許連線。如要進一步瞭解防火牆政策,請參閱防火牆政策

遷移至 firewallPolicies 方法的優點

firewallPolicies 方法可在整個Google Cloud 資源階層架構中提供一致的防火牆體驗,並帶來多項作業優勢。

  • 提升機構安全性firewallPolicies 方法會使用進階 Identity and Access Management (IAM) 權限控制項,提升機構安全性。

  • 操作簡單firewallPolicies 方法支援使用進階功能,例如完整網域名稱 (FQDN) 物件、地理位置物件、威脅偵測、入侵防禦和位址群組,方便操作並提高效率。

遷移作業的運作方式

開始遷移程序前,請先完成下列步驟 (詳情請參閱「事前準備」一節):

  • 確認您使用的是 Terraform 供應程式 4.0.0 以上版本。 Google Cloud
  • 確認 Terraform 狀態與目前的設定相符。
  • 找出遷移範圍內的資源,包括政策、規則和關聯。
  • 準備指令,手動或使用自動化指令碼將新的 firewallPolicies 資源匯入 Terraform 狀態。
  • 查看適用於您 Terraform 版本的備份與復原程序建議,並備份目前的 Terraform 狀態。

重新設定 Terraform 以遷移 organizationSecurityPolicies 資源的程序包括下列步驟:

  1. 從 Terraform 狀態中移除現有資源。 從 Terraform 狀態中移除現有的 organizationSecurityPolicies 資源。

  2. 更新 Terraform 設定。 編輯 Terraform 設定檔,將現有資源類型、名稱和屬性替換為新的資源類型、名稱和屬性。

  3. 將新資源匯入 Terraform 狀態。 將新的 firewallPolicies 資源匯入 Terraform 狀態。

事前準備

本節說明遷移程序的必要條件。

確認支援 Terraform 供應器

請確認您使用的是 4.0.0 以上版本的Google CloudTerraform 供應程式,其中包含 Terraform 登錄檔的下列資源:

確認 Terraform 狀態為最新版本

執行下列 Terraform 指令,確認 Terraform 狀態與目前的設定相符。

terraform plan

為避免任何不一致的情況,建議您先套用所有待處理的變更或動作,再繼續進行遷移程序。

找出要遷移的資源

執行下列 Terraform 指令,產生遷移範圍內的資源清單,包括政策、規則和關聯。

terraform state list | grep ^google_compute_organization_security_policy

輸出結果會與下列內容相似:

google_compute_organization_security_policy.policy
google_compute_organization_security_policy_association.association["folders/45678"]
google_compute_organization_security_policy_rule.rule["allow-inbound-ssh"]
google_compute_organization_security_policy_rule.rule["deny-all-egress"]

您需要這些資源才能遷移至 firewallPolicies 方法。儲存這些提案,以備不時之需。

使用自動化指令碼準備匯入指令

為避免遷移期間發生錯誤或遺漏設定,建議使用自動化指令碼產生匯入 firewallPolicies 資源至 Terraform 狀態所需的指令。

執行下列 Terraform 指令碼,即可完成這些工作:

  • 從現有資源位址產生新的資源位址。
  • 從現有資源位址取得資源 ID。
  • 從資源 ID 產生匯入 ID。
  • 顯示所有新 firewallPolicies 資源的匯入指令。
terraform state list | grep ^google_compute_organization_security_policy | while read -r resource_address; do
# Generate the new resource address for google_compute_firewall_policy
new_address=$(echo "$resource_address" | sed 's/google_compute_organization_security_policy/google_compute_firewall_policy/')

# Get the full resource ID from terraform state and remove quotes
resource_id=$(echo "$resource_address.id" | terraform console | tr -d '"')

# Use awk to parse the resource_id and generate the correct import identifier
import_id=$(echo "$resource_id" | awk -F'/' '
  /association/ {
    split($0, a, "/association/");
    assoc_name = a[2];
    gsub(/\//, "%2F", assoc_name);
    print $4 "/" assoc_name;
    next
  }
  /priority/ {
    print $4 "/" $6;
    next
  }
  {
    print $4
  }
')

# Print the final import command
echo "terraform import '$new_address' '$import_id'"
done

您需要這個指令碼的輸出內容,才能匯入資源。儲存輸出內容以供日後使用。

手動準備匯入指令

如果無法採用自動化方法,可以手動產生指令來匯入 firewallPolicies 資源。您可以使用 terraform console 指令取得資源的 ID。

下列 Terraform 指令會顯示 google_compute_organization_security_policy.policy 資源的資源 ID:

echo google_compute_organization_security_policy.policy.id | terraform console

輸出結果會與下列內容相似:

"locations/global/securityPolicies/12345"

同樣地,請取得「識別要遷移的資源」一節中識別的其他資源的資源 ID。

或者,您也可以使用下列 Terraform 指令,一併取得所有已識別資源的資源 ID:

terraform state list | grep ^google_compute_organization_security_policy | while read -r line; do echo "$line".id | terraform console; done

輸出結果會與下列內容相似:

"locations/global/securityPolicies/12345"
"locations/global/securityPolicies/12345/association/locations/global/securityPolicies/23456-folders/56789"
"locations/global/securityPolicies/12345/priority/1000"
"locations/global/securityPolicies/12345/priority/65535"

如要匯入 firewallPolicies 資源,您需要匯入 ID。如本節所述,匯入 ID 由稱為政策號碼的數字 ID、關聯名稱和規則優先順序號碼組成。

  • 第三個正斜線字元 (/) 後方的數字 ID 是政策編號,代表政策的匯入 ID。下表顯示政策的資源 ID 和匯入 ID 範例。

    資源 ID 匯入 ID
    "locations/global/securityPolicies/12345" 12345
  • 政策號碼和關聯名稱代表關聯的匯入 ID。關聯名稱是資源 ID 的一部分,顯示在 /association/ 元素之後。

    將關聯名稱中的任何正斜線字元 (/) 替換為 %2F,讓 terraform import 指令將關聯名稱解讀為單一實體。下表顯示關聯的資源 ID 和匯入 ID 範例。

    資源 ID 匯入 ID
    "locations/global/securityPolicies/12345/association/assoc-name" 12345/assoc-name
    "locations/global/securityPolicies/12345/association/locations/global/securityPolicies/23456-folders/56789" 12345/locations%2Fglobal%2FsecurityPolicies%2F23456-folders%2F56789
  • 政策編號和規則優先順序編號代表規則的匯入 ID。下表顯示規則的資源 ID 和匯入 ID 範例。

    資源 ID 匯入 ID
    "locations/global/securityPolicies/12345/priority/1000" 12345/1000

如要匯入 firewallPolicies 資源,您需要這些資源的更新資源例項名稱。將前置字串 google_compute_organization_security_policy 替換為 google_compute_firewall_policy,為「找出要遷移的資源」一節中識別的所有資源產生資源執行個體名稱。以下列出更新後的資源執行個體名稱範例:

google_compute_firewall_policy.policy
google_compute_firewall_policy_association.association["folders/45678"]
google_compute_firewall_policy_rule.rule["allow-inbound-ssh"]
google_compute_firewall_policy_rule.rule["deny-all-egress"]

將資源執行個體名稱與相關聯的匯入 ID 結合,即可取得 terraform import 指令。以下列出 terraform import 指令的範例:

terraform import 'google_compute_firewall_policy.policy' '12345'
terraform import 'google_compute_firewall_policy_association.association["folders/23456"]' '12345/locations%2Fglobal%2FsecurityPolicies%2F23456-folders%2F56789'
terraform import 'google_compute_firewall_policy_rule.rule["allow-inbound-ssh"]' '12345/1000'
terraform import 'google_compute_firewall_policy_rule.rule["deny-all-egress"]' '12345/65535'

請儲存這些匯入指令,以供日後參考。

備份 Terraform 狀態

建議您先備份 Terraform 狀態,再繼續進行遷移程序。使用下列 Terraform 指令,在 terraform.tfstate.backup 檔案中建立備份。

terraform state pull > terraform.tfstate.backup

如果您以非預期的方式變更 Terraform 狀態,可以使用備份檔 terraform.tfstate.backup 透過下列指令還原原始 Terraform 狀態:

terraform state push terraform.tfstate.backup

遷移 organizationSecurityPolicies 項資源

本節說明如何將 Terraform 設定從 organizationSecurityPolicies 方法遷移至 firewallPolicies 方法。

從 Terraform 狀態中移除現有資源

如要從 Terraform 狀態中移除「organizationSecurityPolicies」資源,請執行下列 Terraform 指令。這些資源位於「找出要遷移的資源」一節。

terraform state list | grep ^google_compute_organization_security_policy | while read -r resource; do
  terraform state rm "$resource"
done

更新 Terraform 設定

如要更新 Terraform 設定檔,請找出「找出要遷移的資源」一節中找到的資源定義。使用下列指令尋找定義。

grep -r google_compute_organization_security_policy .

舉例來說,Terraform 設定檔會以以下方式定義政策 google_compute_organization_security_policy.policy

resource "google_compute_organization_security_policy" "policy" {
  …
  }

請使用下表編輯機構安全政策資源的定義,以建立新的階層式防火牆政策資源。

現有 Terraform 資源 新的 Terraform 資源
資源名稱 google_compute_organization_security_policy google_compute_firewall_policy
政策中的欄位名稱 display_name short_name

使用下表編輯機構安全政策關聯資源的定義,建立新的階層式防火牆政策關聯資源。

現有 Terraform 資源 新的 Terraform 資源
資源名稱 google_compute_organization_security_policy_association google_compute_firewall_policy_association
關聯中的欄位名稱 policy_id firewall_policy
關聯中的欄位名稱 attachment_id attachment_target

請使用下表編輯機構安全性政策規則資源的定義,建立新的階層式防火牆政策規則資源。

現有 Terraform 資源 新的 Terraform 資源
資源名稱 google_compute_organization_security_policy_rule google_compute_firewall_policy_rule
規則中的欄位名稱 policy_id (安全性政策 ID) firewall_policy
從規則中移除的欄位名稱 versioned_expr — (欄位不存在)
match 物件的定義: 移除 config 集並將 layer4_config 變更為 layer4_configs
match {
  config {
    src_ip_ranges = SRC_IP_RANGES
    dest_ip_ranges = DEST_IP_RANGES
    layer4_config {
      ip_protocol = IP_PROTOCOL
      ports = [PORT1, PORT2]
    }
    layer4_config {
      ip_protocol = IP_PROTOCOL
    }
  }
}
  
match {
  src_ip_ranges = SRC_IP_RANGES
  dest_ip_ranges = DEST_IP_RANGES
  layer4_configs {
    ip_protocol = IP_PROTOCOL
    ports = [PORT1, PORT2]
  }
  layer4_configs {
    ip_protocol = IP_PROTOCOL
  }
}
  
規則中的欄位名稱 layer4_config layer4_configs

您可以使用下列 Terraform 指令,驗證修改後的 Terraform 設定是否有效:

terraform validate

將資源匯入 Terraform 狀態

如要將 firewallPolicies 資源匯入 Terraform 設定檔,請執行在「使用自動化指令碼準備匯入指令」或「手動準備匯入指令」一節中產生的 Terraform 匯入指令。

匯入 firewallPolicies 資源後,Terraform 會使用 firewallPolicies 方法存取這些資源。

驗證 Terraform 設定並修正差異

執行下列 Terraform 指令,檢查是否有任何動作。

terraform plan

由於遷移作業不會變更任何基礎 Google Cloud 資源,因此 Terraform 建立的方案不得包含任何動作。

舉例來說,在執行 terraform plan 指令後取得的下列輸出內容中,Terraform 動作表示資源 google_compute_firewall_policy_association 中的 name 必須更新。

Terraform will perform the following actions:

 # google_compute_firewall_policy_association.association["folders/23456"] must be replaced
-/+ resource "google_compute_firewall_policy_association" "association" {
    ~ firewall_policy   = "12345" -> "locations/global/firewallPolicies/12345"
    ~ id                = "locations/global/firewallPolicies/12345/associations/locations%2Fglobal%2FsecurityPolicies%2F12345-folders%2F23456" -> (known after apply)
    ~ name              = "locations/global/securityPolicies/12345-folders/23456" -> "locations/global/firewallPolicies/12345-folders/23456" # forces replacement
    + short_name        = (known after apply)
      # (1 unchanged attribute hidden)
  }

在這種情況下,您必須驗證並更新 Terraform 設定檔,確保 name 屬性與已安裝的名稱一致。

您可以設定 Terraform,將資源 google_compute_firewall_policy_association 中的預期 name 變更為原始值 locations/global/securityPolicies/12345-folders/23456,方法是在設定中替換 name 欄位,如下所示:

name = "${replace(local.policy_id, "firewallPolicies", "securityPolicies")}-${each.value}"

上述變更會使用取代函式,將 local.policy_id 的值更新為 securityPolicies,而非 firewallPolicies。因為 Terraform 現在預期 name 屬性會有 locations/global/securityPolicies/12345-folders/23456,所以執行 terraform plan 不會再顯示與 name 屬性相關的 Terraform 動作。

如果 terraform plan 指令未指出任何變更或 Terraform 動作,即表示遷移作業已完成。

後續步驟