0
0
Lập trình
Sơn Tùng Lê
Sơn Tùng Lê103931498422911686980

Khám Phá Terraform với YAML và YISP: Giải Pháp Mới

Đăng vào 4 ngày trước

• 6 phút đọc

Giới thiệu

Terraform là một trong những công cụ hàng đầu cho hạ tầng dưới dạng mã (Infrastructure as Code - IaC). Tuy nhiên, khi bạn bắt đầu quản lý nhiều môi trường (như dev/prod), việc xử lý các khác biệt giữa các môi trường có thể trở nên phức tạp hơn nhiều. Nhiều người đã tìm kiếm Terragrunt như một giải pháp cho vấn đề này.

Mặc dù ngôn ngữ riêng của Terraform, HCL (HashiCorp Configuration Language), khá dễ tiếp cận, việc sử dụng các cấu trúc như count hay for một cách thành thạo cần phải có thời gian luyện tập. Cuối cùng, HCL là một DSL (Domain Specific Language) riêng của Terraform - không phải là thứ có thể dễ dàng tái sử dụng ở nơi khác.

Vì lý do đó, trong bài viết này, tôi muốn thử một cách tiếp cận khác: định nghĩa một dự án Terraform bằng YAML và trình đánh giá biểu thức YISP. Với YAML + YISP, bạn có thể tự do định nghĩa và kết hợp các mô-đun theo những cách linh hoạt hơn, và kiến thức này có thể áp dụng cho các lĩnh vực khác dựa trên YAML như các tệp manifest của Kubernetes.

Liệu điều này có thực tiễn hay không vẫn là một câu hỏi mở — nhưng có thể nó sẽ mở ra những cách tiếp cận mới để xử lý các biến thể cụ thể của môi trường.


Tổng Quan Về Cú Pháp JSON của Terraform

Terraform thường yêu cầu các tệp .tf được viết bằng HCL, nhưng bạn cũng có thể cung cấp cấu hình bằng định dạng JSON.

Ví dụ, tệp HCL sau:

hcl Copy
tf {
  required_providers {
    local = {
      source  = "hashicorp/local"
      version = "2.4.0"
    }
  }
}

provider "local" {}

resource "local_file" "hello1" {
  content  = "1st Hello, World!"
  filename = "hello1.txt"
}

resource "local_file" "hello2" {
  content  = "2nd Hello, World!"
  filename = "hello2.txt"
}

Có thể được viết lại dưới dạng JSON như sau:

json Copy
{
  "provider": {
    "local": {}
  },
  "resource": {
    "local_file": {
      "hello1": {
        "content": "1st Hello, World!",
        "filename": "hello1.txt"
      },
      "hello2": {
        "content": "2nd Hello, World!",
        "filename": "hello2.txt"
      }
    }
  },
  "terraform": {
    "required_providers": {
      "local": {
        "source": "hashicorp/local",
        "version": "2.4.0"
      }
    }
  }
}

Lưu tệp này với tên <filename>.tf.json, và Terraform sẽ chấp nhận nó khi bạn thực hiện terraform apply như thường lệ.


YISP là gì?

YISP là một công cụ nhỏ giúp bạn nhúng và đánh giá các biểu thức bên trong YAML.

Ví dụ, YAML sau:

yaml Copy
# index.yaml
mynumber: !yisp
  - add
  - 5
  - 3

Sẽ được đánh giá thành:

yaml Copy
# kết quả
mynumber: 8

Chỉ cần chạy yisp build ..

YISP cũng hỗ trợ nhập nhiều tệp YAML, hợp nhất các đối tượng hoặc thậm chí xuất JSON thay vì YAML.

Trong thí nghiệm này, chúng ta sẽ sử dụng YISP để làm cho việc viết JSON Terraform dễ dàng hơn trong YAML, và để quản lý các khác biệt cụ thể của môi trường thông qua nhập khẩu và vá lỗi.


Bước Đầu Tiên

Dưới đây là một định nghĩa Terraform đơn giản viết bằng YAML:

