1. Terraform Plan and Apply là gì?
Terraform Plan và Apply là các lệnh cơ bản trong Terraform được sử dụng để thực thi các tài nguyên (resources) đã được định nghĩa trong code Terraform.
Lệnh Terraform Plan được sử dụng để tạo ra một kế hoạch thực thi (execution plan) cho tất cả các tài nguyên trong code Terraform, bao gồm cả các tài nguyên mới, cập nhật hoặc xóa bỏ. Kế hoạch thực thi này sẽ cho phép người dùng xem trước các thay đổi sẽ được áp dụng vào hạ tầng của mình.
Lệnh Terraform Apply được sử dụng để thực thi kế hoạch được tạo ra bởi lệnh Plan, từ đó cập nhật hoặc tạo mới các tài nguyên.
Cú pháp khai báo:
- Lệnh Plan:
terraform plan [options] [DIR]
- Lệnh Apply:
terraform apply [options] [DIR]
Trong đó, DIR
là thư mục chứa các file Terraform, và options
là các tùy chọn khác nhau được sử dụng để cấu hình việc thực thi các lệnh này.
2. Các lưu ý khi sử dụng Plan and Apply.
Các lưu ý khi sử dụng Plan and Apply trong Terraform:
- Tạo một plan trước khi thực hiện các thay đổi thực tế: Trước khi thực hiện bất kỳ thay đổi nào trên hạ tầng, nên sử dụng lệnh
terraform plan
để tạo ra một kế hoạch về các tài nguyên sẽ được tạo, cập nhật hoặc xóa. Kế hoạch này cung cấp cho bạn cái nhìn tổng quan về những gì sẽ xảy ra, giúp bạn tránh các lỗi không mong muốn. - Kiểm tra tài nguyên trước khi áp dụng thay đổi: Để đảm bảo rằng tài nguyên được cấu hình chính xác và có thể hoạt động như mong muốn, bạn nên sử dụng lệnh
terraform validate
để kiểm tra cú pháp và lỗi trong các file cấu hình của mình. - Lưu ý về tác động của thay đổi: Các thay đổi trong hạ tầng có thể có tác động rất lớn đến môi trường của bạn, vì vậy bạn cần phải cẩn thận và chắc chắn rằng bạn đã kiểm tra kỹ lưỡng các thay đổi trước khi áp dụng chúng bằng lệnh
terraform apply
. - Xác nhận các thay đổi trước khi áp dụng: Trước khi thực hiện bất kỳ thay đổi nào, bạn cần phải xác nhận lại các thay đổi đó bằng cách trả lời yêu cầu xác nhận
yes
hoặcno
. Điều này giúp tránh các thay đổi không mong muốn và giảm thiểu rủi ro trong quá trình triển khai. - Lưu trữ state file ở nơi an toàn: Terraform sử dụng state file để theo dõi trạng thái hiện tại của hạ tầng. Vì vậy, bạn cần phải đảm bảo rằng state file được lưu trữ ở nơi an toàn và bảo vệ nó khỏi các rủi ro bảo mật.
- Đảm bảo sự đồng bộ giữa các file cấu hình và state file: Để đảm bảo sự đồng bộ giữa các file cấu hình và state file, bạn nên chắc chắn rằng bạn đã tải lại trạng thái hiện tại của hạ tầng bằng lệnh
terraform get
trước khi thực hiện bất kì thay đổi nào. - Khi sử dụng Plan, hãy luôn kiểm tra kết quả Plan kỹ trước khi thực hiện Apply, đảm bảo rằng tất cả các thay đổi sẽ được áp dụng chính xác và đáp ứng được các yêu cầu cấu hình hệ thống.
- Khi sử dụng Apply, hãy cẩn thận và xem xét kỹ trước khi xác nhận thực hiện việc thay đổi hệ thống. Đảm bảo rằng bạn đã xác định rõ những thay đổi mà bạn muốn thực hiện và hiểu rõ tác động của chúng đến hệ thống của bạn.
- Có thể sử dụng các cờ khác nhau trong lệnh Apply để xác định cách thức áp dụng thay đổi vào hệ thống. Ví dụ, –auto-approve sẽ tự động xác nhận việc áp dụng thay đổi mà không yêu cầu sự xác nhận bổ sung từ người dùng.
- Nên sử dụng các công cụ bổ sung để giám sát việc triển khai và xác định lỗi nếu có. Ví dụ, bạn có thể sử dụng AWS CloudWatch để giám sát các tài nguyên của mình trên AWS và ghi lại các hoạt động triển khai của Terraform.
- Khi sử dụng Terraform để triển khai các tài nguyên trên môi trường sản phẩm thực, hãy sử dụng các bản phát hành ổn định của Terraform và các nhà cung cấp dịch vụ đang được sử dụng. Nếu cần, bạn có thể tạo một môi trường thử nghiệm để kiểm tra các thay đổi trước khi áp dụng chúng vào môi trường sản phẩm thực.
- Bảo mật là một yếu tố quan trọng khi triển khai hệ thống. Nên bảo mật các thông tin nhạy cảm như khóa bí mật, chứng chỉ và thông tin đăng nhập bằng cách sử dụng một quản lý mật khẩu hoặc công cụ tương tự.
- Nếu bạn sử dụng nhiều tài khoản đăng nhập vào các dịch vụ đám mây khác nhau, hãy đảm bảo rằng bạn đang sử dụng tài khoản đúng để thực hiện các thao tác cần thiết trên dịch vụ tương ứng.
- Luôn chú ý đến các cập nhật mới của Terraform và các nhà cung cấp dịch vụ, để đảm bảo rằng bạn không gặp lỗi khi triển khai liên quan đến bản cập nhật của Terraform.
3. Ví dụ minh hoạ.
Ví dụ 1:
Ví dụ sau sử dụng Terraform để tạo một máy ảo trên hệ thống KVM. Mã nguồn này định nghĩa một máy ảo với một ổ cứng và một card mạng.
provider "libvirt" {
uri = "qemu:///system"
}
resource "libvirt_volume" "example_volume" {
name = "example.qcow2"
capacity = "1G"
pool = "default"
}
resource "libvirt_domain" "example_domain" {
name = "example"
memory = "1024"
vcpu = 1
disk {
volume_id = "${libvirt_volume.example_volume.id}"
}
network_interface {
network_name = "default"
}
}
Giải thích các tài nguyên được định nghĩa:
libvirt_volume
: tạo một ổ cứng cho máy ảo. Thuộc tínhname
là tên file ảnh đĩa,capacity
là dung lượng đĩa, vàpool
là tên của pool ảnh đĩa được sử dụng.libvirt_domain
: định nghĩa một máy ảo với thuộc tínhname
là tên máy ảo,memory
là dung lượng RAM, vàvcpu
là số lượng CPU. Trong đó,disk
vànetwork_interface
là hai thiết bị được gắn kết với máy ảo, được định nghĩa thông qua resourcelibvirt_volume
vàlibvirt_network
, mỗi resource đều có mộtid
duy nhất.
Sau khi đã định nghĩa cấu hình, chúng ta có thể sử dụng Terraform để kiểm tra và triển khai các thay đổi bằng cách sử dụng terraform plan
và terraform apply
.
terraform plan
: Kiểm tra các thay đổi và xem trước những gì sẽ được thực thi trên hệ thống KVM. Ví dụ, nếu chúng ta thêm một thiết bị mạng vào máy ảo, Terraform sẽ hiển thị kế hoạch của việc thêm một card mạng.terraform apply
: Thực thi các thay đổi và áp dụng chúng lên hệ thống KVM. Ví dụ, nếu chúng ta thêm một thiết bị mạng vào máy ảo, Terraform sẽ thực hiện việc tạo mới một card mạng và kết nối nó với máy ảo.
Ví dụ 2:
Giả sử bạn muốn tạo một instance EC2 trên AWS và sử dụng Terraform để quản lý hạ tầng của mình. Để thực hiện việc này, bạn sẽ cần tạo một file Terraform configuration với cấu trúc như sau:
provider "aws" {
region = "us-west-2"
}
resource "aws_instance" "example" {
ami = "ami-0c55b159cbfafe1f0"
instance_type = "t2.micro"
tags = {
Name = "example-instance"
}
}
Trong đoạn mã này, chúng ta sử dụng provider aws
để cung cấp thông tin về region mà instance sẽ được tạo và định nghĩa một resource aws_instance
để tạo ra một instance EC2 với AMI ID và instance type được chỉ định. Ngoài ra, chúng ta cũng định nghĩa một tag Name
cho instance.
Sau khi đã định nghĩa được Terraform configuration, chúng ta có thể sử dụng lệnh terraform plan
để xác định các thay đổi sẽ được áp dụng khi chạy lệnh terraform apply
:
$ terraform plan
Terraform will perform the following actions:
# aws_instance.example will be created
+ resource "aws_instance" "example" {
+ ami = "ami-0c55b159cbfafe1f0"
+ arn = (known after apply)
+ associate_public_ip_address = (known after apply)
+ availability_zone = (known after apply)
+ cpu_core_count = (known after apply)
+ cpu_threads_per_core = (known after apply)
+ disable_api_termination = (known after apply)
+ ebs_optimized = (known after apply)
+ get_password_data = false
+ id = (known after apply)
+ instance_state = (known after apply)
+ instance_type = "t2.micro"
+ ipv6_address_count = (known after apply)
+ ipv6_addresses = (known after apply)
+ key_name = (known after apply)
+ network_interface_id = (known after apply)
+ password_data = (known after apply)
+ placement_group = (known after apply)
+ primary_network_interface_id = (known after apply)
+ private_dns = (known after apply)
+ private_ip = (known after apply)
+ public_dns = (known after apply)
+ public_ip = (known after apply)
+ security_groups = (known after apply)
+ source_dest_check = true
+ subnet_id = (known after apply)
+ tags = {
+ "Name" = "example-instance"
}
+ tenancy = (known after apply)
+ user_data = (known after apply)
+ volume_tags = (known after apply)
+ vpc_security_group_ids = (known after apply)
+ credit_specification {
+ cpu_credits = "standard"
}
}
Plan: 1 to add, 0 to change, 0 to destroy.
Mình sẽ giải thích chi tiết hơn trong ví dụ này, chúng ta đang tạo một VPC với tên là “my-vpc” và địa chỉ CIDR là “10.0.0.0/16”. Tiếp theo, chúng ta tạo một public subnet trong VPC với tên là “my-public-subnet” và địa chỉ CIDR là “10.0.1.0/24”. Sau đó, chúng ta tạo một internet gateway với tên là “my-igw”. Sau đó, chúng ta sử dụng resource “aws_route_table” để tạo một route table với tên là “my-public-route-table” và liên kết nó với subnet public vừa tạo.
Để tạo được các resource trên, chúng ta cần xác định các input cho các resource đó. Trong trường hợp này, chúng ta sử dụng module “vpc” để định nghĩa các input cho VPC, subnet, và internet gateway. Trong module “vpc”, chúng ta định nghĩa các biến đầu vào như “vpc_name”, “vpc_cidr_block”, “subnet_name”, “subnet_cidr_block”, “igw_name”. Để đảm bảo tính nhất quán giữa các biến đầu vào, chúng ta sử dụng local value “tags” để lưu trữ các tags được sử dụng cho các resource.
Sau khi đã định nghĩa các input, chúng ta sử dụng provider “aws” để cung cấp thông tin về tài khoản AWS và region. Tiếp theo, chúng ta sử dụng resource “aws_vpc” để tạo VPC với các đầu vào là tên VPC và CIDR block. Resource “aws_subnet” được sử dụng để tạo subnet public với các đầu vào là tên subnet và CIDR block, và thuộc về VPC đã tạo. Resource “aws_internet_gateway” được sử dụng để tạo internet gateway với đầu vào là tên internet gateway.
Sau khi các resource đã được tạo thành công, chúng ta sử dụng resource “aws_route_table” để tạo một route table với đầu vào là tên route table và VPC ID. Resource “aws_route” được sử dụng để tạo một route cho internet gateway với đầu vào là route table ID và destination CIDR block. Cuối cùng, resource “aws_route_table_association” được sử dụng để kết nối route table với subnet public vừa tạo.
Sau khi đã khai báo các resource và input, ta có thể chạy lệnh “terraform plan” để kiểm tra sự thay đổi của infrastructure so với trạng thái hiện tại. Lệnh “terraform apply” được sử dụng để áp dụng các thay đổi đó và cập nhật infrastructure.