Chuyển đến nội dung chính

Xây Dựng Stack AWS CDK Đầu Tiên: Hướng Dẫn Thân Thiện Cho Người Mới Bắt Đầu

Học cách xây dựng và triển khai stack AWS CDK đầu tiên bằng Python. Hướng dẫn thân thiện cho người mới này bao gồm thiết lập, constructs, triển khai, kiểm thử và CI/CD.
· 15 phút đọc

Khám phá cùng AI

Quản lý hạ tầng đám mây bằng các mẫu JSON hoặc YAML thuần có thể tốn công và dễ sai sót. AWS Cloud Development Kit (CDK) thay đổi điều đó bằng cách cho phép bạn định nghĩa tài nguyên đám mây bằng các ngôn ngữ lập trình hiện đại như Python, TypeScript, Java và C#.

Với CDK, hạ tầng trở thành mã nguồn có thể tái sử dụng, kiểm thử và quản lý phiên bản. Nó giúp bạn tư duy như một nhà phát triển ngay cả khi cung cấp các hệ thống đám mây phức tạp.

Trong hướng dẫn này, bạn sẽ học cách thiết lập một dự án AWS CDK bằng Python. Chúng ta sẽ đi qua quy trình viết stack đầu tiên, thêm một tài nguyên AWS thiết yếu và triển khai nó lên tài khoản AWS của bạn. Kết thúc, bạn sẽ hiểu rõ cách CDK hoạt động và cách dùng nó để quản lý hạ tầng theo phong cách thân thiện với nhà phát triển, bằng mã.

Để hiểu rõ hơn về các thực tiễn đằng sau những công cụ như AWS CDK, hãy khám phá các nguyên tắc nền tảng trong khóa học DevOps Concepts của chúng tôi.

Yêu cầu tiên quyết

Trước khi viết mã với AWS CDK, hãy đảm bảo môi trường của bạn đã được thiết lập đúng. Bạn sẽ cần:

Tài khoản AWS để thử nghiệm

Bạn cần truy cập vào một tài khoản AWS để triển khai ứng dụng mà chúng ta sẽ xây dựng. Nếu hệ thống của bạn đã được cấu hình thông tin xác thực cho người dùng cấp quản trị, bạn có thể bỏ qua phần này.

Nếu bạn chưa có tài khoản AWS, tạo tài khoản tại đây.

Để có lộ trình học có cấu trúc bao quát các kiến thức nền tảng về AWS, lộ trình AWS Cloud Practitioner là một điểm khởi đầu tuyệt vời.

Người dùng quản trị

Bạn sẽ cần một người dùng có quyền truy cập lập trình và đầy đủ quyền để theo dõi các bước.

  1. Đăng nhập vào tài khoản AWS của bạn.
  2. Mở Bảng điều khiển IAM.
  3. Tạo người dùng mới — bạn có thể đặt tên như “datacamp-cdk”
  4. Chọn Programmatic access.
  5. Nhấp Next: Permissions.
  6. Chọn Attach existing policies directly và đánh dấu AdministratorAccess.
  7. Nhấp lần lượt Next: Tags, Next: Review, rồi Create User.

Ở màn hình cuối, hãy ghi lại Access key ID và Secret access key của bạn. Bạn sẽ cần chúng ở bước tiếp theo.

Cấu hình thông tin xác thực AWS

Mở terminal và chạy:

aws configure

Bạn sẽ được nhắc nhập thông tin xác thực từ bảng điều khiển IAM:

AWS Access Key ID [None]: <your access key ID>
AWS Secret Access Key [None]: <your secret access key>
Default region name [None]: us-east-1
Default output format [None]: 

Chọn IDE để phát triển

AWS CDK cho phép nhà phát triển làm việc trong môi trường lập trình đầy đủ thay vì các mẫu YAML hoặc JSON. Môi trường giàu tính năng này cho phép bạn dùng IDE ưa thích đồng thời hưởng lợi từ tính năng gợi ý mã, linting theo thời gian thực và công cụ refactor để quản lý mã hạ tầng hiệu quả.

Để có trải nghiệm phát triển tốt nhất với CDK cho Python, tôi gợi ý dùng một IDE hỗ trợ các tính năng sau:

  • Tô màu cú pháp
  • Gợi ý mã
  • Điều hướng thông minh và gợi ý
  • Hỗ trợ môi trường ảo

Cài đặt Python và pip

Để dùng AWS CDK với Python, bạn cần cài Python phiên bản 3.8 trở lên trên hệ thống. Nếu chưa có, bạn có thể tải bản mới nhất từ trang web chính thức của Python.

Nếu bạn dùng Windows, hãy đảm bảo Python được thêm vào biến môi trường PATH của hệ thống. Để kiểm tra, mở terminal hoặc Command Prompt và chạy:

python --version

Nếu bạn thấy lỗi “command not found” hoặc tương tự, có thể Python chưa nằm trong PATH. Cách nhanh nhất là đánh dấu hộp “Add Python 3.x to PATH” khi cài đặt.

