- vừa được xem lúc

Terraform Series - Bài 9 - CI/CD with Terraform Cloud and Zero-downtime deployments

0 0 25

Người đăng: Quân Huỳnh

Theo Viblo Asia

Giới thiệu

Chào các bạn tới với series về Terraform, ở bài trước chúng ta đã tìm hiểu về Remote Backend với Terraform Cloud. Ở bài này chúng ta sẽ tìm cách sử dụng Terraform Cloud để xây dựng CI/CD cho infrastructure của ta. Sau đó chúng ta sẽ tìm hiểu một thuộc tính của Terraform mà giúp ta thực hiện Zero-downtime deployments.

image.png

CI/CD with Terraform Cloud

Như ta đã nói ở bài trước, khi ta tạo một workspaces trên Terraform Cloud thì sẽ có ba cách sử dụng là:

  • Version control system workflow.
  • CLI-driven workflow.
  • API-driven workflow.

Với CLI-driven workflow giúp ta trong việc xây dựng Remote Backend, còn Version control system workflow (VCS) sẽ giúp ta trong việc xây dựng luồng CI/CD.

Với Terraform Cloud VCS, việc xây dựng CI/CD rất dễ dàng, tất cả những gì chúng ta cần làm là tạo một github repository, kết nối repository đó tới Terraform Cloud, sau đó ta chỉ việc đẩy code lên github và Terraform Cloud sẽ thực hiện toàn bộ luồng CI/CD cho ta.

Create github repository

Oke, trước tiên các bạn tạo một repository trên github, đây là repository của mình cho ví dụ này https://github.com/hoalongnatsu/terraform-cloud-vcs-example. Sau đó đăng nhập vào Terraform Cloud, cách đăng ký tài khoản và cấu hình aws credentials các bạn xem ở bài trước, màn hình sau khi đăng nhập vào Terraform Cloud.

image.png

Create VCS Workspace

Ở trang Workspaces ta bấm New Workspaces, sau đó chọn Version control workflow.

image.png

Bước tiếp theo, chỗ Connect to a version control provider, các bạn bấm vào icon Github.

image.png

Sau khi bạn bấm vào icon Github và kết nối tới github của bạn, nó sẽ dẫn ta qua bước thứ ba là chọn repository, các bạn chọn repository mà các bạn tạo cho ví dụ này, repo của mình tên là terraform-cloud-vcs-example.

image.png

Sau đó nó sẽ dẫn ta qua bước cuối cùng, các bạn điền Workspace Name vào và bấm tạo workspace.

image.png

Đợi một chút để terraform cloud setup và bạn sẽ thấy workspace của ta hiện chữ Configuration uploaded successfully .

image.png

Oke, vậy là ta đã tạo workspace xong, bây giờ ta chỉ cần viết code và push nó lên github, Terraform Cloud VCS sẽ chạy và tạo infrastructure cho ta.

Implement CI/CD

Các bạn thêm 3 file sau vào repo.

terraform { required_providers { aws = { source = "hashicorp/aws" version = "~> 4.0" } }
}
variable "region" { type = string default = "us-west-2"
}
provider "aws" { region = var.region
} data "aws_ami" "ami" { most_recent = true filter { name = "name" values = ["ubuntu/images/hvm-ssd/ubuntu-focal-20.04-amd64-server-*"] } owners = ["099720109477"]
} resource "aws_instance" "ansible_server" { ami = data.aws_ami.ami.id instance_type = "t3.micro"
}

Commit code và push lên github.

git add .
git commit -m "init code"
git push

Sau đó ta quay lại UI của Terraform Cloud, các bạn bấm vào Action chọn Start new run.

image.png

Ta sẽ thấy Terraform Cloud in ra cho ta plan step, thay vì chạy câu lệnh CLI và thấy tất cả resource của ta in ta trên terminal. Thì Terraform Cloud sẽ in resource của ta trên UI, rất trực quan và dễ hiểu.

image.png

Kéo xuống phía dưới ta sẽ thấy có chỗ để chúng ta bấm apply. Ta có thể cấu hình bước này là auto luôn, nhưng đối với môi trường production ta không nên cho phép nó auto apply. Các bạn bấm Confirm & Apply.

image.png

Nhập vào comment, và bấm Confirm Plan.

image.png

Terraform Cloud sẽ trigger quá trình apply.

image.png

