Skip to main content
BlogDevOps

Terraform MCP Server GA: Setup Agent Aman Sejak 1.1.0

Jalankan Terraform MCP server GA dengan aman: pin 1.3.0, matikan ENABLE_TF_OPERATIONS, pasang org allowlist, dan hadapi breaking change 1.1.0.

Matthews Wong

Software Engineer

Oktober 202611 menit baca
Terraform MCP Server GA: Setup Agent Aman Sejak 1.1.0

Ringkasan Utama

Agar Terraform MCP server aman dijalankan, pin image 1.3.0, muat hanya toolset yang dibutuhkan, biarkan ENABLE_TF_OPERATIONS di default false, dan set MCP_ORGANIZATION_ALLOWLIST di setiap deployment HTTP bersama. Sejak 1.1.0 client tidak bisa lagi menentukan TFE_ADDRESS, dan sejak 1.2.0 panggilan ke organization di luar daftar ditolak.

Saya membuka release notes Terraform MCP server dengan harapan menemukan daftar fitur, dan ternyata isinya lebih mirip changelog keamanan. Keempat rilis dari 1.0.0 sampai 1.3.0 menyentuh apa yang bisa dilakukan caller, header proxy palsu, atau agent yang terlalu bersemangat, dan 1.1.0 membuat client yang tadinya berjalan jadi rusak.

Tulisan ini adalah pembacaan teliti atas release notes, halaman reference, halaman deployment, dan README repositori HashiCorp, ditambah laporan InfoQ tentang pengumuman general availability. Saya belum menjalankan server ini terhadap organisasi HCP Terraform production, jadi setiap flag dan default di bawah berasal dari halaman yang saya baca pada 17 Oktober 2026, dan bila dua halaman tidak sepakat, saya katakan terus terang.

Apa sebenarnya yang dibawa general availability ke mesin Anda

Server ini adalah jembatan open-source antara MCP client dan Terraform. Laporan InfoQ tanggal 13 Juni menyebut kegunaan utamanya: mencari dokumentasi registry, menjelaskan file plan dengan bahasa biasa, dan menjawab pertanyaan tentang workspace. Ia mendukung dua transport, stdio dan StreamableHTTP, dan bisa berjalan lokal untuk satu developer atau sebagai shared service untuk tim. Halaman reference mengelompokkan tool-nya ke dalam tiga toolset.

  • registry: mencari provider, module, dan policy publik. Tidak butuh token.
  • registry-private: module dan provider privat. Baru terdaftar bila ada TFE_TOKEN yang valid.
  • terraform: workspace, run, plan, variable, state, project, dan team. Juga baru terdaftar bila ada TFE_TOKEN yang valid.

Pembagian itu adalah seluruh model keamanannya dalam bentuk kecil. Server tanpa token hanyalah alat pencari dokumentasi; menambahkan token adalah langkah yang mengubahnya menjadi sesuatu yang bisa menyentuh infrastruktur. Jadi anggap token, bukan container, sebagai hal yang Anda berikan akses. Peringatan HashiCorp sendiri tegas: server ini tidak boleh dipakai dengan MCP client atau LLM yang tidak tepercaya, karena bisa membuka data Terraform.

Empat rilis dalam sebelas minggu, dibaca sebagai log keamanan

Release notes berjalan dari 9 Juni sampai 25 Agustus 2026, tepat sebelas minggu. Dibaca berurutan, ceritanya adalah server yang dirilis sebagai alat lokal lalu diperkeras ketika orang mulai menjalankannya sebagai layanan bersama.

