Bỏ qua để đến nội dung

Triển khai hạ tầng ở quy mô lớn

Hãy tưởng tượng bạn cần dựng một hệ thống gồm: một security group, hai EC2 instance dùng security group đó, một S3 bucket, và một load balancer đứng trước hai instance này. Nếu làm tay trên Console, bạn phải click qua rất nhiều màn hình, nhớ đúng thứ tự (ví dụ phải tạo security group trước khi gán cho EC2), và rất dễ quên mất một cấu hình nhỏ. Khi cần dựng lại hệ thống này ở một region khác, hoặc cho một team khác, bạn lại phải làm tay từ đầu — vừa chậm, vừa dễ sai, vừa khó kiểm soát.

AWS CloudFormation giải quyết vấn đề đó bằng cách cho phép bạn mô tả (khai báo - declarative) toàn bộ hạ tầng mong muốn trong một file văn bản gọi là template (viết bằng JSON hoặc YAML), rồi đưa file đó cho CloudFormation. CloudFormation sẽ tự đọc template, tự tính toán thứ tự tạo resource hợp lý (ví dụ phải có VPC trước khi có subnet, phải có security group trước khi gán cho EC2), rồi tạo ra chính xác những gì bạn đã khai báo. CloudFormation hỗ trợ gần như toàn bộ các loại resource của AWS.

Điểm mấu chốt cần nhớ: bạn không viết ra các bước phải làm (imperative, kiểu “làm bước 1, rồi bước 2, rồi bước 3…”), mà chỉ viết ra kết quả cuối cùng bạn muốn có. CloudFormation tự lo phần “làm thế nào”. Đây chính là bản chất của Infrastructure as Code (IaC) — hạ tầng được viết ra như một đoạn code, có thể lưu trong Git, review, và chạy lại bất cứ khi nào cần.

Vì sao nên dùng CloudFormation thay vì tạo resource bằng tay? Có bốn nhóm lợi ích chính mà đề thi hay nhắc tới:

  • Infrastructure as Code: không có resource nào được tạo “chui” bằng tay ngoài quy trình — mọi thay đổi hạ tầng đều đi qua một file code, được review giống như review code ứng dụng. Điều này giúp tổ chức kiểm soát tốt hơn ai thay đổi gì, khi nào.
  • Quản lý chi phí (Cost): mỗi resource trong một “stack” (một lần triển khai template) đều được gắn thẻ (tag) theo định danh của stack, nên bạn có thể biết chính xác một stack đang tốn bao nhiêu tiền. Bạn cũng có thể ước tính chi phí trước khi triển khai dựa trên template, và áp dụng chiến lược tiết kiệm — ví dụ tự động xóa các stack môi trường Dev vào 5 giờ chiều và tạo lại vào 8 giờ sáng hôm sau để không trả tiền qua đêm.
  • Tăng năng suất (Productivity): có thể phá hủy và tạo lại toàn bộ hạ tầng chỉ bằng một lệnh; CloudFormation còn có thể tự sinh sơ đồ (diagram) thể hiện các resource và quan hệ giữa chúng; vì là khai báo, bạn không cần tự nghĩ thứ tự tạo resource; và bạn có thể tận dụng hàng ngàn template mẫu có sẵn trên Internet và trong tài liệu AWS thay vì viết lại từ đầu.
  • Hỗ trợ hầu hết mọi dịch vụ AWS: với các resource chưa được hỗ trợ sẵn, CloudFormation vẫn cho phép định nghĩa “custom resource” để lấp đầy khoảng trống.

Viết template CloudFormation bằng JSON/YAML có nhược điểm: không có vòng lặp, không có hàm, không có kiểm tra kiểu dữ liệu như một ngôn ngữ lập trình thật. Nếu bạn là developer và muốn định nghĩa hạ tầng bằng chính ngôn ngữ mình đang dùng hàng ngày (JavaScript/TypeScript, Python, Java, .NET), AWS cung cấp AWS Cloud Development Kit (CDK).

