Bài 13: Terraform Data Sources Truy Vấn Thông Tin Hạ Tầng


Danh sách bài viết trong series Terraform Associate (003)

Terraform Data Sources Là Gì?

8f62ece8-374a-4a14-84ce-233fcf45fa54

Terraform Data Sources là cơ chế cho phép bạn truy vấn và lấy thông tin từ hạ tầng hiện có hoặc từ nhà cung cấp dịch vụ (VD: AWS, Azure) để sử dụng trong cấu hình Terraform. Data Sources không tạo tài nguyên mà chỉ đọc dữ liệu (read-only), chẳng hạn như AMI mới nhất, thông tin VPC, hoặc subnet ID. Data Sources được khai báo trong block data và được tham chiếu bằng cú pháp data.<TYPE>.<NAME>.<ATTRIBUTE>. Hiểu và sử dụng Data Sources là kỹ năng quan trọng trong kỳ thi Terraform Associate (003), liên quan đến mục tiêu 7 (Read, Generate, and Modify Configuration).

Vai Trò Của Data Sources Trong Quản Lý Hạ Tầng

Data Sources đóng vai trò quan trọng trong quản lý hạ tầng:

  • Truy vấn thông tin động: Lấy dữ liệu thời gian thực (VD: AMI mới nhất) mà không cần hardcode.
  • Tích hợp tài nguyên hiện có: Sử dụng tài nguyên đã tồn tại (VD: VPC, subnet) trong cấu hình.
  • Tối ưu hóa cấu hình: Giảm phụ thuộc vào giá trị tĩnh, tăng tính linh hoạt.
  • Hỗ trợ tự động hóa: Dùng Data Sources để cung cấp dữ liệu đầu vào cho resource hoặc module.
  • Tái sử dụng hạ tầng: Kết nối với các tài nguyên đã được tạo bởi đội khác hoặc công cụ khác.

Cấu Trúc Và Khai Báo Data Sources

Cú Pháp Cơ Bản Của Data Source

Cú pháp khai báo một Data Source:

data "<PROVIDER>_<TYPE>" "<NAME>" {
  [CONFIGURATION]
}
  • <PROVIDER>_<TYPE>: Loại Data Source (VD: aws_ami, aws_vpc).
  • <NAME>: Tên duy nhất trong dự án (VD: latest_ami).
  • [CONFIGURATION]: Điều kiện lọc hoặc tham số (VD: filter cho AMI).

Các Loại Data Source Phổ Biến

  • aws_ami: Truy vấn AMI (VD: tìm AMI Amazon Linux 2 mới nhất).
  • aws_vpc: Truy vấn thông tin VPC hiện có.
  • aws_subnet_ids: Lấy danh sách subnet ID trong một VPC.
  • aws_availability_zones: Lấy danh sách vùng khả dụng (Availability Zones).
  • aws_caller_identity: Lấy thông tin tài khoản AWS hiện tại.

Sử Dụng Data Sources Để Truy Vấn Thông Tin

Truy Vấn AMI Mới Nhất

  • File main.tf:

    provider "aws" {
    region     = "us-east-1"
    access_key = "YOUR_ACCESS_KEY"
    secret_key = "YOUR_SECRET_KEY"
    }
    
    data "aws_ami" "latest_amazon_linux" {
    most_recent = true
    owners      = ["amazon"]
    
    filter {
      name   = "name"
      values = ["amzn2-ami-hvm-*-x86_64-gp2"]
    }
    
    filter {
      name   = "virtualization-type"
      values = ["hvm"]
    }
    }
    
    resource "aws_instance" "web_server" {
    ami           = data.aws_ami.latest_amazon_linux.id
    instance_type = "t2.micro"
    tags = {
      Name = "WebServer"
    }
    }
    
    output "ami_id" {
    value = data.aws_ami.latest_amazon_linux.id
    }
    
    output "instance_id" {
    value = aws_instance.web_server.id
    }
  • Quy trình:

    1. terraform init: Output:

      Initializing provider plugins...
      - Finding hashicorp/aws versions matching "~> 5.0"...
      - Installing hashicorp/aws v5.17.0...
      - Installed hashicorp/aws v5.17.0 (signed by HashiCorp)
      
      Terraform has been successfully initialized!
    2. terraform apply -auto-approve: Output:

      data.aws_ami.latest_amazon_linux: Reading...
      data.aws_ami.latest_amazon_linux: Read complete after 2s [id=ami-0c55b159cbfafe1f0]
      
      aws_instance.web_server: Creating...
      aws_instance.web_server: Creation complete after 45s [id=i-1234567890abcdef0]
      
      Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
      
      Outputs:
      ami_id = "ami-0c55b159cbfafe1f0"
      instance_id = "i-1234567890abcdef0"

