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 .
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:
1 |
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 đó.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 |
# 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-cuongquach-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-cuongquach-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-cuongquach-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-cuongquach-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-cuongquach-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.
1 2 |
# 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.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
... { "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.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
# 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-cuongquach-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://cuongquach.com/