RilisPerubahan terkait keamananArtinya bagi Anda
1.0.0, 9 Juni 2026Container berjalan sebagai user non-root. MCP_FORWARD_CLIENT_IP meneruskan IP client lewat X-Forwarded-For pada request keluar. Metrik OpenTelemetry mencatat nama dan versi tiap client. get_sentinel_mock ditambahkan.Image cocok untuk kebijakan Kubernetes yang melarang root. Anda bisa melihat MCP client mana yang terhubung setelah metrik aktif.
1.1.0, 14 Juli 2026Breaking: TFE_ADDRESS di header atau query parameter menghasilkan 403, dan X-Forwarded-For tidak lagi dipercaya secara default. Menambah organization allowlist dan force_unlock_workspace di balik ENABLE_TF_OPERATIONS.Set TFE_ADDRESS di server. Jika ada proxy di depannya, set MCP_XFF_TRUSTED_HOPS sesuai jumlah proxy yang Anda jalankan.
1.2.0, 4 Agustus 2026Panggilan dengan terraform_org_name yang tidak ada di MCP_ORGANIZATION_ALLOWLIST ditolak. delete_project hanya terdaftar dengan ENABLE_TF_OPERATIONS. TF_MCP_SHARED_SECRET mengirim header X-Tf-Mcp-Secret ke backend. /health mendapat field version.Allowlist diberlakukan per panggilan mulai di sini. Pakai /health untuk memastikan versi mana yang sebenarnya menjawab.
1.3.0, 25 Agustus 2026Enam tool team: list_teams, get_team, create_team, add_team_member, grant_team_access, dan delete_team. delete_team hanya terdaftar dengan ENABLE_TF_OPERATIONS. Juga whoami dan get_project.Permukaan tool bertambah di setiap rilis minor. Cek ulang apa yang kini bisa dijangkau token Anda setelah tiap upgrade.

Catatan 1.1.0 juga memuat tiga perbaikan yang penting jika Anda pernah menjalankan 1.0.x sebagai layanan HTTP bersama: validasi allowlist kini memakai bearer token yang sama dengan request ke Terraform API, yang menutup bypass lewat header TFE_TOKEN yang bertentangan; pemakaian ulang token lintas tenant di stateless HTTP mode diperbaiki; dan client cache per sesi yang melewati validasi per token diperbaiki. Saya membacanya sebagai pengakuan bahwa mode bersama punya celah sebelum 1.1.0. Allowlist tercatat di 1.1.0 dan penolakan per panggilan di 1.2.0, jadi pakai 1.2.0 atau lebih baru sebelum Anda mengandalkannya.

Tiga gerbang, dan apa yang tidak dihentikan masing-masing

Tidak ada satu kontrol pun yang cukup, karena masing-masing menghentikan hal yang berbeda. Kolom yang berguna di tabel berikut adalah kolom kanan: apa yang dibiarkan terbuka oleh sebuah gerbang adalah apa yang harus ditutup gerbang berikutnya.

KontrolYang dihentikanYang dibiarkan terbuka
Scope token (TFE_TOKEN, atau bearer token lewat HTTP)Apa pun yang dilarang oleh izin token itu sendiri. Tanpa token, toolset registry-private dan terraform tidak pernah terdaftar.Semua yang boleh dilakukan token. Halaman deployment meminta Anda membatasi izinnya, karena server tidak akan mempersempitnya untuk Anda.
--toolsets atau --toolsTool di luar daftar tidak diekspos ke client sama sekali.Apa pun di dalam toolset yang dipilih. Kedua flag tidak bisa dipakai bersamaan, dan defaultnya berbeda di dua halaman resmi (lihat di bawah).
ENABLE_TF_OPERATIONS (default false)Registrasi action_run, delete_workspace_safely, force_unlock_workspace, delete_project, dan delete_team, serta opsi auto_approve dan is_destroy pada create_run.Tool yang tidak dicantumkan docs sebagai terkunci, termasuk create_workspace dan update_workspace, yang di halaman yang sama disebut berpotensi destruktif.
MCP_ORGANIZATION_ALLOWLIST (khusus HTTP)Panggilan yang menyebut organization di luar daftar. Jika aktif, bearer token harus bisa menjangkau minimal satu organization yang terdaftar; pencocokan tidak membedakan huruf besar kecil.stdio, yang tidak menyediakan flag ini. Saya juga tidak menemukan keterangan bahwa ia menyaring tool yang tidak punya argumen organization.
Jaringan: bind loopback, TLS, gatewayAkses tanpa autentikasi dari host lain. Mode HTTP bind ke 127.0.0.1 secara default.Caller yang memang sudah menjadi client resmi. Posisi di jaringan bukan identitas.

Dibaca dari atas ke bawah, urutan pertahanannya: jangan beri server token yang tidak dibutuhkan, jangan daftarkan tool yang tidak akan dipakai, biarkan lima tool destruktif mati, batasi organization, lalu batasi jaringan. Melewatkan baris pertama karena baris-baris berikutnya ada adalah kesalahan yang hendak dicegah tabel ini.

Setup lokal yang tidak bisa menjangkau production

