Tìm hiểu cấu hình Workspace trong Terraform – Cuongquach.com | Một chủ đề nho nhỏ trong Terraform (IaC), chúng ta cùng điểm qua cách sử dụng tính năng Workspace trong Terraform dùng để làm gì ? và dùng như thế nào nhé ?
Contents
Workspace trong Terraform là gì ?
Đầu tiên, cần lưu ý là khái niệm “Workspace” sử dụng trong chương trình mã nguồn mở “Terraform” sẽ khác so với Workspace
trong dịch vụ Terraform Cloud/Terraform Enterprise đã được HashiCorp cung cấp. Trong bài viết này chúng ta đề cập đến Workspace
trong chương trình mã nguồn mở Terraform
.
Đầu tiên ôn lại đôi chút là, trạng thái của đối tượng resource do terraform
quản lý sẽ được lưu trữ ở một file terraform.tfstate
có định dạng JSON. Các nguồn storage dùng để lưu trữ thông tin trạng thái state đó thường được gọi là backend
, có thể là:
- Local filesystem
- S3 AWS
- GCP
- Azure
- …
Terraform luôn bắt đầu làm việc với một workspace mặc định tên là ‘default‘. Workspace này không thể bị xoá bỏ được vì mặc định nó sẽ luôn tồn tại. Nếu bạn sử dụng Terraform mà không chỉ định workspace khác thì bạn sẽ luôn luôn lưu trữ dữ liệu state của resource trên “default” workspace.
Vậy Workspace trong Terraform có thể coi là một kĩ thuật để quy hoạch lưu trữ nhiều trạng thái (state) về các resource khác nhau trong cùng 1 thư mục cấu hình resource terraform.
Một số lưu ý khác:
- Nếu không xài workspace nào khác ngoài
default
thì cấu trúc thư mục chứa fileterraform.tfstate
của bạn chỉ như này.
. ├── main.tf ├── terraform.tfstate
- Khi cấu hình nhiều Workspace khác nhau, thì các file state sẽ được cấu trúc trong thư mục storage backend như sau : ./terraform.tfstate.d/<workspace_name>/terraform.tfstate
. ├── main.tf ├── terraform.tfstate └── terraform.tfstate.d └── qa └── terraform.tfstate └── dev └── terraform.tfstate └── uat └── terraform.tfstate
Khi nào sử dụng Workspace Terraform
- Thường có thể bạn sẽ làm lab/test thực hành cấu hình Terraform nhiều môi trường khác nhau chẳng hạn.
- Bạn cũng có thể ứng dụng Workspace với Git Version Control khi chạy CI/CD để quản lý hạ tầng ở các môi trường khác nhau. Ví dụ: ở branch
dev
thì sẽ chạy workspacedev
, ở branchqa
thì sẽ chạy workspaceqa
. Đây thường là mô hình sử dụng dễ gặp với Terraform Workspace. => Còn với ý kiến mình thì mình không áp dụng kỹ thuật này để quản lý nhiều môi trường resource với Terraform.
Cú pháp sử dụng Terraform Workspace
+ Cú pháp tạo Workspace mới
terraform workspace new <workspace_name>
+ Cú pháp chuyển Workspace
terraform workspace select <workspace_name>
+ Cú pháp xoá Workspace
terraform workspace delete <workspace_name>
+ Cú pháp liệt kê Workspace
terraform workspace list
Lab thực hành Workspace Terraform
Giờ ta tạo resource AWS để lab phần workspace này nhé. Mình sẽ tạo AWS VPC và AWS Internet Gateway ở workspace default trước.
# cd /opt # mkdir terraform-lab # cd terraform-lab # touch main.tf
Phần chứng thực giữa Terraform với AWS , mình đã tạo 1 IAM User với Credentials Access Key/Secret Key và export dưới hình thức biến môi trường để lab (phần này các bạn tự tìm hiểu lại nhé).
# export AWS_ACCESS_KEY_ID="xxx" # export AWS_SECRET_ACCESS_KEY="xxx" # export AWS_DEFAULT_REGION="ap-southeast-1"
File cấu hình Terraform ‘main.tf’ . Bạn sẽ truy xuất thông tin workspace ở biến ${terraform.workspace}
.
provider "aws" {} # Create a VPC resource "aws_vpc" "main" { cidr_block = "10.0.0.0/16" tags = { Name = "${terraform.workspace}-VPC" } } # Create an Internet Gateway then attach to above VPC resource "aws_internet_gateway" "gw" { vpc_id = aws_vpc.main.id tags = { Name = "${terraform.workspace}-IGW" } }
Giờ ta plan, apply và show nhé.
# 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 Terraform will perform the following actions: # aws_internet_gateway.gw will be created + resource "aws_internet_gateway" "gw" { + arn = (known after apply) + id = (known after apply) + owner_id = (known after apply) + tags = { + "Name" = "default-IGW" } + vpc_id = (known after apply) } # aws_vpc.main will be created + resource "aws_vpc" "main" { + 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 = (known after apply) + 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" = "default-VPC" } } Plan: 2 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 aws_vpc.main: Creating... aws_vpc.main: Creation complete after 3s [id=vpc-0eae7e2fc2e7fe06a] aws_internet_gateway.gw: Creating... aws_internet_gateway.gw: Creation complete after 1s [id=igw-06965b26b6c59f309] Apply complete! Resources: 2 added, 0 changed, 0 destroyed. # terraform show # aws_internet_gateway.gw: resource "aws_internet_gateway" "gw" { arn = "arn:aws:ec2:ap-southeast-1:764510719561:internet-gateway/igw-094a57c9141ce13b8" id = "igw-094a57c9141ce13b8" owner_id = "764510719561" tags = { "Name" = "default-IGW" } vpc_id = "vpc-0ae7e6ba1874ca963" } # aws_vpc.main: resource "aws_vpc" "main" { arn = "arn:aws:ec2:ap-southeast-1:764510719561:vpc/vpc-0ae7e6ba1874ca963" assign_generated_ipv6_cidr_block = false cidr_block = "10.0.0.0/16" default_network_acl_id = "acl-0e79e26a952ea8fda" default_route_table_id = "rtb-053266f45adb25ae7" default_security_group_id = "sg-07825306fdd7b966d" dhcp_options_id = "dopt-47836621" enable_classiclink = false enable_classiclink_dns_support = false enable_dns_hostnames = false enable_dns_support = true id = "vpc-0ae7e6ba1874ca963" instance_tenancy = "default" main_route_table_id = "rtb-053266f45adb25ae7" owner_id = "764510719561" tags = { "Name" = "default-VPC" } }
Bạn sẽ thấy có một file ‘terraform.tfstate’ được Terraform khởi tạo ở ngay local thư mục chứa file config (đang xài backend local filesystem nhé).
Giờ ta tạo một Workspace khác, dùng cho môi trường Dev chẳng hạn.
# terraform workspace new development Created and switched to workspace "development"! You're now on a new, empty workspace. Workspaces isolate their state, so if you run "terraform plan" Terraform will not see any existing state for this configuration.
Khi bạn chạy terraform show
, sẽ thấy terraform không thể hiện thông tin các resource đã khởi tạo ở Workspace default
.
# terraform show No state.
Giờ bạn thử plan, apply lại thử lần nữa nào. Để ý phần “tag” sẽ thấy tên của Workspace mới.
# 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 Terraform will perform the following actions: # aws_internet_gateway.gw will be created + resource "aws_internet_gateway" "gw" { + arn = (known after apply) + id = (known after apply) + owner_id = (known after apply) + tags = { + "Name" = "development-IGW" } + vpc_id = (known after apply) } # aws_vpc.main will be created + resource "aws_vpc" "main" { + 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 = (known after apply) + 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" = "development-VPC" } } Plan: 2 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 aws_vpc.main: Creating... aws_vpc.main: Creation complete after 8s [id=vpc-0c139f1d6ab2ccda9] aws_internet_gateway.gw: Creating... aws_internet_gateway.gw: Creation complete after 1s [id=igw-0b4454384187ccb8e]
Lúc này bạn list các file trong thư mục local ra sẽ thấy các file terraform.tfstate
.
# tree . .terraform ├── environment └── plugins └── darwin_amd64 ├── lock.json └── terraform-provider-aws_v3.4.0_x5 ├── main.tf ├── terraform.tfstate └── terraform.tfstate.d └── development └── terraform.tfstate
Nguồn: https://cuongquach.com/