Với CDK, bạn viết code bình thường (có class, có hàm, có vòng lặp for) để định nghĩa hạ tầng. Sau đó CDK CLI sẽ “compile” (biên dịch) đoạn code đó thành một CloudFormation template chuẩn (JSON/YAML), rồi CloudFormation nhận template đó và triển khai như thường. Quy trình có thể hình dung như sau:

CDK Application (ngôn ngữ lập trình) → CDK CLI → CloudFormation Template → CloudFormation

Điểm mạnh của CDK là bạn có thể triển khai cả hạ tầng và code runtime của ứng dụng cùng lúc trong một lần deploy — rất phù hợp khi viết Lambda function (định nghĩa function, permission, trigger… trong cùng một file code) hoặc khi đóng gói ứng dụng container chạy trên ECS/EKS.

Phần lớn các ứng dụng web đều gặp chung một nhóm vấn đề: quản lý hạ tầng (server nào, bao nhiêu server), triển khai code lên đúng server, cấu hình database và load balancer, và xử lý vấn đề scale khi lượng truy cập tăng giảm. Điều thú vị là hầu hết web app lại dùng chung một kiểu kiến trúc: một Application Load Balancer (ALB) đứng trước, phân phối traffic cho một Auto Scaling Group (ASG) gồm nhiều EC2 instance.

Một kiến trúc “3-tier” điển hình chạy Multi-AZ để đảm bảo độ sẵn sàng cao thường gồm: nhiều Availability Zone, mỗi AZ có các instance trong một Auto Scaling Group đứng sau ELB; tầng cache dùng ElastiCache để lưu session hoặc dữ liệu truy vấn thường xuyên; và tầng dữ liệu chính dùng Amazon RDS để đọc/ghi.

Vấn đề là: nếu developer nào cũng phải tự dựng lại toàn bộ kiến trúc này (ALB, ASG, RDS, cấu hình scaling, health check…) bằng tay hoặc bằng CloudFormation thủ công, họ sẽ mất rất nhiều thời gian cho hạ tầng thay vì viết code ứng dụng. Điều họ thật sự muốn là: “Tôi chỉ cần đưa code lên, và nó phải chạy được — nhất quán trên mọi ứng dụng và mọi môi trường (dev, test, production)”.

AWS Elastic Beanstalk ra đời chính là để giải quyết bài toán ở trên. Nó là một góc nhìn “thân thiện với developer” (developer-centric) để triển khai ứng dụng lên AWS. Bên dưới, Beanstalk vẫn dùng đúng những dịch vụ bạn đã biết: EC2, Auto Scaling Group, Elastic Load Balancer, RDS — nhưng gói tất cả lại trong một giao diện duy nhất, dễ hiểu, dễ theo dõi. Bạn vẫn có toàn quyền chỉnh cấu hình chi tiết nếu muốn, nhưng mặc định Beanstalk đã tự chọn cấu hình hợp lý cho bạn.

Về bản chất, Elastic Beanstalk là một Platform as a Service (PaaS): bạn không quản lý “hạ tầng” theo nghĩa từng máy chủ riêng lẻ, mà quản lý ở mức “ứng dụng”. Elastic Beanstalk bản thân là dịch vụ miễn phí (AWS không tính phí riêng cho Beanstalk), nhưng bạn vẫn phải trả tiền cho các resource bên dưới mà nó tạo ra (EC2, RDS, ELB…).

Elastic Beanstalk là dịch vụ được quản lý (managed service) theo nghĩa: AWS lo phần cấu hình instance/OS, thực hiện chiến lược triển khai (deployment strategy) mà bạn chọn, tự động cấp phát công suất (capacity provisioning), tự cấu hình load balancing và auto-scaling, và tự giám sát tình trạng hoạt động (health) của ứng dụng. Phần duy nhất bạn — developer — chịu trách nhiệm là code ứng dụng.