Đợi nó chạy xong.

image.png

Lúc này các bạn lên AWS Console thì sẽ thấy EC2 của ta đã được tạo.

Update resource

Bây giờ ta sẽ cập nhật lại instance_type của EC2 và push code lên lại github.

resource "aws_instance" "ansible_server" { ami = data.aws_ami.ami.id instance_type = "t3.small" // t3.micro -> t3.small
}
git commit -am "update instance type"
git push

Lúc này bạn sẽ thấy Terraform Cloud tự động phát hiện code của ta đã thay đổi và trigger lại plan step mới.

image.png

Các bạn bấm Confirm & Apply.

image.png

Sau khi nó chạy xong ta sẽ thấy EC2 của ta được update lại với instance type mới.

Destroy resource

Khi xài Terraform Cloud để destroy cũng khá đơn giản. Các bạn bấm vào Settings, chọn Destruction and Deletion.

image.png

Sau đó ta chọn Delete from Terraform Cloud.

image.png

Nhập vào tên và bấn delete.

image.png

Nếu các bạn bấm Delete workspace thì resource của ta đã bị xóa đi. Nhưng lúc này các bạn chưa xóa vội nhé, ta sẽ để nó lại để làm ví dụ tiếp theo.

Zero-downtime deployment

Đối với EC2 của ta, khi ta thay đổi giá trị ami.

resource "aws_instance" "ansible_server" { ami = data.aws_ami.ami.id // change here instance_type = "t3.small"
}

Vì ami của EC2 là một force-new attributes (ami, user_data), nên khi ta tiến hành quá trình apply thì resource EC2 hiện tại sẽ bị destroy và một thằng mới sẽ được tạo ra. Đây là hành động mặc định của Terraform đối với các resource mà có force-new attributes bị thay đổi. Điều này có thể dẫn tới hệ thống của ta bị downtime trong một khoảng thời gian dài.

image.png

Để tránh downtime trong trường hợp này, terraform cung cấp cho một meta argument tên là create_before_destroy.

Use create_before_destroy

Đây là một meta argument giúp ta giải quyết được vấn đề zero-downtime deployment khi ta thay đổi force-new attributes của một resource.

Thay vì Terraform sẽ hành động như mặc định là xóa resource trước rồi tạo resource mới sau, thì Terraform sẽ hành động ngược lại là sẽ tạo resource trước, kiểm tra resource đó được tạo xong rồi thì nó mới tiến hành xóa resource cũ.

Ta sử dụng thuộc tính create_before_destroy như sau, cập nhật lại main.tf

resource "aws_instance" "ansible_server" { ami = data.aws_ami.ami.id instance_type = "t3.small" lifecycle { create_before_destroy = true }
}

Ta thêm một block là lifecycle, trong đó ta sẽ khai báo thuộc tính create_before_destroy là true. Ok bây giờ bạn commit code và đẩy lên github, confirm cho Terraform Cloud apply, quan sát trên AWS Console chỗ EC2 thì ta sẽ thấy lúc này một con EC2 mới sẽ được tạo ra trước sau đó con cũ mới bị xóa đi.

Considering when use create_before_destroy

Thuộc tính create_before_destroy có thể rất thuận tiện, nhưng ta cần nên lưu ý một điều là không phải lúc nào ta cũng có thể sử dụng thuộc tính này cho resource được, vì sẽ có một xài resource bị conflict.

Ví dụ như là đối với AWS thì S3 bucket là unique tên toàn bộ hệ thống của AWS, nên nếu ta dùng thuộc tính create_before_destroy với S3 thì nó sẽ bị lỗi, vì lúc này S3 bucket mới sẽ được tạo ra trước, nhưng bucket name của nó sẽ giống y như thằng cũ thì ta sẽ gặp lỗi ngay.

Vì lý do trên nên ta cần xem xét cẩn thận khi dùng create_before_destroy, ta phải xác định rõ resource nào ta có thể dùng create_before_destroy cho nó còn resource nào thì không thể dùng.

No zero-downtime deployment

Tuy gọi là zero-downtime deployment, nhưng không phải lúc nào ta cũng có thể thực hiện việc này hoàn toàn được. Vì zero-downtime deployment là một vấn đề cần rất nhiều thứ để giải quyết và chỉ có thể áp dụng được với một số resource, như là cập nhật lại các resource mà chứa application, chứ không phải lúc nào ta cũng có thể áp dụng được zero-downtime deployment cho toàn bộ resource trong hệ thống của ta được.

