OpenCode là agentic coding tool mã nguồn mở, cho phép bạn tự chọn model backend (Claude, GPT, model local qua Ollama...) và tùy biến sâu hành vi agent qua config file. Khi ghép với Terraform MCP, OpenCode trở thành một lựa chọn linh hoạt cho team muốn kiểm soát chi phí model hoặc chạy hoàn toàn on-premise cho hạ tầng nhạy cảm. Bài này hướng dẫn cài đặt, quy trình validate/plan, một ví dụ refactor thực tế, và các hạn chế cần biết trước khi đưa vào quy trình chính thức.
Cài Đặt Và Kết Nối Terraform MCP Vào OpenCode
OpenCode quản lý MCP server qua file opencode.json ở root project (hoặc ~/.config/opencode/opencode.json cho cấu hình toàn cục). Cấu trúc tương tự chuẩn MCP chung nhưng OpenCode có thêm field enabled cho phép tắt/mở nhanh từng server mà không cần xóa cấu hình.
{
"mcp": {
"terraform": {
"type": "local",
"command": ["terraform-mcp-server", "--workdir", "./infra/staging"],
"enabled": true,
"environment": {
"AWS_PROFILE": "terraform-agent-readonly"
}
}
}
}
Khởi động OpenCode và kiểm tra server đã kết nối:
opencode
/mcp
Lệnh /mcp liệt kê trạng thái từng server MCP đã khai báo — nếu terraform hiện ● connected, bạn có thể bắt đầu dùng. Nếu hiện ✗ failed, nguyên nhân phổ biến nhất là binary terraform-mcp-server không nằm trong PATH, hoặc --workdir chỉ tới thư mục không có file .tf nào (server khởi tạo thất bại vì không tìm thấy Terraform configuration).
Mẹo: Test riêng binary trước khi tích hợp vào OpenCode: chạy trực tiếp
terraform-mcp-server --workdir ./infra/stagingngoài terminal, xem log stderr có lỗi gì không. Debug MCP server độc lập với client luôn nhanh hơn debug qua lớp OpenCode, vì bạn thấy log gốc thay vì log đã bị OpenCode bọc lại.
Chạy Validate Và Plan Từ OpenCode
Với OpenCode, cách prompt hiệu quả nhất là chia nhỏ tác vụ theo từng bước rõ ràng, vì OpenCode (tùy model backend bạn chọn) có thể ít "chủ động" gọi nhiều tool liên tiếp hơn Claude Code nếu bạn chỉ đưa yêu cầu mơ hồ.
Bước 1: chạy terraform_validate cho module hiện tại, báo lỗi cú pháp nếu có.
Bước 2: nếu validate pass, chạy terraform_plan.
Bước 3: tóm tắt plan theo 3 nhóm create/update/destroy,
liệt kê rõ resource nào bị destroy hoặc replace.
Output mẫu agent trả về sau khi chạy đủ 3 bước:
[validate] OK - 0 errors, 0 warnings
[plan] Tổng: 4 to add, 1 to change, 0 to destroy
Create: aws_db_subnet_group.main, aws_security_group.db,
aws_security_group_rule.db_ingress_app,
aws_db_instance.postgres
Update: aws_vpc.main (thêm tag "Environment=staging")
Destroy: (không có)
Vì kết quả plan này không có resource nào bị destroy/replace, đây là plan an toàn để apply. Nhưng nguyên tắc vẫn giữ nguyên như mọi công cụ khác: agent chỉ nên dừng ở bước generate và tóm tắt, con người là người ra lệnh terraform apply cuối cùng, đặc biệt với resource stateful như aws_db_instance ở ví dụ trên — dù lần này chỉ là "create" (chưa có rủi ro mất dữ liệu), việc giữ nguyên tắc nhất quán quan trọng hơn việc xét từng trường hợp một.
Mẹo: Với OpenCode, tách rõ prompt thành các bước đánh số (1, 2, 3...) như ví dụ trên thường cho kết quả nhất quán hơn một prompt dài mô tả toàn bộ mong muốn trong một câu — đặc biệt quan trọng khi bạn dùng model nhỏ hơn (chạy local qua Ollama) để tiết kiệm chi phí.
Ví Dụ Thực Tế: Refactor Resource Trùng Lặp Thành Module
Một tình huống rất phổ biến: team viết Terraform config kiểu "copy-paste" — 3 security group gần giống nhau cho 3 microservice, chỉ khác vài port. Đây là lúc AI agent hỗ trợ refactor rất hiệu quả nếu bạn hướng dẫn đúng.
Config ban đầu (rút gọn) trong main.tf:
resource "aws_security_group" "svc_orders" {
name = "svc-orders-sg"
vpc_id = aws_vpc.main.id
ingress {
from_port = 8081
to_port = 8081
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]
}
}
resource "aws_security_group" "svc_billing" {
name = "svc-billing-sg"
vpc_id = aws_vpc.main.id
ingress {
from_port = 8082
to_port = 8082
protocol = "tcp"
cidr_blocks = ["10.0.0.0/16"]
}
}
Prompt cho OpenCode:
Trong main.tf có 3 security group gần giống nhau (svc_orders,
svc_billing, svc_notification), chỉ khác port. Refactor thành
một module "service_sg" nhận input service_name và port, sinh
ra security group tương ứng. Cập nhật main.tf để gọi module này
3 lần thay cho 3 resource block cũ. Sau khi sửa, chạy plan và
xác nhận không có resource nào bị destroy/replace ngoài ý muốn.
Kết quả mong đợi: module mới modules/service_sg/, và ở main.tf gốc, ba lệnh gọi module thay cho ba resource block. Điểm mấu chốt cần verify: vì tên resource sau refactor thay đổi (từ aws_security_group.svc_orders sang module.svc_orders_sg.aws_security_group.this), Terraform sẽ coi đây là destroy resource cũ + create resource mới nếu không xử lý đúng — trừ khi bạn dùng terraform state mv để giữ nguyên resource, tránh việc security group đang gắn vào instance chạy production bị xóa đi tạo lại không cần thiết.
terraform state mv aws_security_group.svc_orders \
module.svc_orders_sg.aws_security_group.this
Mẹo: Sau bất kỳ lần refactor nào đổi tên/resource address, luôn chạy
terraform planngay và tìm dòng# forces replacementhoặcwill be destroyedtrước khi commit — nếu thấy resource stateful (DB, security group đang gắn traffic thật) nằm trong danh sách này, dùngterraform state mvđể giữ nguyên resource thay vì để Terraform destroy/create lại.
Hạn Chế Cần Biết Của Terraform MCP Trong OpenCode
Không phải mọi thứ đều mượt. Một số hạn chế thực tế khi dùng OpenCode với Terraform MCP mà bạn nên biết trước để tránh bất ngờ:
- Model nhỏ dễ "quên" gọi tool đúng thứ tự. Nếu bạn dùng model local nhỏ (7B-13B) qua Ollama để tiết kiệm chi phí, khả năng lập kế hoạch tool-calling nhiều bước (multi-step) yếu hơn model lớn — nên chia prompt thành từng bước rõ ràng như phần trước, đừng kỳ vọng agent tự lên kế hoạch phức tạp.
- Không có sandbox mặc định cho lệnh apply. Khác với một số IDE tích hợp có cơ chế "require confirmation" mặc định cho tool nguy hiểm, OpenCode để việc này tùy vào cấu hình permission bạn khai báo — cần tự thêm rule chặn
terraform_applyvào danh sách cần approval tường minh. - Context window giới hạn với plan output lớn. Với hạ tầng lớn (hàng trăm resource), output
terraform plan -jsoncó thể vượt quá context window (cửa sổ ngữ cảnh) của model đang dùng, khiến agent chỉ đọc được một phần plan mà không báo rõ nó đã bị cắt. Nên luôn filter plan theo module con (-target=module.xxx) khi hạ tầng lớn, tránh dump toàn bộ.
{
"permission": {
"terraform_apply": "ask",
"terraform_plan": "allow",
"terraform_validate": "allow"
}
}
Mẹo: Luôn set permission
"terraform_apply": "ask"tường minh trongopencode.json, đừng để giá trị mặc định của tool đó tự quyết — mặc định có thể thay đổi giữa các version OpenCode, còn config tường minh của bạn thì không đổi.
Mẹo Thực Chiến Để Dùng OpenCode Với Terraform Hiệu Quả Hơn
Sau khi đã setup và biết rõ hạn chế, đây là vài kinh nghiệm thực tế giúp workflow OpenCode + Terraform MCP mượt hơn trong công việc hàng ngày, đặc biệt khi bạn phải xử lý nhiều repo infra hoặc nhiều model backend khác nhau:
- Chuẩn hóa prompt template theo bước, lưu thành file dùng lại. Vì OpenCode nhạy với cách chia bước hơn các công cụ khác, hãy lưu các prompt "Bước 1/2/3" đã hoạt động tốt vào một file
.opencode/prompts/plan-review.mdtrong repo, để cả team dùng lại thay vì mỗi người tự viết lại từ đầu. - Luôn pin version của
terraform-mcp-servertrong tài liệu cài đặt của team, vì đây là dự án phát triển nhanh, một bản cập nhật có thể đổi tên tool (ví dụterraform_planđổi thànhplan) khiến prompt cũ không còn hoạt động đúng. - Với repo có nhiều module con, đặt nhiều entry MCP server riêng theo từng
--workdir(ví dụterraform-network,terraform-database) thay vì một server trỏ vào root — giúp agent luôn biết rõ đang làm việc với module nào, giảm rủi ro chạy nhầm plan trên module không liên quan tới yêu cầu.
{
"mcp": {
"terraform-network": {
"type": "local",
"command": ["terraform-mcp-server", "--workdir", "./infra/network"],
"enabled": true
},
"terraform-database": {
"type": "local",
"command": ["terraform-mcp-server", "--workdir", "./infra/database"],
"enabled": false
}
}
}
Chỉ bật (enabled: true) đúng server bạn đang cần làm việc trong phiên hiện tại, tắt các server còn lại — cách này giảm khả năng agent nhầm module khi bạn có nhiều context mở cùng lúc.
Mẹo: Đừng bật tất cả MCP server Terraform của mọi module cùng lúc "cho chắc" — chỉ bật đúng server của module bạn đang thực sự sửa. Càng ít tool khả dụng không liên quan, agent càng ít khả năng gọi nhầm tool vào module sai trong một phiên làm việc dài.