这是 AWS CDK v2 开发者指南。旧版 CDK v1 于 2022 年 6 月 1 日进入维护阶段,并于 2023 年 6 月 1 日终止支持。
本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
教程:创建你的第一个 AWS CDK 应用程序
开始使用 C AWS loud Development Kit (AWS AWS CDK),使用 CDK 命令行界面 (CD AWS K CLI) 开发您的第一个 CDK 应用程序、引导 AWS 您的环境并在上部署应用程序。 AWS
先决条件
在开始本教程之前,请完成 AWS CDK 入门中的所有设置步骤。
关于本教程
在本教程中,您将 AWS 使用 AWS CDK创建和部署一个简单的应用程序。该应用程序由一个 AWS Lambda 函数组成,该函数在调用时会返回一条Hello World!消息。该函数将通过 Lambda 函数 URL 调用,该网址充当 Lambda 函数的专用 HTTP(S) 端点。
在本教程中,您将执行以下操作:
-
创建您的项目-使用 CDK CLI cdk init 命令创建 CDK 项目。
-
配置您的 AWS 环境-配置要将应用程序部署到的 AWS 环境。
-
引导您的 AWS 环境-使用 CDK CLI 命令引导您的 AWS 环境,为部署做好准备。cdk bootstrap
-
开发您的应用程序-使用构造库中的构造来定义您的 AWS Lambda 函数和 Lambda 函数 URL 资源。
-
为@@ 应用程序做好部署准备-使用 CDK CLI 构建您的应用程序并合成模板。 AWS CloudFormation
-
部署您的应用程序-使用 CDK CLI cdk deploy 命令部署您的应用程序并配置您的 AWS 资源。
-
与您的应用程序交互- AWS 通过调用已部署的 Lambda 函数并接收响应,与该函数进行交互。
-
修改应用程序:修改 Lambda 函数并部署以实现更改。
-
删除您的应用程序-删除您使用 CDK CLI cdk destroy 命令创建的所有资源。
步骤 1:创建 CDK 项目
在此步骤中,您将新建一个 CDK 项目。CDK 项目应位于自己的目录中,并具有自己的本地模块依赖关系。
- 创建 CDK 项目
-
-
在您选择的起始目录中,创建并导航到名为 hello-cdk 的目录:
$ mkdir hello-cdk && cd hello-cdk
请务必完全按照此处所示命名项目目录 hello-cdk。CDK CLI 使用此目录名称来命名您的 CDK 代码中的内容。如果您使用了其他目录名称,则在本教程中将遇到问题。
-
在hello-cdk目录中,使用 CDK CLI cdk 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 > 现有的 Maven 项目。确保将项目设置设为使用 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 存储库。
在项目初始化期间,CDK CLI 会创建一个包含单个 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
}
// ...
在此步骤中,您将为 CDK 堆栈配置 AWS 环境。通过这样做,您可以指定要将 CDK 堆栈部署到哪个环境。
首先,确定要使用的 AWS 环境。 AWS 环境由 AWS 账户和 AWS 区域组成。
使用 AWS CLI 在本地计算机上配置安全证书时,可以使用 AWS CLI 获取特定配置文件的 AWS 环境信息。
- 使用 AWS CLI 获取您的 AWS 账户 ID
-
-
运行以下 AWS CLI 命令以获取您的default个人资料的 AWS 账户 ID:
$ aws sts get-caller-identity --query "Account" --output text
-
如果您更喜欢使用命名配置文件,请使用 --profile 选项提供配置文件的名称:
$ aws sts get-caller-identity --profile your-profile-name --query "Account" --output text
- 使用 AWS CLI 获取您的 AWS 区域
-
-
运行以下 AWS CLI 命令以获取您为default个人资料配置的区域:
$ aws configure get region
-
如果您更喜欢使用命名配置文件,请使用 --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 项目的根目录进行引导,您无需提供任何其他信息。CDK CLI 从您的项目中获取环境信息。在 CDK 项目之外进行引导时,必须使用 cdk bootstrap 命令提供环境信息。有关更多信息,请参阅引导您的环境以与 AWS CDK 配合使用。
步骤 4:构建 CDK 应用程序
在大多数编程环境中,都是在进行更改后生成或编译代码。对于 CDK 来说,这不是必需的,因为 AWS CDK CLI 会自动执行此步骤。但是,当您想捕获语法和类型错误时,仍然可以手动构建。以下是示例:
- 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 应用程序。要进行验证,请使用 CDK CLI cdk list 命令显示您的堆栈。输出应显示名为 HelloCdkStack 的单个堆栈:
$ cdk list
HelloCdkStack
如果您没有看到此输出,请确认您位于项目的正确工作目录中,然后重试。如果您仍然看不到堆栈,请重复步骤 1:创建 CDK 项目并重试。
步骤 6:定义 Lambda 函数
在此步骤中,您将从 AWS 构造库中导入aws_lambda模块并使用 FunctionL2 构造。
按如下方式修改 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 类采用三个参数:
-
scope:将 Stack 实例定义为 Function 构造的父级。所有定义 AWS 资源的构造都是在堆栈的范围内创建的。您可以在构造内部定义构造,从而创建层次结构(树)。在这里,在大多数情况下,作用域是this(self在 Python 中)。
-
ID — 您的 AWS CDK 应用程序Function中的构造 ID。此 ID 加上基于函数在堆栈中的位置的哈希值,可在部署期间唯一标识该函数。当您在应用程序中更新构造并重新部署以更新已部署的资源时, AWS CDK 也会引用此 ID。在本例中,构造 ID 是 HelloWorldFunction。函数也可以有一个名称,使用 functionName 属性指定。它不同于构造 ID。
-
props:一组定义函数属性的值。在本例中,您将定义 runtime、handler 和 code 属性。
在 AWS CDK 支持的语言中,道具的表示方式有所不同。
-
在 and 中 TypeScript JavaScript,props是单个参数,您可以传入一个包含所需属性的对象。
-
在 Python 中,道具作为关键字参数传递。
-
在 Java 中,提供了一个生成器来传递道具。有两种 props:一个用于 FunctionProps,第二个用于 Function,以便您一步构建构造及其 props 对象。示例代码使用了后者。
-
在 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
在此步骤中,您将通过使用 CDK CLI cdk synth 命令合成 CloudFormation 模板来准备部署。此命令对您的 CDK 代码执行基本验证,运行您的 CDK 应用程序,并从 CDK 堆栈生成 CloudFormation 模板。
如果应用程序包含多个堆栈,则必须指定要使用哪些堆栈进行合成。由于您的应用程序包含单个堆栈,CDK CLI 会自动检测要合成的堆栈。
如果您没有合成模板,CDK CLI 将在您部署时自动执行此步骤。但是,建议您在每次部署之前运行此步骤,以检查是否存在合成错误。
在合成模板之前,您可以选择构建应用程序,以捕获语法和类型错误。有关说明,请参阅步骤 4:构建 CDK 应用程序。
要合成 CloudFormation 模板,请从项目的根目录运行以下命令:
$ cdk synth
如果您收到如下错误,请确认您是否位于 hello-cdk 目录中并重试:
--app is required either in command-line, in cdk.json or in ~/.cdk.json
如果成功,CDK CLI 会将YAML格式化 CloudFormation 模板输出到项目目录中,stdout并将JSON格式化模板保存在项目cdk.out目录中。
以下是 CloudFormation 模板的输出示例:
Resources:
HelloWorldFunctionServiceRole<unique-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
HelloWorldFunction<unique-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:
- HelloWorldFunctionServiceRole<unique-identifier>
- Arn
Runtime: nodejs20.x
DependsOn:
- HelloWorldFunctionServiceRole<unique-identifier>
Metadata:
aws:cdk:path: HelloCdkStack/HelloWorldFunction/Resource
HelloWorldFunctionFunctionUrl<unique-identifier>:
Type: AWS::Lambda::Url
Properties:
AuthType: NONE
TargetFunctionArn:
Fn::GetAtt:
- HelloWorldFunction<unique-identifier>
- Arn
Metadata:
aws:cdk:path: HelloCdkStack/HelloWorldFunction/FunctionUrl/Resource
HelloWorldFunctioninvokefunctionurl<unique-identifier>:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunctionUrl
FunctionName:
Fn::GetAtt:
- HelloWorldFunction<unique-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:
- HelloWorldFunctionFunctionUrl<unique-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 堆栈
在此步骤中,您将使用 CDK CLI cdk 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 堆栈,因为该应用程序包含单个堆栈。
部署期间,CDK CLI 会在部署堆栈时显示进度信息。完成后,您可以前往 AWS CloudFormation 控制台查看 HelloCdkStack 堆栈。您也可以前往 Lambda 控制台查看 HelloWorldFunction 资源。
部署完成后,CDK CLI 将输出您的终端节点 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 通过函数 URL 调用 Lambda 函数,从而与应用程序进行交互。访问网址时,Lambda 函数会返回 Hello World! 消息。
要调用函数,请通过浏览器或命令行访问函数 URL。以下是示例:
$ curl https://<api-id>.lambda-url.<Region>.on.aws/
"Hello World!"%
步骤 11:修改应用程序
在此步骤中,您将修改调用 Lambda 函数时返回的消息。您可以使用 CDK CLI cdk 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 资源执行任何直接更新。您的代码定义了所需的资源的状态。要修改已部署的资源,您将使用 CDK CLI 将所需状态合成到新 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 HelloWorldFunction<unique-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
要创建此差异,CDK CLI 会向您的 AWS 账户查询堆栈的最新 AWS CloudFormation 模板。HelloCdkStack然后,它将最新的模板与刚从应用程序中合成的模板进行比较。
要实现您的更改,请运行 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:删除应用程序
在此步骤中,您将使用 CDK CLI cdk destroy 命令删除您的应用程序。此命令删除与您的 CDK CloudFormation 堆栈关联的堆栈,其中包括您创建的资源。
要删除应用程序,请运行 cdk destroy 命令并确认删除应用程序的请求。以下是示例:
$ cdk destroy
Are you sure you want to delete: HelloCdkStack (y/n)? y
HelloCdkStack: destroying... [1/1]
✅ HelloCdkStack: destroyed
后续步骤
恭喜您!您已完成本教程,并已使用 AWS CDK 成功创建、修改和删除 AWS 云端资源。现在,您已准备好开始使用 AWS CDK 了。
要了解有关以首选编程语言使用 AWS CDK 的更多信息,请参阅使用 AWS CDK 库。
有关其他资源,请参阅以下资源:
AWS CDK 是一个开源项目。要做出贡献,请参阅为 C AWS loud Development Kit 做出贡献 (AWS CDK)。