こんにちは!ACSD松崎です。この記事は、Googleの新しい生成AIモデル、Geminiを使って手書きの構成図からTerraformの定義ファイルを作ろうとした際のメモになります。
Geminiとは
2023年12月7日に発表されたmade by Googleの生成AIです。2023年12月末現在、Gemini Ultra / Pro / Nanoの3タイプが存在し、そのうちGemini ProをGoogle Bardから利用することができます。
やりたかったこと
- Azureのラフな手書き構成図からterrraformファイルを作ってもらう。
- terraform fileの品質としては、terraform validateをエラーなしで通過する状態を目指す
試した結果
試した結果は以下となりました。マルチモーダルな処理には満足なのですが、terraform fileの作成の精度に課題という結果ですね。
- 手書きの画像をもとに、システム構成をGeminiに理解してもらう → OK
- 理解したシステム構成をもとに、terraform validateをパスするterraformファイルを生成させる → NG
検証メモ
Geminiに読み込ませてみる
まずはGoogle Bardを使って、バックエンドで動いているGeminiに作ってみた手書きの構成図を読み込ませてみます。果たしてGeminiは内容を理解することができますでしょうか...?
回答が返ってきました!Azure Databaseと記述していた部分がAzure Database for PostgreSQLに置き換えられていますが、概ね正しく内容を理解しているように見えます。いい感じですね。 ※アウトプットが長いので、一部省略しています
Terraformファイルを作ってもらう
理解したシステム構成を元に、Google Geminiにterraformファイルを生成してみます。
出力結果は以下となりました。これを terraform validate
してみましょう。
※provider部分はあらかじめ別に用意しておいたものを使っていますので、割愛します。
resource "azurerm_resource_group" "default" { name = "terraform-demo" location = "japaneast" } resource "azurerm_virtual_network" "default" { name = "terraform-demo-network" location = azurerm_resource_group.default.location address_space = ["10.0.0.0/16"] } resource "azurerm_subnet" "default" { name = "terraform-demo-subnet" virtual_network_id = azurerm_virtual_network.default.id address_prefix = "10.0.1.0/24" } resource "azurerm_network_interface" "default" { name = "terraform-demo-nic" location = azurerm_resource_group.default.location virtual_network_id = azurerm_virtual_network.default.id subnet_id = azurerm_subnet.default.id } resource "azurerm_public_ip" "default" { name = "terraform-demo-ip" location = azurerm_resource_group.default.location resource_group_name = azurerm_resource_group.default.name allocation_method = "Static" } resource "azurerm_virtual_machine" "default" { name = "terraform-demo-vm" location = azurerm_resource_group.default.location resource_group_name = azurerm_resource_group.default.name network_interface_ids = [azurerm_network_interface.default.id] vm_size = "Standard_D2s_v3" os_type = "Linux" os_disk_size_gb = 128 admin_username = "azureuser" admin_password = "Pa$$w0rd" public_ip_address_id = azurerm_public_ip.default.id } resource "azurerm_postgresql_server" "default" { name = "terraform-demo-postgres" location = azurerm_resource_group.default.location resource_group_name = azurerm_resource_group.default.name sku = "Standard_D2s_v3" version = "13" admin_username = "postgres" admin_password = "Pa$$w0rd" } resource "azurerm_postgresql_database" "default" { name = "terraform-demo" server_id = azurerm_postgresql_server.default.id }
terraform validate
の実行結果ですが、以下のように Missing required argument
Unsupported argument
を中心に、多数(合計19)のエラーが出ました。terraformのリソース定義に従った形で、Geminiがterraformファイルを作ってくれなかったということですね。
│ Error: Missing required argument │ │ on main.tf line 6, in resource "azurerm_virtual_network" "default": │ 6: resource "azurerm_virtual_network" "default" { │ │ The argument "resource_group_name" is required, but no definition was found. │ Error: Unsupported argument │ │ on main.tf line 14, in resource "azurerm_subnet" "default": │ 14: virtual_network_id = azurerm_virtual_network.default.id │ │ An argument named "virtual_network_id" is not expected here. (※他に17のErr MSGが出たが長くなるので割愛)
ここで終わるのは悔しいので、ChatGPT(GPT4)を使って、terraformファイルの修正を試みてみましょう。プロンプトは以下となります。
以下のTerraformファイルをterraform validateしたところエラーを検出しました。エラーの内容を踏まえ、terraformファイルを修正してください。 # terraform file [Geminiに生成されたterraformファイル] # Err Msg [terraform validate実行時のエラー]
ChatGPT(GPT4)の生成結果ですが、以下のように不足していたパラメーターが全体的に補完されています。これを再び terraform validate
してみます。
resource "azurerm_resource_group" "default" { name = "terraform-demo" location = "japaneast" } resource "azurerm_virtual_network" "default" { name = "terraform-demo-network" location = azurerm_resource_group.default.location resource_group_name = azurerm_resource_group.default.name address_space = ["10.0.0.0/16"] } resource "azurerm_subnet" "default" { name = "terraform-demo-subnet" resource_group_name = azurerm_resource_group.default.name virtual_network_name = azurerm_virtual_network.default.name address_prefixes = ["10.0.1.0/24"] } resource "azurerm_network_interface" "default" { name = "terraform-demo-nic" location = azurerm_resource_group.default.location resource_group_name = azurerm_resource_group.default.name ip_configuration { name = "internal" subnet_id = azurerm_subnet.default.id private_ip_address_allocation = "Dynamic" } } resource "azurerm_public_ip" "default" { name = "terraform-demo-ip" location = azurerm_resource_group.default.location resource_group_name = azurerm_resource_group.default.name allocation_method = "Static" } resource "azurerm_virtual_machine" "default" { name = "terraform-demo-vm" location = azurerm_resource_group.default.location resource_group_name = azurerm_resource_group.default.name network_interface_ids = [azurerm_network_interface.default.id] vm_size = "Standard_D2s_v3" os_type = "Linux" os_disk_size_gb = 128 admin_username = "azureuser" admin_password = "Pa$$w0rd" public_ip_address_id = azurerm_public_ip.default.id } resource "azurerm_postgresql_server" "default" { name = "terraform-demo-postgres" location = azurerm_resource_group.default.location resource_group_name = azurerm_resource_group.default.name sku_name = "GP_Gen5_2" version = "13" ssl_enforcement_enabled = true administrator_login = "postgres" administrator_login_password = "Pa$$w0rd" } resource "azurerm_postgresql_database" "default" { name = "terraform-demo" resource_group_name = azurerm_resource_group.default.name server_name = azurerm_postgresql_server.default.name charset = "UTF8" collation = "English_United States.1252" }
エラーの総数が19→7まで減りましたが、逆にいうと0にはできませんでした。うーん、やはり「生成AIで完動するファイルを簡単に生成」とまではいきませんね。もう少し頑張ってみたい気持ちもありますが、今回の検証はここまでにしたいと思います。
│ Error: Insufficient storage_os_disk blocks │ │ on main.tf line 33, in resource "azurerm_virtual_machine" "default": │ 33: resource "azurerm_virtual_machine" "default" { │ │ At least 1 "storage_os_disk" blocks are required. ╵ ╷ │ Error: Unsupported argument │ │ on main.tf line 39, in resource "azurerm_virtual_machine" "default": │ 39: os_type = "Linux" │ │ An argument named "os_type" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on main.tf line 40, in resource "azurerm_virtual_machine" "default": │ 40: os_disk_size_gb = 128 │ │ An argument named "os_disk_size_gb" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on main.tf line 41, in resource "azurerm_virtual_machine" "default": │ 41: admin_username = "azureuser" │ │ An argument named "admin_username" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on main.tf line 42, in resource "azurerm_virtual_machine" "default": │ 42: admin_password = "Pa$$w0rd" │ │ An argument named "admin_password" is not expected here. ╵ ╷ │ Error: Unsupported argument │ │ on main.tf line 43, in resource "azurerm_virtual_machine" "default": │ 43: public_ip_address_id = azurerm_public_ip.default.id │ │ An argument named "public_ip_address_id" is not expected here. ╵ ╷ │ Error: expected version to be one of [9.5 9.6 11 10 10.0], got 13 │ │ with azurerm_postgresql_server.default, │ on main.tf line 50, in resource "azurerm_postgresql_server" "default": │ 50: version = "13"
終わりに
生成AIによるIaCファイルの自動生成はまだまだ課題が多そうという結果になりました。残念ではありますが、技術的なニーズのある分野だと思いますので、今回の結果を踏まえつつ、もう少しベターなやり方がないか引き続き考えてみたいと思います。
私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。ご相談等ありましたらぜひご連絡ください。
また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。