Monday, January 20, 2025

[Terraform] Lesson 6 – Resource Meta Arguments

-

1. Resource Meta Arguments là gì?

Resource Meta Arguments trong Terraform là các thuộc tính đặc biệt được sử dụng để quản lý tài nguyên trong các khối dữ liệu (resource blocks) của Terraform. Những thuộc tính này không phải là thuộc tính thông thường như các thuộc tính được định nghĩa bởi provider, mà là các thuộc tính đặc biệt được sử dụng để kiểm soát cách Terraform quản lý tài nguyên.

2. Các thuộc tính.

Có nhiều thuộc tính Meta Arguments khác nhau, bao gồm:

  • depends_on: Chỉ định các phụ thuộc giữa các tài nguyên trong khối dữ liệu. Terraform sẽ đảm bảo rằng các tài nguyên được tạo ra theo thứ tự đúng để đảm bảo rằng các phụ thuộc của chúng được đáp ứng.
  • count: Xác định số lượng các phiên bản tài nguyên được tạo ra. Thường được sử dụng để tạo ra nhiều tài nguyên có cùng cấu trúc, ví dụ như nhiều máy chủ trong một nhóm.
  • for_each: Tương tự như count, nhưng sử dụng một bản đồ để xác định số lượng các phiên bản tài nguyên được tạo ra.
  • lifecycle: Cho phép bạn quản lý vòng đời của tài nguyên. Thuộc tính này có thể được sử dụng để chỉ định các hành động được thực hiện khi tài nguyên được thay đổi, hoặc khi tài nguyên được xóa.

3. Cú pháp khai báo.

Resource Meta Arguments được khai báo trong phần meta của một resource, có thể được sử dụng để thêm các cấu hình bổ sung cho resource đó, bao gồm:

  • depends_on: Xác định rằng resource này phải được tạo ra trước hoặc sau các resource khác được liệt kê. Điều này đảm bảo rằng các resource được tạo ra theo đúng thứ tự.
  • count: Xác định số lượng instance của một resource sẽ được tạo ra. Khi sử dụng argument này, bạn cần cung cấp một biểu thức để tính toán số lượng instance.
  • for_each: Tương tự như count, tuy nhiên for_each sử dụng một bản đồ hoặc tập hợp để định danh các instance của một resource.
  • lifecycle: Xác định cách Terraform xử lý các thay đổi trạng thái của một resource. Ví dụ như, sử dụng prevent_destroy để ngăn chặn việc xóa resource.

Dưới đây là ví dụ về cú pháp khai báo Resource Meta Arguments:

resource "aws_instance" "example" {
  count = 2

  ami           = "ami-0c55b159cbfafe1f0"
  instance_type = "t2.micro"

  tags = {
    Name = "example-instance-${count.index}"
  }

  lifecycle {
    ignore_changes = [
      ebs_block_device.volume_type,
    ]
  }
}

resource "aws_ebs_volume" "example" {
  count = 2

  availability_zone = "us-west-2a"
  size              = 1

  depends_on = [
    aws_instance.example[0],
    aws_instance.example[1],
  ]

  lifecycle {
    prevent_destroy = true
  }
}

Trong ví dụ trên, count được sử dụng để tạo hai instance của aws_instance.exampleaws_ebs_volume.example. depends_on được sử dụng để đảm bảo rằng aws_ebs_volume.example được tạo ra sau khi aws_instance.example đã được tạo. Cuối cùng, lifecycle được sử dụng để bỏ qua các thay đổi trạng thái của ebs_block_device.volume_type trong aws_instance.example và ngăn chặn việc xóa aws_ebs_volume.example.

3. Các Resource Meta Arguments.