yaml Copy
# tf.yaml
tf:
  required_providers:
    local:
      source: hashicorp/local
      version: "2.4.0"

---
provider:
  local: {}

---
resource:
  local_file:
    hello1:
      content: "1st Hello, World!"
      filename: "hello1.txt"

---
resource:
  local_file:
    hello2:
      content: "2nd Hello, World!"
      filename: "hello2.txt"

Sau đó, trong index.yaml, hợp nhất chúng thành một đối tượng:

yaml Copy
# index.yaml
!yisp
- lists.reduce
- - include
  - tf.yaml
- maps.merge

Chạy yisp build . sẽ xuất ra cấu trúc JSON tương tự như đã trình bày trước đó.


Sử Dụng Makefile

Các lệnh Terraform không chấp nhận cấu hình qua stdin — chúng yêu cầu một tệp thực tế. Để tối ưu hóa quy trình làm việc, hãy sử dụng Makefile tự động tạo JSON trước khi chạy Terraform:

makefile Copy
rendered.tf.json:
    yisp build . -o json > rendered.tf.json

init: rendered.tf.json
    terraform init

plan: rendered.tf.json
    terraform plan

apply: rendered.tf.json
    terraform apply

Giờ đây, bạn có thể chỉ cần chạy make plan hoặc make apply, và YAML sẽ được chuyển đổi thành JSON khi cần.


Tổ Chức Mô-đun cho Các Khác Biệt Môi Trường

Hãy tiến thêm một bước nữa và giới thiệu các mô-đun để xử lý các biến thể dev/prod. Dưới đây là cấu trúc thư mục:

Copy
📁 .
├── 📁 base
│   ├── 📄 core.yaml
│   └── 📄 localfile.yaml
└── 📁 env
    ├── 📁 dev
    │   ├── 📄 index.yaml
    │   └── 📄 localfile.yaml
    └── 📁 prod
        ├── 📄 index.yaml
        └── 📄 localfile.yaml

Cấu Hình Cơ Bản (base/core.yaml)

yaml Copy
# base/core.yaml
tf:
  required_providers:
    local:
      source: hashicorp/local
      version: "2.4.0"

---
provider:
  local: {}

Định Nghĩa Mô-đun (base/localfile.yaml)

yaml Copy
# base/localfile.yaml
!yisp &main
- lambda
- [ props ]
- !quote
  resource:
    local_file:
      hello:
        content: !yisp
        - strings.format
        - "Hello: %s"
        - *props.name
        filename: "hello1.txt"

Sử Dụng Mô-đun (env/dev/localfile.yaml)

yaml Copy
# env/dev/localfile.yaml
!yisp
- import
- ["localfile", "../../base/localfile.yaml"]

---
!yisp
- *localfile.main
- name: "alice"

Hợp Nhất Cuối Cùng (env/dev/index.yaml)

yaml Copy
# env/dev/index.yaml
!yisp
- lists.reduce
- - include
  - ../../base/core.yaml
  - localfile.yaml
- maps.merge

Đánh giá điều này sẽ cho chúng ta:

yaml Copy
# đầu ra
tf:
  required_providers:
    local:
      source: hashicorp/local
      version: "2.4.0"
provider:
  local: {}
resource:
  local_file:
    hello:
      content: "Hello: alice"
      filename: "hello1.txt"

Ở đây chúng ta có một tài nguyên local_file ghi "Hello: alice". Đối với môi trường sản xuất, bạn chỉ cần điều chỉnh các tham số và tái sử dụng cùng một mô-đun.


Kết Luận

Trong bài viết này, chúng ta đã thử sử dụng YISP để định nghĩa Terraform trong YAML, đồng thời phân chia các khác biệt cụ thể của môi trường thành các mô-đun.

Chưa chắc liệu phương pháp này có thực tiễn trong sản xuất hay không, nhưng đây là một khám phá thú vị: giống như kustomize của Kubernetes giúp quản lý các biến thể manifest, chúng ta có thể thử nghiệm với những ý tưởng tương tự cho Terraform.

Nếu bạn thấy thú vị, hãy thử nghiệm với thiết lập của riêng bạn!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào