

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

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

# 一般的な AWS CDK の問題のトラブルシューティング
<a name="troubleshooting"></a>

このトピックでは、AWS CDK に関する次の問題のトラブルシューティング方法について説明します。
+  [AWS CDK を更新すると、AWS CDK ツールキット (CLI) が AWS コンストラクトライブラリとの不一致を報告する](#troubleshooting-toolkit) 
+  [AWS CDK スタックをデプロイすると、NoSuchBucket エラーが表示される](#troubleshooting-nobucket) 
+  [AWS CDK スタックをデプロイすると、forbidden: null メッセージが表示される](#troubleshooting-forbidden-null) 
+  [AWS CDK スタックを合成すると、cdk.json または \~/.cdk.json のコマンドラインで --app が必要であるというメッセージが表示される](#troubleshooting-app-required) 
+  [AWS CDK スタックを合成すると、AWS CloudFormation テンプレートに含まれるリソースが多すぎるためにエラーが発生する](#troubleshooting-resource-count) 
+  [Auto Scaling グループまたは VPC に 3 つ (またはそれ以上) のアベイラビリティーゾーンを指定したが、2 つしかデプロイされない](#troubleshooting-availability-zones) 
+  [cdk 破棄を発行しても、S3 バケット DynamoDB テーブルまたはその他のリソースが削除されない](#troubleshooting-resource-not-deleted) 

## AWS CDK を更新すると、AWS CDK Toolkit (CLI) が AWS コンストラクトライブラリとの不一致を報告する
<a name="troubleshooting-toolkit"></a>

AWS CDK Toolkit (`cdk` コマンドを提供) のバージョンは、メインの AWS コンストラクトライブラリモジュールのバージョンである `aws-cdk-lib` と少なくとも同等である必要があります。Toolkit は下位互換性があるように設計されています。最新の 2.x バージョンの Toolkit は、ライブラリの任意の 1.x または 2.x リリースで使用できます。このため、このコンポーネントをグローバルにインストールして最新の状態に保つことをお勧めします。

```
npm update -g aws-cdk
```

複数のバージョンの AWS CDK Toolkit を使用する必要がある場合、特定バージョンのツールキットをプロジェクトフォルダにローカルにインストールします。

TypeScript または JavaScript を使用している場合、プロジェクトディレクトリに CDK Toolkit のバージョニングされたローカルコピーが既に含まれています。

別の言語を使用している場合、`npm` を使用して AWS CDK Toolkit をインストールし、`-g` フラグを省略して目的のバージョンを指定します。例:

```
npm install aws-cdk@2.0
```

ローカルにインストールされた AWS CDK Toolkit を実行するには、`cdk` のみではなく `npx aws-cdk` コマンドを使用します。例:

```
npx aws-cdk deploy MyStack
```

 `npx aws-cdk` は、AWS CDK Toolkit のローカルバージョンが存在する場合は、それを実行します。プロジェクトにローカルインストールがない場合、グローバルバージョンに戻ります。`cdk` が常にこの方法で呼び出されるように、シェルエイリアスを設定すると便利な場合があります。

**Example**  

```
alias cdk="npx aws-cdk"
```

```
doskey cdk=npx aws-cdk $*
```

## AWS CDK スタックをデプロイすると、`NoSuchBucket` エラーが表示される
<a name="troubleshooting-nobucket"></a>

AWS 環境はブートストラップされていないため、デプロイ中にリソースを保持する Amazon S3 バケットがありません。次のコマンドを使用し、ステージングバケットやその他の必要なリソースを作成できます。

```
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```

予想しない AWS 料金が発生しないように、AWS CDK は環境を自動的にブートストラップしません。デプロイする各環境を明示的にブートストラップする必要があります。

デフォルトでは、ブートストラップリソースは現在の AWS CDK アプリケーションのスタックで使用されるリージョンに作成されます。または、ローカルの AWS プロファイルで指定されたリージョン (`aws configure` によって設定) で、そのプロファイルのアカウントを使用して作成されます。コマンドラインに、次のように別のアカウントおよびリージョンを指定できます。(アプリのディレクトリにない場合、アカウントおよびリージョンを指定する必要があります)

```
cdk bootstrap aws://ACCOUNT-NUMBER/REGION
```

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

## AWS CDK スタックをデプロイすると、`forbidden: null` メッセージが表示される
<a name="troubleshooting-forbidden-null"></a>

ブートストラップリソースを必要とするスタックをデプロイしていますが、書き込み許可のない IAM ロールまたはアカウントを使用しています。(アセットを含むか、50K を超える AWS CloudFormation テンプレートを合成するスタックをデプロイする場合、ステージングバケットは使用されます) エラーメッセージに記載されているバケットに対して `s3:*` アクションを実行する許可を持つアカウントまたはロールを使用します。

## AWS CDK スタックを合成すると、`--app is required either in command-line, in cdk.json or in ~/.cdk.json` メッセージが表示される
<a name="troubleshooting-app-required"></a>

このメッセージは通常、`cdk synth` を発行するときに AWS CDK プロジェクトのメインディレクトリにないことを意味します。`cdk init` コマンドによって作成されたこのディレクトリの `cdk.json` ファイルには、AWS CDK アプリの実行 (およびそれに伴う合成) に必要なコマンドラインが含まれています。例えば、TypeScript アプリの場合、デフォルトの `cdk.json` は次のようになります。

```
{
  "app": "npx ts-node bin/my-cdk-app.ts"
}
```

AWS CDK Toolkit がそこで「`cdk.json`」を見つけてアプリを正常に実行できるように、プロジェクトのメインディレクトリでのみ `cdk` コマンドを発行することをお勧めします。

何らかの理由でこれが実用的でない場合、AWS CDK Toolkit は他の 2 つの場所でアプリのコマンドラインを検索します。
+ ホームディレクトリの `cdk.json` で
+ `-a` オプションを使用して `cdk synth` コマンド自体で

例えば、次のように TypeScript アプリからスタックを合成できます。

```
cdk synth --app "npx ts-node my-cdk-app.ts" MyStack
```

## AWS CDK スタックを合成すると、AWS CloudFormation テンプレートに含まれるリソースが多すぎるためにエラーが発生する
<a name="troubleshooting-resource-count"></a>

AWS CDK は AWS CloudFormation テンプレートを生成してデプロイします。 AWSCloudFormation には、スタックに含めることができるリソースの数にハード制限があります。AWS CDK を使用すると、この制限に対して予想よりも速く達する可能性があります。

**注記**  
これを記述している時点では、AWS CloudFormation リソース制限は 500 です。現在のリソース制限については、「[AWS CloudFormation クォータ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html)」を参照してください。

AWS コンストラクトライブラリの上位のインテントベースコンストラクトでは、ログ記録、キー管理、承認、その他の目的に必要な補助リソースが自動的にプロビジョニングされます。例えば、あるリソースに別のリソースへのアクセスを許可すると、関連サービスが通信するために必要な IAM オブジェクトが生成されます。

私たちの経験では、インテントベースのコンストラクトを実際に使用すると、コンストラクトごとに 1 ～ 5 AWS CloudFormation リソースになりますが、異なる場合があります。サーバーレスアプリケーションの場合、API エンドポイントごとに 5 ～ 8 AWS リソースが一般的です。

抽象化の高いレベルを表すパターンを使用すると、さらに少ないコードで AWS リソースをさらに多く定義できます。「[例: AWS CDK を使用して AWS Fargate サービスを作成する](ecs-example.md)」の AWS CDK コードは、例えば、3 つのコンストラクトのみを定義しながら、50 を超える AWS CloudFormation リソースを生成します。

AWS CloudFormation リソース制限を超えると、AWS CloudFormation 合成時にエラーが発生します。スタックが 80% の制限を超える場合、AWS CDK は警告を通知します。スタックに `maxResources` プロパティを設定するか、`maxResources` を 0 に設定して検証を無効にすることにより、別の制限を適用できます。

**ヒント**  
次のユーティリティスクリプトを使用し、合成された出力のリソースの正確な数を取得できます。(すべての AWS CDK デベロッパーに Node.js が必要なため、スクリプトは JavaScript で記述されています)  

```
// rescount.js - count the resources defined in a stack
// invoke with: node rescount.js <path-to-stack-json>
// e.g. node rescount.js cdk.out/MyStack.template.json

import * as fs from 'fs';
const path = process.argv[2];

if (path) fs.readFile(path, 'utf8', function(err, contents) {
  console.log(err ? `${err}` :
  `${Object.keys(JSON.parse(contents).Resources).length} resources defined in ${path}`);
}); else console.log("Please specify the path to the stack's output .json file");
```

スタックのリソース数が制限に近づいたら、再設計を検討してスタックに含まれるリソースの数を減らしてください。例えば、Lambda 関数をいくつか組み合わせるか、スタックを複数のスタックに分割することができます。CDK は[スタック間のリファレンス](resources.md#resource-stack)をサポートしているため、ユーザーに合った方法でアプリの機能をさまざまなスタックに分割できます。

**注記**  
 AWS CloudFormation エキスパートは、リソース制限の解決策としてネストされたスタックの使用をよく提案します。AWS CDK は、[NestedStack](stacks.md#stack-nesting) コンストラクトを介してこのアプローチをサポートします。

## Auto Scaling グループまたは VPC に 3 つ (またはそれ以上) のアベイラビリティーゾーンを指定したが、2 つしかデプロイされない
<a name="troubleshooting-availability-zones"></a>

要求するアベイラビリティーゾーンの数を取得するには、スタックの `env` プロパティでアカウントおよびリージョンを指定します。両方を指定しない場合、AWS CDK はデフォルトでスタックを環境に依存しないものとして合成します。その後、AWS CloudFormation を使用してスタックを特定のリージョンにデプロイできます。一部のリージョンには 2 つのアベイラビリティーゾーンしかないため、環境に依存しないテンプレートは 3 つ以上は使用しません。

**注記**  
以前、リージョンは 1 つのアベイラビリティーゾーンのみで起動することがありました。環境に依存しない AWS CDK スタックは、このようなリージョンにデプロイできません。ただし、これを記述している時点では、すべての AWS リージョンには少なくとも 2 つのアベイラビリティーゾーンがあります。

この動作を変更するには、スタックの [availabilityZones](https://docs.aws.amazon.com/cdk/api/v2/docs/aws-cdk-lib.Stack.html#availabilityzones) (Python: `availability_zones`) プロパティを上書きし、使用するゾーンを明示的に指定します。

合成時にスタックのアカウントおよびリージョンを指定し、任意のリージョンにデプロイする柔軟性を維持する方法の詳細については、「[AWS CDK の環境](environments.md)」を参照してください。

## `cdk destroy` を発行しても、S3 バケット、DynamoDB テーブル、その他のリソースが削除されない
<a name="troubleshooting-resource-not-deleted"></a>

デフォルトでは、ユーザーデータを含むことができるリソースには `RETAIN` の `removalPolicy` (Python: `removal_policy`) プロパティがあり、スタックが廃棄されたときにリソースは削除されません。代わりに、リソースはスタックから切り離された状態になります。その後、スタックが廃棄された後にリソースを手動で削除する必要があります。これを行わない限り、スタックの再デプロイは失敗します。デプロイ中に作成される新しいリソースの名前が、孤立したリソースの名前と競合するためです。

リソースの削除ポリシーを `DESTROY` に設定する場合、スタックが廃棄されるとそのリソースは削除されます。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import { Construct } from 'constructs';
import * as s3 from 'aws-cdk-lib/aws-s3';

export class CdkTestStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY,
    });
  }
}
```

```
const cdk = require('aws-cdk-lib');
const s3 = require('aws-cdk-lib/aws-s3');

class CdkTestStack extends cdk.Stack {
  constructor(scope, id, props) {
    super(scope, id, props);

    const bucket = new s3.Bucket(this, 'Bucket', {
      removalPolicy: cdk.RemovalPolicy.DESTROY
    });
  }
}

module.exports = { CdkTestStack }
```

```
import aws_cdk as cdk
from constructs import Construct
import aws_cdk.aws_s3 as s3

class CdkTestStack(cdk.stack):
    def __init__(self, scope: Construct, id: str, **kwargs):
        super().__init__(scope, id, **kwargs)

        bucket = s3.Bucket(self, "Bucket",
            removal_policy=cdk.RemovalPolicy.DESTROY)
```

```
software.amazon.awscdk.*;
import software.amazon.awscdk.services.s3.*;
import software.constructs;

public class CdkTestStack extends Stack {
    public CdkTestStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public CdkTestStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);

        Bucket.Builder.create(this, "Bucket")
                .removalPolicy(RemovalPolicy.DESTROY).build();
    }
}
```

```
using Amazon.CDK;
using Amazon.CDK.AWS.S3;

public CdkTestStack(Construct scope, string id, IStackProps props) : base(scope, id, props)
{
    new Bucket(this, "Bucket", new BucketProps {
        RemovalPolicy = RemovalPolicy.DESTROY
    });
}
```

**注記**  
 AWS CloudFormation は空ではない Amazon S3 バケットを削除できません。Amazon S3 バケットの削除ポリシーを `DESTROY` に設定し、データが含まれている場合、バケットを削除できないため、スタックを破棄しようとすると失敗します。バケットの `autoDeleteObjects` プロパティを `true` に設定することにより、AWS CDK がバケット内のオブジェクトを削除してから破棄できます。