Các Resource Meta Arguments trong Terraform bao gồm:

  • depends_on: Định nghĩa một phụ thuộc giữa các tài nguyên. Nó đảm bảo rằng Terraform sẽ xây dựng các tài nguyên theo thứ tự đúng và giúp đảm bảo tính nhất quán của cấu hình.
  • count: Định nghĩa số lần lặp lại tài nguyên. Nó giúp đơn giản hóa việc tạo và quản lý nhiều tài nguyên tương tự. Nó cũng có thể được sử dụng để xác định số lượng tài nguyên cần thiết để tạo ra các cụm, bảng, hay danh sách động.
  • for_each: Cho phép định nghĩa các tài nguyên được tạo ra dựa trên các phần tử trong một bộ sưu tập. Nó cũng giúp giải quyết vấn đề tạo ra các tài nguyên trùng lặp trong trường hợp bạn có nhiều bản ghi hoặc các tài nguyên cần được tạo ra dựa trên các bộ khóa – giá trị.
  • provider: Cho phép chỉ định nhà cung cấp sẽ được sử dụng cho các tài nguyên. Điều này cho phép bạn chuyển đổi giữa các nhà cung cấp đồng thời giữ nguyên cùng một cấu hình.
  • lifecycle: Cho phép xác định cách mà Terraform sẽ xử lý các tài nguyên của bạn. Ví dụ: ignore_changes, create_before_destroy, prevent_destroy, và delete_before_create.
  • provisioner: Cho phép thực hiện các tác vụ bổ sung trên các tài nguyên. Ví dụ: chạy lệnh cục bộ (local-exec), chạy trên máy chủ từ xa (remote-exec), chia sẻ dữ liệu giữa các tài nguyên (file), hoặc sử dụng công cụ đóng gói để cài đặt các phần mềm.

Tất cả các meta argument này cùng nhau giúp đơn giản hóa việc quản lý và tạo ra các tài nguyên hệ thống theo cách hợp lý và linh hoạt.

4. Một số lưu ý khi sử dụng Resource Meta Arguments.

Có một số lưu ý khi sử dụng Resource Meta Arguments trong Terraform như sau:

  • Cẩn thận sử dụng “depends_on”: Đây là một tính năng rất hữu ích để đảm bảo rằng các tài nguyên được tạo ra theo đúng thứ tự và tránh gây ra lỗi trong quá trình triển khai. Tuy nhiên, nên sử dụng tính năng này một cách cẩn thận, vì nó có thể làm chậm quá trình triển khai nếu bạn không cẩn thận.
  • Tránh sử dụng “lifecycle”: Tính năng này cho phép bạn cấu hình các hành động đặc biệt được thực hiện trên tài nguyên khi nó được tạo ra hoặc xóa đi. Tuy nhiên, nên tránh sử dụng tính năng này trong các trường hợp bình thường, vì nó có thể dẫn đến các vấn đề không mong muốn trong quá trình triển khai.
  • Chú ý đến sự phụ thuộc giữa các tài nguyên: Nếu bạn đặt sự phụ thuộc giữa các tài nguyên một cách sai lầm, bạn có thể gây ra sự cố trong quá trình triển khai và làm cho tài nguyên của bạn không đồng bộ. Vì vậy, nên cẩn thận khi đặt sự phụ thuộc giữa các tài nguyên và đảm bảo rằng nó phù hợp với yêu cầu của bạn.
  • Sử dụng “count” và “for_each” một cách hiệu quả: Tính năng này cho phép bạn tạo nhiều tài nguyên dựa trên một số lượng hoặc danh sách các giá trị. Tuy nhiên, bạn nên sử dụng tính năng này một cách cẩn thận, vì nó có thể làm cho mã của bạn khó đọc và khó hiểu nếu sử dụng một cách không hiệu quả.
  • Tối ưu hóa thời gian triển khai: Nên cố gắng giảm thiểu thời gian triển khai của mã của bạn bằng cách tối ưu hóa các tài nguyên và các phụ thuộc giữa chúng. Bằng cách làm như vậy, bạn có thể tăng tốc độ triển khai của mã của mình và giảm thiểu rủi ro trong quá trình triển khai.

5. Ví dụ minh hoạ cho các môi trường khác nhau.

Ví dụ 1:

Dưới đây là ví dụ sử dụng depends_oncount trong một khối dữ liệu (resource block) để tạo ra nhiều máy chủ trong một nhóm và đảm bảo rằng các máy chủ được tạo ra theo đúng thứ tự:

resource "aws_instance" "example" {
  count = var.instance_count

  ami           = var.ami_id
  instance_type = var.instance_type

  tags = {
    Name = "example-instance-${count.index}"
  }
}

