Tìm hiểu tính năng Terraform taint – Cuongquach.com | Khi bạn sử dụng Terraform để quản lý các resource hạ tầng Cloud hay On-Premise. Bạn sẽ bắt gặp một tính năng được hỗ trợ bởi Terraform mang tên : taint
.
Youtube Video
Terraform taint là gì ?
Terraform taint
là một tính năng của chương trình Terraform được sử dụng để đánh dấu trạng thái của các resource trong file state
quản lý bởi Terraform là tainted
. Khi resource có trạng thái này sẽ được xoá bỏ và khởi tạo mới trong những lần apply
kế tiếp.
Tính năng này sẽ không thay đổi hạ tầng mà Terraform quản lý, mà chỉ chỉnh sửa thông tin trạng thái resource trong file state
. Khi resource ở trạng thái tainted
, thì khi bạn chạy terraform plan
để kiểm tra các sự thay đổi trong resource cấu hình sẽ thấy thông tin yêu cầu xoá và tạo mới.
Lưu ý, là với các resource có sử dụng thông tin phụ thuộc (dependency) thì khi một resource bị tainted
và tạo mới lại thì resource phụ thuộc cũng sẽ bị xoá và tạo mới chung.
Các trường hợp sử dụng Terraform taint
- Sử dụng
taint
để rolling deploy Auto Scaling Group của AWS cho Web Service chẳng hạn, vì Terraform không có hỗ trợ cơ chế rolling change cho ASG. - Rebuild lại một số resource mà không cần phải destroy toàn bộ các resource trong thư mục cấu hình.
Cú pháp:
terraform taint [options] address
Trong đó, phần address
sẽ là địa chỉ định danh của resource trong file terraform.tfstate
, có thể là ví dụ như dưới :
- aws_instance.foo
- aws_instance.bar[1]
- aws_instance.baz[”key”]
- module.foo.module.bar.aws_instance.qux
Lab thực hành Terraform taint
Giả sử mình tạo resource AWS VPC, PublicSubnet, Internet Gateway, RouteTable thuộc VPC đó.
# mkdir /opt/lab-vpc-tf/ # vi main.tf provider "aws" { region = "ap-southeast-1" } data "aws_security_group" "default" { name = "default" vpc_id = module.vpc.vpc_id } module "vpc" { source = "terraform-aws-modules/vpc/aws" version = "2.48.0" name = "simple-vpc-vinastar-lab" cidr = "10.0.0.0/16" azs = ["ap-southeast-1a"] public_subnets = ["10.0.101.0/24"] enable_ipv6 = false enable_nat_gateway = false single_nat_gateway = false } # export AWS_ACCESS_KEY_ID="xxxx" # export AWS_SECRET_ACCESS_KEY="xxxx" # export AWS_DEFAULT_REGION="ap-southeast-1" # terraform init # terraform plan Refreshing Terraform state in-memory prior to plan... The refreshed state will be used to calculate this plan, but will not be persisted to local or remote state storage. ------------------------------------------------------------------------ An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: + create <= read (data resources) Terraform will perform the following actions: # data.aws_security_group.default will be read during apply # (config refers to values not yet known) <= data "aws_security_group" "default" { + arn = (known after apply) + description = (known after apply) + id = (known after apply) + name = "default" + tags = (known after apply) + vpc_id = (known after apply) } # module.vpc.aws_internet_gateway.this[0] will be created + resource "aws_internet_gateway" "this" { + arn = (known after apply) + id = (known after apply) + owner_id = (known after apply) + tags = { + "Name" = "simple-vpc-vinastar-lab" } + vpc_id = (known after apply) } # module.vpc.aws_route.public_internet_gateway[0] will be created + resource "aws_route" "public_internet_gateway" { + destination_cidr_block = "0.0.0.0/0" + destination_prefix_list_id = (known after apply) + egress_only_gateway_id = (known after apply) + gateway_id = (known after apply) + id = (known after apply) + instance_id = (known after apply) + instance_owner_id = (known after apply) + local_gateway_id = (known after apply) + nat_gateway_id = (known after apply) + network_interface_id = (known after apply) + origin = (known after apply) + route_table_id = (known after apply) + state = (known after apply) + timeouts { + create = "5m" } } # module.vpc.aws_route_table.public[0] will be created + resource "aws_route_table" "public" { + id = (known after apply) + owner_id = (known after apply) + propagating_vgws = (known after apply) + route = (known after apply) + tags = { + "Name" = "simple-vpc-vinastar-lab-public" } + vpc_id = (known after apply) } # module.vpc.aws_route_table_association.public[0] will be created + resource "aws_route_table_association" "public" { + id = (known after apply) + route_table_id = (known after apply) + subnet_id = (known after apply) } # module.vpc.aws_subnet.public[0] will be created + resource "aws_subnet" "public" { + arn = (known after apply) + assign_ipv6_address_on_creation = false + availability_zone = "ap-southeast-1a" + availability_zone_id = (known after apply) + cidr_block = "10.0.101.0/24" + id = (known after apply) + ipv6_cidr_block_association_id = (known after apply) + map_public_ip_on_launch = true + owner_id = (known after apply) + tags = { + "Name" = "simple-vpc-vinastar-lab-public-ap-southeast-1a" } + vpc_id = (known after apply) } # module.vpc.aws_vpc.this[0] will be created + resource "aws_vpc" "this" { + arn = (known after apply) + assign_generated_ipv6_cidr_block = false + cidr_block = "10.0.0.0/16" + default_network_acl_id = (known after apply) + default_route_table_id = (known after apply) + default_security_group_id = (known after apply) + dhcp_options_id = (known after apply) + enable_classiclink = (known after apply) + enable_classiclink_dns_support = (known after apply) + enable_dns_hostnames = false + enable_dns_support = true + id = (known after apply) + instance_tenancy = "default" + ipv6_association_id = (known after apply) + ipv6_cidr_block = (known after apply) + main_route_table_id = (known after apply) + owner_id = (known after apply) + tags = { + "Name" = "simple-vpc-vinastar-lab" } } Plan: 6 to add, 0 to change, 0 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run. # terraform apply -auto-approve
Giờ chúng ta sẽ taint
một Terraform resource đã được tạo.
# terraform taint -lock=true "module.vpc.aws_subnet.public[0]" Resource instance module.vpc.aws_subnet.public[0] has been marked as tainted.
Lúc này nếu bạn coi file terraform.tfstate
sẽ thấy cấu hình của resource aws_subnet.public
index 0 có trạng thái là tainted
.
... { "module": "module.vpc", "mode": "managed", "type": "aws_subnet", "name": "public", "each": "list", "provider": "provider.aws", "instances": [ { "index_key": 0, "status": "tainted", ...
Khi bạn chạy terraform plan
sau khi taint
sẽ thấy resource aws_subnet.public
được yêu cầu xoá (destroy) và khởi tạo lại mới (create). Tương ứng với resource khác phụ thuộc module.vpc.aws_route_table_association.public
sẽ bị liên đới do phụ thuộc.
# terraform plan An execution plan has been generated and is shown below. Resource actions are indicated with the following symbols: -/+ destroy and then create replacement Terraform will perform the following actions: # module.vpc.aws_route_table_association.public[0] must be replaced -/+ resource "aws_route_table_association" "public" { ~ id = "rtbassoc-0cc7a80a98940d3b7" -> (known after apply) route_table_id = "rtb-091b17ee78cd57e67" ~ subnet_id = "subnet-0f1f64f4832440f95" -> (known after apply) # forces replacement } # module.vpc.aws_subnet.public[0] is tainted, so must be replaced -/+ resource "aws_subnet" "public" { ~ arn = "arn:aws:ec2:ap-southeast-1:764510719561:subnet/subnet-0f1f64f4832440f95" -> (known after apply) assign_ipv6_address_on_creation = false availability_zone = "ap-southeast-1a" ~ availability_zone_id = "apse1-az2" -> (known after apply) cidr_block = "10.0.101.0/24" ~ id = "subnet-0f1f64f4832440f95" -> (known after apply) + ipv6_cidr_block_association_id = (known after apply) map_public_ip_on_launch = true ~ owner_id = "764510719561" -> (known after apply) tags = { "Name" = "simple-vpc-vinastar-lab-public-ap-southeast-1a" } vpc_id = "vpc-0a9ede37fb00766ee" } Plan: 2 to add, 0 to change, 2 to destroy. ------------------------------------------------------------------------ Note: You didn't specify an "-out" parameter to save this plan, so Terraform can't guarantee that exactly these actions will be performed if "terraform apply" is subsequently run.
Đơn giản dễ hiểu phải không nào .
Nguồn: https://vinastar.com/