亚马逊AWS官方博客

AWS 云开发工具包 (CDK) – TypeScript 和 Python 版现已正式发布

将基础设施作为代码来管理(基础设施即代码)具有极大的优势,往往是成功贯彻开发运营实践的敲门砖。这样将不再需要倚赖手动执行的步骤,管理员和开发人员均可以使用配置文件,自动化预置应用程序需要的计算、存储、网络和应用服务。

例如,通过定义基础设施即代码,您可以实现如下目标:

  • 将基础设施和应用程序代码存储在同一存储库中
  • 实现基础设施更改的跨环境、跨 AWS 账户和跨 AWS 区域可重复性和可预见性
  • 在暂存环境中复制生产环境,从而支持持续测试
  • 在您刚刚用于压力测试的性能测试环境中复制生产环境
  • 使用与代码更改相同的工具来发布基础设施更改,从而确保部署也包含对基础设施的更新
  • 将软件开发最佳实践应用于基础设施管理,例如代码评审或频繁部署小的更改

用于管理基础设施的配置文件一般会作为 YAML 或 JSON 文本文件实现,但这会丧失现代编程语言的大部分优势。特别是对 YAML 文件,可能会非常难以检测到在向其他系统传输过程中被截断的文件,或在模板之间复制粘贴时丢失的文件。

如果可以借助自己喜欢的编程语言的强大功能来定义云基础设施,岂不是更好? 为此,我们在去年推出了开发人员预览版的 AWS 云开发工具包 (CDK),这是一个可扩展的开源软件开发框架,让您可以使用熟悉的编程语言来构建模型和预置云基础设施。

今天我无比兴奋地告诉大家,适用于 TypeScript 和 Pytho 的 AWS CDK 现已正式发布!

借助 AWS CDK,您可以设计、创作和分享满足您独特需求的自定义组件。例如,您可以创建一个组件来设置自己的标准 VPC,以及它的关联路由和安全性配置。或者使用 AWS CodeBuildCodePipeline 等工具为您的微服务创建标准的 CI/CD 管道。

我个人真正喜欢的是,通过使用 AWS CDK,您可以使用同样的编程语言在您的 IDE 中构建应用程序(包括基础设施),加上现代 IDE 已经内置的自动填充和参数建议支持,不再需要在不同的工具或技术之间进行思维切换。 AWS CDK 诞生之后,快速将 AWS 基础设施代码化,完成配置并将它与您的应用程序代码绑定,真正变得趣味无限!

AWS CDK 的工作原理
AWS CDK 中的一切都是一种构件 (construct)。您可以将构件想象成云组件,它代表任意复杂度的架构:S3 存储桶或 SNS 主题等单个资源、静态网站、甚至是覆盖多个 AWS 账户和区域的复杂的多堆栈应用程序。为提高其可复用性,构件可以包含其他构件。 您可以将若干构件组合成堆栈(可以部署到 AWS 环境中)以及应用程序(一个或多个堆栈的集合)。

如何使用 AWS CDK
我们根据客户的反馈不断增加新功能。这意味着在创建 AWS 资源时,您往往需要指定许多选项和依赖项。例如在创建 VPC 时,您必须思考需要使用多少个可用区 (AZ) 以及如何配置子网,从而赋予对将在该 VPC 中部署的资源的私有和公有访问权限。

为方便定义 AWS 资源的状态,AWS 构件库通过您可以在需要时进行自定义的合理默认设置,将许多 AWS 服务的丰富功能完整呈现。在上例中,该 VPC 构件会默认为该 VPC 中的所有可用区创建公有和私有子网,如果未指定可用区数量,则将使用 3 个可用区。

要创建和管理 CDK 应用程序,您可以使用 AWS CDK 命令行界面 (CLI),这是一种命令行工具,需要使用 Node.js 并且可以使用如下命令轻松安装:

npm install -g aws-cdk

然后您可以将 CDK CLI 与不同的命令结合使用:

  • cdk init 命令用于使用支持的任意一种编程语言,在当前目录中初始化新的 CDK 项目
  • cdk synth 命令用于打印此应用程序的 CloudFormation 模板
  • cdk deploy 命令用于在您的 AWS 账户中部署应用程序
  • cdk diff 用于比较项目文件中的内容和已经部署的内容

直接运行 cdk 命令可以查看可用的命令和选项。

您可以在部署自动化工作流中轻松包含 CDK CLI,例如使用 JenkinsAWS CodeBuild

下面我们使用不同的编程语言,通过 AWS CDK 来构件两个示例项目。

TypeScript 示例
对于第一个项目,我将使用 TypeScript 来定义基础设施:

cdk init app --language=typescript

下面简要概括了我要构建的内容,但并未深入介绍 VPC 中的公有/私有子网的详细信息。有一个在线前端向队列中写入消息,另外还有一个异步后端,使用来自该队列的消息:

在堆栈中,下面的 TypeScript 代码定义了我需要的资源以及资源之间的关系:

  • 首先我定义了 VPC 以及该 VPC 中的一个 Amazon ECS 集群。通过使用 AWS 构件库提供的默认设置,此处我不需要指定任何参数。
  • 然后我使用一个 ECS 模式,该模式通过几行代码建立了一个 Amazon SQS 队列以及一个在 AWS Fargate 上运行的 ECS 服务以使用该队列中的消息。
  • ECS 模式库提供了较高级别的 ECS 构件,这些构件采用常用的架构模式,例如负载均衡服务、队列处理和计划任务等。
  • 该 ECS 模式将创建一个名称与该队列相同的 Lambda 函数,作为一个环境变量通过,并获得向该队列发送消息的权限。
  • 该 Lambda 函数的代码和 Docker 映像作为资产通过。资产可让您将来自项目的文件或目录捆绑打包,然后与 Lambda 或 ECS 结合使用。
  • 最后,一个 Amazon API Gateway 终端节点将提供到该函数的 HTTPS REST 接口。
const myVpc = new ec2.Vpc(this, "MyVPC");

const myCluster = new ecs.Cluster(this, "MyCluster", {
  vpc: myVpc
});

const myQueueProcessingService = new ecs_patterns.QueueProcessingFargateService(
  this, "MyQueueProcessingService", {
    cluster: myCluster,
    memoryLimitMiB: 512,
    image: ecs.ContainerImage.fromAsset("my-queue-consumer")
  });

const myFunction = new lambda.Function(
  this, "MyFrontendFunction", {
    runtime: lambda.Runtime.NODEJS_10_X,
    timeout: Duration.seconds(3),
    handler: "index.handler",
    code: lambda.Code.asset("my-front-end"),
    environment: {
      QUEUE_NAME: myQueueProcessingService.sqsQueue.queueName
    }
  });

myQueueProcessingService.sqsQueue.grantSendMessages(myFunction);

const myApi = new apigateway.LambdaRestApi(
  this, "MyFrontendApi", {
    handler: myFunction
  });

我发现此代码的可读性极高,维护也比对应的 JSON 或 YAML 文件更为方便。此外,此例中的 cdk synth 命令输出了 800 多行简单的 CloudFormation YAML 代码。

Python 示例
对于第二个项目,我将使用 Python:

cdk init app --language=python

我想要构建一个每 10 分钟执行一次的 Lambda 函数:

在 Python 中初始化 CDK 项目时,已经为您见了一个 virtualenv。您可以激活 virtualenv 并使用如下命令安装您的项目需求:

source .env/bin/activate

pip install -r requirements.txt

请注意,如果您不从活动的 virtualenv 启动某些编辑器(例如 Visual Studio Code),Python 自动填写功能可能不起作用。

在堆栈中,下面的 Python 代码定义了 Lambda 函数以及定期将该函数作为目标调用的 CloudWatch 事件规则:

myFunction = aws_lambda.Function(
    self, "MyPeriodicFunction",
    code=aws_lambda.Code.asset("src"),
    handler="index.main",
    timeout=core.Duration.seconds(30),
    runtime=aws_lambda.Runtime.PYTHON_3_7,
)

myRule = aws_events.Rule(
    self, "MyRule",
    schedule=aws_events.Schedule.rate(core.Duration.minutes(10)),
)
myRule.add_target(aws_events_targets.LambdaFunction(myFunction))

同样,即使您并不详细了解 AWS CDK,这也非常容易理解。例如,持续时间包含时间单位,您无需考虑它是用秒、毫秒还是天来表示。此例中的 cdk synth 命令输出了 90 多行简单的 CloudFormation YAML 代码。

现已推出
使用 AWS CDK 不会产生任何额外的费用,您只需为此工具部署的 AWS 资源付费。

要快速学会使用此 CDK,请首先学习此超级棒的详细分步在线教程

以下存储库中提供了更多 CDK 项目的示例,它们使用不同的编程语言:

https://github.com/aws-samples/aws-cdk-examples

有关更多信息,请参阅此处的编写您自己的构件

AWS CDK 属于开源项目,我们欢迎大家做出贡献,使它变得更加好用:

https://github.com/awslabs/aws-cdk

在 GitHub 上查看我们的源代码,立即使用 TypeScript 或 Python 开始构建您的基础设施,或者在开发人员预览版中尝试不同的语言(例如 C# 和 Java)并向我们提供反馈!