[プレビュー]Google CloudリソースをTerraformにエクスポートしてみた。(+Cloud ConsoleからリソースのHCLを確認する小ネタ)
アライアンス事業部 エンジニアの村田です。
Cloud Console(GUI) や Cloud SDK(CLI)によってGoogle Cloud上にデプロイした既存リソースをコード化し、新しいプロジェクトに複製したいケースはありませんでしょうか? Google Cloud上の既存リソースを一括エクスポートでTerraform形式(HCL)にコード化するための機能がプレビューにて利用可能でしたので、本ブログにて試してみました。
※Google Cloud上の既存リソースをHCLに一括エクスポートできる機能はプレビューリリースのためテスト利用にお使いください。
※以下Google Cloudのチュートリアルを参考にしています。 https://cloud.google.com/docs/terraform/resource-management/export?hl=ja
検証環境
以下ローカル環境で検証しています。
OS : Ubuntu 22.04.2 LTS (GNU/Linux 5.15.90.1-microsoft-standard-WSL2 x86_64)
※Windows 11のWSL上に立てています。
ローカル環境で本検証を実行するにはgcloud CLI(Cloud SDK)のインストールと初期化が必要です。手順は以下をご参照ください。(Cloud Shellを利用する場合は以下手順は不要です。)
gcloud CLI をインストールする | Google Cloud CLI のドキュメント
準備
Google Cloud の Terraform一括エクスポートツールを利用するために、以下コマンドでConfig Connectorをインストールします。
gcloud components install config-connector
対象プロジェクトのGoogle Cloudリソースをエクスポートするために、Cloud Asset APIを有効化します。
gcloud services enable cloudasset.googleapis.com
Google Cloudのbetaバージョン機能やサービスを利用するためのgcloud betaコマンドをインストールします。
gcloud components install beta
Google Cloudプロジェクト全体のエクスポート
プロジェクトのリソース構成を出力するディレクトリを作成します。
mkdir OUTPUT_DIRECTORY
プロジェクト構成全体を Terraform HCL コードにエクスポートします。
gcloud beta resource-config bulk-export \ --path=OUTPUT_DIRECTORY \ --project=<Google CloudプロジェクトID> \ --resource-format=terraform
resource-config
Google Cloudリソースを宣言的に管理するためのコマンド。本コマンドを利用するために、前述のconfig-connectorのインストールが必要。
bulk-export
一括エクスポートのためのコマンド。
--path
エクスポート先ディレクトリ。
--project
エクスポート対象のプロジェクト。
--resource-format
エクスポートするコンフィグレーションのフォーマット。terraform
:Terraform HCL または krm
: KRM YAML のいずれかを指定可能。
指定したディレクトリ配下に詳細なリソースごと/インスタンスごとに、以下の構成で多数のtfファイルがエクスポートされました。(プロジェクトIDなどの情報はマスクしています)
$ tree . ├── xxxxxxxx │ └── Project │ └── xxxxxxxx.tf ├── xxxxxxxx │ └── Service │ ├── artifactregistry-googleapis-com.tf │ ├── autoscaling-googleapis-com.tf │ ├── bigquery-googleapis-com.tf │ ├── bigquerymigration-googleapis-com.tf │ ├── bigquerystorage-googleapis-com.tf │ ├── cloudapis-googleapis-com.tf │ ├── cloudasset-googleapis-com.tf │ ├── cloudbuild-googleapis-com.tf │ ├── cloudtrace-googleapis-com.tf │ ├── compute-googleapis-com.tf │ ├── container-googleapis-com.tf │ ├── containerfilesystem-googleapis-com.tf │ ├── containerregistry-googleapis-com.tf │ ├── datastore-googleapis-com.tf │ ├── dns-googleapis-com.tf │ ├── iam-googleapis-com.tf │ ├── iamcredentials-googleapis-com.tf │ ├── logging-googleapis-com.tf │ ├── monitoring-googleapis-com.tf │ ├── networkconnectivity-googleapis-com.tf │ ├── osconfig-googleapis-com.tf │ ├── oslogin-googleapis-com.tf │ ├── pubsub-googleapis-com.tf │ ├── run-googleapis-com.tf │ ├── servicemanagement-googleapis-com.tf │ ├── serviceusage-googleapis-com.tf │ ├── sourcerepo-googleapis-com.tf │ ├── sql-component-googleapis-com.tf │ ├── storage-api-googleapis-com.tf │ ├── storage-component-googleapis-com.tf │ └── storage-googleapis-com.tf ├── xxxxxxxx │ └── ComputeDisk │ └── us-west1-a │ └── flask-vm.tf └── projects └── xxxxxxxx ├── ComputeFirewall │ ├── allow-ssh.tf │ ├── default-allow-http.tf │ ├── default-allow-https.tf │ ├── default-allow-icmp.tf │ ├── default-allow-internal.tf │ ├── default-allow-rdp.tf │ ├── default-allow-ssh.tf │ └── flask-app-firewall.tf ├── ComputeInstance │ └── us-west1-a │ └── flask-vm.tf ├── ComputeNetwork │ └── my-custom-mode-network.tf ├── ComputeResourcePolicy │ └── us-central1 │ └── test-schedule.tf ├── ComputeSubnetwork │ └── us-west1 │ └── my-custom-subnet.tf ├── IAMServiceAccount │ ├── xxxxxxxx-compute.tf │ ├── xxxxxxxx-sa.tf │ ├── xxxxxxxx-sa.tf │ └── terraform-account.tf └── StorageBucket └── US ├── export-xxxxxxxxxx.tf └── xxxxxxxx-cloudbuild.tf 20 directories, 51 files
一部のtfファイルの中身を見てみます。(flask-vmというCompute Engineインスタンスを確認。プロジェクトIDや外部IPなどの情報はマスクしています)
$ cat projects/xxxxxxxx/ComputeInstance/us-west1-a/flask-vm.tf resource "google_compute_instance" "flask_vm" { boot_disk { auto_delete = true device_name = "persistent-disk-0" initialize_params { image = "https://www.googleapis.com/compute/beta/projects/debian-cloud/global/images/debian-11-bullseye-v20231010" size = 10 type = "pd-standard" } mode = "READ_WRITE" source = "https://www.googleapis.com/compute/v1/projects/xxxxxx/zones/us-west1-a/disks/flask-vm" } machine_type = "f1-micro" metadata = { startup-script = "sudo apt-get update; sudo apt-get install -yq build-essential python3-pip rsync; pip install flask" } name = "flask-vm" network_interface { access_config { nat_ip = "xx.xxx.xx.xx" network_tier = "PREMIUM" } network = "https://www.googleapis.com/compute/v1/projects/xxxxxx/global/networks/my-custom-mode-network" network_ip = "10.0.1.2" stack_type = "IPV4_ONLY" subnetwork = "https://www.googleapis.com/compute/v1/projects/xxxxxx/regions/us-west1/subnetworks/my-custom-subnet" subnetwork_project = "xxxxxx" } project = "xxxxxx" scheduling { automatic_restart = true on_host_maintenance = "MIGRATE" provisioning_model = "STANDARD" } shielded_instance_config { enable_integrity_monitoring = true enable_vtpm = true } tags = ["ssh"] zone = "us-west1-a" }
一部のGoogle Cloudリソースタイプのみエクスポート
--resource-types
でリソースタイプを指定することで、一部のリソースタイプのみをエクスポートすることができます。
gcloud beta resource-config bulk-export \ --resource-types=<リソースタイプ> \ --path=OUTPUT_DIRECTORY \ --project=<Google CloudプロジェクトID> \ --resource-format=terraform
指定可能なリソースタイプは以下コマンドを入力して確認できます。
$ gcloud beta resource-config list-resource-types ┌──────────────────────────────────────┬──────────────┬─────────┬──────┐ │ KRM KIND │ BULK EXPORT? │ EXPORT? │ IAM? │ ├──────────────────────────────────────┼──────────────┼─────────┼──────┤ │ AccessContextManagerAccessLevel │ │ │ │ │ AccessContextManagerAccessPolicy │ │ │ x │ │ AccessContextManagerServicePerimeter │ │ │ │ │ ArtifactRegistryRepository │ x │ x │ x │ │ BigQueryDataset │ x │ x │ │ │ BigQueryJob │ │ x │ │ │ BigQueryTable │ x │ x │ x │ │ BigtableAppProfile │ x │ x │ │ │ BigtableGCPolicy │ │ │ │ │ BigtableInstance │ x │ x │ x │ │ BigtableTable │ x │ x │ x │ │ CloudBuildTrigger │ │ │ │ │ CloudIdentityGroup │ │ │ │ ...
BULK EXPORT?
列にx
が記載してある行のKRM KIND
が指定可能なリソースタイプです。
ComputeInstance
とComputeNetwork
のみをOUTPUT_DIRECTORY_2
にエクスポートしてみます。
gcloud beta resource-config bulk-export \ --resource-types=ComputeInstance,ComputeNetwork \ --path=OUTPUT_DIRECTORY_2 \ --project=<Google CloudプロジェクトID> \ --resource-format=terraform
以下のようにエクスポートされました。(プロジェクトIDはマスクしています)
$ tree . └── projects └── xxxxxxxxxx ├── ComputeInstance │ └── us-west1-a │ └── flask-vm.tf └── ComputeNetwork └── my-custom-mode-network.tf 5 directories, 2 files
[Tips]Cloud ConsoleからTerraformコードを確認する
Cloud Console の GUI画面からリソースのコードを確認する方法もあります。
Compute Enigineなど一部のリソースについては、リソース作成中の画面で[同等のコード]をクリックすることで画面右側に作成中のリソースについてコードをリアルタイム表示してくれます。
なお、Terraform(HCL)以外にもgcloudコマンド等によるコマンドラインでの設定、REST API(JSON)による設定も確認することもできます。
おわりに
今回、TerraformでGoogle Cloudを管理するための小ネタ的機能を試してみましたが、今後はTerraformによるGoogle Cloudのコード管理について様々な運用パターンでのベストプラクティスなど発信していきたいと思っています。