Terraform リソースを organizationSecurityPolicies から firewallPolicies に移行する

Google は、Cloud Next Generation Firewall ポリシーの構成に firewallPolicies メソッドを使用することをおすすめします。このドキュメントでは、organizationSecurityPolicies メソッドではなく firewallPolicies メソッドを使用するように Terraform 構成を移行する方法について説明します。

firewallPolicies メソッドは、きめ細かい制御が可能な組織管理オプションを提供します。Terraform を使用したリソース管理には、firewallPolicies メソッドをおすすめします。このドキュメントは、Terraform のベスト プラクティスと基本的な Terraform の操作に精通していることを前提としています。

ファイアウォール ポリシーを使用すると、接続を明示的に拒否または許可する複数のファイアウォール ルールをグループ化できます。ファイアウォール ポリシーの詳細については、ファイアウォール ポリシーをご覧ください。

firewallPolicies メソッドに移行するメリット

firewallPolicies メソッドは、Google Cloud リソース階層全体で一貫性のあるファイアウォール エクスペリエンスを提供し、運用面でも多くのメリットがあります。

  • 組織のセキュリティの強化: firewallPolicies メソッドは、高度な Identity and Access Management(IAM)権限制御を使用して組織のセキュリティを適用します。

  • 運用の容易さ: firewallPolicies メソッドは、完全修飾ドメイン名(FQDN)オブジェクト、位置情報オブジェクト、脅威検知、侵入防止、アドレス グループなどの高度な機能の使用をサポートしており、運用の容易さと効率性を高めます。

移行の仕組み

移行プロセスを開始する前に、始める前にセクションで説明されている次の手順を完了する必要があります。

  • Google Cloudの Terraform プロバイダのバージョン 4.0.0 以降を使用していることを確認します。
  • Terraform の状態が現在の構成と一致していることを確認します。
  • ポリシー、ルール、関連付けなど、移行のスコープ内のリソースを特定します。
  • 新しい firewallPolicies リソースを Terraform の状態にインポートするコマンドを、手動または自動スクリプトを使用して準備します。
  • お使いの Terraform のバージョンで推奨されているバックアップと復元の手順を確認し、現在の Terraform 状態のバックアップを作成します。

organizationSecurityPolicies リソースを移行するように Terraform を再構成するプロセスには、次の手順が含まれます。

  1. Terraform の状態から既存のリソースを削除します。Terraform の状態から既存の organizationSecurityPolicies リソースを削除します。

  2. Terraform 構成を更新します。Terraform 構成ファイルを編集して、既存のリソースタイプ、名前、属性を新しいリソースタイプ、名前、属性に置き換えます。

  3. 新しいリソースを Terraform の状態にインポートします。新しい firewallPolicies リソースを Terraform の状態にインポートします。

始める前に

このセクションでは、移行プロセスの前提条件について説明します。

Terraform プロバイダがサポートされていることを確認する

Google Cloudの Terraform プロバイダのバージョン 4.0.0 以降を使用していることを確認します。これには、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 は、このセクションで説明するように、ポリシー番号と呼ばれる数値識別子、関連付け名、ルール優先度番号で構成されます。

  • 3 番目のスラッシュ文字(/)の後の数値識別子はポリシー番号です。これは、ポリシーのインポート ID を表します。次の表は、ポリシーのリソース ID とインポート ID の例を示しています。

    リソース ID インポート ID
    "locations/global/securityPolicies/12345" 12345
  • ポリシー番号と関連付け名は、関連付けのインポート ID を表します。関連付け名は、要素 /association/ の後に表示されるリソース ID の一部です。

    関連付け名に含まれるスラッシュ(/)を %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_policygoogle_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 の状態から既存のリソースを削除する

移行するリソースを特定するセクションで特定された organizationSecurityPolicies リソースを Terraform 状態から削除するには、次の 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_configlayer4_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_associationname を更新する必要があることを示しています。

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)
  }

この場合は、name 属性がすでにインストールされている名前と一致するように、Terraform 構成ファイルを確認して更新する必要があります。

Terraform を構成して、リソース google_compute_firewall_policy_association の想定される name を元の値 locations/global/securityPolicies/12345-folders/23456 に変更するには、構成の name フィールドを次のように置き換えます。

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

上記の変更では、replace 関数を使用して、local.policy_id の値を firewallPolicies ではなく securityPolicies に更新しています。Terraform は name 属性に locations/global/securityPolicies/12345-folders/23456 を想定するようになったため、terraform plan を実行しても name 属性に関連する Terraform アクションは表示されなくなります。

terraform plan コマンドで変更や Terraform アクションが示されていない場合、移行は完了しています。

次のステップ