Bạn cũng sẽ cần pip, trình cài đặt gói của Python, để cài đặt các phụ thuộc AWS CDK sau này. Hầu hết các bản phân phối Python hiện đại đều có sẵn pip.

pip --version

Nếu chưa có, hãy làm theo hướng dẫn cài đặt pip chính thức.

Bắt Đầu Với AWS CDK

Trước khi viết mã, điều cần thiết là hiểu AWS CDK là gì, vì sao nó tồn tại và nó phù hợp thế nào trong bức tranh rộng hơn của hạ tầng như mã (IaC). Phần này sẽ giới thiệu các khái niệm cốt lõi đằng sau CDK và so sánh nó với những công cụ IaC phổ biến khác.

AWS CDK là gì và vì sao được sử dụng?

AWS Cloud Development Kit (CDK) là một framework mã nguồn mở cho phép người dùng tạo hạ tầng đám mây thông qua các ngôn ngữ lập trình quen thuộc, bao gồm Python, TypeScript, Java và C#. 

CDK cho phép người dùng tạo các mẫu CloudFormation một cách lập trình bằng mã thực tế thay vì phải viết thủ công các mẫu JSON hoặc YAML.

Điều này có nghĩa là bạn có thể:

  • Tái sử dụng logic bằng vòng lặp và hàm.
  • Tổ chức hạ tầng bằng mô-đun và lớp.
  • IDE của bạn cung cấp công cụ gợi ý mã, kiểm tra lỗi và khả năng refactor.

Cốt lõi của CDK xoay quanh ba khái niệm chính:

  • App – Điểm vào của dự án CDK. Nó có thể chứa một hoặc nhiều stack.
  • Stack – Đơn vị triển khai tương ứng với một CloudFormation stack. Mỗi stack định nghĩa một tập tài nguyên sẽ được tạo.
  • Construct – Khối xây dựng của CDK. Construct đại diện cho các thành phần đám mây như S3 bucket, hàm Lambda, VPC và các mẫu phức hợp kết hợp nhiều tài nguyên.

Sơ đồ minh họa cấu trúc AWS CDK: một App chứa một Stack (ví dụ: MyStack), bao gồm ba construct — S3 Bucket, Lambda Function và VPC — được kết nối theo thứ bậc từ trên xuống.

Thứ bậc trực quan của một ứng dụng AWS CDK

CDK so với Terraform và CloudFormation

Bảng sau mô tả sự khác biệt giữa các công cụ có sẵn trên AWS để quản lý hạ tầng.

Tính năng

AWS CDK

Terraform

AWS CloudFormation

Hỗ trợ ngôn ngữ

Python, TypeScript, Java, C#

HCL (khai báo)

YAML / JSON

Mức độ trừu tượng

Cao (OOP + thư viện)

Trung bình

Thấp

Tính mô-đun

Mạnh (construct, lớp)

Mạnh (module)

Yếu (nested stack)

Quản lý trạng thái

Do CloudFormation xử lý

Do Terraform xử lý (tfstate)

Do CloudFormation xử lý

Đa đám mây

Chỉ AWS

Có

Chỉ AWS

Ngôn ngữ hỗ trợ và yêu cầu

AWS CDK hỗ trợ nhiều ngôn ngữ lập trình, cho phép nhà phát triển chọn ngôn ngữ mình quen thuộc nhất:

  • TypeScript
  • Python
  • Java
  • C#/.NET
  • Go

Trong hướng dẫn này, chúng ta tập trung vào Python, nhưng các khái niệm cốt lõi áp dụng cho tất cả ngôn ngữ được hỗ trợ.

Cài đặt và thiết lập

Giờ môi trường đã sẵn sàng, đến lúc dùng Python để khởi tạo ứng dụng AWS CDK đầu tiên. Lệnh init của CDK thiết lập toàn bộ cấu trúc dự án, bao gồm tệp, thư mục và môi trường ảo, giúp bạn bắt đầu nhanh chóng.

Tạo thư mục dự án

Mở terminal và chạy lệnh sau để tạo thư mục mới và di chuyển vào đó:

mkdir cdk_datacamp && cd cdk_datacamp

Khởi tạo ứng dụng CDK

cdk init sample-app --language python

Lệnh này tạo một dự án khởi đầu được cấu hình sẵn với ví dụ cơ bản bao gồm:

  • Một stack mẫu (cdk_datacamp_stack)
  • Một hàng đợi SQS được đăng ký vào một chủ đề SNS
  • Tệp cdk.json cấu hình cách ứng dụng CDK của bạn chạy
  • Môi trường ảo (trong .venv) cho các phụ thuộc Python

Khi lệnh hoàn tất, bạn sẽ thấy kết quả tương tự như sau:

Kết quả terminal AWS CDK khi khởi tạo dự án Python, bao gồm các bước tạo và kích hoạt môi trường ảo thủ công, cài đặt requirements và chạy cdk synth.

