

これは AWS CDK v2 デベロッパーガイドです。旧版の CDK v1 は 2022 年 6 月 1 日にメンテナンスを開始し、2023 年 6 月 1 日にサポートを終了しました。

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# CDK コードのリファクタリング時にデプロイされたリソースを保持する
<a name="refactor"></a>

**重要**  
CDK のリファクタリングは、プレビューリリースに含まれ、変更される可能性があります。

 AWS Cloud Development Kit (AWS CDK) リファクタリングを使用すると、コンストラクトの名前変更、スタック間のリソースの移動、アプリケーションの再編成など、CDK コードをリファクタリングしながら、デプロイされたリソースを置き換えるのではなく保持できます。この機能は、意図せずにリソースを置き換えることなく、優れたソフトウェアエンジニアリングのベストプラクティスを維持するのに役立ちます。

## リソースの保持による CDK のリファクタリングとは
<a name="refactor-intro"></a>

CDK アプリケーションをデプロイすると、 AWS CloudFormation はリソースを論理 IDs。 AWS CDK はIDs とそのコンストラクトツリー内のパスに基づいてこれらの論理 ID を生成します。コンストラクトの ID を変更したり、コード内の別の場所に移動したりすると、 AWS CloudFormation は通常これを新しいリソースを作成し、古いリソースを削除するリクエストとして解釈します。データベース、ストレージバケット、キューなどのステートフルリソースの場合、この置き換えによりサービスの中断やデータ損失が発生する可能性があります。

CDK のリファクタリングは、次の方法でこの課題に対処します。
+ コードでリソースが移動または名前変更されたタイミングを検出する。
+  AWS CloudFormation のリファクタリング機能を使用して、基盤となる物理リソースを維持します。
+ 実際のリソースを置き換えずに論理 ID を更新する。
+ スタック全体でリソース間の参照を維持する。

CDK CLI `cdk refactor` コマンドまたは CDK Toolkit Library の `refactor` アクションを使用して、CDK のリファクタリングを実行できます。このガイドでは主に CLI アプローチについて説明しますが、基本原則は両方の方法に適用されます。Toolkit Library の使用の詳細については、「[CDK Toolkit Library を使用してプログラムによるアクションを実行する](toolkit-library.md)」を参照してください。

**重要**  
リファクタリングオペレーションは、新しいリソースの追加、リソースの削除、リソースプロパティの変更など、他のアクションとは別に単独で実行する必要があります。  
リソースの追加、削除、または変更とリファクタリングが必要な場合は、まずそれらの変更を個別にデプロイしてから、リファクタリングを使用してリソースを再編成する必要があります。

## CDK のリファクタリングの利点
<a name="refactor-benefits"></a>

CDK リファクタリングは AWS 、CDK 開発者に次の利点を提供します。
+  **コードの編成の改善** – リソースを置き換えることなく、CDK アプリケーションのコンストラクトの名前を変更し、再編成します。
+  **再利用可能なコンポーネントの作成** – デプロイされたリソースを保持しながら、重複したコードを再利用可能な L3 コンストラクトに抽出します。
+  **アーキテクチャの分離の強化** – スタック間でリソースを移動して、アプリケーションのさまざまな部分をより適切に分離します。
+  **リソースの偶発的な置き換えの防止** – コンストラクトの名前を変更するときに、意図しないリソースの再作成を回避します。
+  **サードパーティーライブラリの変更の軽減** – 依存するコンストラクトライブラリの論理 ID の変更からアプリケーションを保護します。
+  **ソフトウェアエンジニアリングのベストプラクティスの適用** – デプロイされたインフラストラクチャを損なうことなくコードをリファクタリングします。

## CDK CLI `cdk refactor` コマンドの仕組み
<a name="refactor-how"></a>

**重要**  
この機能を使用するすべてのコマンドで `--unstable=refactor` オプションを指定する必要があります。

まず、最初の CDK アプリケーションをデプロイして AWS 、アカウントにベースラインリソースを確立します。コンストラクトの名前変更やスタック間のリソースの移動など、CDK コードをリファクタリングした後、 `cdk refactor` コマンドを使用して、デプロイされたリソースのリファクタリングプロセスを開始します。

