I. HCL (HashiCorp Configuration Language) Block
HashiCorp Configuration Language (HCL) là ngôn ngữ cấu hình được tạo HashiCorp. HCL được sử dụng với các cloud infrastructure automation tools của HashiCorp, chẳng hạn như Terraform. Ngôn ngữ này được tạo ra với mục tiêu thân thiện với cả con người và máy móc. Nó cũng có khả năng tương thích với JSON, có nghĩa là nó có thể tương tác với các hệ thống khác ngoài dòng sản phẩm Terraform.
Trong Terraform, block là đơn vị cơ bản được sử dụng để xác định và định cấu hình các khía cạnh khác nhau của cơ sở hạ tầng. Các block được viết bằng HashiCorp Configuration Language (HCL) và cho phép bạn khai báo resources, providers, variables, outputs và các thành phần cấu hình khác trong Terraform. Trong bài viết này chúng ta sẽ tìm hiểu các loại block trong HCL và mục đích sử dụng của chúng.
Block có nhiều loại (block_type
), có thể có 0 hoặc nhiều label
bắt buộc, theo sau là dấu ngoặc { }
chứa nội dung của khối. Các khối có thể được lồng vào nhau. Đây là cách format chung của một block:
block_type "label_1" "label_2" {
argument_1 = value_1
argument_2 = value_2
}
Hãy cùng phân tích vị dụ về một block có block_type
là resource
:
resource "aws_instance" "app_server" {
ami = "ami-830c94e3"
instance_type = "t2.micro"
tags = {
Name = "PathToTerraformCertInstance"
}
}
Ở đây chúng ta có một block loại resource. Vì chúng ta đang sử dụng AWS provider nên chúng ta có thể tài liệu tại đây.
aws_instance
là label
đầu tiên trỏ đến loại resource cung cấp bởi AWS provider và app_server
là label
thứ hai đại diện cho tên của resource. Terraform hỗ trợ truy cập các phần tử bằng cách sử dụng ký hiệu dấu chấm như sau: aws_instance.app_server.tags
Một số resource có thể có các required arguments. Bạn nên kiểm tra các official docs để biết required arguments. Trong trường hợp của chúng ta, aws_instance
có 2 đối số bắt buộc: ami
và instance_type
.
Đối với tags
block, bạn nên tập thói quen gắn tag các resource của mình.
Bây giờ chúng ta đã có cái nhìn tổng quát về Terraform block, hãy cùng khám phá loại block nào chúng ta có thể sử dụng trong cấu hình.
II. Terraform Block Types
Bài viết sẽ đề cập đến các loại block dưới đây:
terraform
blockprovider
blockresource
blockvariable
blocklocals
blockdata
blockmodule
blockoutput
blockprovisioner
block
Chúng ta sẽ xem xét cấu trúc cơ bản và mục đích của từng block. Khi đã quen với các block này, chúng ta có thể bắt đầu xây dựng cơ sở hạ tầng thực tế.
Terraform Block
terraform block
được sử dụng để thiết lập phiên bản của terraform mà chúng ta muốn. Nó cũng có thể chứa require_providers
block bên trong chỉ định phiên bản của các providers mà chúng ta cần, cũng như nơi Terraform nên tải xuống các providers này. terraform block
thường được đặt trong một file riêng biệt được gọi là terraform.tf
như một cách để tách các settings thành file riêng.
Dưới đây là một ví dụ về terraform block
:
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 2.0"
}
}
required_version = ">= 1.0.1"
}
Provider Block
Các provider block
chỉ định loại module đặc biệt cho phép Terraform tương tác với nhiều cloud-hosting platforms hoặc data centers khác nhau. provider block
phải được định cấu hình bằng thông tin xác thực phù hợp trước khi chúng ta có thể sử dụng chúng (ví dụ: AWS thì cần cấu hình secret_key và access_key). Các phiên bản và vị trí tải xuống của Provider thường được chỉ định bên trong terraform block
, nhưng bạn cũng có thể chỉ định nó bên trong block này.
provider "aws" {
version = "~> 3.0"
region = "us-east-1"
}
Resource Block
Các resource block
được sử dụng để quản lý các resources như compute instances
, virtual networks
, databases
, buckets
, hoặc DNS resources
. Loại block này là xương sống của bất kỳ terraform configuration
nào vì nó đại diện cho các resources thực tế.
resource "aws_instance" "example_resource" {
ami = "ami-005e54dee72cc1d00" # us-west-2
instance_type = "t2.micro"
credit_specification {
cpu_credits = "unlimited"
}
}
Variable Block
block này thường được gọi là input variable block. variable block
cung cấp các tham số cho các module terraform và cho phép người dùng tùy chỉnh dữ liệu được cung cấp cho các module terraform khác mà không cần sửa đổi source code.
Các variable thường nằm trong tập tin riêng của chúng có tên là variables.tf
. Để sử dụng một variable, nó cần được khai báo dưới dạng một block. Một variable block
sẽ như sau:
variable "example_variable" {
type = var_type
description = var_description
default = value_1
sensitive = var_boolean_value
}
Terraform có thứ tự ưu tiên nghiêm ngặt cho việc cài đặt các biến, đây là từ cao nhất đến thấp nhất:
- Command line (
-var
vàvar-file
) *.auto.tfvars
hoặc*auto.tfvars.json
terraform.tfvars.json
terraform.tfvars
file- Env variables
- Variable defaults
Locals Block
Thường được gọi là local variables block(biến cục bộ), block này được sử dụng để giữ các giá trị hoặc biểu thức được tham chiếu thường xuyên nhằm giữ cho code sạch sẽ và gọn gàng.
local block
có thể chứa nhiều biến bên trong. Các biểu thức trong giá trị cục bộ không giới hạn ở các hằng số bằng chữ. Chúng cũng có thể tham chiếu các giá trị khác trong module để biến đổi hoặc kết hợp chúng. Các biến này có thể được gọi bằng cú pháp local.var_name
, lưu ý rằng nó được định nghĩa là locals
nhưng khi gọi thì sẽ chuyển thành local.
(không có s
).
locals {
service_name = "forum"
owner = "Community Team"
instance_ids = concat(aws_instance.blue.*.id, aws_instance.green.*.id)
}
Data Block
Mục đích chính của data block
là load hoặc query dữ liệu từ các API không phải của Terraform. data block
có thể được sử dụng để mang lại sự linh hoạt cho cấu hình của bạn hoặc để kết nối các workspaces việc khác nhau. Một cách mà chúng ta sẽ sử dụng data block
là truy vấn API AWS để có được một danh sách các active Availability Zones để deploy resources.
Data được truy cập với format data.<TYPE>.<NAME>.<ATTRIBUTE>
# Find the latest available AMI that is tagged with Component = web
data "aws_ami" "web" {
filter {
name = "state"
values = ["available"]
}
filter {
name = "tag:Component"
values = ["web"]
}
most_recent = true
}
resource "aws_instance" "web" {
ami = data.aws_ami.web.id
instance_type = "t1.micro"
}
Module Block
Module là nơi chứa nhiều resources được sử dụng cùng nhau. Một module bao gồm các files .tf
và/hoặc .tf.json
được lưu trữ trong một thư mục. Đây là cách chính để đóng gói và tái sử dụng các tài nguyên trong Terraform.
Mỗi cấu hình Terraform đều có ít nhất một model (root module) chứa các resources được định nghĩa trong tệp .tf
.
Đây là ví dụ về một module:
Output Block
Đây là một block hầu như luôn có mặt trong tất cả các cấu hình. Nó cho phép Terraform xuất structured data về cấu hình của bạn. Người dùng có thể sử dụng output này để xem dữ liệu như IP hoặc tên resources ở terminal. Một trường hợp sử dụng khác liên quan đến việc sử dụng dữ liệu này trong Terraform workspace khác hoặc chia sẻ dữ liệu giữa các mudule.
output "test_server_public_ip" {
description = "My test output for EC2 public IP"
value = aws_instance.test_web_server.public_ip
sensitive = true
}
output "public_url" {
description = "Public URL for my web server"
value = "https://${aws_instance.test_web_server.public_ip}:8000/index.html"
}
Provisioner Block
Provisioners cho phép chúng ta chỉ định các hành động sẽ được thực hiện trên các local hoặc remote machines để chuẩn bị resources cho các service.
Có hai loại Terraform provisioners: local-exec
và remote-exec
.
local-exec
được thực thi sau khi tài nguyên được tạo. Nó chạy các process trên máy chạy Terraform, nghĩa là máy mà bạn chạy ứng dụng terraform. Đây rất có thể là máy tính của riêng bạn.
remote-exec
được thực thi từ xa, giống như EC2 instance trên AWS.
Đây là ví dụ về provisioner cho EC2 instance. Ví dụ này chứa cả local-exec
và remote-exec
:
resource "aws_instance" "web_server" {
# ...
provisioner "local-exec" {
command = "Get-Date > completed.txt"
interpreter = ["PowerShell", "-Command"]
}
provisioner "remote-exec" {
inline = [
"chmod +x /tmp/script.sh",
"/tmp/script.sh args",
]
}
}
III. Kết:
Đây là phần cuối của bài viết khá dài về các Terraform block. Bây giờ chúng ta đã biết mình có những công cụ nào để sử dụng, chúng ta có thể bắt đầu tạo cơ sở hạ tầng thực tế.