Bộ khởi tạo dự án CDK Python 

Thiết lập môi trường ảo

Nếu quá trình cdk init không tự động tạo môi trường ảo, bạn có thể làm thủ công:

python3 -m venv .venv
source .venv/bin/activate

Khi đã kích hoạt, cài đặt các phụ thuộc cần thiết:

pip install -r requirements.txt

Hiểu Các Khái Niệm CDK

Trước khi đi sâu vào mã, hãy khám phá cách các thành phần lõi của AWS CDK — app, stack và construct — phối hợp với nhau trong thực tế. Giờ bạn đã quen với từng khái niệm, điều quan trọng là thấy cách chúng tương tác để hình thành hạ tầng có thể mở rộng và mô-đun. 

Chúng ta cũng sẽ phân tích các cấp độ construct khác nhau (L1, L2, L3) và xem xét các thư viện CDK giúp điều đó trở nên khả thi.

App, stack và construct

Giờ bạn đã biết App, Stack và Construct là gì từ các phần trước, hãy hiểu chúng phối hợp thế nào trong một ứng dụng CDK.

Hãy hình dung như xây một ngôi nhà:

  • App là toàn bộ dự án xây dựng.
  • Mỗi Stack như một tòa nhà hoặc cấu trúc riêng trong dự án.
  • Mỗi Construct là một thành phần như tường, cửa hay hệ thống ống nước nằm trong một stack.

Trong mã, mối quan hệ trông như sau:

# app.py

from aws_cdk import App
from my_project.my_stack import MyStack

# Initialize the CDK application
app = App()

# Instantiate the stack and add it to the app
MyStack(app, "MyFirstStack")

# Synthesize the CloudFormation template
app.synth()
# my_stack.py

from aws_cdk import Stack
from aws_cdk import aws_s3 as s3
from constructs import Construct