リファクタリングコマンドを実行すると、CDK CLI は現在のコードをデプロイされた状態と比較することでローカルの変更を検出します。CDK アプリケーションにデプロイされた状態とまったく同じリソースセットが含まれ、コンストラクトツリー内の場所のみが異なることを確認します。CDK CLI は、古いリソースの場所を新しい場所にマッピングするリファクタリングプランを生成します。CDK CLI は提案された変更を表示し、確認後、 AWS CloudFormation のリファクタリング API を使用してリソースIDs を置き換えずに更新します。

バックグラウンドでは、CDK CLI はプロパティを依存関係と比較することでどのリソースが移動されたかを決定し、機能的に同等だけれどもコンストラクトツリー内のパスが異なるリソースを特定します。リソースの追加、削除、または変更が検出されると、リファクタリングオペレーションはエラーメッセージ付きで拒否されます。

## CDK コードのリファクタリング時にリソースを保持する例
<a name="refactor-example"></a>

この例では、CDK CLI `cdk refactor` コマンドを使用して CDK コードをリファクタリングしながら、デプロイされたリソースを保持します。

CDK アプリケーションの例は、S3 バケット、CloudFront ディストリビューション、Lambda 関数を含む 1 つのスタックで構成されます。コンストラクトファイルは次のように構成されています。

```
App
└─ MyStack
   ├─ Bucket
   ├─ Distribution
   └─ Function
```

以下に、アプリケーション埋め込みリンクの例を示します。

```
const app = new cdk.App();
const myStack = new cdk.Stack(app, 'MyStack');

const bucket = new s3.Bucket(myStack, 'Bucket');
const distribution = new cloudfront.Distribution(myStack, 'Distribution', {
  defaultBehavior: { origin: new origins.S3Origin(bucket) }
});
const function = new lambda.Function(myStack, 'Function', {
  // function properties
});

// Synthesize the app
app.synth();
```

ここで、このコードを次のようにリファクタリングすると仮定します。

1. バケットの名前を `Bucket` からより記述的な `WebsiteOrigin` に変更する。

1. バケットとディストリビューションを新しい `WebStack` スタックに移動する。

リファクタリング後、コンストラクトツリーは次のようになります。

```
App
├─ WebStack
│  ├─ WebsiteOrigin
│  └─ Distribution
└─ MyStack
   └─ Function
```

リファクタリングされたコードは次のとおりです。

```
// Refactored structure
const app = new cdk.App();

// New WebStack with the bucket and distribution
const webStack = new cdk.Stack(app, 'WebStack');
const bucket = new s3.Bucket(webStack, 'WebsiteOrigin');
const distribution = new cloudfront.Distribution(webStack, 'Distribution', {
  defaultBehavior: { origin: new origins.S3Origin(bucket) }
});

// Original MyStack with just the function
const myStack = new cdk.Stack(app, 'MyStack');
const function = new lambda.Function(myStack, 'Function', {
  // function properties
});

// Synthesize the app
app.synth();
```

CDK リファクタリングを行わないと、論理 IDs が変更されるため、 AWS CloudFormation は新しいリソースを作成し、古いリソースを削除します。
+  `MyStack/Bucket/Resource` は `WebStack/WebsiteOrigin/Resource` になります。
+  `MyStack/Distribution/Resource` は `WebStack/Distribution/Resource` になります。

CDK リファクタリングでは、CDK CLI はこれらのパスの変更を検出し、 AWS CloudFormation のリファクタリング機能を使用して基盤となるリソースを維持します。`cdk refactor` を実行すると、CLI に次の変更が表示されます。

```
$ cdk refactor

The following resources were moved or renamed:

┌───────────────────────────────┬───────────────────────────────┬───────────────────────────────────┐
│ Resource Type                 │ Old Construct Path            │ New Construct Path                │
├───────────────────────────────┼───────────────────────────────┼───────────────────────────────────┤
│ AWS::S3::Bucket               │ MyStack/Bucket/Resource       │ WebStack/WebsiteOrigin/Resource   │
├───────────────────────────────┼───────────────────────────────┼───────────────────────────────────┤
│ AWS::CloudFront::Distribution │ MyStack/Distribution/Resource │ WebStack/Distribution/Resource    │
└───────────────────────────────┴───────────────────────────────┴───────────────────────────────────┘

Do you wish refactor these resources (y/n)?
```

`y` を入力して確認すると、CDK CLI にリファクタリングオペレーションの進行状況が表示されます。

```
Refactoring...
✅  Stack refactor complete
```

確認後、CDK CLI はリファクタリングオペレーションを実行し、両方のリソースを保持しながら、新しいコード構造に合わせて論理 ID を更新します。

