教程:创建你的第一个 AWS CDK 应用程序 - AWS Cloud Development Kit (AWS CDK) v2

这是 AWS CDK v2 开发者指南。较旧的 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

教程:创建你的第一个 AWS CDK 应用程序

开始使用 AWS CDK 命令行界面 (AWS CDK CLI) 开发您的第一个CDK应用程序、引导您的 AWS 环境并在上 AWS部署应用程序。 AWS Cloud Development Kit (AWS CDK)

先决条件

在开始本教程之前,请完成中的所有设置步骤开始使用 AWS CDK

关于本教程

在本教程中,您将 AWS 使用创建和部署一个简单的应用程序 AWS CDK。该应用程序由一个AWS Lambda 函数组成,该函数在调用时会返回一条Hello World!消息。该函数将通过 Lambda 函数调用URL,该函数充当您的 Lambda 函数的专用 HTTP (S) 端点。

通过本教程,您将执行以下操作:

  • 创建您的项目-使用CDKCLIcdk init命令创建CDK项目。

  • 配置您的 AWS 环境-配置要将应用程序部署到的 AWS 环境。

  • 引导您的 AWS 环境-使用命令引导您的 AWS 环境,为部署做好准备。CDK CLI cdk bootstrap

  • 开发您的应用程序-使用构造库中的构造来定义您的 AWS Lambda 函数和 Lambda 函数资源。URL

  • 为@@ 应用程序做好部署准备-使用CDKCLI来构建您的应用程序并合成 AWS CloudFormation 模板。

  • 部署您的应用程序-使用CDKCLIcdk deploy命令部署您的应用程序并配置您的 AWS 资源。

  • 与您的应用程序交互- AWS 通过调用已部署的 Lambda 函数并接收响应,与该函数进行交互。

  • 修改您的应用程序-修改您的 Lambda 函数并部署以实现您的更改。

  • 删除您的应用程序-删除您使用CDKCLIcdk destroy命令创建的所有资源。

第 1 步:创建您的CDK项目

在此步骤中,您将创建一个新CDK项目。CDK项目应位于自己的目录中,并具有自己的本地模块依赖关系。

创建CDK项目
  1. 从您选择的起始目录中,创建并导航到名为hello-cdk

    $ mkdir hello-cdk && cd hello-cdk
    重要

    请务必完全按照此处所示命名您的项目目录hello-cdk。CDKCLI使用此目录名来命名CDK代码中的内容。如果您使用不同的目录名称,则在本教程中会遇到问题。

  2. hello-cdk目录中,使用CDKCLIcdk init命令初始化一个新CDK项目。使用以下--language选项指定app模板和您的首选编程语言:

    TypeScript
    $ cdk init app --language typescript
    JavaScript
    $ cdk init app --language javascript
    Python
    $ cdk init app --language python

    创建应用程序后,还要输入以下两个命令。它们会激活应用程序的Python虚拟环境并安装 AWS CDK 核心依赖项。

    $ source .venv/bin/activate # On Windows, run `.\venv\Scripts\activate` instead $ python -m pip install -r requirements.txt
    Java
    $ cdk init app --language java

    如果您使用的是IDE,则现在可以打开或导入项目。例如Eclipse,在中,选择 “文件” > “导入” > “Maven” > “现有 Mave n 项目”。确保将项目设置设置为使用 Java 8 (1.8)。

    C#
    $ cdk init app --language csharp

    如果您使用的是 Visual Studio,请在src目录中打开解决方案文件。

    Go
    $ cdk init app --language go

    创建应用程序后,还要输入以下命令来安装该应用程序所需的 AWS 构造库模块。

    $ go get

cdk init命令在hello-cdk目录中创建文件和文件夹结构,以帮助整理CDK应用程序的源代码。这种文件和文件夹结构称为您的CDK项目。花点时间探索你的CDK项目。

如果您已Git安装,则使用cdk init创建的每个项目也会初始化为Git存储库。

在项目初始化期间,CDKCLI会创建一个包含单个CDK堆栈的CDK应用程序。CDK应用程序实例是使用App构造创建的。以下是CDK应用程序文件中此代码的一部分:

TypeScript

位于bin/hello-cdk.ts

#!/usr/bin/env node import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; import { HelloCdkStack } from '../lib/hello-cdk-stack'; const app = new cdk.App(); new HelloCdkStack(app, 'HelloCdkStack', { });
JavaScript

位于bin/hello-cdk.js

#!/usr/bin/env node const cdk = require('aws-cdk-lib'); const { HelloCdkStack } = require('../lib/hello-cdk-stack'); const app = new cdk.App(); new HelloCdkStack(app, 'HelloCdkStack', { });
Python