class MyStack(Stack):
    def __init__(self, scope: Construct, id: str, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

        # Define an Amazon S3 bucket with default settings
        s3.Bucket(self, "MyBucket")

Tại đây, App khởi tạo một Stack, trong đó bao gồm các Construct như một S3 bucket.

Hiểu các cấp độ construct: L1, L2 và L3

Trong AWS CDK, construct có ba cấp độ trừu tượng, cho bạn sự linh hoạt tùy mức độ kiểm soát hoặc đơn giản bạn cần.

Cấp 1 (L1) – Construct CloudFormation

Đây là các khối xây dựng thô được tạo trực tiếp từ đặc tả AWS CloudFormation. Mỗi tài nguyên AWS trong CloudFormation đều có construct L1 tương đương trong CDK; tên của chúng luôn bắt đầu bằng “Cfn”.

Construct L1 phơi bày mọi tùy chọn cấu hình có thể có nhưng không cung cấp trừu tượng hay mặc định. Chúng lý tưởng khi bạn cần kiểm soát hoàn toàn hoặc dùng các tính năng AWS mới chưa được bao bọc bởi construct cấp cao hơn.

  • Ví dụ: s3.CfnBucket

Cấp 2 (L2) – Construct gốc CDK của AWS

Construct L2 cung cấp trừu tượng cấp cao, thân thiện với nhà phát triển trên các construct L1. Đây là các thành phần có quan điểm sẵn với mặc định hợp lý và phương thức tích hợp giúp đơn giản hóa tác vụ thường ngày. Chúng được thiết kế cho sử dụng hàng ngày và giúp giảm lặp mã trong khi vẫn cho phép tùy biến tốt.

  • Ví dụ: s3.Bucket – Bạn có thể tạo bucket có versioning chỉ với một dòng mã.

Cấp 3 (L3) – Construct theo mẫu

Construct L3 là các trừu tượng gộp nhiều tài nguyên AWS thành các mẫu kiến trúc phổ biến. Chúng có thể do AWS cung cấp hoặc do cộng đồng hay chính bạn xây dựng như các thành phần tái sử dụng. Dùng construct L3 để đóng gói độ phức tạp và tái sử dụng mẫu hạ tầng giữa các dự án hoặc nhóm.

  • Ví dụ: aws_s3_deployment.BucketDeployment – Kết hợp S3 bucket và chiến lược triển khai để tự động tải tài sản.

Hầu hết nhà phát triển bắt đầu với construct L2 và chỉ dùng L1 khi cần. L3 hữu dụng khi dự án lớn dần và bạn muốn trừu tượng hóa các mẫu lặp lại thành thành phần tái sử dụng.

Thư viện và mô-đun CDK

Khi xây dựng với AWS CDK, bạn không tương tác trực tiếp với CloudFormation thô. Thay vào đó, bạn dùng các thư viện mô-đun của CDK, cung cấp construct cho các dịch vụ AWS như S3, Lambda, IAM, v.v. Tất cả mô-đun dịch vụ AWS được gói trong gói lõi gọi là aws-cdk-lib và được tổ chức theo từng dịch vụ.

Các thư viện thường dùng trong Python

Dưới đây là một số thư viện (hoặc mô-đun) được dùng thường xuyên từ aws-cdk-lib trong dự án Python:

  • aws_cdk.aws_s3 – Tạo S3 bucket
  • aws_cdk.aws_lambda – Định nghĩa hàm Lambda
  • aws_cdk.aws_iam – Quản lý vai trò và quyền
  • aws_cdk.aws_dynamodb – Làm việc với bảng DynamoDB
  • aws_cdk.aws_ec2 – Thành phần mạng như VPC và security group
  • aws_cdk.aws_sns / aws_cdk.aws_sns_subscriptions – Chủ đề SNS và subscriber

Các mô-đun này chỉ được import khi cần, giúp dự án nhẹ và mô-đun hóa.

Cách import và dùng một mô-đun CDK

Để dùng một dịch vụ AWS cụ thể, bạn import mô-đun của nó và gọi các lớp construct. Ví dụ, để tạo một S3 bucket:

from aws_cdk import aws_s3 as s3

# Inside your stack
bucket = s3.Bucket(self, "MyBucket")

Ví dụ này dùng construct L2 s3.Bucket, bao gồm các mặc định tích hợp như mã hóa và tùy chọn versioning.

Nếu bạn cần dùng dịch vụ khác, chỉ cần import mô-đun của nó theo cách tương tự:

from aws_cdk import aws_lambda as lambda_
from aws_cdk import aws_iam as iam

Lưu ý: Trong requirements.txt, bạn thường chỉ cần:

aws-cdk-lib==2.179.0
constructs>=10.0.0,<11.0.0

Hai gói này cung cấp cho bạn quyền truy cập vào tất cả construct AWS CDK và chức năng khung lõi.

Tạo CDK Stack Đầu Tiên Của Bạn

Sau khi tìm hiểu hoạt động nội bộ của AWS CDK, bạn có thể áp dụng kiến thức này. Phần sau hướng dẫn bạn xây dựng một stack CDK vận hành được bằng Python. Trước khi triển khai lên tài khoản AWS của bạn, bạn sẽ tạo cấu trúc dự án bằng mã và triển khai các tài nguyên AWS thực tế như S3 bucket và hàm Lambda.

Tạo khung dự án mới

Khi bạn chạy lệnh cdk init với cờ --language python, nó sẽ thiết lập một cấu trúc dự án đầy đủ trông tương tự như sau:

Cây thư mục của một dự án AWS CDK với các tệp chính như app.py, cdk.json, requirements.txt, và các thư mục cho mã nguồn cdk_datacamp cùng tests/unit/test_cdk_datacamp_stack.py.

Cấu trúc thư mục của một dự án AWS CDK bằng Python

Tệp app.py là nơi định nghĩa App, và tệp cdk_datacamp_stack.py là nơi bạn viết mã cho Stack và Construct.

Mẹo: Bạn có thể đổi tên tệp hoặc lớp stack để phù hợp mục đích ứng dụng, như storage_stack.py hoặc monitoring_stack.py.

Thêm tài nguyên AWS

Giờ hãy thêm một số tài nguyên AWS vào stack CDK của bạn. Bạn sẽ viết trong phương thức __init__() của lớp Stack trong tệp cdk_datacamp_stack.py.

S3 bucket

from aws_cdk import aws_s3 as s3

# Create an S3 bucket with versioning and managed encryption
bucket = s3.Bucket(
    self,
    "MyBucket",
    versioned=True,
    encryption=s3.BucketEncryption.S3_MANAGED
)

Hàm Lambda

from aws_cdk import aws_lambda as lambda_

# Define a Lambda function using Python 3.9 runtime
lambda_function = lambda_.Function(
    self,
    "MyFunction",
    runtime=lambda_.Runtime.PYTHON_3_9,
    handler="index.handler",
    code=lambda_.Code.from_asset("lambda")  # Load code from local folder named 'lambda'
)

Triển khai stack

Sau khi bạn đã thêm tài nguyên, đến lúc triển khai chúng lên AWS.

Trong terminal, kích hoạt môi trường ảo và chạy:

cdk deploy

Lệnh này sẽ:

  1. Tổng hợp stack của bạn thành một mẫu CloudFormation
  2. Tải mẫu đó lên AWS
  3. Cấp phát tài nguyên trong tài khoản của bạn

Bạn sẽ được nhắc phê duyệt thay đổi nếu đây là lần đầu triển khai stack.

Sau khi triển khai, bạn có thể:

  1. Mở AWS Console
  2. Đi tới dịch vụ tương ứng (ví dụ: S3, Lambda)
  3. Xem tài nguyên mà CDK vừa tạo

Làm Việc Với CDK Construct

Ứng dụng AWS CDK dựa vào construct như các yếu tố cấu trúc thiết yếu. Khi bạn thành thạo construct, mã hạ tầng của bạn sẽ trở nên mô-đun, dễ bảo trì và dễ đọc hơn, dù bạn dùng construct dịch vụ có sẵn hay tự tạo các mẫu tái sử dụng của riêng mình.

Phần này dạy bạn cách dùng construct L2 (cấp cao) và cách phát triển construct tùy chỉnh để giảm các mẫu lặp lại.

Sử dụng construct L2

Construct L2 là các trừu tượng gốc CDK dễ dùng hơn so với CloudFormation thô (L1). Chúng có mặc định hợp lý và an toàn kiểu, thường cần ít dòng mã hơn để thiết lập một tài nguyên AWS.

Vì sao dùng construct L2?

  • Ít lặp mã — ít trường bắt buộc hơn so với L1
  • Mã Python dễ đọc và tự nhiên hơn
  • Bao gồm các phương thức tiện ích như .add_to_role_policy() hoặc .add_event_notification()
  • Tự động quản lý phụ thuộc giữa các tài nguyên

Ví dụ: Tạo S3 bucket bằng L2

from aws_cdk import aws_s3 as s3
# Create a versioned and encrypted S3 bucket
bucket = s3.Bucket(
    self,
    "MyBucket",
    versioned=True,
    encryption=s3.BucketEncryption.S3_MANAGED
)

Construct L1 tương đương, s3.CfnBucket, sẽ cần thiết lập thủ công mọi thuộc tính và định nghĩa cấu hình dạng dict thô — kém trực quan hơn nhiều.

Các construct L2 phổ biến khác bao gồm:

  • lambda_.Function() cho AWS Lambda
  • dynamodb.Table() cho DynamoDB
  • sqs.Queue() cho SQS
  • sns.Topic() cho SNS

Tạo construct tùy chỉnh

Hạ tầng của bạn sẽ mở rộng với các mẫu lặp lại, như tạo hàm Lambda với quyền cụ thể và S3 bucket. Construct tùy chỉnh là giải pháp lý tưởng cho tình huống này.

Construct tùy chỉnh cho phép bạn kết hợp các tài nguyên liên quan thành một đơn vị logic duy nhất, có thể tái sử dụng trên các stack hoặc dự án.

Khi nào tạo construct tùy chỉnh:

  • Khi bạn có từ 3+ tài nguyên luôn được cấp phát cùng nhau
  • Khi bạn muốn đóng gói logic tái sử dụng
  • Khi bạn muốn giảm trùng lặp mã giữa các stack

Ví dụ: Mẫu tái sử dụng S3 + Lambda

from constructs import Construct
from aws_cdk import aws_s3 as s3, aws_lambda as lambda_
class StorageWithLambda(Construct):
    def __init__(self, scope: Construct, id: str) -> None:
        super().__init__(scope, id)
        # S3 bucket
        self.bucket = s3.Bucket(self, "MyBucket")

        # Lambda function
        self.function = lambda_.Function(
            self,
            "MyFunction",
            runtime=lambda_.Runtime.PYTHON_3_9,
            handler="index.handler",
            code=lambda_.Code.from_asset("lambda")
        )
        # Grant Lambda access to the S3 bucket
        self.bucket.grant_read_write(self.function)

Giờ bạn có thể dùng construct này trong bất kỳ stack nào như sau:

from my_project.storage_with_lambda import StorageWithLambda
storage = StorageWithLambda(self, "ReusableComponent")

Trước khi chạy đoạn trên, hãy tạo một thư mục tên lambda ở thư mục gốc dự án và tạo tệp index.py với nội dung sau:

def handler(event, context):
    return {
        "statusCode": 200,
        "body": "Hello from Lambda!"
    }

Mẹo về khả năng tái sử dụng

  • Tiền tố tệp với construct_ hoặc đặt trong thư mục constructs/
  • Phơi bày output như self.bucket hoặc self.function để linh hoạt
  • Giữ mỗi construct tập trung vào một trách nhiệm

Kiểm Thử và Tổng Hợp Ứng Dụng CDK

Sau khi viết mã hạ tầng, điều quan trọng là kiểm tra những gì CDK sẽ triển khai và lý tưởng nhất là kiểm thử để đảm bảo stack của bạn hoạt động như mong đợi. AWS CDK cung cấp công cụ để tổng hợp mẫu CloudFormation và viết kiểm thử tự động nhằm phát hiện cấu hình sai trước khi triển khai.

Tổng hợp mẫu

Lệnh cdk synth tạo mẫu CloudFormation từ mã CDK của bạn.

cdk synth

Khi chạy, CDK sẽ:

  • Tải ứng dụng của bạn (qua app.py)
  • Giải quyết tất cả construct và stack
  • Xuất mẫu CloudFormation YAML/JSON thô

mẫu AWS CloudFormation đã được tổng hợp với các tài nguyên gồm SQS queue, chính sách hàng đợi cho phép SNS gửi tin nhắn và tài nguyên đăng ký SNS tham chiếu đến hàng đợi.

Mẫu CloudFormation đã được tổng hợp 

Mặc định, kết quả in ra terminal, nhưng bạn cũng có thể xuất ra tệp nếu cần:

cdk synth > template.yaml

Điều này hữu ích khi:

  • Bạn muốn kiểm tra mẫu thực tế trước khi triển khai
  • Bạn đang gỡ lỗi cấu trúc của stack
  • Bạn chia sẻ mẫu với các nhóm không dùng CDK

Kiểm thử hạ tầng

Mặc dù kiểm thử hạ tầng như mã nghe có vẻ lạ, nhưng rất hữu ích, đặc biệt khi stack lớn hoặc bao gồm logic điều kiện, vòng lặp hoặc construct tái sử dụng.

AWS CDK cung cấp mô-đun assertions để kiểm thử các stack đã tổng hợp.

Viết một kiểm thử đơn giản với pytest

Dưới đây là ví dụ kiểm thử kiểm tra xem một tài nguyên cụ thể (như S3 bucket) có được đưa vào stack hay không:

# test/test_cdk_datacamp_stack.py
import aws_cdk as cdk
from aws_cdk.assertions import Template
from cdk_datacamp.cdk_datacamp_stack import CdkDatacampStack
def test_s3_bucket_created():
    app = cdk.App()
    stack = CdkDatacampStack(app, "TestStack")
    template = Template.from_stack(stack)
    # Assert that an S3 bucket exists
    template.resource_count_is("AWS::S3::Bucket", 1)

Để chạy kiểm thử, đảm bảo pytest đã được cài:

pip install -U pytest

Sau đó chạy:

pytest

Nếu mọi thứ vượt qua, bạn sẽ thấy dấu kiểm màu xanh. Nếu không, kết quả kiểm thử sẽ cho biết điều gì còn thiếu.

kết quả pytest trên môi trường Linux dùng Python 3.11.11 và pytest 8.3.5, hiển thị cả ba ca kiểm thử đều vượt qua với chỉ báo màu xanh và thời gian thực thi 2,89 giây.      

Kết quả Pytest cho thấy tất cả ca kiểm thử cho AWS CDK stack chạy thành công

Bạn cũng có thể đưa xác thực vào trong stack CDK của mình. Kiểm thử xác thực là các kiểm tra lúc chạy bên trong mã construct hoặc stack, xác thực đầu vào trước khi triển khai. Chúng giúp phát hiện cấu hình sai hoặc áp đặt ràng buộc sớm trong vòng đời phát triển.

Giả sử chúng ta muốn truyền bucket_name dưới dạng biến ngữ cảnh, nhưng muốn xác thực rằng:

  • Tên bucket không rỗng
  • Tuân thủ quy tắc đặt tên S3 (ví dụ: chỉ chữ thường)

Tạo tệp tên test/test_storage_with_lambda.py và thêm nội dung sau:

import pytest
from aws_cdk import App, Stack
from cdk_datacamp.storage_with_lambda import StorageWithLambda

def test_missing_bucket_name():
    app = App()
    stack = Stack(app, "TestStack")

    with pytest.raises(ValueError, match="bucket_name is required"):
        StorageWithLambda(stack, "FailingConstruct", bucket_name=None)

def test_bucket_name_uppercase():
    app = App()
    stack = Stack(app, "TestStack")

    with pytest.raises(ValueError, match="must be lowercase"):
        StorageWithLambda(stack, "FailingConstruct", bucket_name="InvalidName")

 Để kiểm thử phần xác thực, chạy lệnh dưới đây:

test/test_storage_with_lambda.py

kết quả pytest trên môi trường Linux dùng Python 3.11.11 và pytest 8.3.5, hiển thị cả ba ca kiểm thử đều vượt qua với chỉ báo màu xanh.        

Kết quả Pytest cho thấy tất cả ca kiểm thử cho AWS CDK stack chạy thành công

Khi nào nên dùng kiểm thử:

  • Bạn đang tạo construct hoặc mẫu tái sử dụng.
  • Việc triển khai kiểm thử nhằm thiết lập các yêu cầu kỹ thuật chuẩn trong nhóm.
  • Bạn muốn bắt hồi quy hoặc thay đổi ngoài ý muốn trong CI/CD.

Muốn củng cố kiến thức CDK trong bối cảnh phỏng vấn? Những câu hỏi phỏng vấn AWS DevOps hàng đầu này có thể giúp bạn chuẩn bị.

Thực Hành Tốt và Mẹo Khi Làm Việc Với AWS CDK

Sau khi thành thạo việc tạo và triển khai CDK stack, bạn nên tuân theo các thực hành tốt để giữ cho mã hạ tầng sạch, an toàn và có khả năng mở rộng. Phần này sẽ thảo luận cách cấu trúc dự án lớn, xử lý bảo mật đúng cách và tích hợp CDK vào pipeline CI/CD.

Tổ chức các dự án lớn

Khi ứng dụng CDK của bạn phát triển, việc tổ chức mã thành các đơn vị dễ quản lý trở nên thiết yếu.

Dùng nhiều stack

Chia nhỏ hạ tầng theo mối quan tâm. Ví dụ:

  • NetworkingStack: VPC, subnet, security group
  • ComputeStack: EC2, Lambda
  • StorageStack: S3, DynamoDB

Điều này cho phép bạn triển khai, kiểm thử hoặc hủy từng phần hạ tầng một cách độc lập. Sau đây là cách đưa vào app.py:

network_stack = NetworkingStack(app, "NetworkingStack")
compute_stack = ComputeStack(app, "ComputeStack")

Bạn cũng có thể truyền tài nguyên giữa các stack bằng output hoặc tham chiếu.

Tạo construct lồng nhau có thể tái sử dụng

Đóng gói các tài nguyên liên quan (như một Lambda và quyền của nó) thành một construct tùy chỉnh, như bạn đã làm với StorageWithLambda. Điều này cải thiện tính dễ đọc và khả năng tái sử dụng giữa các stack hoặc ứng dụng.

Dùng cấu hình theo môi trường

Hỗ trợ nhiều môi trường (dev, staging, prod) bằng cách sử dụng:

  • cdk.json với các giá trị ngữ cảnh
  • Ghi đè qua CLI: cdk deploy -c env=prod
  • Logic điều kiện trong stack của bạn
env = app.node.try_get_context("env")
if env == "prod":
    bucket_name = "mycompany-prod-logs"

Bảo mật và quyền

Bất kỳ dự án hạ tầng nào cũng phải ưu tiên bảo mật trong các quy trình triển khai tự động của AWS CDK. Phần sau minh họa quản lý tài nguyên IAM an toàn theo nguyên tắc đặc quyền tối thiểu.

Định nghĩa vai trò IAM thay vì dùng mặc định

Các construct CDK, bao gồm Lambda hoặc tác vụ ECS, sẽ tự động tạo IAM role. Dù tiện lợi, điều này có thể hạn chế quyền kiểm soát của bạn đối với quyền hạn và đặt tên.

Thay vào đó, hãy định nghĩa role một cách tường minh:

from aws_cdk import aws_iam as iam

execution_role = iam.Role(
    self,
    "LambdaExecutionRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
    description="Custom role for Lambda with least privilege",
    managed_policies=[
        iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AWSLambdaBasicExecutionRole")
    ]
)

Role này mặc định chỉ cho phép ghi log và không có gì khác.

Áp dụng nguyên tắc đặc quyền tối thiểu

Tránh dùng "*" trong actions hoặc resources trừ khi thực sự cần thiết.

Ví dụ:

lambda_fn.add_to_role_policy(
    iam.PolicyStatement(
        actions=["*"],
        resources=["*"]
    )
)

Bạn cũng có thể dùng các quyền cấp tài nguyên khi có sẵn:

bucket.grant_read(lambda_fn)

Điều này tự động tạo chính sách cần thiết với phạm vi truy cập giới hạn cho S3 bucket.

Dùng managed policy khi có thể

AWS-managed policy giúp đơn giản hóa bảo trì và giảm khả năng xảy ra lỗi.

iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSQSReadOnlyAccess")

Bạn có thể đính kèm chúng vào role tùy chỉnh cho các dịch vụ như ECS, Batch hoặc Step Functions.

Tích hợp CI/CD

AWS CDK phát huy sức mạnh lớn nhờ khả năng tích hợp với các pipeline CI/CD hiện đại. CDK hỗ trợ phân phối hạ tầng tự động qua triển khai mã có kiểm soát phiên bản, tương thích với GitHub, GitLab và các dịch vụ gốc AWS như CodePipeline. Hệ thống giảm lỗi con người, rút ngắn vòng phản hồi và cho phép triển khai qua nhiều môi trường.

GitHub Actions: Tự động hóa triển khai CDK

Bạn có thể dùng GitHub Actions để synthesize, diff, kiểm thử và triển khai các CDK stack ở mỗi lần push hoặc pull request.

Xem tệp .github/workflows/deploy.yml này:

name: Deploy CDK App

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - uses: actions/setup-python@v4
        with:
          python-version: 3.11

      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          npm install -g aws-cdk

      - name: Run unit tests
        run: pytest

      - name: CDK Synth
        run: cdk synth -c environment=prod

      - name: Deploy to AWS
        run: cdk deploy --require-approval never
        env:
          AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
          AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}

