本文介紹如何使用 AWS CDK 和 Python 建立一個基礎 Web 應用架構,包含自動擴充套件群組、應用程式負載平衡器和 RDS 資料函式庫例項。透過 CDK 的 Infrastructure as Code 特性,我們可以更有效率地管理和佈署雲端資源。文章將逐步引導讀者定義 WebStack 類別,並在其中組態 EC2 自動擴充套件群組、應用程式負載平衡器,以及設定使用者資料以安裝 Web 伺服器。此外,文章也說明瞭如何建立 RDS 資料函式庫例項,並設定安全群組以確保資料函式庫的安全性。最後,文章也涵蓋了使用 CDK 生成 CloudFormation 範本,方便開發者管理和佈署雲端基礎設施。

使用 AWS CDK 和 Python 編寫第一個範本

簡介

AWS CDK(Cloud Development Kit)是一種開源框架,允許開發者使用程式語言定義雲端基礎架構。在本文中,我們將使用 Python 和 AWS CDK 建立一個簡單的 Web 應用程式,包括負載平衡器、自動擴充套件群組和 RDS 資料函式庫例項。

步驟1:定義 WebStack 類別

首先,我們需要定義一個名為 WebStack 的類別,該類別將包含我們的 Web 應用程式的資源。

# app/web_stack.py
from aws_cdk import Stack
from constructs import Construct
import aws_cdk.aws_ec2 as ec2
import aws_cdk.aws_autoscaling as autoscaling
import aws_cdk.aws_elasticloadbalancingv2 as elbv2

class WebStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, vpc: ec2.Vpc, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        self.vpc = vpc
        # 建立自動擴充套件群組
        asg = autoscaling.AutoScalingGroup(
            self, 'WebAsg',
            instance_type=ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
            machine_image=ec2.AmazonLinuxImage(),
            vpc=vpc,
            vpc_subnets=ec2.SubnetSelection(subnet_group_name='Private'),
            min_capacity=1, max_capacity=1
        )

內容解密:

在上述程式碼中,我們定義了一個 WebStack 類別,並在其中建立了一個自動擴充套件群組(AutoScalingGroup)。我們指定了例項型別、機器映像、VPC 和子網路等屬性。min_capacitymax_capacity 屬性設定了自動擴充套件群組的最小和最大例項數量。

步驟2:新增應用程式負載平衡器

接下來,我們將新增一個應用程式負載平衡器(Application Load Balancer)到我們的 WebStack 中。

# app/web_stack.py
class WebStack(Stack):
    # ...
    alb = elbv2.ApplicationLoadBalancer(self, "WebLb", vpc=vpc, internet_facing=True,
                                       vpc_subnets=ec2.SubnetSelection(subnet_group_name='Public'))
    listener = alb.add_listener("WebListener", port=80)
    listener.add_targets("Target", port=80, targets=[asg])

內容解密:

在上述程式碼中,我們建立了一個應用程式負載平衡器,並將其組態為面對網際網路。我們還新增了一個監聽器(Listener),並將其連線到自動擴充套件群組。

步驟3:佈署 WebStack

現在,我們可以佈署我們的 WebStack。

$ cdk deploy WebStack

步驟4:新增使用者資料

為了在我們的例項上安裝軟體,我們需要新增使用者資料(User Data)。

# app/web_stack.py
userdata = '''#!/bin/sh
yum install httpd -y
systemctl enable httpd
systemctl start httpd
echo "<html><head><title> Example Web Server</title></head>" > /var/www/html/index.html
echo "<body>" >> /var/www/html/index.html
echo "<div><center><h2>Welcome AWS $(hostname -f)</h2>" >> /var/www/html/index.html
echo "<hr/>" >> /var/www/html/index.html
curl http://169.254.169.254/latest/meta-data/instance-id >> /var/www/html/index.html
echo "</center></div></body></html>" >> /var/www/html/index.html'''

websrv = ec2.UserData.for_linux()
websrv.add_commands(userdata)
asg = autoscaling.AutoScalingGroup(
    self, 'WebAsg',
    # ...
    user_data=websrv
)

內容解密:

在上述程式碼中,我們定義了一個使用者資料指令碼,該指令碼安裝了 httpd 服務並建立了一個簡單的網頁。

步驟5:新增安全群組

為了確保我們的 RDS 資料函式庫例項只能從 Web 伺服器存取,我們需要新增一個安全群組。

# app/web_stack.py
self.webserver_sg = ec2.SecurityGroup(self, "WebServerSg", vpc=vpc)
asg.add_security_group(self.webserver_sg)

內容解密:

在上述程式碼中,我們建立了一個安全群組,並將其新增到自動擴充套件群組中。

渲染儲存層

我們的儲存層將是一個 RDS 資料函式庫例項,建立於核心堆積疊的 VPC 中。

# app/rds_stack.py
from aws_cdk import Stack, RemovalPolicy
from constructs import Construct
import aws_cdk.aws_ec2 as ec2
import aws_cdk.aws_rds as rds

class RdsStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, vpc: ec2.Vpc, **kwargs) -> None:
        super().__init__(scope, construct_id, **kwargs)
        # 建立 RDS 資料函式庫例項
        rds_instance = rds.DatabaseInstance(self, "RdsInstance",
                                              engine=rds.DatabaseInstanceEngine.mysql(
                                                  version=rds.MysqlEngineVersion.VER_8_0_21
                                              ),
                                              instance_identifier="my-rds-instance",
                                              vpc=vpc,
                                              removal_policy=RemovalPolicy.DESTROY
                                              )

內容解密:

在上述程式碼中,我們定義了一個 RdsStack 類別,並在其中建立了一個 RDS 資料函式庫例項。我們指定了資料函式庫引擎、例項識別符號和 VPC 等屬性。

使用AWS CDK生成CloudFormation範本

AWS CDK(Cloud Development Kit)是一種開源軟體開發框架,允許開發者使用熟悉的程式語言定義雲端基礎設施。在本章中,我們將探討如何使用AWS CDK和Python生成CloudFormation範本。

建立RDS堆積疊

首先,我們需要建立一個RDS堆積疊來建立一個RDS例項。以下是相關程式碼: // app/rds_stack.py

import aws_cdk.aws_rds as rds

class RdsStack(Stack):
    def __init__(self, scope: Construct, construct_id: str, vpc: ec2.Vpc, webserver_sg: ec2.SecurityGroup, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)
        self.vpc = vpc
        self.webserver_sg = webserver_sg

        rds_instance = rds.DatabaseInstance(
            self, "Rds",
            credentials=rds.Credentials.from_generated_secret('admin'),
            database_name='db',
            engine=rds.DatabaseInstanceEngine.MYSQL,
            vpc=vpc,
            instance_type=ec2.InstanceType.of(ec2.InstanceClass.BURSTABLE2, ec2.InstanceSize.MICRO),
            removal_policy=core.RemovalPolicy.DESTROY,
            deletion_protection=False
        )
        rds_instance.connections.allow_from(webserver_sg, ec2.Port.tcp(3306))

內容解密:

上述程式碼定義了一個名為RdsStack的類別,繼承自Stack。在建構函式中,我們初始化了VPC和Web伺服器安全群組。然後,我們建立了一個RDS例項,並設定了相關屬性,如資料函式庫名稱、引擎、例項型別等。最後,我們允許Web伺服器安全群組存取RDS例項的3306埠。

新增堆積疊到應用程式

接下來,我們需要將RDS堆積疊新增到我們的應用程式中。以下是相關程式碼: // app.py

import aws_cdk as cdk
from app.core_stack import CoreStack
from app.web_stack import WebStack
from app.rds_stack import RdsStack

app = cdk.App()
core = CoreStack(app, "CoreStack")
web = WebStack(app, "WebStack", vpc=core.vpc)
rds = RdsStack(app, "RdsStack", vpc=core.vpc, webserver_sg=web.webserver_sg)
app.synth()

內容解密:

上述程式碼建立了一個CDK應用程式,並例項化了CoreStackWebStackRdsStack。我們將VPC和Web伺服器安全群組從CoreStackWebStack傳遞給RdsStack

佈署CDK應用程式

現在,我們可以使用cdk deploy命令佈署CDK應用程式。以下是相關命令:

$ cdk deploy core
$ cdk deploy web
$ cdk deploy rds

或者,我們可以使用--all引數一次性佈署所有堆積疊:

$ cdk deploy --all

內容解密:

cdk deploy命令會生成CloudFormation範本並建立變更集。然後,它會執行變更集並建立相關資源。如果存在安全相關資源,CDK會請求確認。

刪除CDK應用程式

如果需要刪除CDK應用程式,我們可以使用cdk destroy命令。以下是相關命令:

$ cdk destroy core

內容解密:

cdk destroy命令會刪除相關堆積疊。由於core堆積疊是其他堆積疊的依賴,因此刪除core堆積疊也會刪除其他堆積疊。

測試CDK應用程式

CDK支援對堆積疊類別和其屬性進行測試。以下是相關程式碼: // tests/unit/test_app_stack.py

import aws_cdk as core
import aws_cdk.assertions as assertions
from aws_cdk.assertions import Template, Match
from app.core_stack import CoreStack

def test_vpc_has_public_subnets():
    app = core.App()
    stack = CoreStack(app, 'core')
    assert len(stack.vpc.public_subnets) > 0

def test_vpc_has_private_subnets():
    app = core.App()
    stack = CoreStack(app, 'core')
    assert len(stack.vpc.private_subnets) > 0

def test_dev_role_is_readonly():
    app = core.App()
    stack = CoreStack(app, 'core')
    template = Template.from_stack(stack)
    template.has_resource_properties(
        'AWS::IAM::Role', {
            'ManagedPolicyArns': [
                Match.object_like({
                    "Fn::Join": ["", ["arn:", {"Ref": "AWS::Partition"}, ":iam::aws:policy/ReadOnlyAccess"]]
                })
            ]
        }
    )

內容解密:

上述程式碼定義了三個測試函式,分別測試VPC是否有公有子網、是否有私有子網,以及開發者角色是否具有唯讀許可權。我們使用CDK的斷言函式庫來渲染CloudFormation範本並檢查相關資源的屬性。