位于app.py

#!/usr/bin/env python3 import os import aws_cdk as cdk from hello_cdk.hello_cdk_stack import HelloCdkStack app = cdk.App() HelloCdkStack(app, "HelloCdkStack",) app.synth()
Java

位于src/main/java/.../HelloCdkApp.java

package com.myorg; import software.amazon.awscdk.App; import software.amazon.awscdk.Environment; import software.amazon.awscdk.StackProps; import java.util.Arrays; public class HelloCdkApp { public static void main(final String[] args) { App app = new App(); new HelloCdkStack(app, "HelloCdkStack", StackProps.builder() .build()); app.synth(); } }
C#

位于src/HelloCdk/Program.cs

using Amazon.CDK; using System; using System.Collections.Generic; using System.Linq; namespace HelloCdk { sealed class Program { public static void Main(string[] args) { var app = new App(); new HelloCdkStack(app, "HelloCdkStack", new StackProps {}); app.Synth(); } } }
Go

位于hello-cdk.go

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) // ... func main() { defer jsii.Close() app := awscdk.NewApp(nil) NewHelloCdkStack(app, "HelloCdkStack", &HelloCdkStackProps{ awscdk.StackProps{ Env: env(), }, }) app.Synth(nil) } // ...

CDK堆栈是使用Stack构造创建的。以下是CDK堆栈文件中此代码的一部分:

TypeScript

位于lib/hello-cdk-stack.ts

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; export class HelloCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Define your constructs here } }
JavaScript

位于lib/hello-cdk-stack.js

const { Stack } = require('aws-cdk-lib'); class HelloCdkStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Define your constructs here } } module.exports = { HelloCdkStack }
Python

位于hello_cdk/hello_cdk_stack.py

from aws_cdk import ( Stack, ) from constructs import Construct class HelloCdkStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Define your constructs here
Java

位于src/main/java/.../HelloCdkStack.java

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Define your constructs here } }
C#

位于src/HelloCdk/HelloCdkStack.cs

using Amazon.CDK; using Constructs; namespace HelloCdk { public class HelloCdkStack : Stack { internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Define your constructs here } } }
Go

位于hello-cdk.go

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) type HelloCdkStackProps struct { awscdk.StackProps } func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) return stack } // ...

步骤 2:配置您的 AWS 环境

在此步骤中,您将为CDK堆栈配置 AWS 环境。通过执行此操作,您可以指定CDK堆栈将部署到哪个环境。

首先,确定要使用的 AWS 环境。 AWS 环境由 AWS 账户 和组成 AWS 区域。

当您使用在 AWS CLI 本地计算机上配置安全证书时,您可以使用 AWS CLI 来获取特定配置文件的 AWS 环境信息。

使用获取 AWS CLI 您的 AWS 账户 身份证
  1. 运行以下 AWS CLI 命令以获取您的default个人资料的 AWS 账户 ID:

    $ aws sts get-caller-identity --query "Account" --output text
  2. 如果您更喜欢使用已命名的个人资料,请使用以下--profile选项提供您的个人资料名称:

    $ aws sts get-caller-identity --profile your-profile-name --query "Account" --output text
使用 AWS CLI 获取您的 AWS 区域
  1. 运行以下 AWS CLI 命令以获取您为default个人资料配置的区域:

    $ aws configure get region
  2. 如果您更喜欢使用已命名的个人资料,请使用以下--profile选项提供您的个人资料名称:

    $ aws configure get region --profile your-profile-name

接下来,您将通过修改应用程序文件中的HelloCdkStack实例来配置CDK堆栈的 AWS 环境。在本教程中,您将对 AWS 环境信息进行硬编码。建议在生产环境中使用此选项。有关配置环境的其他方法的信息,请参阅配置要与... 一起使用的环境 AWS CDK

为CDK堆栈配置环境
  • 在您的应用程序文件中,使用Stack构造的env属性来配置您的环境。以下是 示例:

    TypeScript

    位于bin/hello-cdk.ts

    #!/usr/bin/env node import 'source-map-support/register'; import * as cdk from 'aws-cdk-lib'; import { HelloCdkStack } from '../lib/hello-cdk-stack'; const app = new cdk.App(); new HelloCdkStack(app, 'HelloCdkStack', { env: { account: '123456789012', region: 'us-east-1' }, });
    JavaScript

    位于bin/hello-cdk.js

    #!/usr/bin/env node const cdk = require('aws-cdk-lib'); const { HelloCdkStack } = require('../lib/hello-cdk-stack'); const app = new cdk.App(); new HelloCdkStack(app, 'HelloCdkStack', { env: { account: '123456789012', region: 'us-east-1' }, });
    Python

    位于app.py

    #!/usr/bin/env python3 import os import aws_cdk as cdk from hello_cdk.hello_cdk_stack import HelloCdkStack app = cdk.App() HelloCdkStack(app, "HelloCdkStack", env=cdk.Environment(account='123456789012', region='us-east-1'), ) app.synth()
    Java

    位于src/main/java/.../HelloCdkApp.java

    package com.myorg; import software.amazon.awscdk.App; import software.amazon.awscdk.Environment; import software.amazon.awscdk.StackProps; import java.util.Arrays; public class HelloCdkApp { public static void main(final String[] args) { App app = new App(); new HelloCdkStack(app, "HelloCdkStack", StackProps.builder() .env(Environment.builder() .account("123456789012") .region("us-east-1") .build()) .build()); app.synth(); } }
    C#

    位于src/HelloCdk/Program.cs

    using Amazon.CDK; using System; using System.Collections.Generic; using System.Linq; namespace HelloCdk { sealed class Program { public static void Main(string[] args) { var app = new App(); new HelloCdkStack(app, "HelloCdkStack", new StackProps { Env = new Amazon.CDK.Environment { Account = "123456789012", Region = "us-east-1", } }); app.Synth(); } } }
    Go

    位于hello-cdk.go

    package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" ) // ... func main() { defer jsii.Close() app := awscdk.NewApp(nil) NewHelloCdkStack(app, "HelloCdkStack", &HelloCdkStackProps{ awscdk.StackProps{ Env: env(), }, }) app.Synth(nil) } func env() *awscdk.Environment { return &awscdk.Environment{ Account: jsii.String("123456789012"), Region: jsii.String("us-east-1"), } }

步骤 3:引导您的环境 AWS

在此步骤中,您将引导您在上一步中配置的 AWS 环境。这会让您的环境为CDK部署做好准备。

要引导您的环境,请从CDK项目的根目录运行以下命令:

$ cdk bootstrap

通过从CDK项目的根目录进行引导,您无需提供任何其他信息。从您的项目中CDKCLI获取环境信息。在CDK项目之外进行引导时,必须使用cdk bootstrap命令提供环境信息。有关更多信息,请参阅 引导您的环境以用于 AWS CDK

第 4 步:构建您的CDK应用程序

在大多数编程环境中,都是在进行更改后生成或编译代码。这不是必需的, AWS CDK 因为CDKCLI会自动执行此步骤。但是,当你想捕获 catch 语法和键入错误时,你仍然可以手动构建。以下是 示例:

TypeScript
$ npm run build > hello-cdk@0.1.0 build > tsc
JavaScript

无需执行任何构建步骤。

Python

无需执行任何构建步骤。

Java
$ mvn compile -q

或者Control-B在 Eclipse 中按(其他 Java IDEs 可能会有所不同)

C#
$ dotnet build src

或者在 Visual Studio 中按 F6

Go
$ go build

第 5 步:在应用程序中列出CDK堆栈

此时,你应该有一个包含单个CDK堆栈的CDK应用程序。要进行验证,请使用CDKCLIcdk list命令显示您的堆栈。输出应显示一个名为HelloCdkStack

$ cdk list HelloCdkStack

如果您没有看到此输出,请确认您位于项目的正确工作目录中,然后重试。如果您仍然看不到您的堆栈,请重复第 1 步:创建您的CDK项目并重试。

第 6 步:定义您的 Lambda 函数

在此步骤中,您将从 AWS 构造库中导入aws_lambda模块并使用 Function L2 构造。

按如下方式修改您的CDK堆栈文件:

TypeScript

位于lib/hello-cdk-stack.ts

import * as cdk from 'aws-cdk-lib'; import { Construct } from 'constructs'; // Import the Lambda module import * as lambda from 'aws-cdk-lib/aws-lambda'; export class HelloCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Define the Lambda function resource const myFunction = new lambda.Function(this, "HelloWorldFunction", { runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime handler: "index.handler", code: lambda.Code.fromInline(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; `), }); } }
JavaScript

位于lib/hello-cdk-stack.js

const { Stack } = require('aws-cdk-lib'); // Import the Lambda module const lambda = require('aws-cdk-lib/aws-lambda'); class HelloCdkStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Define the Lambda function resource const myFunction = new lambda.Function(this, "HelloWorldFunction", { runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime handler: "index.handler", code: lambda.Code.fromInline(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; `), }); } } module.exports = { HelloCdkStack }
Python