Dùng cdk diff trong PR để xem trước thay đổi hạ tầng trước khi merge.

CDK pipelines: CI/CD gốc CDK với CodePipeline

Đối với triển khai được quản lý hoàn toàn trong AWS, CDK cung cấp mô-đun aws_cdk.pipelines, cho phép bạn định nghĩa toàn bộ pipeline CI/CD dưới dạng mã, giống như hạ tầng.

Dưới đây là ví dụ đơn giản hóa:

from aws_cdk import pipelines, SecretValue, Stack
from constructs import Construct
from my_app_stage import MyAppStage  # replace with your actual stage import

class PipelineStack(Stack):
    def __init__(
        self,
        scope: Construct,
        construct_id: str,
        **kwargs
    ) -> None:
        super().__init__(scope, construct_id, **kwargs)

        # Define the source of the pipeline from a GitHub repository
        source = pipelines.CodePipelineSource.git_hub(
            repo_string="your-org/your-repo",  # GitHub org/repo
            branch="main",
            authentication=SecretValue.secrets_manager("GITHUB_TOKEN")
        )

        # Define the CodePipeline and its synthesis step
        pipeline = pipelines.CodePipeline(
            self,
            "MyAppPipeline",
            synth=pipelines.ShellStep(
                "Synth",
                input=source,
                commands=[
                    "pip install -r requirements.txt",
                    "npm install -g aws-cdk",
                    "cdk synth"
                ]
            )
        )

        # Add an application stage (e.g., production deployment)
        pipeline.add_stage(
            MyAppStage(self, "ProdStage")
        )

