6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

こんにちは!
最近、Azure環境でTerraformを使う機会があり、以前から一部で話題になっていたTerraform MCP Serverを試してみました。
この記事では、Terraform MCP Serverの概要、Windows 11上でのセットアップ方法、動作確認の様子を簡単にまとめています。

MCP/MCPサーバとは?

MCP(Model Context Protocol)は、Anthropic社が提唱する「AIが外部のデータやツールとやり取りするための標準的なプロトコル」です。
AIはMCPを通じて、さまざまなデータソースや外部システムとリアルタイムで接続し、より正確かつ最新の情報をもとに応答できるようになります。

MCPはよく「AI用のUSB-Cポート」に例えられます。つまり、AIに外部知識やツールを外付けして使うための共通インターフェースと考えるとイメージしやすいです。

Terraform MCP Serverとは?

Terraform MCP Serverは、Terraform Registry(プロバイダーやモジュール)の情報をMCPを通じてAIに提供し、最新情報に基づいたインフラ構成コード(IaC)を生成できるようにするサーバです。

Terraform MCP Serverを使うことで、AIが最新ドキュメントを参照しながらコードを生成できるようになります。

主な機能

  • プロバイダーのドキュメント取得
  • モジュールのドキュメント取得

構成

Terraform MCP ServerはDockerイメージとして提供されているため、今回はWindows 11環境にWSL2 + Ubuntuを導入し、その上でTerraform MCP Serverを動かします。

  • Windows 11(23H2)
  • Azure CLI(2.75.0)
  • Terraform(1.12.2)
  • VS Code(GitHub Copilot拡張機能インストール済み)

なお、AVD環境のWindows 11でWSL2を有効化する場合は、セッションホストのVMサイズがNested Virtualizationに対応している(例:Standard_D4s_v4など)必要があります。→ 公式ドキュメント

セットアップ

1. WSL2のインストール

以下のPowerShellコマンドを管理者権限で実行し、WSL2をインストールします。

wsl --install

コマンド実行後は、画面の指示に従いシステムを再起動してください。

再起動後は既定のLinuxディストリビューションが自動的にインストールされます。既定ではUbuntuがインストールされますが、別のLinux ディストリビューションをインストールすることもできます。→ 公式ドキュメント

2. Ubuntuを起動する

以下のPowerShellコマンドを実行し、既定のディストリビューションを起動します。
初回起動時にはユーザ名とパスワードの登録が求められるため、入力しログインします。

wsl

3. Docker Engineのインストール

以下の手順に従い、UbuntuにDocker Engineをインストールします。

1. Dockerのaptリポジトリを設定

# Add Docker's official GPG key:
sudo apt-get update
sudo apt-get install ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

# Add the repository to Apt sources:
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "${UBUNTU_CODENAME:-$VERSION_CODENAME}") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update

2. Dockerパッケージをインストールする

sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

3. テストコンテナを実行し、インストールに成功したことを確認する

sudo docker run hello-world

4. dockerグループに、ユーザーを所属させる

sudo usermod -aG docker <ユーザ名>

4. Terraform MCP Serverの設定

VS Codeのユーザー設定ファイルsetting.jsonに、次のJSONブロックを追加します。
設定ファイルはCtrl + Shift + PからPreferences: Open User Settings (JSON)を選択して開きます。

setting.json
{
  "mcp": {
    "servers": {
      "terraform": {
        "command": "wsl",
        "args": [
          "docker",
          "run",
          "-i",
          "--rm",
          "hashicorp/terraform-mcp-server"
        ]
      }
    }
  }
}

5. Terraform MCP Serverの起動

赤枠の▷起動をクリックすると、Terraform MCP Serverが起動します。

image.png

動作確認

それではVS CodeでGitHub Copilot Chatを起動し、Agentモードで指示を出してみます。
azurermプロバイダー v4.32.0(2025年6月21日時点)より、azurerm_virtual_networkでip_address_pool(IPAM:IPアドレス管理)という引数がサポートされるようになりましたので、コードで生成できるか試します。→IPAMについてはこちら

MCPサーバーなしの場合

image.png

以下のコードが生成されました。

main.tf
# IPAMリソースグループ
resource "azurerm_resource_group" "ipam_rg" {
  name     = "ipam-rg"
  location = "japaneast"
}

# IPAMインスタンス
resource "azurerm_ipam" "example" {
  name                = "example-ipam"
  resource_group_name = azurerm_resource_group.ipam_rg.name
  location            = azurerm_resource_group.ipam_rg.location
}

# IPAMアドレスプール
resource "azurerm_ipam_pool" "example_pool" {
  name                = "example-ipam-pool"
  ipam_id             = azurerm_ipam.example.id
  resource_group_name = azurerm_resource_group.ipam_rg.name
  location            = azurerm_resource_group.ipam_rg.location
  address_prefix      = "10.10.0.0/16"
}

# IPAMからサブネット範囲を割り当て
resource "azurerm_ipam_subnet" "vnet_subnet" {
  name        = "vnet-subnet"
  ipam_pool_id = azurerm_ipam_pool.example_pool.id
  size        = 24
}

