IaC và Terraform

Infrastructure as Code

Hạ tầng (infrastructure) bao gồm nhiều module khác nhau như database, caching layer, load balancer, service,... Khi triển khai ứng dụng, cần phải đảm bảo rằng các component này được deploy và cấu hình đúng cách để đảm bảo hiệu suất và độ tin cậy.

IaC (Infrastructure as Code) là một giải pháp ra đời bằng cách mô hình hóa hạ tầng triển khai để tối ưu hóa quá trình xây dựng và cấu hình hạ tầng. IaC cho phép định nghĩa và quản lý các tài nguyên bằng code, thay vì phải thực hiện các thao tác cầu hình manual, lặp đi lặp lại và dễ phát sinh rủi ro. Nhờ đó, có thể đảm bảo rằng các tài nguyên được deploy và cấu hình đúng cách, và cũng có thể tái sử dụng cấu hình, thử nghiệm, gỡ lỗi, mở rộng và quản lý tài nguyên một cách nhanh chóng và thuận tiện.

Terraform

Terraform là một công cụ IaC phổ biến, được sử dụng rộng rãi khi xây dựng hạ tầng trên cloud. Terraform hỗ trợ nhiều cloud provider (AWS, Azure,...) giúp việc triển khai hạ tầng trên nhiều nền tảng cloud mà không phải rework khi có thay đổi, triển khai hybrid... Terraform có một cộng đồng người dùng lớn, liên tục cập nhật.

Quy trình làm việc

  1. Write infra: Định nghĩa các tài nguyên cloud bằng code, sử dụng HCL - HashiCorp Configuration Language (instance, network, storage, v.v.).
  2. Plan: Visualize resource đã được định nghĩa, kiểm tra trạng thái tài nguyên tạo mới, thay đổi.
  3. Apply: Áp dụng cấu hình lên cloud provider đã thiết lập.

Cấu trúc project

Một RootModule trong Terraform thông thường sẽ có các file .tf sau:

  • main.tf: File chính của RootModule, nơi chứa các definitions của tài nguyên cloud và dependencies.
  • variables.tf: File này định nghĩa các biến (variables) được sử dụng trong RootModule.
  • output.tf: File này định nghĩa các output của RootModule, giúp bạn có thể lấy thông tin về trạng thái của tài nguyên cloud sau khi deploy.

File được tạo bởi Terraform

  • terraform.tfstate: File này chứa trạng thái hiện tại của các tài nguyên. Terraform sẽ đọc file này để xác định xem đã có bao nhiêu tài nguyên được deploy và trạng thái của chúng là gì.
  • terraform.tfstate.backup: File này chứa một bản backup của trạng thái tài nguyên. Bạn có thể sử dụng file này để khôi phục lại các tài nguyên cloud nếu cần thiết.

Phần thi khởi động với Hello world 😤

Cài đặt

Terraform hỗ trợ nhiều hệ điều hành khác nhau như Windows, Linux, MacOS, Solaris, FreeBSD và OpenBSD... Tham khảo thêm ở trang chủ Hashicorp. Ở đây mình sẽ sử dụng Homebrew để cài đặt trên MacOS:

brew tap hashicorp/tap
brew install hashicorp/tap/terraform

Cấu hình provider (AWS)

Bài viết này mình sẽ hand on với AWS (vì mấy provider khác mình không biết dùng 😼). Trước tiên, để Terraform có thể truy cập vào tài nguyên của AWS, ta cần cấp quyền cho client bằng cách dùng access key cho tài khoản AWS. Nếu như đã cài đặt awscli và cấu hình access key có thể bỏ qua bước này. Nếu chưa cầu hình, có thể tham khảo hướng dẫn ở đây. Hoặc nếu đã có access key, có thể cấu hình nhanh bằng cách:

  • Tạo tệp tin credentials bằng câu lệnh:
vi ~/.aws/credentials
  • Dán nội dung ở dưới và thêm vào giá trị access key :
[default]
aws_access_key_id=
aws_secret_access_key=

Xắn cái tay áo lên, code

Tạo mới 1 folder, mở 1 text editor hỗ trợ HCL syntax highlighting như vim, emacs, Sublime Text, Atom, Visual Studio Code, and IntelliJ.

1. Init infra

Tạo file main.tf, cấu hình region mà đang làm việc, mình ở đông Lào nên chọn server Singapore

  provider "aws" {
    region = "ap-southeast-1"
  }

Với mỗi provider lại có 10 vạn 8 ngàn kiểu resource mà có thể tạo như là database, VM, k8s, caching layer... Nhưng syntax để tạo 1 resource Terraform thường theo cấu trúc:

  resource "<PROVIDER>_<TYPE>" "<NAME>" {
    [CONFIG …]
  }
  • PROVIDER là tên của provider
  • TYPE là tên loại resource tương ứng
  • NAME là tên của resource tự định nghĩa, có thể sử dung xuyên suốt trong Terraform project
  • CONFIG là tập hợp các arguments cấu hình chi tiết cho resource.