同じマッピングは、スタック別に整理された `cdk diff` コマンドの出力にも表示されます。

```
Stack MyStack
Resources
[-] AWS::S3::Bucket Bucket Bucket1234567 destroy (OR move to WebStack.WebsiteOrigin1234567 via refactoring)
[-] AWS::CloudFront::Distribution Distribution Distribution1234567 destroy (OR move to WebStack.Distribution1234567)
...

Stack WebStack
Resources
[+] AWS::S3::Bucket WebsiteOrigin WebsiteOrigin1234567 (OR move from MyStack.Bucket1234567)
[+] AWS::CloudFront::Distribution Distribution Distribution1234567 (OR move from MyStack.Distribution1234567)
...
```

## CDK のリファクタリングの使用を開始する
<a name="_get_started_with_cdk_refactoring"></a>

リファクタリングの使用を開始するには、以下の前提条件を完了します。

 **最新のテンプレートを使用して環境をブートストラップする**   
CDK のリファクタリング機能では、ブートストラップスタックに新しいアクセス許可が必要です。必要なアクセス許可を確実に持つようにするには、最新のテンプレートを使用して環境をブートストラップします。  

```
cdk bootstrap
```
ブートストラップの詳細については、「[AWS CDK のブートストラップ環境](bootstrapping-env.md)」を参照してください。

 **最新の CDK CLI バージョンをインストールする**   
CDK のリファクタリングでは、CDK CLI の最新バージョンが必要です。最新バージョンがあることを確認します。  

```
npm install -g aws-cdk
```
インストール手順については、「[AWS CDK の使用を開始する](getting-started.md)」を参照してください。

## オーバーライドファイルを使用してリファクタリングのあいまいさを解決する
<a name="override-file"></a>

CDK CLI は、コードとデプロイされたリソースとの比較に基づいて、すべてのリソースマッピングを自動的に計算します。ほとんどの場合、この自動検出はうまく機能しますが、CLI が単独で解決できないあいまいさに遭遇することがあります。CDK CLI にガイダンスを提供するには、オーバーライドファイルを使用します。

 **あいまいさを解決するオーバーライドファイルを作成する**   
オーバーライドファイルは、CDK CLI がリソースのリファクタリング解決を決定できない場合にマッピングを提供する JSON ファイルです。ファイルには、環境別に整理されたリソースマッピングが含まれています。  

```
{
    "environments": [
        {
            "account": "123456789012",
            "region": "us-east-2",
            "resources": {
                "StackA.OldName": "StackB.NewName",
                "StackC.Foo": "StackC.Bar"
            }
        }
    ]
}
```
このファイルでは:  
+ `environments` 配列には、アカウントとリージョンがある 1 つ以上の環境エントリが含まれます。
+ 各環境内で、 `resources` オブジェクトにはマッピングが含まれます。
+ キーは、現在の場所を `<stack name>.<logical ID>` 形式で表します。
+ 値は新しい場所を同じ形式で表します。
CDK CLI でオーバーライドファイルを使用するには:  

```
cdk refactor --override-file=overrides.json
```

## 複数の環境にわたるスタックのリファクタリング
<a name="refactor-environments"></a>

CDK アプリケーションには、異なる環境 (AWS アカウントとリージョン) にデプロイする複数のスタックを含めることができます。このようなアプリケーションでのリファクタリング中にリソースを保持する場合、CDK CLI は特定の方法で環境を処理します。
+ CLI は環境ごとにスタックをグループ化し、各環境で個別にリファクタリングを実行します。
+ リファクタリング中にスタック間でリソースを移動できますが、移動に関係するすべてのスタックが同じ環境にある必要があります。
+ 環境間でリソースを移動しようとすると、エラーが発生します。

この動作により、リソースは元の AWS アカウントとリージョン内に留まります。これは、CloudFormation リソースをアカウントまたはリージョンの境界を越えて物理的に移動できないために必要です。

例えば、CDK アプリケーションが開発環境と本番環境の両方のスタックを定義している場合、リファクタリングオペレーションは各環境で個別に実行されます。リソースは、開発環境内または本番稼働環境内のスタック間で移動できますが、開発から本番稼働、またはその逆に移動することはできません。

## 置き換えるように設計されたリソースの処理
<a name="refactor-replaceable-resources"></a>

一部の CDK コンストラクトは、設計の一環として CloudFormation のリソースの置き換え動作に依存しています。例えば、API Gateway の `Deployment` と Lambda の `Version` コンストラクトは、プロパティが変更されたときに新しいリソースを作成するように設計されています。