Trong đoạn mã trên:

  • SecretValue.secrets_manager("GITHUB_TOKEN") lấy token GitHub của bạn từ Secrets Manager một cách an toàn.
  • MyAppStage nên là một lớp mở rộng Stage và bao bọc các CDK stack thực tế của bạn.

Nếu bạn đang triển khai hệ thống học máy, việc tích hợp CDK với thực hành triển khai liên tục được đề cập trong khóa học CI/CD for Machine Learning của chúng tôi.

Kết luận

Hướng dẫn này đã chỉ cho bạn cách xây dựng và triển khai hạ tầng đám mây bằng Python thông qua các thao tác với AWS Cloud Development Kit (CDK). Bạn đã học cách:

  • Tạo CDK stack đầu tiên.
  • Định nghĩa và xác thực các tài nguyên như S3 bucket và hàm Lambda.
  • Tổ chức dự án thông qua construct tùy chỉnh và mẫu đa stack.
  • Áp dụng thực hành bảo mật tốt theo nguyên tắc đặc quyền tối thiểu.
  • Tự động hóa triển khai bằng cách kết hợp GitHub Actions với CDK Pipelines.
  • Viết kiểm thử để xác thực logic hạ tầng.

Giờ bạn đã triển khai ứng dụng CDK đầu tiên, dưới đây là vài cách để nâng cao hơn:

  • Dùng môi trường tham số hóa cho dev/staging/prod
  • Thêm CloudWatch alarms, API Gateway hoặc Step Functions
  • Khám phá các construct CDK như aws_s3_deployment, aws_ecs_patterns và cdk.pipelines
  • Chuyển các construct của bạn thành thư viện Python nội bộ để tái sử dụng