Dí dụ như cấu hình tạo 1 VM trên AWS (EC2) thì đoạn code cấu hình trong file main.tf:

  resource "aws_instance" "example" {
    ami           =  "ami-0464f90f5928bccb8" 
    instance_type = "t2.micro"
  }

aws_instance hỗ trợ nhiều cấu hình chi tiết. Nhưng ở đây mình chỉ cấu hình 2 trường bắt buộc

  • ami - Amazon Machine Image, nó giống như Image của Docker thì ở đây là Image để tạo nên VM, ví dụ ở trên mình sử dụng là ID của Amazon Linux 2023 AMIap-southeast-1.
  • instance_type định nghĩa loại EC2 instance khởi chạy, mỗi loại cung cấp một số CPU, memory, disk space, và networking capacity khác nhau.

Mở terminal ở thư mục đang làm việc, chạy lệnh:

terraform init

Terraform sẽ tải về các module theo các resource được cấu hình ở trong project tại folder .terraform, tạo file lock .terraform.lock.hcl cho các module giống như package-lock.json của npm, sử dụng để quản lý version cho các module được tải về.

2. Plan

Vâng và sau khi tải về các module, chạy lệnh terraform plan. Trước khi thay đổi bất cứ resource gì, đây là cách để kiểm tra lại code trước khi áp dụng. Output của command này là 1 phần của output diff của Unix, Linux, và git. Resource đứng sau:

  • (+) sẽ được tạo.
  • (-) sẽ bị xóa.
  • (~) sẽ bị thay đổi.
terraform plan

Terraform used the selected providers to generate the following execution plan. Resource actions
are indicated with the following symbols:
  + create

Terraform will perform the following actions:

  # aws_instance.example will be created
  + resource "aws_instance" "example" {
      + ami                                  = "ami-0464f90f5928bccb8"
      + get_password_data                    = false
      + instance_type                        = "t2.micro"
      + source_dest_check                    = true
      + user_data_replace_on_change          = false
      (...)
    }

Plan: 1 to add, 0 to change, 0 to destroy.

────────────────────────────────────────────────────────────────────────────────────────────────

Note: You didn't use the -out option to save this plan, so Terraform can't guarantee to take
exactly these actions if you run "terraform apply" now.

3. Apply

Để thực sự áp dụng cấu hình, chạy lệnh terraform apply. Output của lệnh này có phần giống với plan command, nhưng apply yêu cầu xác nhận trước khi thực hiện. Plan thường được sử dụng để kiểm tra nhanh chóng hoặc trong quá trình kiểm tra lại mã. Sau khi kiểm tra, để xác nhận, gõ yes và hit Enter. Output là quá trình tạo resource, nhận thông báo thành công dạng:

terraform apply

(...)

Do you want to perform these actions?
  Terraform will perform the actions described above.
  Only 'yes' will be accepted to approve.

  Enter a value: yes

aws_instance.example: Creating...
aws_instance.example: Still creating... [10s elapsed]
aws_instance.example: Still creating... [20s elapsed]
aws_instance.example: Creation complete after 33s [id=i-089ba6fa30a7df2bf]

Apply complete! Resources: 1 added, 0 changed, 0 destroyed.

4. Destroy

Đến đây thì EC2 instance đã được tạo thành công. Bây giờ mà muốn xóa hết tất cả thay vì thì chỉ cần chạy lệnh terraform destroy, gõ yes để xác nhận ko còn lưu luyến gì.

terraform destroy

aws_instance.example: Refreshing state... [id=i-089ba6fa30a7df2bf]

Terraform used the selected providers to generate the following execution plan. Resource actions
are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  # aws_instance.example will be destroyed
  - resource "aws_instance" "example" {
    (...)
    }

Plan: 0 to add, 0 to change, 1 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

aws_instance.example: Destroying... [id=i-089ba6fa30a7df2bf]
aws_instance.example: Still destroying... [id=i-089ba6fa30a7df2bf, 10s elapsed]
aws_instance.example: Still destroying... [id=i-089ba6fa30a7df2bf, 20s elapsed]
aws_instance.example: Destruction complete after 41s

Destroy complete! Resources: 1 destroyed.

Vậy là đã xóa thành công. Chúc mừng gia đình. Ta vừa hoàn thành mấy động tác khởi động cơ bản với việc thêm xóa EC2 instance 🥳.
Bài sau sẽ 1 bước lên mây với đầy đủ resource để có thể sử dụng cho 1 dự án cơ bản hê hê. Cám ơn vì đã đọc (hoặc là lướt) đến đây.