リファクタリングするときは、リソースの置き換えにつながる変更を含めないでください。それ以外の場合、CDK CLI はこれらのリソースを検出して保持することがあります。つまり、置き換えるように設計されたリソースは、リファクタリングオペレーションとは別に処理する必要があります。

置き換えるように設計されたリソースを適切に管理するには:

1. まず、アプリケーションをデプロイして、必要に応じてこれらのリソースを置き換えます。

1. 次に、リファクタリングオペレーションを個別に実行してコードを再編成します。

この 2 ステップのアプローチにより、置き換えられるように設計されたリソースが適切に処理される一方で、他のリソースの CDK リファクタリングのメリットを享受できます。

## 一般的な考慮事項と制限事項
<a name="refactor-considerations"></a>

CDK リファクタリング中にリソースを保持するときは、以下の考慮事項に留意してください。
+  **環境の制約**: リソースは、同じ環境内のスタック間でのみ移動できます。環境間の移動はサポートされていません。
+  **あいまいさ**: 複数の同一のリソースを同時に名前を変更した場合、CDK CLI は正しいマッピングを自動的に判断できない可能性があります。このような場合は、オーバーライドファイルを使用して明示的なマッピングを提供する必要があります。
+  **ブートストラップ要件**: リファクタリング中にリソースを保持するには、必要なアクセス許可を含む最新バージョンでブートストラップスタックを更新する必要があります。
+  **特定のコンストラクトを除外**: API ゲートウェイの `Deployment` や Lambda の `Version` などの一部のコンストラクトは、リソースの置き換えに依存し、リファクタリングから自動的に除外されます。

## CI/CD パイプラインを使用したリファクタリング
<a name="refactor-pipelines"></a>

CI/CD パイプラインでリファクタリング機能を使用するには、パイプラインの一部として CDK CLI を実行できる必要があります。リファクタリングを CI/CD ワークフローに統合する際の重要な考慮事項を以下に示します。

 **CI/CD でリファクタリングを使用するための前提条件**   
この機能を利用するには、CI/CD 環境で CDK CLI を使用できる必要があります。

 **リファクタリングをパイプラインワークフローに統合する**   
CI/CD パイプラインでのデプロイに CLI を使用している場合、スクリプトは通常次のようになります。  

```
...
cdk deploy <stack filter>
...
```
ワークフローの一部としてリファクタリングを含める場合、基本的な例は次の通りです。  

```
...
cdk refactor <stack filter>
cdk deploy <stack filter>
...
```
パイプラインの別のステップとしてリファクタリングすることもできます。

 **リファクタリングの失敗の処理**   
リファクタリングとともに実際のリソース変更がコードに含まれている場合、`cdk refactor` は失敗することに注意してください。パイプラインではリファクタリングを自動的に呼び出すため、潜在的な障害を処理する必要があります。  

```
# Allow refactoring to fail but continue the pipeline
cdk refactor <stack filter> || true
cdk deploy <stack filter>
```
または、リファクタリングが正常に実行されるまでデプロイが行われないようにすることもできます。  

```
# Only deploy if refactoring succeeds
cdk refactor <stack filter> && cdk deploy <stack filter>
```

 **CI/CD 環境のベストプラクティス**   
CI/CD パイプラインでリファクタリングを効果的に使用するには:  
+  **リファクタリングを他の変更と分離する**: リファクタリングオペレーションは、リソースの追加、削除、または変更とは別にする必要があります。パイプラインでは、リファクタリング専用のコミットとデプロイを行うことを検討してください。
+  **オーバーライドファイルを適切に使用する**: オーバーライドファイルは、あいまいなケースを解決するためのフォールバックとしてのみ CDK CLI で使用されることを理解します。
+  **パイプラインで `--force` が不要**: CI/CD パイプラインなどの非インタラクティブ環境では、CDK リファクタリングコマンドは確認を促すことなく自動的に続行されます。`--force` オプションは、インタラクティブ環境でのみ必要です。

## 関連リソース
<a name="refactor-resources"></a>

CDK CLI `cdk refactor` コマンドのオプションと引数については、「` cdk refactor `」を参照してください。

CDK Toolkit Library の `refactor` アクションの使用を開始するには、「[CDK Toolkit Library を使用してプログラムによるアクションを実行する](toolkit-library.md)」を参照してください。