

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

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

# 从 AWS CDK v1 迁移到 AWS CDK v2
<a name="migrating-v2"></a>

AWS 云开发工具包 (AWS CDK) 的版本 2 旨在让您更轻松地以首选编程语言编写基础设施即代码。本主题介绍 AWS CDK 的 v1 和 v2 之间的变更情况。

**提示**  
要识别使用 AWS CDK v1 部署的堆栈，请使用 [awscdk-v1-stack-finder](https://www.npmjs.com/package/awscdk-v1-stack-finder) 实用程序。

从 AWS CDK v1 到 CDK v2 的主要变更如下。
+  AWS CDK v2 将 AWS 构造库的稳定部分（包括核心库）都整合到单个包 `aws-cdk-lib` 中。开发人员无需再为他们使用的各种 AWS 服务安装额外的软件包。这种单软件包方法还意味着您不必同步各种 CDK 库软件包的版本。

  L1 (CfnXXXX) 构造表示 AWS CloudFormation 中确切可用的资源始终被视为稳定，因此包含在 `aws-cdk-lib` 中。
+ 实验性模块不包含在 `aws-cdk-lib` 中，我们仍在与社区合作在其中开发新的 [L2 或 L3 构造](constructs.md#constructs-lib-levels)。相反，它们是作为单独的软件包进行分发的。实验软件包以 `alpha` 后缀和语义版本号命名。语义版本号与和其兼容的 AWS 构造库的第一个版本相匹配，也带有 `alpha` 后缀。构造在被认定为稳定后会移入 `aws-cdk-lib`，从而允许主构造库遵循严格的语义版本控制。

  在服务级别指定稳定性。例如，如果我们开始为 Amazon AppFlow 创建一个或多个 [L2 构造](constructs.md#constructs-lib-levels)（在撰写本文时只有 L1 构造），则这些构造会首先出现在名为 `@aws-cdk/aws-appflow-alpha` 的模块中。然后，当我们认为新构造可以满足客户的基本需求时，这些构造就会移入 `aws-cdk-lib`。

  模块被认定为稳定且合并到 `aws-cdk-lib` 中后，就会使用下一个项目符号中描述的“BetAN”约定添加新的 API。

  每次发布 AWS CDK 时都会发布实验性模块的新版本。但是在大多数情况下，它们不需要同时发布。您可以随时升级 `aws-cdk-lib` 或实验性模块。有一种情况例外，即当两个或多个相关的实验性模块相互依赖时，它们的版本必须相同。
+ 对于正在添加新功能的稳定模块，新 API（无论是全新的构造还是现有构造上的新方法或属性）都会在工作进行时获得 `Beta1` 后缀。（当需要进行重大更改时，接下来后缀为 `Beta2`、`Beta3`，依此类推。） 当认定 API 稳定时，会添加不带后缀的 API 版本。将弃用除最新方法（无论是测试版还是最终版）之外的所有方法。

  例如，如果我们在构造中添加一个新方法 `grantPower()`，其最初会显示为 `grantPowerBeta1()`。如果需要进行重大更改（例如，新的必需参数或属性），则该方法的下一个版本将被命名为 `grantPowerBeta2()`，依此类推。当工作完成并且 API 最终确定后，将添加方法 `grantPower()`（不带后缀），并弃用 BetaN 方法。

  在下一个主要版本（3.0）发布之前，所有测试版 API 都将保留在构造库中，并且其签名不会改变。如果您使用这些 API，会看到弃用警告，因此您应尽早转到 API 的最终版本。但是，任何未来的 AWS CDK 2.x 版本都不会破坏您的应用程序。
+ `Construct` CDK 类已与相关类型一起从 AWS 中提取到单独的库中。这样做是为了支持将构造编程模型应用于其他领域。如果您正在编写自己的构造或使用相关的 API，则必须将 `constructs` 模块声明为依赖项，并对导入进行细微的更改。如果您使用的是高级功能（例如连接到 CDK 应用程序生命周期），则可能需要进行更多更改。有关完整详细信息，请参阅 [RFC](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0192-remove-constructs-compat.md#release-notes)。
+ AWS CDK v1.x 及其构造库中已弃用的属性、方法和类型已从 CDK v2 API 中完全删除。在大多数支持的语言中，这些 API 会在 v1.x 下生成警告，因此您可能已经迁移到替换 API。GitHub 中提供 CDK v1.x 中[已弃用 API 的完整列表](https://github.com/aws/aws-cdk/blob/master/DEPRECATED_APIs.md)。
+ 在 AWS CDK v1.x 中受功能标志限制的行为默认在 CDK v2 中处于启用状态。不再需要早期的功能标志，而且在大多数情况下也不支持这些标志。在非常特殊的情况下，仍有一些标志可用于让您恢复到 CDK v1 行为。有关更多信息，请参阅[更新功能标志](#migrating-v2-v1-upgrade-cdk-json)。
+ 对于 CDK v2，必须使用现代引导堆栈引导部署到的环境。不再支持旧版引导堆栈（即 v1 下的默认堆栈）。此外，CDK v2 还需要新版本的现代堆栈。要升级现有环境，请对其重新进行引导。无需再设置任何功能标志或环境变量即可使用现代引导堆栈。

**重要**  
现代引导模板可以有效地向 `--trust` 列表中的任何 AWS 账户授予 `--cloudformation-execution-policies` 隐含的权限。默认情况下，这会扩展对引导账户中任何资源的读取和写入权限。请务必使用您熟悉的策略和可信账户来[配置引导堆栈](bootstrapping-customizing.md)。

## 新的先决条件
<a name="migrating-v2-prerequisites"></a>

AWS CDK v2 的大多数要求都与 AWS CDK v1.x 相同。此处列出了其他要求。
+ 对于 TypeScript 开发人员来说，需要使用 TypeScript 3.8 或更高版本。
+ 需要新版本的 CDK Toolkit 才能与 CDK v2 一起使用。CDK v2 现已正式发布，因此安装 CDK Toolkit时，v2 是默认版本。该版本向后兼容 CDK v1 项目，因此除非要创建 CDK v1 项目，否则无需安装早期版本。要进行升级，请发出 `npm install -g aws-cdk` 命令。

## 从 AWS CDK v2 开发人员预览版升级
<a name="migrating-v2-dp-upgrade"></a>

如果您使用的是 CDK v2 开发人员预览版，则您的项目中就有 AWS CDK 候选发布版本（例如 `2.0.0-rc1`）的依赖项。将其更新为 `2.0.0`，然后更新项目中安装的模块。

**Example**  
 `npm install` 或者`yarn install` 
 `npm install` 或者`yarn install` 

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

```
mvn package
```

```
dotnet restore
```

```
go get
```

更新依赖项后，发出 `npm update -g aws-cdk` 命令将 CDK Toolkit 更新到发布版本。

## 从 AWS CDK v1 迁移到 CDK v2
<a name="migrating-v2-v1-uppgrade"></a>

要将您的应用程序迁移到 AWS CDK v2，请先更新 `cdk.json` 中的功能标志。然后，根据需要更新应用程序的依赖项和导入项，以适应其编写的编程语言。

### 更新至最新的 v1
<a name="migrating-v2-v1-recent-v1"></a>

我们看到许多客户通过一个步骤就从旧版本的 AWS CDK v1 升级到最新版本的 v2。尽管做到这一点当然是可能的，但就既要跨多年的变更进行升级（不幸的是，可能并非所有这些变更都进行了与如今相同数量的演化测试），还要跨具有新默认值和不同代码组织的版本进行升级。

为了获得最安全的升级体验并更能够轻松地诊断任何意外更改的来源，我们建议您将这两个步骤分开：首先升级到最新的 v1 版本，然后再切换到 v2。

### 更新功能标志
<a name="migrating-v2-v1-upgrade-cdk-json"></a>

如果存在以下 v1 功能标志，请从 `cdk.json` 中将其删除，因为默认情况下，这些标志在 AWS CDK v2 中均处于活动状态。如果这些标志的旧效应对您的基础设施很重要，则需要对源代码进行更改。有关更多信息，请参阅 [GitHub 上的标志列表](https://github.com/aws/aws-cdk/blob/main/packages/%40aws-cdk/cx-api/FEATURE_FLAGS.md)。
+  `@aws-cdk/core:enableStackNameDuplicates` 
+  `aws-cdk:enableDiffNoFail` 
+  `@aws-cdk/aws-ecr-assets:dockerIgnoreSupport` 
+  `@aws-cdk/aws-secretsmanager:parseOwnedSecretName` 
+  `@aws-cdk/aws-kms:defaultKeyPolicies` 
+  `@aws-cdk/aws-s3:grantWriteWithoutAcl` 
+  `@aws-cdk/aws-efs:defaultEncryptionAtRest` 

可以将少数 v1 功能标记设置为 `false`，以恢复到特定的 AWS CDK v1 行为；有关完整参考，请参阅[恢复到 v1 行为](featureflags.md#featureflags-disabling)或 GitHub 上的列表。

对于这两种类型的标志，请使用 `cdk diff` 命令检查对合成模板的更改，以查看对任何这些标志进行更改是否会影响您的基础设施。

### CDK Toolkit 兼容性
<a name="work-with-cdk-v2-cli"></a>

CDK v2 需要 CDK Toolkit 的 v2 或更高版本。此版本向后兼容 CDK v1 应用程序。因此，无论项目使用 v1 还是 v2，您都可以在所有 AWS CDK 项目中使用全局安装的 CDK 工具包版本。有一个例外情况，即 CDK Toolkit v2 仅创建 CDK v2 项目。

如果您需要同时创建 v1 和 v2 CDK 项目，**请勿全局安装 CDK Toolkit v2**。（如果您已经安装了该版本，请将其删除：`npm remove -g aws-cdk`。） 要调用 CDK Toolkit，请根据需要使用 `npx` 来运行 CDK Toolkit 的 v1 或 v2。

```
npx aws-cdk@1.x init app --language typescript
npx aws-cdk@2.x init app --language typescript
```

**提示**  
设置命令行别名，以便您可以使用 `cdk` 和 `cdk1` 命令调用所需版本的 CDK Toolkit。  

```
alias cdk1="npx aws-cdk@1.x"
alias cdk="npx aws-cdk@2.x"
```

```
doskey cdk1=npx aws-cdk@1.x $*
doskey cdk=npx aws-cdk@2.x $*
```

### 更新依赖项和导入项
<a name="migrating-v2-v1-upgrade-dependencies"></a>

更新应用程序的依赖项，然后安装新的软件包。最后，更新代码中的导入项。

**Example**    
 **应用程序**：  
对于 CDK 应用程序，请按如下方式更新 `package.json`。删除 v1 风格的单个稳定模块的依赖项，并建立应用程序所需的最低版本的 `aws-cdk-lib`（此处为 2.0.0）。  
实验性构造在单独的、独立版本控制的软件包中提供，其名称以 `alpha` 和 alpha 版本号为结尾。alpha 版本号对应于与之兼容的 `aws-cdk-lib` 的第一个版本。此处我们已将 `aws-codestar` 固定为 v2.0.0-alpha.1。  

```
{
  "dependencies": {
    "aws-cdk-lib": "^2.0.0",
    "@aws-cdk/aws-codestar-alpha": "2.0.0-alpha.1",
    "constructs": "^10.0.0"
  }
}
```  
 **构造库**   
对于构造库，请为应用程序建立所需的 `aws-cdk-lib` 的最低版本（此处为 2.0.0），然后按如下方式更新 `package.json`。  
请注意，`aws-cdk-lib` 同时显示为对等依赖项和开发依赖项。  

```
{
  "peerDependencies": {
    "aws-cdk-lib": "^2.0.0",
    "constructs": "^10.0.0"
  },
  "devDependencies": {
    "aws-cdk-lib": "^2.0.0",
    "constructs": "^10.0.0",
    "typescript": "~3.9.0"
  }
}
```
在发布兼容 v2 的库时，您应该对库的版本号执行主要版本升级，因为这对库使用者来说是一个重大变更。单个库无法同时支持 CDK v1 和 v2。要继续为仍在使用 v1 的客户提供支持，您可以并行维护早期版本，或者为 v2 创建新的包。  
您可以自行决定想继续支持 AWS CDK v1 客户多长时间。您可能会从 CDK v1 本身的生命周期中获得提示，该版本于 2022 年 6 月 1 日进入维护阶段，并于 2023 年 6 月 1 日终止生命周期。有关完整详细信息，请参阅 [AWS CDK 维护策略](https://github.com/aws/aws-cdk-rfcs/blob/master/text/0079-cdk-2.0.md#aws-cdk-maintenance-policy)。  
 **库和应用程序**   
通过运行 `npm install` 或 `yarn install` 命令来安装新的依赖项。  
将您的导入更改为从新的 `constructs` 模块导入 `Construct`、从 `aws-cdk-lib` 的顶层导入核心类型（例如 `App` 和 `Stack`），以及从 `aws-cdk-lib` 下的命名空间导入您所用服务的稳定构造库模块。  

```
import { Construct } from 'constructs';
import { App, Stack } from 'aws-cdk-lib';                 // core constructs
import { aws_s3 as s3 } from 'aws-cdk-lib';               // stable module
import * as codestar from '@aws-cdk/aws-codestar-alpha';  // experimental module
```
按如下方式更新 `package.json`。删除 v1 风格的单个稳定模块的依赖项，并建立应用程序所需的最低版本的 `aws-cdk-lib`（此处为 2.0.0）。  
实验性构造在单独的、独立版本控制的软件包中提供，其名称以 `alpha` 和 alpha 版本号为结尾。alpha 版本号对应于与之兼容的 `aws-cdk-lib` 的第一个版本。此处我们已将 `aws-codestar` 固定为 v2.0.0-alpha.1。  

```
{
  "dependencies": {
    "aws-cdk-lib": "^2.0.0",
    "@aws-cdk/aws-codestar-alpha": "2.0.0-alpha.1",
    "constructs": "^10.0.0"
  }
}
```
通过运行 `npm install` 或 `yarn install` 命令来安装新的依赖项。  
更改应用程序的导入项以执行以下操作：  
+ 从新的 `constructs` 模块导入 `Construct`
+ 从 `aws-cdk-lib` 的顶层导入核心类型，例如 `App` 和 `Stack` 
+ 从 `aws-cdk-lib` 下的命名空间导入 AWS 构造库模块 

```
const { Construct } = require('constructs');
const { App, Stack } = require('aws-cdk-lib');              // core constructs
const s3 = require('aws-cdk-lib').aws_s3;                   // stable module
const codestar = require('@aws-cdk/aws-codestar-alpha');    // experimental module
```
按如下方式更新 `requirements.txt` 或 `setup.py` 中的 `install_requires` 定义。删除 v1 风格的单个稳定模块的依赖项。  
实验性构造在单独的、独立版本控制的软件包中提供，其名称以 `alpha` 和 alpha 版本号为结尾。alpha 版本号对应于与之兼容的 `aws-cdk-lib` 的第一个版本。此处我们已将 `aws-codestar` 固定为 v2.0.0alpha1。  

```
install_requires=[
     "aws-cdk-lib>=2.0.0",
     "constructs>=10.0.0",
     "aws-cdk.aws-codestar-alpha>=2.0.0alpha1",
     # ...
],
```
使用 `pip uninstall` 卸载已安装在应用程序虚拟环境中的任何其他版本的 AWS CDK 模块。然后使用 `python -m pip install -r requirements.txt` 安装新的依赖项。
更改应用程序的导入项以执行以下操作：  
+ 从新的 `constructs` 模块导入 `Construct`
+ 从 `aws_cdk` 的顶层导入核心类型，例如 `App` 和 `Stack` 
+ 从 `aws_cdk` 下的命名空间导入 AWS 构造库模块 

```
from constructs import Construct
from aws_cdk import App, Stack                    # core constructs
from aws_cdk import aws_s3 as s3                  # stable module
import aws_cdk.aws_codestar_alpha as codestar     # experimental module

# ...

class MyConstruct(Construct):
    # ...

class MyStack(Stack):
    # ...

s3.Bucket(...)
```
在 `pom.xml` 中，删除稳定模块的所有 `software.amazon.awscdk` 依赖项，并将其替换为 `software.constructs`（用于 `Construct`）和 `software.amazon.awscdk` 的依赖项。  
实验性构造在单独的、独立版本控制的软件包中提供，其名称以 `alpha` 和 alpha 版本号为结尾。alpha 版本号对应于与之兼容的 `aws-cdk-lib` 的第一个版本。此处我们已将 `aws-codestar` 固定为 v2.0.0-alpha.1。  

```
<dependency>
    <groupId>software.amazon.awscdk</groupId>
    <artifactId>aws-cdk-lib</artifactId>
    <version>2.0.0</version>
</dependency><dependency>
    <groupId>software.amazon.awscdk</groupId>
    <artifactId>code-star-alpha</artifactId>
    <version>2.0.0-alpha.1</version>
</dependency>
<dependency>
    <groupId>software.constructs</groupId>
    <artifactId>constructs</artifactId>
    <version>10.0.0</version>
</dependency>
```
通过运行 `mvn package`命令来安装新的依赖项。  
更改您的代码以执行以下操作：  
+ 从新的 `software.constructs` 库中导入 `Construct`
+ 从 `software.amazon.awscdk` 中导入核心类，例如 `Stack` 和 `App` 
+ 从 `software.amazon.awscdk.services` 中导入服务构造 

```
import software.constructs.Construct;
import software.amazon.awscdk.Stack;
import software.amazon.awscdk.StackProps;
import software.amazon.awscdk.App;
import software.amazon.awscdk.services.s3.Bucket;
import software.amazon.awscdk.services.codestar.alpha.GitHubRepository;
```
升级 C\$1 CDK 应用程序依赖项的最直接方法是手动编辑 `.csproj` 文件。删除所有稳定 `Amazon.CDK.*` 软件包引用，并将其替换为对 `Amazon.CDK.Lib` 和 `Constructs` 软件包的引用。  
实验性构造在单独的、独立版本控制的软件包中提供，其名称以 `alpha` 和 alpha 版本号为结尾。alpha 版本号对应于与之兼容的 `aws-cdk-lib` 的第一个版本。此处我们已将 `aws-codestar` 固定为 v2.0.0-alpha.1。  

```
<PackageReference Include="Amazon.CDK.Lib" Version="2.0.0" />
<PackageReference Include="Amazon.CDK.AWS.Codestar.Alpha" Version="2.0.0-alpha.1" />
<PackageReference Include="Constructs" Version="10.0.0" />
```
通过运行 `dotnet restore`命令来安装新的依赖项。  
按如下方式更改源文件中的导入项。  

```
using Constructs;                   // for Construct class
using Amazon.CDK;                   // for core classes like App and Stack
using Amazon.CDK.AWS.S3;            // for stable constructs like Bucket
using Amazon.CDK.Codestar.Alpha;    // for experimental constructs
```
发出 `go get` 命令将您的依赖项更新到最新版本，并更新项目的 `.mod` 文件。

## 在部署之前测试迁移的应用程序
<a name="migrating-v2-diff"></a>

在部署堆栈之前，请使用 `cdk diff` 来检查资源是否存在意外更改。预计**不会**对逻辑 ID 进行更改（这会导致资源替换）。

预期更改包括但不限于：
+ 更改 `CDKMetadata` 资源。
+ 更新资产哈希值。
+ 更改与新式堆栈合成相关的内容。如果您的应用程序使用了 v1 中的旧版堆栈合成器，则适用。
+ 添加 `CheckBootstrapVersion` 规则。

升级到 AWS CDK v2 本身通常不会导致意外更改。通常，先前由功能标志更改的弃用行为才会导致这种结果。这是从 CDK 1.85.x 之前的版本升级会出现的情况。升级到最新的 v1.x 版本时，您会看到相同的更改。您通常可以执行以下操作来解决该问题：

1. 将您的应用程序升级到最新的 v1.x 版本

1. 删除功能标志

1. 根据需要修改您的代码

1. 部署

1. 升级到 v2

**注意**  
如果升级后的应用程序在两阶段升级后无法部署，请[报告此问题](https://github.com/aws/aws-cdk/issues/new/choose)。

当您准备好在应用程序中部署堆栈时，可以考虑先部署一个副本，以便对其进行测试。执行此操作的最简单方法是将其部署到其他区域。但是，您也可以更改堆栈的 ID。测试完成后，请务必使用 `cdk destroy` 销毁测试副本。

## 故障排除
<a name="migrating-v2-trouble"></a>

 **导入时出现 TypeScript `'from' expected` 或 `';' expected` 错误**   
升级到 TypeScript 3.8 或更高版本。

 **运行“cdk bootstrap”**   
如果您看到以下错误：  

```
❌  MyStack failed: Error: MyStack: SSM parameter /cdk-bootstrap/hnb659fds/version not found. Has the environment been bootstrapped? Please run 'cdk bootstrap' (see https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html)
    at CloudFormationDeployments.validateBootstrapStackVersion (.../aws-cdk/lib/api/cloudformation-deployments.ts:323:13)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
MyStack: SSM parameter /cdk-bootstrap/hnb659fds/version not found. Has the environment been bootstrapped? Please run 'cdk bootstrap' (see https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html)
```
 AWS CDK v2 需要更新的引导堆栈，此外，所有 v2 部署都需要引导资源。（使用 v1，您无需进行引导即可部署简单的堆栈。） 有关完整详细信息，请参阅 [AWS CDK 引导](bootstrapping.md)。

## 查找 v1 堆栈
<a name="finding-v1-stacks"></a>

将 CDK 应用程序从 v1 迁移到 v2 时，您可能需要识别使用 v1 创建的已部署的 AWS CloudFormation 堆栈。为此，请运行以下命令：

```
npx awscdk-v1-stack-finder
```

有关使用详细信息，请参阅 awscdk-v1-stack-finder [README](https://github.com/cdklabs/awscdk-v1-stack-finder/blob/main/README.md)。