Untuk satu developer di stdio, config paling aman adalah yang tidak bisa merusak walaupun modelnya dimanipulasi. Contoh client di README membawa token di argumen Docker, yang tidak masalah untuk percobaan pertama tetapi salah untuk file yang disinkronkan ke repositori dotfiles. Ada juga satu hal yang perlu dipastikan: README menyebut registry sebagai toolset default, sedangkan halaman reference mengatakan bahwa tanpa --toolsets server mengaktifkan semua toolset. Tanpa token keduanya hanya memberi registry, tetapi dengan token hasilnya bisa berbeda, jadi sebutkan toolset secara eksplisit.

// Wrong: a literal token in a config file that gets synced or committed,
// and no decision about which toolsets load or how the server is bounded.
{
  "mcpServers": {
    "terraform": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "TFE_ADDRESS=https://app.terraform.io",
        "-e", "TFE_TOKEN=paste-a-token-here",
        "hashicorp/terraform-mcp-server:1.3.0"
      ]
    }
  }
}

// Right: values live in the client's env block (kept out of the args), the
// image is pinned, and ENABLE_TF_OPERATIONS is simply absent, so it stays false.
{
  "mcpServers": {
    "terraform": {
      "command": "docker",
      "args": [
        "run", "-i", "--rm",
        "-e", "TFE_ADDRESS",
        "-e", "TFE_TOKEN",
        "hashicorp/terraform-mcp-server:1.3.0"
      ],
      "env": {
        "TFE_ADDRESS": "https://app.terraform.io",
        "TFE_TOKEN": "paste-a-narrowly-scoped-token-here"
      }
    }
  }
}

Jika Anda hanya butuh pencarian dokumentasi dan module, lewati token sama sekali. Itu setup lokal terkuat, karena toolset Terraform tidak bisa terdaftar tanpa token.

# Registry only, no token: the registry-private and terraform toolsets
# register only with a valid TFE_TOKEN, so this is a documentation search tool.
claude mcp add terraform -s user -t stdio -- \
  docker run -i --rm hashicorp/terraform-mcp-server:1.3.0

# Binary form, when you want to name the toolset instead of inferring it.
# --toolsets and --tools cannot be combined.
terraform-mcp-server stdio --toolsets registry

Buat team token khusus untuk agent dan beri nama sesuai agent-nya. Ketika sesuatu tampak janggal di audit trail HCP Terraform, token bernama agent-readonly memberi tahu siapa yang harus ditanya; token pribadi Anda tidak memberi tahu apa-apa.

Lima tool di balik ENABLE_TF_OPERATIONS

ENABLE_TF_OPERATIONS adalah saklar registrasi, bukan izin. Saat false, tool destruktif tidak ada di daftar tool, sehingga model tidak bisa memanggilnya walaupun sebuah prompt injection memintanya. Halaman reference menyebut lima tool yang membutuhkannya, dan mengatakan create_run membutuhkannya untuk membuka opsi auto_approve dan is_destroy.

ToolToolsetEfek menurut halaman referenceDikunci ENABLE_TF_OPERATIONS
action_runterraformMenerapkan, membatalkan, atau membuang run; bisa apply atau destroy infrastrukturYa
delete_workspace_safelyterraformMenghapus workspace secara permanenYa
force_unlock_workspaceterraformMembuka paksa workspace yang macet; butuh izin adminYa (ditambahkan di 1.1.0)
delete_projectterraformMenghapus project; gagal jika masih berisi workspace atau StacksYa (ditambahkan di 1.2.0)
delete_teamterraformMenghapus team secara permanenYa (ditambahkan di 1.3.0)
create_runterraformMembuat run; opsi auto_approve dan is_destroy membutuhkan variabel tersebutSebagian
create_workspace, update_workspaceterraformDisebut berpotensi destruktif, tetapi tidak dicantumkan sebagai butuh variabel tersebutTidak

Baris terakhir adalah celahnya. Dengan variabel mati, agent yang memegang token write biasa tetap bisa membuat dan mengubah workspace, dan menurut pembacaan saya atas docs ia bisa mengantrekan run yang berhenti sebelum auto-approval. Itu default yang layak, karena analisis plan lewat pembaca plan dan run adalah kegunaan utamanya, tetapi artinya variabel itu bukan jawaban lengkap. Jawabannya adalah tokennya: jika agent hanya perlu membaca, buat token yang hanya bisa membaca.

Menjalankannya sebagai layanan HTTP bersama

