Cách mình đã viết Cloudformation template để deploy một project

Mở bài

Chào các bạn, mình là Hậu - Group 1 VJP.

Để biết Cloudformation (Cfn) là gì thì các bạn có thể tham khảo thêm tại doc của AWS.

Đại khái thì nó là 1 template, bạn viết thiết kế của hệ thống ra một bản thiết kế (yaml, json) rồi deploy nó trên môi trường AWS thì nó sẽ tự động tạo ra các resource theo đúng những gì bản thiết kế các bạn mô tả.

Ở một bài viết về Cloudformation tại vtitech.vn trước đó có đề cập tới các mẹo hay để viết Cfn các bạn có thể đọc lại tại đây. Lần này mình sẽ đề cập tới một khía cạnh khác khi làm việc với Cfn để deploy 1 hệ thống phức tạp hơn.

Đặt vấn đề

Khi viết cfn cho một hệ thống phức tạp, nên tổ chức các file template như thế nào cho dễ quản lý, sửa đổi, update và reuse.

Nào cùng đi phân tích.

Thân bài

Sơ đồ hệ thống lấy làm ví dụ.

Phân tích:

  • Hệ thống có rất nhiều service và chắc chắn nhiều resource.
  • Nhiều service liên quan tới nhau.
  • Có những resource có ouput là input của resource khác.

Có những cách viết Cfn sau:

Cách 1: Viết tất cả vào 1 file, các resource liên quan tới nhau thì chỉ cần tạo liên hệ (!Ref ResourceName).

=> Cách này chỉ phù hợp với hệ thống nhỏ, ít resource, khi edit hay reuse sẽ rất khó. Đối với các hệ thống lớn thì cách này chắc chắn là không thể.

Cách 2: Chia nhỏ hệ thống ra thành nhiều file, deploy theo kiểu nested file.

=> Cách này nói chung là ok, nhưng mà chia theo tiêu chí nào, và triển khai cụ thể như thế nào thì chúng ta cùng đi tiếp nhé.

Mình thường làm theo thứ tự như sau:

  1. Chia theo region
  2. Chia theo mối liên quan.
  3. Chia theo loại service.
Chia folder Cfn template

Regional Services:

Cloudformation là loại "Regional Services" nên đối với hệ thống deploy trên nhiều region thì chúng ta bắt buộc phải chia theo region rồi (Vẫn có cách từ 1 region để deploy 1 stack ở 1 region khác nhưng mình chưa thử :D). Nên mình sẽ chia folder theo region ( tokyo và virginia).

Mối liên kết giữa các service:

Bên VPC, RDS, ALB-EC2 có mối liên kết khá chặt chẽ nên mình nhóm nó vào 1 folder tokyo để deploy 1 cụm 1 lúc. Các service lẻ, có thể đứng 1 mình được mình cho vào folder Other mặc dù cùng deploy ở tokyo region.

Việc tách ra folder Other:

Là để thuận tiện trong quá trình dev - test. Có thể dev-test từng thành phần riêng lẻ mà ít có ảnh hưởng tới các service khác. Ví dụ động vào cụm VPC, RDS, ALB-EC2 thì giả sử lỗi cụm đó thì nó vừa mất thời gian vừa ảnh hưởng tới nhiều hệ thống khác. Cái cụm đó mình coi là core và ưu tiên cho done cái đó trước.

Trình tự dev các template:

Các file template rời rạc mình sẽ viết riêng rẽ và lần lượt thêm vào. Và cuối cùng mình sẽ viết file master để tổng hợp các file thành phần lại. Các Mỗi folder sẽ có 1 file master. Các file master này sẽ copy các parameter từ file thành phần sang.

Tên template file:

Việc đặt tên các file template (.yaml) cũng cần ngắn gọn nhất có thể, chỉ cần danh từ là đủ. "Project-A-Environment X-Create-ALB-EC2.yaml" đặt tên dài thế này không cần thiết.

Về việc nested stack:

Vì là Cfn dạng nested nên sẽ có sự liên lạc giữa các file template. Tức là output của template này sẽ là input của template khác. Cfn có cung cấp một tính năng phục vụ cho việc này là "Export" và "Import". Mình không đánh giá cao việc dùng bộ đôi này, nó làm tăng tính kết dính giữa các Cfn template. Mình muốn tách rời chúng ra, có thể deploy riêng rẽ các file thành phần, và có thể reuse theo một format có sẵn, nên tất cả mình ưu tiên dùng parameter bằng text.

Path File của nested template:

Dùng Cfn nested nên phải cung cấp đường link các file template. Mình hay dùng cấu trúc thư mục của source code kết hợp với S3 bucket để làm đường link động cho các template thành phần.
Cụ thể là mình sẽ để parameter cho các stack con trong file master như thế này.

  • https://<BucketName>.s3.amazonaws.com/Virginia/Master.yaml
    https://<BucketName>.s3.amazonaws.com/Virginia/Cloudfront.yaml
    https://<BucketName>.s3.amazonaws.com/Virginia/ACM.yaml
  • ........
  • https://<BucketName>.s3.amazonaws.com/Tokyo/Master.yaml
  • https://<BucketName>.s3.amazonaws.com/Tokyo/VPC.yaml
  • ……..

Sau này khi thay đổi môi trường thì chỉ cần thay BucketName chứa template là được rồi, rất nhẹ nhàng.

Tên các resource:

Mình thường định nghĩa ra 2 parameter: SystemName và Environment. Hai thành phần này cùng với tên của resource (cố dịnh trong file template) sẽ phần nào đó (không phải tuyệt đối) tạo thành tên unique tránh trùng tên và tạo thành tên resrouce có ý nghĩa khi tạo thành. Ngoài ra hai thành phần này có thể đặt làm tag name để tiện quản lý.

Đối với việc deploy nhiều lần bị trùng tên hay lỗi:

Anh em vẫn mong có một thành phần nào đó random để có thể unique dễ dàng hơn nhưng việc này là hơi khó trong AWS clouformation. Để lươn lẹo tạo ra thì mình có search được đoạn code trên mạng có thể giúp ích anh em tạo ra một chuỗi ký tự gần random. Gần thôi nhé.

      AutoScalingGroupName:
        Fn::Join:
          - '-'
          - - my-auto-scaling-group
            - Fn::Select:
                - 4
                - Fn::Split:
                    - '-'
                    - Fn::Select:
                        - 2
                        - Fn::Split:
                            - /
                            - Ref: AWS::StackId

Kết luận

Trên đây mình đã chia sẻ cách mình đã tổ chức các file Cfn template để dễ dàng quản lý, sửa đổi và reuse. Hy vọng sẽ giúp anh em trong công việc.

Leave a Reply

Your email address will not be published. Required fields are marked *