Elastic Beanstalk hỗ trợ nhiều nền tảng lập trình phổ biến: Go, Java SE, Java với Tomcat, .NET trên Windows Server với IIS, Node.js, PHP, Python, Ruby, Packer Builder, cùng các chế độ container Docker (Single Container, Multi-Container, hoặc Preconfigured Docker). Nếu ngôn ngữ bạn dùng không có trong danh sách sẵn, bạn vẫn có thể đóng gói ứng dụng vào Docker container để chạy trên Beanstalk.

Elastic Beanstalk cung cấp ba mô hình kiến trúc khác nhau, tùy vào mục đích sử dụng:

Mô hình Phù hợp với
Single Instance Môi trường Development — đơn giản, rẻ, không cần độ sẵn sàng cao
Load Balancer + Auto Scaling Group Ứng dụng web ở Production/Pre-production — cần khả năng chịu tải và độ sẵn sàng cao
Auto Scaling Group (không có Load Balancer) Ứng dụng không phải web ở Production, ví dụ các worker xử lý job nền

Về giám sát, Elastic Beanstalk có một “health agent” chạy trên các instance, liên tục đẩy các chỉ số (metrics) về CloudWatch, đồng thời kiểm tra tình trạng ứng dụng và phát ra các sự kiện (health events) khi có bất thường (ví dụ ứng dụng trả lỗi 5xx liên tục). Nhờ đó, trên giao diện Beanstalk bạn có thể thấy ngay trạng thái “Ok / Warning / Severe” của môi trường mà không cần tự cấu hình CloudWatch Alarm.

Trước khi push code ứng dụng lên server để triển khai, code đó cần được lưu trữ ở một nơi có quản lý phiên bản (version control) — thông thường dùng công nghệ Git. Nền tảng phổ biến nhất trên thị trường là GitHub. Trước đây, sản phẩm cạnh tranh của AWS trong lĩnh vực này là AWS CodeCommit — một dịch vụ source-control lưu trữ Git repository, giúp nhiều người cùng cộng tác trên một codebase, với mọi thay đổi được tự động ghi lại phiên bản (versioned). CodeCommit được quảng bá là fully managed, có khả năng mở rộng, độ sẵn sàng cao, riêng tư/an toàn và tích hợp sẵn với các dịch vụ AWS khác.

Sau khi có code trong repository, bước tiếp theo là biên dịch (compile) mã nguồn, chạy các bộ test tự động, và tạo ra một “gói” (package/artifact) đã sẵn sàng để triển khai. AWS CodeBuild là dịch vụ build code chạy hoàn toàn trên cloud, đảm nhiệm chính xác công việc này. Kết quả (artifact) do CodeBuild tạo ra có thể được CodeDeploy lấy để triển khai lên server.

CodeBuild có các đặc điểm: fully managed và serverless (bạn không cần quản lý máy chủ build), có thể tự động scale liên tục và có độ sẵn sàng cao, được thiết kế an toàn (bảo mật), và tính phí theo mô hình pay-as-you-go — bạn chỉ trả tiền cho đúng thời gian build thực tế diễn ra, không phải trả tiền khi không có build nào chạy.

Luồng hoạt động điển hình: CodeCommit (hoặc bất kỳ Git repo nào) → CodeBuild lấy code về (retrieve code) → build code (compile, test) → tạo ra artifact sẵn sàng để deploy.

AWS CodeDeploy lo phần triển khai ứng dụng một cách tự động lên các server đích. Điểm đặc biệt của CodeDeploy là nó hoạt động theo mô hình hybrid — có thể triển khai lên cả EC2 instance trên AWS các server on-premises (đặt tại trung tâm dữ liệu riêng của doanh nghiệp). Điều kiện là các server/instance đích phải được cài đặt sẵn CodeDeploy Agent trước khi CodeDeploy có thể điều khiển chúng.