Halaman deployment merekomendasikan API gateway dengan autentikasi, TLS, dan IP allowlisting di antara client dan server, dan mengirim server dengan CORS strict serta daftar origin kosong secara default. Config di bawah menjaga port yang dipublikasikan tetap di loopback sehingga hanya gateway itu yang bisa menjangkaunya, mengatur organization allowlist, dan membiarkan ENABLE_TF_OPERATIONS tidak diset. README mewajibkan MCP_TLS_CERT_FILE dan MCP_TLS_KEY_FILE untuk deployment non-localhost, jadi akhiri TLS di gateway atau set kedua variabel itu.

# Shared service. TRANSPORT_HOST=0.0.0.0 is for inside the container;
# the host-side publish stays on loopback so only a gateway you run can reach it.
# ENABLE_TF_OPERATIONS is deliberately absent: its default is false.
docker run -d --name terraform-mcp --restart unless-stopped \
  -p 127.0.0.1:8080:8080 \
  -e TRANSPORT_MODE=streamable-http \
  -e TRANSPORT_HOST=0.0.0.0 \
  -e TFE_ADDRESS=https://app.terraform.io \
  -e MCP_ORGANIZATION_ALLOWLIST=acme-platform,acme-sandbox \
  -e MCP_CORS_MODE=strict \
  -e MCP_REMOTE_IP_METHOD=RemoteAddr \
  -e MCP_RATE_LIMIT_GLOBAL=5:10 \
  -e MCP_RATE_LIMIT_SESSION=2:5 \
  hashicorp/terraform-mcp-server:1.3.0

# Defaults are 10:20 global and 5:10 per session (rps:burst). The tighter
# values above are my choice for agents that can loop, not a HashiCorp number.

# A client then points at the endpoint (README form):
claude mcp add --transport http terraform http://localhost:8080/mcp

Satu jebakannya adalah IP client. Sejak 1.1.0 server memakai RemoteAddr dan mengabaikan X-Forwarded-For, yang memang benar, tetapi artinya di belakang gateway setiap request tampak berasal dari gateway. Jika Anda ingin alamat per client, set MCP_REMOTE_IP_METHOD ke X-Forwarded-For dan MCP_XFF_TRUSTED_HOPS tepat sejumlah proxy yang Anda jalankan. README memperingatkan bahwa nilai lain membuat client bisa memalsukan alamatnya.

Di mana setup ini masih bocor

Biaya pertama adalah upgrade. Jika ada client Anda yang mengirim TFE_ADDRESS di header atau query parameter, 1.1.0 menjawabnya dengan 403, dan token di query parameter ditolak dengan 400. Perbaikannya di sisi server: set TFE_ADDRESS di sana dan berhenti mengirimnya. Itu desain yang lebih baik, karena client yang bisa memilih host Terraform bisa mengarahkan server ke host yang ia kendalikan, tetapi akan terlihat seperti outage sampai Anda menemukan barisnya di catatan rilis.

Biaya kedua adalah stdio. Flag organization allowlist hanya tercantum di opsi streamable-http, jadi developer yang menjalankan server stdio lokal dengan token yang luas hanya dilindungi oleh token itu. Ketiga adalah TF_MCP_SHARED_SECRET, yang merupakan kredensial statis yang dikirim di header; README meminta agar hanya dipakai lewat TLS.

ENABLE_TF_OPERATIONS adalah saklar tingkat server. Saya tidak menemukan varian per client atau per sesi di docs, jadi menyalakannya mengaktifkan tool destruktif untuk semua client instance itu sekaligus. Jika Anda membutuhkannya untuk sesi yang diawasi, jalankan instance kedua di port lain dan jauhkan dari gateway bersama.

Semua ini tidak membuat server aman dipakai dengan model yang tidak tepercaya. Kontrol-kontrol ini membatasi kerusakan; mereka tidak membuat prompt injection mustahil, dan itulah sebabnya saran HashiCorp sendiri adalah menghindari client dan LLM yang tidak tepercaya sama sekali.

Yang dikerjakan hari Senin

