AWS CDK 101 - Hello world

*Bài viết có sử dụng/ tổng hợp 1 số tài liệu trên internet

CDK là gì?

AWS Cloud Development Kit (AWS CDK) là một khung phát triển (framework) phần mềm mã nguồn mở để xác định tài nguyên ứng dụng đám mây bằng các ngôn ngữ lập trình quen thuộc. Đây là công cụ tổng hợp ứng dụng AWS CDK thành các CloudFormation template và triển khai hạ tầng trên AWS Cloud.

AWS CDK là một open source project và version Generally Available (GA) của AWS CDKsv2 đã được Werner Vogels - CTO của Amazon công bố vào tháng 12 năm 2021 trong sự kiện re:invent. V2 của CDK hỗ trợ các ngôn ngữ sau:

Ngôn ngữStability
TypeScriptStable
JavaScriptStable
PythonStable
JavaStable
C#/.NETStable
GoExperimental

Tổng quan

AWS CDK gồm 3 thành phần chính (basic building blocks):

  1. App là thành phần chính của cấu trúc, hợp nhất tất cả các stacks trong ứng dụng và sau đó triển khai trên AWS
  2. Stack gần tương tự với Stack trong CloudFormation, là một đơn vị (template) chứa các tài nguyên AWS ở dạng cấu trúc (constructs) và có thể sử dụng để triển khai.
  3. Construct là thành phần cơ bản chứa các tài nguyên AWS (một hoặc nhiều). Bạn có thể tuỳ ý tạo ra và kết hợp các tài nguyên để tạo ra cấu trúc (construct) riêng của mình

CDK Construct

  • Mỗi CDK Application gồm nhiều Stack
  • Mỗi Stack gồm nhiều construct
  • Construct có thể chứa nhiều tài nguyên khác nhau

Có 3 cách để xây dựng construct

L1  Construct

Nó chính là các tài nguyên giống với CloudFormation, các thuộc tính được ánh xạ với các thuộc tính trong CloudFormation. Nếu chúng ta chỉ sử dụng L1 Construct, thực sự thì không có lợi ích nào so với việc sử dụng CloudFormation.

L2 Construct

Là tài nguyên AWS được nhóm AWS CDK phát triển, đóng gói cấu trúc L1 bằng cách cài đặt các thuộc tính một cách tốt nhất về mặt bảo mật, tối ưu các giá trị mặc định cho tài nguyên. Có thể coi đây như là các boilerplate cho các tài nguyên và bạn không cần hiểu quá rõ để tạo chúng trên AWS.

L3 Construct

Hay còn được gọi là các mẫu (patterns) là một nhóm các cấu trúc L2 được kết hợp để cung cấp một giải pháp đầy đủ.

Ví dụ: Ta có thể gom nhiều tài nguyên lại với nhau để tạo thành 3 tiers web application, EC2 instances cho backend + frontend được liên kết với RDS và cuối cùng là Application Loadbalancer để cân bằng tải.

Bạn có thể khởi tạo nhóm tài nguyên này bằng cách một vài dòng code và nó giúp bạn có thể tái sử dụng ở các dự án/ stack khác

So sánh

Các lý thuyết bên trên nghe có vẻ mơ hồ. Nhưng hãy nhìn vào ví dụ sau để thấy cùng 1 đoạn code, L1, L2, L3 khác nhau như thế nào nhé

Code:

s3.CfnBucket(self, 's3_bucket_l1')

L1

s3bucketl1:
  Type: AWS::S3::Bucket

L2:

s3bucketl249651147:
  Type: AWS::S3::Bucket
  UpdateReplacePolicy: Retain
  DeletionPolicy: Retain

Hiểu đơn giản, ở các layer càng cao, thì bạn càng code ít. CDK sẽ tự tạo các thuộc tính / role cho bạn. Mình thì thích tự define hơn

Tại thời điểm viết bài, mình chưa thử L3 nên chưa so sánh ở đây

So sánh CDK vs Terraform vs CloudFormation

Ref: https://acloudguru.com/blog/engineering/cloudformation-terraform-or-cdk-guide-to-iac-on-aws

First CDK APP

Thử tạo 1 app để xem CDK hoạt động thế nào nhé

Mình sẽ thử với python. App name: pikachu ^^

init

mkdir pikachu && cd pikachu

cdk init pikachu --language python

result:

Applying project template pikachu for python
Initializing a new git repository...
Executing Creating virtualenv...

# Welcome to your CDK Python project!

You should explore the contents of this project. It demonstrates a CDK app with an instance of a stack (`CdkWorkshopStack`)
which contains an Amazon SQS queue that is subscribed to an Amazon SNS topic.

The `cdk.json` file tells the CDK Toolkit how to execute your app.

This project is set up like a standard Python project.  The initialization process also creates
a virtualenv within this project, stored under the .venv directory.  To create the virtualenv
it assumes that there is a `python3` executable in your path with access to the `venv` package.
If for any reason the automatic creation of the virtualenv fails, you can create the virtualenv
manually once the init process completes.

To manually create a virtualenv on MacOS and Linux:

```
python3 -m venv .venv
```

After the init process completes and the virtualenv is created, you can use the following
step to activate your virtualenv.

```
source .venv/bin/activate
```

If you are a Windows platform, you would activate the virtualenv like this:

```
% .venv\Scripts\activate.bat
```

Once the virtualenv is activated, you can install the required dependencies.

```
pip install -r requirements.txt
```

At this point you can now synthesize the CloudFormation template for this code.

```
cdk synth
```

You can now begin exploring the source code, contained in the cdk_workshop directory.
There is also a very trivial test included that can be run like this:

```
pytest
```

To add additional dependencies, for example other CDK libraries, just add to
your requirements.txt file and rerun the `pip install -r requirements.txt`
command.

## Useful commands

 * `cdk ls`          list all stacks in the app
 * `cdk synth`       emits the synthesized CloudFormation template
 * `cdk deploy`      deploy this stack to your default AWS account/region
 * `cdk diff`        compare deployed stack with current state
 * `cdk docs`        open CDK documentation

Enjoy!

Để có thể sử dụng CDK thì hãy đảm bảo bạn đã config aws-cli nhé.

virtualenv

source .venv/bin/activate
pip install -r requirements.txt

diagram

lambda

Create file resource/lambda/hello.py

import json

def handler(event, context):
    print('request: {}'.format(json.dumps(event)))
    return {
        'statusCode': 200,
        'headers': {
            'Content-Type': 'text/plain'
        },
        'body': 'Hello, ahjhj'
    }

Edit pikachu/pikachu_stack.py

from constructs import Construct
from aws_cdk import (
    Stack,
    aws_lambda as _lambda,
    aws_apigateway as apigw,
)


class PikachuStack(Stack):

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

        # Define lambda resource
        hello_lambda = _lambda.Function(
            self,
            'HelloHandle',
            runtime=_lambda.Runtime.PYTHON_3_9,
            code=_lambda.Code.from_asset('resource/lambda'),
            handler='hello.handler',
            function_name='Dzaiiiii',
        )

        apigw.LambdaRestApi(
            self, 'Endpoint',
            handler=hello_lambda,
            rest_api_name='My APIGW',
        )
cdk diff

Chúng ta sẽ có kết quả như sau

Deploy

cdk deploy

CDK sẽ tạo các role cần thiết

Ta có thể theo dõi quá trình tạo resource

Kết quả deploy sẽ cho ta 1 endpoint

Check kết quả trên aws console

Vào thử URL của API GW:

Work like a charm. Hjhj