Ví dụ đơn giản nhất là dịch vụ database của AWS là RDS, khi ta thay đổi instance_type của nó thì ta không thể sử dụng thuộc tính create_before_destroy để thực hiện zero-downtime deployment được, vì lúc này RDS của ta nó đâu có bị xóa và tạo lại đâu, nó chỉ cập nhật lại instance_type và bị downtime mà thôi.

Tất nhiên là cũng sẽ có cách để triển khai zero-downtime deployment cho database được, nhưng quá trình thực hiện sẽ rất phúc tạp và cần kết hợp nhiều công cụ khác nhau chứ không thể chỉ dùng Terraform được.

Ở bài tiếp theo mình sẽ nói về một khái niệm mà có thể giúp ta thực hiện zero-downtime deployment cho database được, là blue/green deployment. Và cũng sẽ làm một ví dụ về blue/green deployment cho autoscaling group, đây là một trong những cách để giảm thiểu thời gian downtime cho hệ thống.

Kết luận

Vậy là ta đã tìm hiểu xong về cách thực hiện CI/CD với Terraform Cloud, và một cách đơn giản để thực hiện zero-downtime deployment cho resource của ta. Nếu có thắc mắc hoặc cần giải thích rõ thêm chỗ nào thì các bạn có thể hỏi dưới phần comment. Hẹn gặp mọi người ở bài tiếp theo ta sẽ tìm hiểu về Blue/Green Deployment.

Mục tìm kiếm đồng đội

Hiện tại thì bên công ty mình, là Hoàng Phúc International, với hơn 30 năm kinh nghiệm trong lĩnh vực thời trang. Và là trang thương mại điện tử về thời trang lớn nhất Việt Nam. Team công nghệ của HPI đang tìm kiếm đồng đội cho các vị trí như:

Với mục tiêu trong vòng 5 năm tới về mảng công nghệ là:

  • Sẽ có trang web nằm trong top 10 trang web nhanh nhất VN với 20 triệu lượt truy cập mỗi tháng.
  • 5 triệu loyal customers và có hơn 10 triệu transactions mỗi năm.

Team đang xây dựng một hệ thống rất lớn với rất nhiều vấn để cần giải quyết, và sẽ có rất nhiều bài toàn thú vị cho các bạn. Nếu các bạn có hứng thú trong việc xây dựng một hệ thống lớn, linh hoạt, dễ dàng mở rộng, và performance cao với kiến trúc microservices thì hãy tham gia với tụi mình.

Nếu các bạn quan tâm hãy gửi CV ở trong trang tuyển dụng của Hoàng Phúc International hoặc qua email của mình nha _@.com. Cảm ơn các bạn đã đọc.

Bình luận

Bài viết tương tự

- vừa được xem lúc

Đề thi interview DevOps ở Châu Âu

Well. Chào mọi người, mình là Rice - một DevOps Engineers ở đâu đó tại Châu Âu.

0 0 65

- vừa được xem lúc

In calculus, love also means zero.

Mình nhớ hồi năm 2 đại học, thầy giáo môn calculus, trong một giây phút ngẫu hứng, đã đưa ra cái definition này. Lúc đấy mình cũng không nghĩ gì nhiều.

0 0 51

- vừa được xem lúc

Chuyện thay đổi

Thay đổi là một thứ gì đó luôn luôn đáng sợ. Cách đây vài tháng mình có duyên đi làm cho một banking solution tên là X.

0 0 30

- vừa được xem lúc

Pet vs Cattle - Thú cưng và gia súc

Khái niệm. Pets vs Cattle là một khái niệm cơ bản của DevOps. Bài viết này sẽ nói về sự phát triển của các mô hình dịch vụ từ cốt lõi Pets and Cattle. 1.

0 0 22

- vừa được xem lúc

Git workflow được Google và Facebook sử dụng có gì hay ho

Với developer thì Git hẳn là công cụ rất quen thuộc và không thể thiếu rồi. Thế nhưng có mấy ai thực sự hiểu được Git.

0 0 66

- vừa được xem lúc

Kubernetes - Học cách sử dụng Kubernetes Namespace cơ bản

Namespace trong Kubernetes là gì. Tại sao nên sử dụng namespace.

0 0 96