resource "aws_security_group" "example" {
  name_prefix = "example-"

  ingress {
    from_port   = 0
    to_port     = 65535
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
  }

  depends_on = [aws_instance.example]
}

Đoạn code trên sử dụng Terraform để tạo ra một instance EC2 và một security group trên AWS.

Đối với resource aws_instance, các thuộc tính sau được khai báo:

  • count: Số lượng instance cần tạo, được truyền vào thông qua biến instance_count.
  • ami: AMI ID của instance, được truyền vào thông qua biến ami_id.
  • instance_type: Loại instance, được truyền vào thông qua biến instance_type.
  • tags: Một map các cặp key-value để gắn tag cho instance, trong đó tên của instance sẽ bao gồm index của instance đó trong danh sách các instance.

Đối với resource aws_security_group, các thuộc tính sau được khai báo:

  • name_prefix: Tiền tố của tên security group.
  • ingress: Luồng traffic vào security group, được cấu hình để cho phép tất cả các traffic TCP từ tất cả các IP.
  • depends_on: Xác định resource aws_instance là một dependency của resource aws_security_group. Điều này đảm bảo rằng instance được tạo ra trước khi tạo ra security group, vì vậy security group có thể được cấu hình để cho phép traffic vào instance.

Với count được sử dụng trong resource aws_instance, nếu instance_count được truyền vào với giá trị là 2, Terraform sẽ tạo ra hai instance với tên lần lượt là example-instance-0example-instance-1. Bằng cách này, chúng ta có thể đánh số các resource được tạo ra theo cách tuần tự, để dễ dàng quản lý và theo dõi chúng.

Ngoài ra, depends_on cho phép xác định mối quan hệ giữa các resource và đảm bảo rằng chúng được tạo ra theo đúng thứ tự. Trong trường hợp này, resource aws_security_group phụ thuộc vào resource aws_instance, nên Terraform sẽ tạo ra instance trước, và sau đó tạo ra security group.

Ví dụ 2:

Để khai báo Additional replication options trong Terraform, chúng ta sử dụng thuộc tính options trong khối replication_configuration của tài nguyên aws_dms_replication_instance, vsphere_replication_config, hoặc libvirt_rbd_storage_pool.

Ví dụ về khai báo options trong aws_dms_replication_instance:

resource "aws_dms_replication_instance" "example" {
  ...
  
  replication_configuration {
    ...
    
    replication_task_settings = jsonencode({
      targetMetadata = "metadata",
      targetDbType   = "mysql",
      tableMappings = "{\"rules\":[{\"rule-type\":\"selection\",\"rule-id\":\"1\",\"rule-name\":\"1\",\"object-locator\":{\"schema-name\":\"test\",\"table-name\":\"example\"},\"rule-action\":\"include\",\"filters\":[]},{\"rule-type\":\"selection\",\"rule-id\":\"2\",\"rule-name\":\"2\",\"object-locator\":{\"schema-name\":\"test\",\"table-name\":\"example2\"},\"rule-action\":\"include\",\"filters\":[]}]}",
      fullLoadSettings = "{\"targetTablePrepMode\":\"DROP_AND_CREATE\",\"createPkAfterFullLoad\":false,\"stopTaskCachedChangesApplied\":false,\"stopTaskCachedChangesNotApplied\":false}",
    })
    
    options = jsonencode({
      maxFullLoadSubTasks = 8,
      preloadEnabled      = true,
    })
  }
}

Trong ví dụ trên, chúng ta sử dụng jsonencode để chuyển đổi các giá trị thành chuỗi JSON và gán cho thuộc tính replication_task_settingsoptions.

Ví dụ 3:

Ví dụ về Resource Meta Arguments cho VSphere::

resource "vsphere_virtual_machine" "example" {
  ...

  clone {
    template_uuid = data.vsphere_virtual_machine_template.example.id
  }

  customize {
    linux_options {
      host_name = var.vm_hostname
    }

    network_interface {
      network_id   = var.vm_network_id
      adapter_type = var.vm_adapter_type
    }
  }

  provisioner "file" {
    source      = "${path.module}/script.sh"
    destination = "/tmp/script.sh"
  }

  depends_on = [
    vsphere_datastore_cluster.example,
    vsphere_network_interface.example,
  ]
}