Truy Vấn Thông Tin VPC Tồn Tại

  • File main.tf:

    provider "aws" {
    region     = "us-east-1"
    access_key = "YOUR_ACCESS_KEY"
    secret_key = "YOUR_SECRET_KEY"
    }
    
    data "aws_vpc" "existing_vpc" {
    filter {
      name   = "tag:Name"
      values = ["my-vpc"]
    }
    }
    
    data "aws_subnet_ids" "existing_subnets" {
    vpc_id = data.aws_vpc.existing_vpc.id
    filter {
      name   = "tag:Type"
      values = ["public"]
    }
    }
    
    resource "aws_instance" "web_server" {
    ami           = "ami-0c55b159cbfafe1f0"
    instance_type = "t2.micro"
    subnet_id     = tolist(data.aws_subnet_ids.existing_subnets.ids)[0]
    tags = {
      Name = "WebServer"
    }
    }
    
    output "vpc_id" {
    value = data.aws_vpc.existing_vpc.id
    }
    
    output "subnet_id" {
    value = tolist(data.aws_subnet_ids.existing_subnets.ids)[0]
    }
  • Quy trình:
    1. terraform init: Output:
      Initializing provider plugins...
      Finding hashicorp/aws versions matching "~> 5.0"...
      Installing hashicorp/aws v5.17.0...
      Installed hashicorp/aws v5.17.0 (signed by HashiCorp)
      Terraform has been successfully initialized!
    2. terraform apply -auto-approve: Output:
      data.aws_vpc.existing_vpc: Reading...
      data.aws_vpc.existing_vpc: Read complete after 1s [id=vpc-12345678]
      data.aws_subnet_ids.existing_subnets: Reading...
      data.aws_subnet_ids.existing_subnets: Read complete after 1s [id=subnet-12345678]
      aws_instance.web_server: Creating...
      aws_instance.web_server: Creation complete after 45s [id=i-1234567890abcdef0]
      Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
      Outputs:
      vpc_id = "vpc-12345678"
      subnet_id = "subnet-12345678"