位于hello_cdk/hello_cdk_stack.py

from aws_cdk import ( Stack, aws_lambda as _lambda, # Import the Lambda module ) from constructs import Construct class HelloCdkStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Define the Lambda function resource my_function = _lambda.Function( self, "HelloWorldFunction", runtime = _lambda.Runtime.NODEJS_20_X, # Provide any supported Node.js runtime handler = "index.handler", code = _lambda.Code.from_inline( """ exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; """ ), )
Java

位于src/main/java/.../HelloCdkStack.java

package com.myorg; import software.constructs.Construct; import software.amazon.awscdk.Stack; import software.amazon.awscdk.StackProps; // Import Lambda function import software.amazon.awscdk.services.lambda.Code; import software.amazon.awscdk.services.lambda.Function; import software.amazon.awscdk.services.lambda.Runtime; public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Define the Lambda function resource Function myFunction = Function.Builder.create(this, "HelloWorldFunction") .runtime(Runtime.NODEJS_20_X) // Provide any supported Node.js runtime .handler("index.handler") .code(Code.fromInline( "exports.handler = async function(event) {" + " return {" + " statusCode: 200," + " body: JSON.stringify('Hello World!')" + " };" + "};")) .build(); } }
C#

位于src/main/java/.../HelloCdkStack.java

using Amazon.CDK; using Constructs; // Import the Lambda module using Amazon.CDK.AWS.Lambda; namespace HelloCdk { public class HelloCdkStack : Stack { internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Define the Lambda function resource var myFunction = new Function(this, "HelloWorldFunction", new FunctionProps { Runtime = Runtime.NODEJS_20_X, // Provide any supported Node.js runtime Handler = "index.handler", Code = Code.FromInline(@" exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; "), }); } } }
Go

位于hello-cdk.go

package main import ( "github.com/aws/aws-cdk-go/awscdk/v2" "github.com/aws/constructs-go/constructs/v10" "github.com/aws/jsii-runtime-go" // Import the Lambda module "github.com/aws/aws-cdk-go/awscdk/v2/awslambda" ) type HelloCdkStackProps struct { awscdk.StackProps } func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // Define the Lambda function resource myFunction := awslambda.NewFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.FunctionProps{ Runtime: awslambda.Runtime_NODEJS_20_X(), // Provide any supported Node.js runtime Handler: jsii.String("index.handler"), Code: awslambda.Code_FromInline(jsii.String(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; `)), }) return stack } // ...

让我们仔细看看这个Function构造。像所有构造一样,该Function类采用三个参数:

  • s@@ cop e — 将您的Stack实例定义为Function构造的父实例。所有定义 AWS 资源的构造都是在堆栈的范围内创建的。你可以在构造内部定义构造,从而创建层次结构(树)。在这里,在大多数情况下,作用域是thisselfinPython)。

  • ID — 您的 AWS CDK 应用程序Function中的逻辑 ID。此 ID 加上基于函数在堆栈中的位置的哈希值,可在部署期间唯一标识该函数。当您在应用程序中更新构造并重新部署以更新已部署的资源时, AWS CDK 也会引用此 ID。这里,你的逻辑 ID 是HelloWorldFunction。函数也可以有一个名称,使用functionName属性指定。这与逻辑 ID 不同。

  • props — 一组定义函数属性的值。在这里,您可以定义runtimehandler、和code属性。

    在支持的语言中,道具的表示方式不同。 AWS CDK

    • 在 and 中 TypeScriptJavaScript,props是单个参数,您可以传入一个包含所需属性的对象。

    • 在中Python,props 作为关键字参数传递。

    • 在中Java,提供了一个生成器来传递道具。有两个:一个用于FunctionProps,第二个用于Function让你一步构建构造及其道具对象。此代码使用后者。

    • 在中C#,你使用FunctionProps对象初始化器实例化一个对象,并将其作为第三个参数传递。

    如果构造的 props 是可选的,则可以完全省略该props参数。

所有构造都采用相同的三个参数,因此在学习新结构时很容易保持定向。正如你所预料的那样,你可以对任何构造进行子类化以扩展它以满足你的需求,或者如果你想更改其默认值。

第 7 步:定义您的 Lambda 函数 URL

在此步骤中,您将使用Function构造的addFunctionUrl辅助方法来定义 Lambda 函数。URL要URL在部署时输出此值,您需要使用CfnOutput构造创建 AWS CloudFormation 输出。

将以下内容添加到您的CDK堆栈文件中:

TypeScript

位于lib/hello-cdk-stack.ts

// ... export class HelloCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Define the Lambda function resource // ... // Define the Lambda function URL resource const myFunctionUrl = myFunction.addFunctionUrl({ authType: lambda.FunctionUrlAuthType.NONE, }); // Define a CloudFormation output for your URL new cdk.CfnOutput(this, "myFunctionUrlOutput", { value: myFunctionUrl.url, }) } }
JavaScript

位于lib/hello-cdk-stack.js

const { Stack, CfnOutput } = require('aws-cdk-lib'); // Import CfnOutput class HelloCdkStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Define the Lambda function resource // ... // Define the Lambda function URL resource const myFunctionUrl = myFunction.addFunctionUrl({ authType: lambda.FunctionUrlAuthType.NONE, }); // Define a CloudFormation output for your URL new CfnOutput(this, "myFunctionUrlOutput", { value: myFunctionUrl.url, }) } } module.exports = { HelloCdkStack }
Python

位于hello_cdk/hello_cdk_stack.py

from aws_cdk import ( # ... CfnOutput # Import CfnOutput ) from constructs import Construct class HelloCdkStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Define the Lambda function resource # ... # Define the Lambda function URL resource my_function_url = my_function.add_function_url( auth_type = _lambda.FunctionUrlAuthType.NONE, ) # Define a CloudFormation output for your URL CfnOutput(self, "myFunctionUrlOutput", value=my_function_url.url)
Java

位于src/main/java/.../HelloCdkStack.java

package com.myorg; // ... // Import Lambda function URL import software.amazon.awscdk.services.lambda.FunctionUrl; import software.amazon.awscdk.services.lambda.FunctionUrlAuthType; import software.amazon.awscdk.services.lambda.FunctionUrlOptions; // Import CfnOutput import software.amazon.awscdk.CfnOutput; public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Define the Lambda function resource // ... // Define the Lambda function URL resource FunctionUrl myFunctionUrl = myFunction.addFunctionUrl(FunctionUrlOptions.builder() .authType(FunctionUrlAuthType.NONE) .build()); // Define a CloudFormation output for your URL CfnOutput.Builder.create(this, "myFunctionUrlOutput") .value(myFunctionUrl.getUrl()) .build(); } }
C#

位于src/main/java/.../HelloCdkStack.java

// ... namespace HelloCdk { public class HelloCdkStack : Stack { internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Define the Lambda function resource // ... // Define the Lambda function URL resource var myFunctionUrl = myFunction.AddFunctionUrl(new FunctionUrlOptions { AuthType = FunctionUrlAuthType.NONE }); // Define a CloudFormation output for your URL new CfnOutput(this, "myFunctionUrlOutput", new CfnOutputProps { Value = myFunctionUrl.Url }); } } }
Go

位于hello-cdk.go

// ... func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // Define the Lambda function resource // ... // Define the Lambda function URL resource myFunctionUrl := myFunction.AddFunctionUrl(&awslambda.FunctionUrlOptions{ AuthType: awslambda.FunctionUrlAuthType_NONE, }) // Define a CloudFormation output for your URL awscdk.NewCfnOutput(stack, jsii.String("myFunctionUrlOutput"), &awscdk.CfnOutputProps{ Value: myFunctionUrl.Url(), }) return stack } // ...
警告

为了简化本教程,您的 Lambda 函数URL是在不进行身份验证的情况下定义的。部署后,这将创建一个可公开访问的端点,可用于调用您的函数。完成本教程后,请第 12 步:删除您的应用程序按照操作删除这些资源。

第 8 步:合成模板 CloudFormation

在此步骤中,您将通过使用CDKCLIcdk synth命令合成 CloudFormation 模板来为部署做准备。此命令对您的CDK代码执行基本验证,运行您的CDK应用程序,并从CDK堆栈中生成 CloudFormation 模板。

如果您的应用程序包含多个堆栈,则必须指定要合成哪些堆栈。由于您的应用程序包含单个堆栈,因此会CDKCLI自动检测要合成的堆栈。

如果您没有合成模板,则CDKCLI将在您部署时自动执行此步骤。但是,我们建议您在每次部署之前运行此步骤以检查合成错误。

在合成模板之前,您可以选择构建应用程序以捕获 catch 语法和类型错误。有关说明,请参阅 第 4 步:构建您的CDK应用程序

要合成 CloudFormation 模板,请从项目的根目录运行以下命令:

$ cdk synth
注意

如果您收到类似以下的错误,请确认您在hello-cdk目录中并重试:

--app is required either in command-line, in cdk.json or in ~/.cdk.json

如果成功,则CDKCLI会将YAML格式化 CloudFormation 模板输出到项目目录中,stdout并将JSON格式化模板保存在项目cdk.out目录中。

以下是 CloudFormation 模板的输出示例:

Resources: HelloWorldFunctionServiceRoleunique-identifier: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Statement: - Action: sts:AssumeRole Effect: Allow Principal: Service: lambda.amazonaws.com Version: "2012-10-17" ManagedPolicyArns: - Fn::Join: - "" - - "arn:" - Ref: AWS::Partition - :iam::aws:policy/service-role/AWSLambdaBasicExecutionRole Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/ServiceRole/Resource HelloWorldFunctionunique-identifier: Type: AWS::Lambda::Function Properties: Code: ZipFile: " \ exports.handler = async function(event) { \ return { \ statusCode: 200, \ body: JSON.stringify('Hello World!'), \ }; \ }; \ " Handler: index.handler Role: Fn::GetAtt: - HelloWorldFunctionServiceRoleunique-identifier - Arn Runtime: nodejs20.x DependsOn: - HelloWorldFunctionServiceRoleunique-identifier Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/Resource HelloWorldFunctionFunctionUrlunique-identifier: Type: AWS::Lambda::Url Properties: AuthType: NONE TargetFunctionArn: Fn::GetAtt: - HelloWorldFunctionunique-identifier - Arn Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/FunctionUrl/Resource HelloWorldFunctioninvokefunctionurlunique-identifier: Type: AWS::Lambda::Permission Properties: Action: lambda:InvokeFunctionUrl FunctionName: Fn::GetAtt: - HelloWorldFunctionunique-identifier - Arn FunctionUrlAuthType: NONE Principal: "*" Metadata: aws:cdk:path: HelloCdkStack/HelloWorldFunction/invoke-function-url CDKMetadata: Type: AWS::CDK::Metadata Properties: Analytics: v2:deflate64:unique-identifier Metadata: aws:cdk:path: HelloCdkStack/CDKMetadata/Default Condition: CDKMetadataAvailable Outputs: myFunctionUrlOutput: Value: Fn::GetAtt: - HelloWorldFunctionFunctionUrlunique-identifier - FunctionUrl Parameters: BootstrapVersion: Type: AWS::SSM::Parameter::Value<String> Default: /cdk-bootstrap/unique-identifier/version Description: Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip] Rules: CheckBootstrapVersion: Assertions: - Assert: Fn::Not: - Fn::Contains: - - "1" - "2" - "3" - "4" - "5" - Ref: BootstrapVersion AssertDescription: CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI.
注意

默认情况下,生成的每个模板都包含一个AWS::CDK::Metadata资源。该 AWS CDK 团队使用这些元数据来深入了解 AWS CDK 使用情况,并找到改进的方法。有关详细信息,包括如何选择退出版本报告,请参阅版本报告

通过定义单个 L2 结构, AWS CDK 可以创建一个包含您的 Lambda 资源以及您的资源在应用程序中进行交互所需的权限和粘合逻辑的广泛 CloudFormation 模板。

第 9 步:部署您的CDK堆栈

在此步骤中,您将使用CDKCLIcdk deploy命令部署CDK堆栈。此命令检索您生成的 CloudFormation 模板并通过该模板进行部署 AWS CloudFormation,该模板会将您的资源配置为堆栈的一部分。 CloudFormation

在项目的根目录下,运行以下命令。如果出现提示,请确认更改:

$ cdk deploy ✨ Synthesis time: 2.69s HelloCdkStack: start: Building unique-identifier:current_account-current_region HelloCdkStack: success: Built unique-identifier:current_account-current_region HelloCdkStack: start: Publishing unique-identifier:current_account-current_region HelloCdkStack: success: Published unique-identifier:current_account-current_region This deployment will make potentially sensitive changes according to your current security approval level (--require-approval broadening). Please confirm you intend to make the following modifications: IAM Statement Changes ┌───┬───────────────────────────────────────┬────────┬──────────────────────────┬──────────────────────────────┬───────────┐ │ │ Resource │ Effect │ Action │ Principal │ Condition │ ├───┼───────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤ │ + │ ${HelloWorldFunction.Arn} │ Allow │ lambda:InvokeFunctionUrl │ * │ │ ├───┼───────────────────────────────────────┼────────┼──────────────────────────┼──────────────────────────────┼───────────┤ │ + │ ${HelloWorldFunction/ServiceRole.Arn} │ Allow │ sts:AssumeRole │ Service:lambda.amazonaws.com │ │ └───┴───────────────────────────────────────┴────────┴──────────────────────────┴──────────────────────────────┴───────────┘ IAM Policy Changes ┌───┬───────────────────────────────────┬────────────────────────────────────────────────────────────────────────────────┐ │ │ Resource │ Managed Policy ARN │ ├───┼───────────────────────────────────┼────────────────────────────────────────────────────────────────────────────────┤ │ + │ ${HelloWorldFunction/ServiceRole} │ arn:${AWS::Partition}:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole │ └───┴───────────────────────────────────┴────────────────────────────────────────────────────────────────────────────────┘ (NOTE: There may be security-related changes not in this list. See https://github.com/aws/aws-cdk/issues/1299) Do you wish to deploy these changes (y/n)? y

与之类似cdk synth,您无需指定 AWS CDK 堆栈,因为该应用程序包含单个堆栈。

部署期间,会在部署堆栈时CDKCLI显示进度信息。完成后,您可以前往AWS CloudFormation 控制台查看您的HelloCdkStack堆栈。您也可以前往 Lambda 控制台查看您的HelloWorldFunction资源。

部署完成后,CDKCLI将输出您的终端节点URL。复制此文件URL以供下一步使用。以下是 示例:

... HelloCdkStack: deploying... [1/1] HelloCdkStack: creating CloudFormation changeset... ✅ HelloCdkStack ✨ Deployment time: 41.65s Outputs: HelloCdkStack.myFunctionUrlOutput = https://<api-id>.lambda-url.<Region>.on.aws/ Stack ARN: arn:aws:cloudformation:Region:account-id:stack/HelloCdkStack/unique-identifier ✨ Total time: 44.34s

第 10 步:在上与您的应用程序进行交互 AWS

在此步骤中,您可以 AWS 通过函数调用 Lambda 函数来与应用程序进行交互。URL当您访问时URL,您的 Lambda 函数会返回消息。Hello World!

要调用您的函数,请URL通过浏览器或命令行访问该函数。以下是 示例:

$ curl https://<api-id>.lambda-url.<Region>.on.aws/ "Hello World!"%

步骤 11:修改您的应用程序

在此步骤中,您将修改 Lambda 函数在调用时返回的消息。您可以使用CDKCLIcdk diff命令执行差异以预览更改并部署以更新应用程序。然后,您可以与应用程序进行交互 AWS 以查看您的新消息。

按如下方式修改CDK堆栈文件中的myFunction实例:

TypeScript

位于lib/hello-cdk-stack.ts

// ... export class HelloCdkStack extends cdk.Stack { constructor(scope: Construct, id: string, props?: cdk.StackProps) { super(scope, id, props); // Modify the Lambda function resource const myFunction = new lambda.Function(this, "HelloWorldFunction", { runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime handler: "index.handler", code: lambda.Code.fromInline(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; `), }); // ...
JavaScript

位于lib/hello-cdk-stack.js

// ... class HelloCdkStack extends Stack { constructor(scope, id, props) { super(scope, id, props); // Modify the Lambda function resource const myFunction = new lambda.Function(this, "HelloWorldFunction", { runtime: lambda.Runtime.NODEJS_20_X, // Provide any supported Node.js runtime handler: "index.handler", code: lambda.Code.fromInline(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; `), }); // ... } } module.exports = { HelloCdkStack }
Python

位于hello_cdk/hello_cdk_stack.py

# ... class HelloCdkStack(Stack): def __init__(self, scope: Construct, construct_id: str, **kwargs) -> None: super().__init__(scope, construct_id, **kwargs) # Modify the Lambda function resource my_function = _lambda.Function( self, "HelloWorldFunction", runtime = _lambda.Runtime.NODEJS_20_X, # Provide any supported Node.js runtime handler = "index.handler", code = _lambda.Code.from_inline( """ exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; """ ), ) # ...
Java

位于src/main/java/.../HelloCdkStack.java

// ... public class HelloCdkStack extends Stack { public HelloCdkStack(final Construct scope, final String id) { this(scope, id, null); } public HelloCdkStack(final Construct scope, final String id, final StackProps props) { super(scope, id, props); // Modify the Lambda function resource Function myFunction = Function.Builder.create(this, "HelloWorldFunction") .runtime(Runtime.NODEJS_20_X) // Provide any supported Node.js runtime .handler("index.handler") .code(Code.fromInline( "exports.handler = async function(event) {" + " return {" + " statusCode: 200," + " body: JSON.stringify('Hello CDK!')" + " };" + "};")) .build(); // ... } }
C#

// ... namespace HelloCdk { public class HelloCdkStack : Stack { internal HelloCdkStack(Construct scope, string id, IStackProps props = null) : base(scope, id, props) { // Modify the Lambda function resource var myFunction = new Function(this, "HelloWorldFunction", new FunctionProps { Runtime = Runtime.NODEJS_20_X, // Provide any supported Node.js runtime Handler = "index.handler", Code = Code.FromInline(@" exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; "), }); // ... } } }
Go

// ... type HelloCdkStackProps struct { awscdk.StackProps } func NewHelloCdkStack(scope constructs.Construct, id string, props *HelloCdkStackProps) awscdk.Stack { var sprops awscdk.StackProps if props != nil { sprops = props.StackProps } stack := awscdk.NewStack(scope, &id, &sprops) // Modify the Lambda function resource myFunction := awslambda.NewFunction(stack, jsii.String("HelloWorldFunction"), &awslambda.FunctionProps{ Runtime: awslambda.Runtime_NODEJS_20_X(), // Provide any supported Node.js runtime Handler: jsii.String("index.handler"), Code: awslambda.Code_FromInline(jsii.String(` exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; `)), }) // ...

目前,您的代码更改尚未对已部署的 Lambda 资源进行任何直接更新。您的代码定义了资源的所需状态。要修改已部署的资源,您将使用将所需状态合成CDKCLI到新 AWS CloudFormation 模板中。然后,您将新 CloudFormation 模板部署为更改集。变更集仅进行必要的更改以达到新的所需状态。

要预览您的更改,请运行该cdk diff命令。以下是 示例:

$ cdk diff Stack HelloCdkStack Hold on while we create a read-only change set to get a diff with accurate replacement information (use --no-change-set to use a less accurate but faster template-only diff) Resources [~] AWS::Lambda::Function HelloWorldFunction HelloWorldFunctionunique-identifier └─ [~] Code └─ [~] .ZipFile: ├─ [-] exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello World!'), }; }; └─ [+] exports.handler = async function(event) { return { statusCode: 200, body: JSON.stringify('Hello CDK!'), }; }; ✨ Number of stacks with differences: 1

要创建此差异,需要向您的 AWS 账户 账户CDKCLI查询HelloCdkStack堆栈的最新 AWS CloudFormation 模板。然后,它将最新的模板与刚从您的应用程序中合成的模板进行比较。

要实现您的更改,请运行该cdk deploy命令。以下是 示例:

$ cdk deploy ✨ Synthesis time: 2.12s HelloCdkStack: start: Building unique-identifier:current_account-current_region HelloCdkStack: success: Built unique-identifier:current_account-current_region HelloCdkStack: start: Publishing unique-identifier:current_account-current_region HelloCdkStack: success: Published unique-identifier:current_account-current_region HelloCdkStack: deploying... [1/1] HelloCdkStack: creating CloudFormation changeset... ✅ HelloCdkStack ✨ Deployment time: 26.96s Outputs: HelloCdkStack.myFunctionUrlOutput = https://unique-identifier.lambda-url.<Region>.on.aws/ Stack ARN: arn:aws:cloudformation:Region:account-id:stack/HelloCdkStack/unique-identifier ✨ Total time: 29.07s

要与您的应用程序交互,请重复此操作第 10 步:在上与您的应用程序进行交互 AWS。以下是 示例:

$ curl https://<api-id>.lambda-url.<Region>.on.aws/ "Hello CDK!"%

第 12 步:删除您的应用程序

在此步骤中,您将使用CDKCLIcdk destroy命令删除您的应用程序。此命令删除与您的 CloudFormation 堆栈关联的CDK堆栈,其中包括您创建的资源。

要删除您的应用程序,请运行cdk destroy命令并确认您删除该应用程序的请求。以下是 示例:

$ cdk destroy Are you sure you want to delete: HelloCdkStack (y/n)? y HelloCdkStack: destroying... [1/1] ✅ HelloCdkStack: destroyed

后续步骤

恭喜您!您已完成本教程,并已使用成功创建、修改和删除中的资源 AWS Cloud。 AWS CDK 您现在可以开始使用了 AWS CDK。

要了解有关使用首选编程语言 AWS CDK 的更多信息,请参阅与 AWS CDK 图书馆合作

有关其他资源,请参阅以下内容:

  • 试试CDK工作坊,更深入地了解更复杂的项目。

  • 请参阅API参考资料,开始探索可用于您最喜欢的 AWS 服务的CDK结构。

  • 访问 C onstruc t Hub,发现由 AWS 和其他人创建的构造。

  • 浏览使用示例 AWS CDK.

AWS CDK 是一个开源项目。要做出贡献,请参阅 “贡献” AWS Cloud Development Kit (AWS CDK)