Trong ví dụ này, provisioner "file" được sử dụng để sao chép một tập tin từ máy đang chạy Terraform đến máy ảo VSphere. depends_on được sử dụng để chỉ định các phụ thuộc của máy ảo VSphere đến các tài nguyên khác như vsphere_datastore_clustervsphere_network_interface.

Ví dụ 4:

Ví dụ về khai báo options trong libvirt_rbd_storage_pool trong Ceph Storage:

resource "libvirt_rbd_storage_pool" "example" {
  ...
  
  pool_options = jsonencode({
    auth_supported      = "cephx",
    auth_enabled        = true,
    auth_username       = "client.admin",
    auth_secret_uuid    = "a128d0a5-1b7e-4630-9ec7-9f67bb82a7a5",
    auth_secret_type    = "ceph",
    object_size         = 4194304,
    rados_pool          = "libvirt-pool",
    rados_user          = "libvirt",
    rbd_ceph_conf       = "/etc/ceph/ceph.conf",
    rbd_features        = ["layering", "striping"],
    rbd_secret_uuid     = "15d9ee7f-dbe4-4c8b-8c4e-4a4d82a143cb",
    rbd_secret_type     = "ceph",
    rbd_user            = "libvirt",
    thin_provisioning   = true,
  })
}

Trong đoạn mã này, ta đang khai báo một resource kiểu libvirt_rbd_storage_pool. Resource này sẽ tạo một pool lưu trữ cho các máy ảo KVM sử dụng ceph rbd. Cụ thể, trong đoạn mã này, ta đang khai báo các tùy chọn bổ sung cho pool lưu trữ này thông qua thuộc tính pool_options. Các tùy chọn này được khai báo bằng cách chuyển đổi một đối tượng JSON thành một chuỗi bằng cách sử dụng hàm jsonencode().

Các tùy chọn được khai báo bao gồm:

  • auth_supported: chỉ định phương thức xác thực được hỗ trợ.
  • auth_enabled: chỉ định liệu xác thực đã được kích hoạt hay chưa.
  • auth_username: chỉ định tên người dùng được sử dụng để xác thực với Ceph.
  • auth_secret_uuid: chỉ định UUID của bí mật được sử dụng để xác thực.
  • auth_secret_type: chỉ định loại bí mật được sử dụng để xác thực.
  • object_size: chỉ định kích thước của các đối tượng lưu trữ.
  • rados_pool: chỉ định tên pool trong Ceph để lưu trữ dữ liệu.
  • rados_user: chỉ định tên người dùng được sử dụng để truy cập Ceph.
  • rbd_ceph_conf: chỉ định đường dẫn tới file cấu hình Ceph.
  • rbd_features: chỉ định các tính năng được kích hoạt cho các ổ đĩa RBD.
  • rbd_secret_uuid: chỉ định UUID của bí mật được sử dụng để truy cập ổ đĩa RBD.
  • rbd_secret_type: chỉ định loại bí mật được sử dụng để truy cập ổ đĩa RBD.
  • rbd_user: chỉ định tên người dùng được sử dụng để truy cập ổ đĩa RBD.
  • thin_provisioning: chỉ định liệu ổ đĩa RBD có được cấp phát chưa.

Tất cả các tùy chọn này sẽ được sử dụng khi ta tạo pool lưu trữ ceph rbd cho các máy ảo KVM.

Ví dụ 5:

Ví dụ về Resource Meta Arguments cho KVM:

resource "libvirt_domain" "example" {
  ...

  console {
    type = "pty"
    target_port = "0"
  }

  lifecycle {
    ignore_changes = [
      "graphics.0.listen",
      "graphics.0.password",
    ]
  }

  depends_on = [
    libvirt_network.example,
    libvirt_storage_pool.example,
  ]
}

Trong ví dụ này, lifecycle được sử dụng để chỉ định những thay đổi nào của tài nguyên sẽ không được quan tâm trong vòng đời của nó. depends_on được sử dụng để chỉ định các phụ thuộc của máy ảo KVM đến các tài nguyên khác như libvirt_networklibvirt_storage_pool.

LEAVE A REPLY

Please enter your comment!
Please enter your name here

4,956FansLike
256FollowersFollow
223SubscribersSubscribe
spot_img

Related Stories