Ví Dụ Thực Tế: Sử Dụng Data Sources Với AWS

  • File main.tf (kết hợp nhiều Data Sources):

    provider "aws" {
    region     = "us-east-1"
    access_key = "YOUR_ACCESS_KEY"
    secret_key = "YOUR_SECRET_KEY"
    }
    
    data "aws_ami" "latest_amazon_linux" {
    most_recent = true
    owners      = ["amazon"]
    
    filter {
      name   = "name"
      values = ["amzn2-ami-hvm-*-x86_64-gp2"]
    }
    }
    
    data "aws_vpc" "default_vpc" {
    default = true
    }
    
    data "aws_subnet_ids" "default_subnets" {
    vpc_id = data.aws_vpc.default_vpc.id
    }
    
    data "aws_availability_zones" "available" {
    state = "available"
    }
    
    resource "aws_instance" "web_server" {
    count         = 2
    ami           = data.aws_ami.latest_amazon_linux.id
    instance_type = "t2.micro"
    subnet_id     = tolist(data.aws_subnet_ids.default_subnets.ids)[count.index % length(data.aws_subnet_ids.default_subnets.ids)]
    availability_zone = data.aws_availability_zones.available.names[count.index % length(data.aws_availability_zones.available.names)]
    tags = {
      Name = "WebServer-${count.index}"
    }
    }
    
    output "ami_id" {
    value = data.aws_ami.latest_amazon_linux.id
    }
    
    output "vpc_id" {
    value = data.aws_vpc.default_vpc.id
    }
    
    output "subnet_ids" {
    value = data.aws_subnet_ids.default_subnets.ids
    }
    
    output "availability_zones" {
    value = data.aws_availability_zones.available.names
    }
    
    output "instance_ids" {
    value = aws_instance.web_server[*].id
    }
  • Quy trình:
    1. terraform init: Output:
      Initializing provider plugins...
      Finding hashicorp/aws versions matching "~> 5.0"...
      Installing hashicorp/aws v5.17.0...
      Installed hashicorp/aws v5.17.0 (signed by HashiCorp)
      Terraform has been successfully initialized!
    2. terraform apply -auto-approve: Output:
      data.aws_ami.latest_amazon_linux: Reading...
      data.aws_ami.latest_amazon_linux: Read complete after 2s [id=ami-0c55b159cbfafe1f0]
      data.aws_vpc.default_vpc: Reading...
      data.aws_vpc.default_vpc: Read complete after 1s [id=vpc-12345678]
      data.aws_subnet_ids.default_subnets: Reading...
      data.aws_subnet_ids.default_subnets: Read complete after 1s [id=subnet-12345678]
      data.aws_availability_zones.available: Reading...
      data.aws_availability_zones.available: Read complete after 1s
      aws_instance.web_server[0]: Creating...
      aws_instance.web_server[1]: Creating...
      aws_instance.web_server[0]: Creation complete after 45s [id=i-0abcdef123456789]
      aws_instance.web_server[1]: Creation complete after 45s [id=i-1abcdef123456789]
      Apply complete! Resources: 2 added, 0 changed, 0 destroyed.
      Outputs:
      ami_id = "ami-0c55b159cbfafe1f0"
      vpc_id = "vpc-12345678"
      subnet_ids = [
      "subnet-12345678",
      "subnet-87654321"
      ]
      availability_zones = [
      "us-east-1a",
      "us-east-1b"
      ]
      instance_ids = [
      "i-0abcdef123456789",
      "i-1abcdef123456789"
      ]

Lưu Ý Quan Trọng Khi Sử Dụng Data Sources

  • Chỉ đọc, không tạo: Data Sources không tạo tài nguyên, chỉ truy vấn dữ liệu.
  • Kiểm tra tồn tại: Đảm bảo tài nguyên truy vấn (VD: VPC, subnet) tồn tại, nếu không Terraform sẽ báo lỗi.
  • Tối ưu truy vấn: Sử dụng filter để thu hẹp kết quả (VD: tìm đúng AMI).
  • Phụ thuộc ngầm: Data Sources tự động tạo phụ thuộc (VD: aws_instance sẽ đợi aws_ami hoàn thành).
  • Xử lý lỗi: Nếu truy vấn thất bại (VD: “No matching AMI found”), kiểm tra filter hoặc owners.

Liên Hệ Với Chứng Chỉ Terraform Associate (003)

Kỳ thi Terraform Associate (003) kiểm tra khả năng sử dụng Data Sources. Bạn cần nắm:

  • Câu hỏi mẫu:
    • “Data Source trong Terraform dùng để làm gì?”
      Đáp án: Truy vấn thông tin từ nhà cung cấp hoặc hạ tầng hiện có.
    • “Làm thế nào để lấy AMI mới nhất với Data Source?”
      Đáp án: Sử dụng data "aws_ami" với most_recent = truefilter.
    • “Kết quả của Data Source được tham chiếu như thế nào?”
      Đáp án: Dùng data.<TYPE>.<NAME>.<ATTRIBUTE>.
  • Thực hành: Kỳ thi có thể yêu cầu nhận diện cấu hình Data Source hoặc dự đoán output khi sử dụng.

Kết Luận

Terraform Data Sources là công cụ mạnh mẽ để truy vấn thông tin hạ tầng, giúp cấu hình linh hoạt và động hơn. Hiểu cách khai báo, sử dụng Data Sources, và thực hành với ví dụ thực tế sẽ giúp bạn tự tin thi đỗ Terraform Associate (003). Ở bài tiếp theo, chúng ta sẽ tìm hiểu cách xử lý vòng đời tài nguyên với Terraform.

Điều hướng chuỗi bài viết<< Bài 12: Terraform Module: Mô-đun Hóa Cấu Hình
>> Bài 14: Quản Lý Vòng Đời Tài Nguyên Với Terraform

Bài viết khác

Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận

Có thể bạn quan tâm