Để tiếp tục học và xây dựng, hãy xem khóa học Introduction to AWS Boto in Python!

Câu hỏi thường gặp

AWS CDK là gì và khác gì so với CloudFormation hoặc Terraform?

AWS CDK cho phép bạn định nghĩa hạ tầng đám mây bằng các ngôn ngữ lập trình như Python, trong khi CloudFormation và Terraform dựa vào JSON/YAML hoặc HCL. CDK cung cấp mức trừu tượng cao hơn và khả năng tái sử dụng thông qua construct.

Tôi có cần biết CloudFormation để dùng AWS CDK không?

Không, CDK trừu tượng hóa phần lớn độ phức tạp của CloudFormation. Tuy nhiên, việc hiểu CloudFormation sẽ hữu ích khi dùng construct cấp thấp hơn hoặc khi xử lý sự cố triển khai.

Tôi có thể triển khai nhiều môi trường (ví dụ: dev, prod) với AWS CDK không?

Có! CDK hỗ trợ cấu hình theo môi trường bằng các giá trị ngữ cảnh và cờ CLI như cdk deploy -c env=prod.

Làm thế nào để tôi kiểm thử mã hạ tầng CDK?

Bạn có thể dùng pytest cùng với assertions và mô-đun template của CDK để viết kiểm thử đơn vị xác minh tài nguyên và cấu hình của stack trước khi triển khai.

Điều gì xảy ra phía sau khi tôi chạy cdk deploy?

cdk deploy sẽ tổng hợp mã Python của bạn thành mẫu CloudFormation, tải nó lên AWS và cấp phát các tài nguyên đã định nghĩa trong tài khoản của bạn.

Rahul Sharma

Tác giả

Rahul Sharma

Rahul Sharma là AWS Ambassador, Kiến trúc sư DevOps và blogger kỹ thuật, chuyên về điện toán đám mây, thực hành DevOps và công nghệ mã nguồn mở. Với chuyên môn về AWS, Kubernetes và Terraform, anh giúp đơn giản hóa các khái niệm phức tạp cho người học và chuyên gia thông qua những bài viết và hướng dẫn hấp dẫn. Rahul đam mê giải quyết các thách thức DevOps và chia sẻ hiểu biết nhằm trao quyền cho cộng đồng công nghệ.

Chủ đề

Liên quan