Tình huống
Pipeline CI/CD của bạn vừa thất bại ở bước terraform plan. Hoặc bạn đang chạy local và gặp lỗi này:
Error: Invalid provider configuration
on main.tf line 12, in provider "aws":
12: region = var.aws_region
The root module's provider configuration for "aws" is not compatible with the provider "registry.terraform.io/hashicorp/aws" v5.x.x.
Đôi khi thông báo lỗi còn kém rõ ràng hơn — chỉ là Error: Invalid provider configuration với một con trỏ mơ hồ đến provider block của bạn. Dù thế nào, Terraform đang từ chối tiếp tục.
Lỗi này khác với thiếu credentials hoặc không tìm thấy plugin provider. Provider của bạn tồn tại, credentials có thể ổn — nhưng có gì đó trong chính configuration block bị sai.
Nguyên nhân
Terraform xác thực mọi provider block trước khi làm bất cứ điều gì khác. Một số nguyên nhân phổ biến gây ra Error: Invalid provider configuration:
- Thuộc tính lỗi thời hoặc bị đổi tên — ví dụ: dùng
skip_credentials_validationtrong AWS provider v5 nơi nó đã bị loại bỏ - Tên thuộc tính sai — lỗi đánh máy như
reagionthay vìregion - Phiên bản provider không khớp — provider block của bạn dùng các thuộc tính chỉ tồn tại trong v4.x nhưng
required_providersghim vào v5.x (hoặc ngược lại) - Xung đột provider alias — hai provider block có cùng alias, hoặc một module mong đợi alias cụ thể không khớp với những gì bạn khai báo
- Truyền giá trị null/rỗng vào trường bắt buộc — ví dụ:
region = var.aws_regionkhiaws_regionkhông có giá trị mặc định và không được truyền vào
Bước 1 — Xác định chính xác thuộc tính nào gây ra vấn đề
Chạy terraform validate trước — thường cho thông báo lỗi rõ ràng hơn plan:
terraform validate
Nếu thông báo lỗi chỉ đến số dòng cụ thể, hãy mở file đó và kiểm tra provider block. Sau đó chạy:
terraform providers
Lệnh này hiển thị phiên bản provider nào đang thực sự bị khóa. So sánh với những gì trong required_providers block và .terraform.lock.hcl của bạn.
Kiểm tra trực tiếp lock file:
cat .terraform.lock.hcl
Bạn đang tìm kiếm sự không khớp phiên bản — phiên bản bị khóa so với phiên bản mà code của bạn được viết cho.
Sửa nhanh — Các trường hợp phổ biến nhất
Trường hợp 1: Thuộc tính lỗi thời sau khi nâng cấp provider
AWS provider v5 đã loại bỏ một số thuộc tính cũ. Nếu bạn đã nâng cấp từ v4 lên v5 mà không cập nhật provider block, bạn sẽ gặp lỗi này. Kiểm tra changelog của provider để biết các thuộc tính bị loại bỏ trước khi cho rằng code vẫn ổn.
Ví dụ — xóa thuộc tính lỗi thời:
# Trước (lỗi với AWS provider v5)
provider "aws" {
region = var.aws_region
skip_credentials_validation = true # đã bị loại bỏ trong v5
skip_requesting_account_id = true # đã bị loại bỏ trong v5
}
# Sau
provider "aws" {
region = var.aws_region
}
Trường hợp 2: Biến có giá trị null hoặc rỗng
Giá trị biến null là nguyên nhân tinh vi của lỗi này. Khi provider block tham chiếu đến một biến không có giá trị lúc runtime, Terraform thất bại trong quá trình xác thực — không phải lúc nào cũng có thông báo làm rõ điều này.
Kiểm tra bằng cách truyền giá trị tường minh:
terraform plan -var="aws_region=us-east-1"
Hoạt động rồi? Vậy thì biến của bạn không có giá trị lúc runtime. Thêm giá trị mặc định hoặc truyền qua môi trường CI/CD của bạn:
variable "aws_region" {
type = string
default = "us-east-1" # thêm dòng này
}
Trường hợp 3: Provider alias không khớp
Sự không khớp alias rất dễ bỏ qua. Một module mong đợi provider alias secondary sẽ thất bại nếu bạn truyền replica thay thế — Terraform rất nghiêm ngặt về tên alias chính xác. Kiểm tra module mong đợi gì:
# Kiểm tra alias mà module mong đợi
terraform providers
Sau đó khớp chính xác provider block của root module:
provider "aws" {
alias = "secondary" # phải khớp chính xác với những gì module mong đợi
region = "eu-west-1"
}
module "replication" {
source = "./modules/replication"
providers = {
aws.secondary = aws.secondary
}
}
Sửa triệt để — Khóa phiên bản provider đúng cách
Nguyên nhân gốc rễ thường là phiên bản provider không bị ràng buộc đã nâng cấp âm thầm và phá vỡ cấu hình của bạn. Luôn ghim providers trong required_providers:
terraform {
required_version = ">= 1.3.0"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0" # cho phép nâng cấp patch, chặn nhảy phiên bản major
}
google = {
source = "hashicorp/google"
version = "~> 5.20"
}
}
}
Toán tử ~> cho phép nâng cấp minor/patch trong cùng phiên bản major. Dùng = 5.31.0 nếu bạn muốn build hoàn toàn có thể tái tạo.
Sau khi cập nhật, khởi tạo lại để tạo mới lock file:
terraform init -upgrade
Kiểm tra cấu trúc provider block
Đây là provider block tối giản, gọn gàng giúp tránh các lỗi phổ biến nhất:
provider "aws" {
region = var.aws_region
# Chỉ thêm những thứ này nếu bạn thực sự cần
# profile = "my-named-profile" # cho dev local với AWS CLI profiles
# assume_role {
# role_arn = "arn:aws:iam::123456789012:role/TerraformRole"
# }
}
Giữ nó tối giản. Đừng copy-paste provider block từ các hướng dẫn cũ — chúng thường chứa các thuộc tính từ phiên bản provider cũ không còn tồn tại nữa.
Xác minh bản sửa lỗi
Sau khi thực hiện thay đổi, chạy lần lượt theo thứ tự:
# 1. Khởi tạo lại (bắt buộc nếu bạn thay đổi required_providers)
terraform init
# 2. Xác thực cấu hình
terraform validate
# 3. Chạy plan để xác nhận mọi thứ hoạt động
terraform plan
Kết quả terraform validate thành công trông như sau:
Success! The configuration is valid.
Mẹo
Debug một provider block phức tạp — đặc biệt là block có nested blocks — sẽ dễ hơn khi bạn xác thực cấu trúc riêng trước. Tôi dùng YAML ↔ JSON Converter tại ToolCraft để kiểm tra config có đúng định dạng không trước khi đụng vào Terraform. Nó chạy hoàn toàn trên trình duyệt, không upload dữ liệu — điều này quan trọng khi bạn làm việc với infra configs.
Một thói quen đáng xây dựng: mỗi khi nâng cấp phiên bản provider, hãy quét changelog để tìm các thuộc tính bị loại bỏ hoặc đổi tên trước khi chạy terraform init -upgrade. Các phiên bản major của provider (v3→v4→v5) hầu như luôn bao gồm các thay đổi breaking trong chính provider block.