Lima langkah, berurutan, masing-masing cukup murah untuk selesai sebelum makan siang.

  1. Pin tag image ke 1.3.0 dan baca release notes antara tag Anda sekarang dan berikutnya sebelum menaikkan versi minor.
  2. Mulai setiap instance dengan toolset registry tanpa token, dan tambahkan token hanya ketika sebuah tugas benar-benar butuh data workspace.
  3. Ketika menambah token, buat team token khusus dengan izin tersempit yang masih berfungsi, dan biarkan ENABLE_TF_OPERATIONS tidak diset.
  4. Untuk deployment bersama, set MCP_ORGANIZATION_ALLOWLIST, jaga port yang dipublikasikan tetap di loopback di belakang gateway ber-TLS, dan set MCP_XFF_TRUSTED_HOPS ke angka yang tepat atau jangan disentuh.
  5. Jalankan tiga pengecekan di bawah sekarang dan lagi setelah setiap upgrade.
# 1. What the running container actually has. If ENABLE_TF_OPERATIONS=true
#    shows up on a box agents can reach, that is the finding.
docker inspect terraform-mcp \
  --format '{{range .Config.Env}}{{println .}}{{end}}' \
  | grep -E '^(ENABLE_TF_OPERATIONS|MCP_ORGANIZATION_ALLOWLIST|TFE_SKIP_TLS_VERIFY|MCP_REMOTE_IP_METHOD|MCP_XFF_TRUSTED_HOPS)='

# 2. Which version answers. The /health response gained a version field in 1.2.0.
curl -s http://127.0.0.1:8080/health

# 3. The 1.1.0 breaking change as a smoke test. The release notes say a
#    TFE_ADDRESS in a header or query parameter gets a 403. I have not
#    observed this output myself; anything else is a reason to read the logs.
curl -s -o /dev/null -w "%{http_code}\n" \
  "http://127.0.0.1:8080/mcp?TFE_ADDRESS=https://attacker.example"

Perintah pertama yang paling berguna. Ia mencetak apa yang benar-benar dipakai container, yang jarang sama dengan isi compose file yang Anda ingat.

Aturan yang saya bawa dari sini: perlakukan MCP server untuk Terraform sebagai kredensial yang dilengkapi menu tool. Setiap kontrol di 1.1.0 sampai 1.3.0 entah mengecilkan menu atau mempersempit kredensial, jadi putuskan keduanya dengan sengaja, pin versinya, dan baca ulang release notes sebelum setiap upgrade minor.

FAQ

Pertanyaan Umum

Jawaban singkat untuk pertanyaan yang paling sering diajukan pembaca tentang topik ini.

Apa itu Terraform MCP server?

Ini adalah MCP server open-source dari HashiCorp yang memungkinkan AI agent bekerja dengan Terraform, dari mencari dokumentasi registry sampai membaca plan dan workspace. Server ini mencapai general availability sebagai 1.0.0 pada 9 Juni 2026 dan mendukung transport stdio dan StreamableHTTP. HashiCorp memperingatkan agar tidak dipakai dengan MCP client atau LLM yang tidak tepercaya.

Apa fungsi ENABLE_TF_OPERATIONS di Terraform MCP server?

Ini adalah saklar registrasi dengan default false. Selama mati, action_run, delete_workspace_safely, force_unlock_workspace, delete_project, dan delete_team tidak terdaftar, dan create_run tidak bisa memakai auto_approve atau is_destroy. Biarkan tidak diset di setiap instance bersama.

Bagaimana membatasi Terraform MCP server ke organization tertentu?

Set MCP_ORGANIZATION_ALLOWLIST berisi daftar nama organization dipisah koma, atau pakai flag --organization-allowlist pada mode streamable-http. Mulai 1.2.0, panggilan tool yang terraform_org_name-nya tidak ada di daftar akan ditolak. Environment variable lebih diutamakan daripada flag.

Kenapa client saya mendapat 403 setelah upgrade ke Terraform MCP server 1.1.0?

Versi 1.1.0 membawa breaking change: pada streamable HTTP mode, request yang mengirim TFE_ADDRESS di header atau query parameter kini mendapat 403. Set TFE_ADDRESS di server dan berhenti mengirimnya dari client. Rilis yang sama juga berhenti mempercayai X-Forwarded-For secara default.

Apakah aman memberi AI agent token Terraform lewat MCP server?

Keamanannya setara dengan token yang Anda berikan, karena server memakai izin Terraform yang sudah ada dan tidak menambah izin sendiri. Pakai token khusus dengan izin tersempit, muat hanya toolset yang dibutuhkan, dan biarkan ENABLE_TF_OPERATIONS mati. Semua itu tidak membuat model yang tidak tepercaya jadi aman, jadi jauhkan client yang tidak tepercaya.