Hình dung đơn giản: bạn có một nhóm server đang chạy phiên bản ứng dụng v1; CodeDeploy sẽ tuần tự (hoặc theo chiến lược bạn chọn) đẩy phiên bản v2 lên từng server, theo dõi xem việc triển khai có thành công không, và có thể tự động rollback nếu phát hiện lỗi.

Nếu bạn đã có CodeCommit (lưu code), CodeBuild (build code), CodeDeploy (deploy code), thì làm sao để các bước này tự động nối tiếp nhau — mỗi khi có code mới được push lên, tự động build, tự động test, tự động deploy, không cần ai bấm tay từng bước? Đó chính là vai trò của AWS CodePipeline: điều phối (orchestrate) các bước khác nhau để đưa code tự động lên production.

Chuỗi bước điển hình mà CodePipeline điều phối là: Code → Build → Test → Provision → Deploy. Đây chính là nền tảng cho CI/CD (Continuous Integration & Continuous Delivery) — tích hợp liên tục (mỗi thay đổi code được tự động build và test ngay) và triển khai liên tục (mỗi thay đổi hợp lệ được tự động đưa ra production hoặc sẵn sàng để đưa ra production).

CodePipeline là dịch vụ fully managed, tương thích với CodeCommit, CodeBuild, CodeDeploy, Elastic Beanstalk, CloudFormation, GitHub và cả các dịch vụ/plugin của bên thứ ba. Nhờ tự động hóa toàn chuỗi, tổ chức có thể release phần mềm nhanh hơn và cập nhật thường xuyên hơn.

Một pipeline hoàn chỉnh có thể trông như sau, với CodePipeline đóng vai trò “người chỉ huy” đứng trên toàn bộ quy trình:

CodeCommit → CodeBuild → CodeDeploy → Elastic Beanstalk (tất cả được điều phối bởi CodePipeline)

Hầu như mọi ứng dụng hiện đại đều phụ thuộc vào các thư viện/package của bên thứ ba (dependency) để build được — ví dụ một project Node.js phụ thuộc vào hàng trăm package trên npm. Việc lưu trữ, phân phối và quản lý phiên bản các dependency này gọi là artifact management. Theo cách truyền thống, tổ chức phải tự dựng và vận hành một hệ thống artifact riêng — tốn công bảo trì.

AWS CodeArtifact là dịch vụ quản lý artifact an toàn, có khả năng mở rộng và hiệu quả về chi phí, giúp bạn không phải tự vận hành hạ tầng này. CodeArtifact tương thích với các công cụ quản lý package phổ biến: Maven, Gradle (Java), npm, yarn (JavaScript), twine, pip (Python), NuGet (.NET). Cả developer và CodeBuild đều có thể lấy dependency trực tiếp từ CodeArtifact trong quá trình build, thay vì gọi ra Internet công khai — vừa nhanh hơn, vừa kiểm soát được nguồn gốc package.

Khi bạn có vài chục, vài trăm, hay vài ngàn EC2 instance (và có thể cả server on-premises), việc cập nhật bản vá (patch), chạy một lệnh trên toàn bộ server, hay xem tình trạng cấu hình hiện tại của từng máy trở thành bài toán vận hành rất lớn nếu làm tay từng máy một. AWS Systems Manager (SSM) giúp quản lý EC2 và cả hệ thống on-premises ở quy mô lớn — đây cũng là một dịch vụ hybrid giống CodeDeploy, cho bạn cái nhìn về tình trạng hoạt động (operational insights) của toàn bộ hạ tầng.

Systems Manager thực chất là một bộ (suite) gồm hơn 10 sản phẩm/tính năng con, nhưng ba tính năng quan trọng nhất cần nhớ cho kỳ thi là:

  • Patching tự động — giúp tăng mức độ tuân thủ (compliance) về bản vá bảo mật trên toàn bộ hạ tầng.
  • Run Command — chạy một lệnh (command) trên toàn bộ hoặc một nhóm server cùng lúc, không cần SSH tay từng máy.
  • SSM Parameter Store — nơi lưu trữ tập trung các thông số cấu hình (xem mục tiếp theo).