# VNet用リソースグループ
resource "azurerm_resource_group" "vnet_rg" {
  name     = "vnet-rg"
  location = "japaneast"
}

# VNet本体(IPAMから払い出したアドレス範囲を利用)
resource "azurerm_virtual_network" "example_vnet" {
  name                = "example-vnet"
  location            = azurerm_resource_group.vnet_rg.location
  resource_group_name = azurerm_resource_group.vnet_rg.name
  address_space       = [azurerm_ipam_subnet.vnet_subnet.address_prefix]
}

terraform validateコマンドを実行し、構文チェックをしてみます。
azurerm_ipam、azurerm_ipam_pool、azurerm_ipam_subnetはTerraform Registryに存在しない架空のリソースのため、構文エラーが発生しました。
image.png

MCPサーバーありの場合

指示を出す際にドキュメントのようなワードを含めるか、#terraformコンテキストを追加すると、MCPサーバを参照してくれます。
MCPサーバ経由で、Terraform Registryからazurerm_network_manager_ipam_poolやazurerm_virtual_networkの情報を取得していることが分かります。

image.png

以下のコードが生成されました。

main.tf
# サブスクリプション情報取得
data "azurerm_subscription" "current" {}

# リソースグループ
resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "japaneast"
}

# ネットワークマネージャ
resource "azurerm_network_manager" "example" {
  name                = "example-network-manager"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  scope {
    subscription_ids = [data.azurerm_subscription.current.id]
  }
  scope_accesses = ["Connectivity", "SecurityAdmin"]
}

# IPAMプール
resource "azurerm_network_manager_ipam_pool" "example" {
  name               = "example-ipam-pool"
  location           = azurerm_resource_group.example.location
  network_manager_id = azurerm_network_manager.example.id
  display_name       = "example-pool"
  address_prefixes   = ["10.1.0.0/16"]
}

# VNet(IPAMから払い出し)
resource "azurerm_virtual_network" "example" {
  name                = "example-vnet"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  ip_address_pool {
    id                     = azurerm_network_manager_ipam_pool.example.id
    number_of_ip_addresses = "256" # 必要なIP数に応じて調整
  }
  subnet {
    name             = "subnet1"
    address_prefixes = ["10.1.1.0/24"]
  }
}

terraform validateコマンドによる構文チェックは正常に完了しました。
image.png

しかし、terraform applyコマンドでリソースのデプロイを試みたところ、SubnetMustUsePoolReferenceIfVnetBeingCreatedWithPoolというエラーが発生しました。

│ Error: creating Virtual Network
│ Resource Group Name: "example-resources"
│ Virtual Network Name: "example-vnet"): performing CreateOrUpdate: unexpected status 400
| (400 Bad Request) with error: SubnetMustUsePoolReferenceIfVnetBeingCreatedWithPool:
| During | vnet creation, if vnet is configured with pool, all individual subnets must be
| configured with pool reference as well.
│
│   with azurerm_virtual_network.example,
│   on main.tf line 46, in resource "azurerm_virtual_network" "example":
│   46: resource "azurerm_virtual_network" "example" {

VNetをIPAMで構成する場合、配下のすべてのサブネットも同様にIPAMで構成する必要があるとのことです。ただし、azurermプロバイダー v4.32.0(2025年6月21日時点)では、サブネット側がIPAMに対応していないため、現時点ではその対応ができません。

そのため、暫定対応としてサブネットの定義を削除し、再度terraform applyコマンドを実行してみます。

main.tf
# サブスクリプション情報取得
data "azurerm_subscription" "current" {}

# リソースグループ
resource "azurerm_resource_group" "example" {
  name     = "example-resources"
  location = "japaneast"
}

# ネットワークマネージャ
resource "azurerm_network_manager" "example" {
  name                = "example-network-manager"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  scope {
    subscription_ids = [data.azurerm_subscription.current.id]
  }
  scope_accesses = ["Connectivity", "SecurityAdmin"]
}

# IPAMプール
resource "azurerm_network_manager_ipam_pool" "example" {
  name               = "example-ipam-pool"
  location           = azurerm_resource_group.example.location
  network_manager_id = azurerm_network_manager.example.id
  display_name       = "example-pool"
  address_prefixes   = ["10.1.0.0/16"]
}

# VNet(IPAMから払い出し)
resource "azurerm_virtual_network" "example" {
  name                = "example-vnet"
  location            = azurerm_resource_group.example.location
  resource_group_name = azurerm_resource_group.example.name
  ip_address_pool {
    id                     = azurerm_network_manager_ipam_pool.example.id
    number_of_ip_addresses = "256" # 必要なIP数に応じて調整
  }
}

今度はApplyに成功しました。
image.png

Azure Portal上からもリソースが作成されていることを確認できました。
image.png

VNetのアドレス範囲もIPAMプールから払い出されていました。
image.png

まとめ

  • WSL2を使うことで、Terraform MCP Serverを簡単に実行できた
  • Terraform MCP Serverにより、最新情報に基づいたIaCが生成されることを確認できた
  • ただし、生成されたコードが正しく動作するかどうかは、実際にデプロイして動作確認する必要がある

We Are Hiring!

6
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?