SSM hoạt động trên nhiều hệ điều hành: Linux, Windows, macOS, và cả Raspberry Pi OS. Để SSM có thể “nói chuyện” và điều khiển được một máy, máy đó cần cài SSM Agent. Agent này được cài sẵn theo mặc định trên Amazon Linux AMI và một số bản Ubuntu AMI; với các hệ điều hành/AMI khác, bạn phải cài thủ công. Nhờ SSM Agent, Systems Manager mới có thể chạy lệnh, vá lỗi và cấu hình server từ xa.

SSM Session Manager cho phép bạn mở một shell an toàn (secure shell) vào EC2 hoặc server on-premises mà không cần SSH, không cần dựng bastion host, và không cần quản lý SSH key. Vì không cần SSH, bạn cũng không cần mở port 22 — điều này giúp giảm đáng kể bề mặt tấn công (attack surface), một lợi ích bảo mật rất lớn. Session Manager hỗ trợ Linux, macOS và Windows, và có thể gửi log của session (mọi lệnh gõ vào, kết quả trả về) sang S3 hoặc CloudWatch Logs để lưu vết phục vụ audit.

SSM Parameter Store là nơi lưu trữ an toàn cho các thông số cấu hình và bí mật (secrets) — ví dụ API Key, mật khẩu database, các giá trị cấu hình môi trường. Đây là dịch vụ serverless, có khả năng mở rộng, bền vững (durable), và có SDK dễ dùng để ứng dụng có thể đọc giá trị này ngay trong code. Bạn kiểm soát ai được đọc/ghi parameter nào thông qua IAM, hỗ trợ theo dõi phiên bản (version tracking) mỗi khi giá trị thay đổi, và có thể mã hóa giá trị (tùy chọn) bằng AWS KMS — rất phù hợp để lưu các giá trị nhạy cảm mà không muốn hard-code trong source code.

  • AWS CloudFormation: mô tả hạ tầng bằng template khai báo (JSON/YAML), chỉ dùng trong AWS, hỗ trợ hầu hết resource, dễ lặp lại giữa các Region/Account.
  • AWS CDK: viết hạ tầng bằng ngôn ngữ lập trình quen thuộc, tự “compile” ra CloudFormation template; phù hợp khi cần deploy chung hạ tầng và code (Lambda, container).
  • AWS Elastic Beanstalk: PaaS, developer chỉ cần lo code, Beanstalk lo hạ tầng (EC2, ASG, ELB, RDS); giới hạn ở một số ngôn ngữ/platform hoặc Docker.
  • AWS CodeCommit: lưu code trong Git repository riêng tư (đã bị AWS ngừng cấp cho khách hàng mới từ 07/2024, nhưng vẫn có thể xuất hiện trong đề thi).
  • AWS CodeBuild: build & test code trên cloud, tính phí theo thời gian build thực tế.
  • AWS CodeDeploy: triển khai/nâng cấp ứng dụng lên server (hybrid: EC2 và on-premises), cần cài CodeDeploy Agent.
  • AWS CodePipeline: điều phối toàn bộ chuỗi Code → Build → Test → Provision → Deploy, nền tảng của CI/CD trên AWS.
  • AWS CodeArtifact: lưu trữ và phân phối package/dependency phần mềm (Maven, npm, pip, NuGet…).
  • AWS Systems Manager: quản lý, vá lỗi, chạy lệnh trên EC2 và on-premises ở quy mô lớn; cần SSM Agent cài trên máy đích.
  • SSM Session Manager: truy cập shell an toàn, không cần SSH/bastion host/port 22 mở.
  • SSM Parameter Store: lưu trữ có kiểm soát và mã hóa cho config/secrets, tích hợp IAM và KMS.