

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

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

# コンストラクトライブラリから AWS コンストラクトをカスタマイズする
<a name="cfn-layer"></a>

ミックス、ファサード、エスケープハッチ、raw オーバーライド、カスタムリソースを使用して AWS 、コンストラクトライブラリからコンストラクトをカスタマイズします。

## Mixins を使用して L1 コンストラクトに機能を追加する
<a name="develop-customize-mixins"></a>

Mixins を使用すると、完全な L1 コンストラクトに高レベルの機能を追加できます。 L2 これは、L2 コンストラクトがサービスで利用できない場合や、通常は L2 コンストラクトでのみ利用できる特定の機能を持つ L1 コンストラクトを使用する場合に便利です。 L2 

たとえば、自動削除動作を L1 に追加できます。これには通常 `CfnBucket`L2 `Bucket`コンストラクトが必要です。

**Example**  

```
import * as cdk from 'aws-cdk-lib';
import * as s3 from 'aws-cdk-lib/aws-s3';

const bucket = new s3.CfnBucket(this, 'MyBucket');
bucket.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.DELETE;

// Add auto-delete objects behavior using a Mixin
bucket.with(new s3.mixins.BucketAutoDeleteObjects());
```

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

const bucket = new s3.CfnBucket(this, 'MyBucket');
bucket.cfnOptions.deletionPolicy = cdk.CfnDeletionPolicy.DELETE;

// Add auto-delete objects behavior using a Mixin
bucket.with(new s3.mixins.BucketAutoDeleteObjects());
```

```
import aws_cdk as cdk
import aws_cdk.aws_s3 as s3

bucket = s3.CfnBucket(self, "MyBucket")
bucket.cfn_options.deletion_policy = cdk.CfnDeletionPolicy.DELETE

# Add auto-delete objects behavior using a Mixin
bucket.with_(s3.mixins.BucketAutoDeleteObjects())
```

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

CfnBucket bucket = new CfnBucket(this, "MyBucket");
bucket.getCfnOptions().setDeletionPolicy(CfnDeletionPolicy.DELETE);

// Add auto-delete objects behavior using a Mixin
bucket.with(new BucketAutoDeleteObjects());
```

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

var bucket = new CfnBucket(this, "MyBucket");
bucket.CfnOptions.DeletionPolicy = CfnDeletionPolicy.DELETE;

// Add auto-delete objects behavior using a Mixin
bucket.With(new BucketAutoDeleteObjects());
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
bucket.CfnOptions().SetDeletionPolicy(awscdk.CfnDeletionPolicy_DELETE)

bucket.With(awss3.NewBucketAutoDeleteObjects())
```

ミキサーは、各サービスモジュール`mixins`の名前空間から使用できます。Mixins と [Facades](#develop-customize-facades) を組み合わせて、L1 コンストラクトのアクセス許可やその他の統合を取得することもできます。Mixins の詳細については、[「Mixins](mixins.md)」を参照してください。

## L1 コンストラクトの統合にファサードを使用する
<a name="develop-customize-facades"></a>

ファサードは、L1 コンストラクトと L2 コンストラクトの両方のアクセス許可、メトリクス、リフレクションなどの統合を提供するリソース固有のクラスです。最も一般的なファサードは Grants クラスで、インテントベースのアクセス許可メソッドを提供します。

L2 L1 コンストラクトでファサードを直接使用できます。 L2

**Example**  

```
import * as s3 from 'aws-cdk-lib/aws-s3';
import * as iam from 'aws-cdk-lib/aws-iam';

const bucket = new s3.CfnBucket(this, 'MyBucket');
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});

// Use the Grants Facade directly on the L1 construct
s3.BucketGrants.fromBucket(bucket).read(role);
```

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

const bucket = new s3.CfnBucket(this, 'MyBucket');
const role = new iam.Role(this, 'MyRole', {
  assumedBy: new iam.ServicePrincipal('lambda.amazonaws.com'),
});

// Use the Grants Facade directly on the L1 construct
s3.BucketGrants.fromBucket(bucket).read(role);
```

```
import aws_cdk.aws_s3 as s3
import aws_cdk.aws_iam as iam

bucket = s3.CfnBucket(self, "MyBucket")
role = iam.Role(self, "MyRole",
    assumed_by=iam.ServicePrincipal("lambda.amazonaws.com"),
)

# Use the Grants Facade directly on the L1 construct
s3.BucketGrants.from_bucket(bucket).read(role)
```

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

CfnBucket bucket = new CfnBucket(this, "MyBucket");
Role role = Role.Builder.create(this, "MyRole")
        .assumedBy(new ServicePrincipal("lambda.amazonaws.com"))
        .build();

// Use the Grants Facade directly on the L1 construct
BucketGrants.fromBucket(bucket).read(role);
```

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

var bucket = new CfnBucket(this, "MyBucket");
var role = new Role(this, "MyRole", new RoleProps
{
    AssumedBy = new ServicePrincipal("lambda.amazonaws.com")
});

// Use the Grants Facade directly on the L1 construct
BucketGrants.FromBucket(bucket).Read(role);
```

```
bucket := awss3.NewCfnBucket(stack, jsii.String("MyBucket"), nil)
role := awsiam.NewRole(stack, jsii.String("MyRole"), &awsiam.RoleProps{
    AssumedBy: awsiam.NewServicePrincipal(jsii.String("lambda.amazonaws.com"), nil),
})

awss3.BucketGrants_FromBucket(bucket).Read(role, nil)
```

ファサードの詳細については、[「ファサード](facades.md)」を参照してください。

Mixins and Facades がユースケースをカバーしていない場合は、エスケープハッチと raw オーバーライドを使用してコンストラクトを下位レベルでカスタマイズできます。

## エスケープハッチを使用する
<a name="develop-customize-escape"></a>

 AWS コンストラクトライブラリは、さまざまなレベルの抽象化の[コンストラクト](constructs.md)を提供します。

最上位レベルでは、 AWS CDK アプリケーションとその中のスタックは、それ自体がクラウドインフラストラクチャ全体、またはそのかなりのチャンクの抽象化です。これらは、さまざまな環境やニーズに合わせてデプロイできるようにパラメータ化できます。

抽象化は、クラウドアプリケーションを設計および実装するための強力なツールです。 AWS CDK は、抽象化を使用して構築するだけでなく、新しい抽象化を作成する機能も提供します。既存のオープンソースの L2 および L3 コンストラクトをガイダンスとしながら、組織のベストプラクティスや意見を反映させた独自の L2 および L3 コンストラクトを構築することができます。

完璧な抽象化というものは存在せず、優れた抽象化であってもあらゆるユースケースを網羅できるわけではありません。開発中に、ニーズにほぼ適合するコンストラクトが見つかる場合もありますが、大なり小なりカスタマイズが必要になります。

このため、 AWS CDK はコンストラクトモデルから*抜け出す*方法を提供します。これには、下位レベルの抽象化への移行や、まったく異なるモデルへの移行が含まれます。エスケープハッチを使用すると、 AWS CDK パラダイムを*エスケープ*し、ニーズに合わせてカスタマイズできます。その後、変更を新しいコンストラクトでラップすることで、基盤となる複雑さを抽象化し、他の開発者にクリーンな API を提供できます。

以下は、エスケープハッチを使用できる状況の例です。
+  AWS サービス機能は AWS CloudFormation を通じて使用できますが、L2 コンストラクトはありません。
+  AWS サービス機能は AWS CloudFormation を通じて利用でき、サービスには L2 コンストラクトがありますが、これらはまだ機能を公開していません。L2 コンストラクトは CDK チームによってキュレーションされるため、新機能をすぐに利用できない場合があります。
+ この機能は、 AWS CloudFormation を通じてはまだ利用できません。

   AWS CloudFormation で機能を使用できるかどうかを確認するには、[AWS 「リソースタイプとプロパティタイプのリファレンス](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)」を参照してください。

### L1 コンストラクトのエスケープハッチを開発する
<a name="develop-customize-escape-l1"></a>

L2 コンストラクトがサービスで利用できない場合は、自動的に生成された L1 コンストラクトを使用できます。これらのリソースは、`CfnBucket`や `CfnRole` など、`Cfn` で始まる名前で識別できます。同等の AWS CloudFormation リソースを使用するのとまったく同じようにインスタンス化します。

たとえば、分析を有効にして低レベルの Amazon S3 バケット L1 をインスタンス化するには、以下のようなものを記述します。

**Example**  

```
new s3.CfnBucket(this, 'amzn-s3-demo-bucket', {
  analyticsConfigurations: [
    {
      id: 'Config',
      // ...
    }
  ]
});
```

```
new s3.CfnBucket(this, 'amzn-s3-demo-bucket', {
  analyticsConfigurations: [
    {
      id: 'Config'
      // ...
    }
  ]
});
```

```
s3.CfnBucket(self, "amzn-s3-demo-bucket",
    analytics_configurations: [
        dict(id="Config",
             # ...
             )
    ]
)
```

```
CfnBucket.Builder.create(this, "amzn-s3-demo-bucket")
    .analyticsConfigurations(Arrays.asList(java.util.Map.of(    // Java 9 or later
        "id", "Config", // ...
    ))).build();
```

```
new CfnBucket(this, 'amzn-s3-demo-bucket', new CfnBucketProps {
    AnalyticsConfigurations = new Dictionary<string, string>
    {
        ["id"] = "Config",
        // ...
    }
});
```

対応する `CfnXxx` クラスを持たないリソースを定義したい場合がまれにあるかもしれません。これは、 AWS CloudFormation リソース仕様でまだ公開されていない新しいリソースタイプである可能性があります。このような場合は、`cdk.CfnResource` を直接インスタンス化し、リソースタイプとプロパティを指定します。以下の例ではこれを示しています。

**Example**  

```
new cdk.CfnResource(this, 'amzn-s3-demo-bucket', {
  type: 'AWS::S3::Bucket',
  properties: {
    // Note the PascalCase here! These are CloudFormation identifiers.
    AnalyticsConfigurations: [
      {
        Id: 'Config',
        // ...
      }
    ]
  }
});
```

```
new cdk.CfnResource(this, 'amzn-s3-demo-bucket', {
  type: 'AWS::S3::Bucket',
  properties: {
    // Note the PascalCase here! These are CloudFormation identifiers.
    AnalyticsConfigurations: [
      {
        Id: 'Config'
        // ...
      }
    ]
  }
});
```

```
cdk.CfnResource(self, 'amzn-s3-demo-bucket',
  type="AWS::S3::Bucket",
  properties=dict(
    # Note the PascalCase here! These are CloudFormation identifiers.
    "AnalyticsConfigurations": [
      {
        "Id": "Config",
        # ...
      }
    ]
  )
)
```

```
CfnResource.Builder.create(this, "amzn-s3-demo-bucket")
        .type("AWS::S3::Bucket")
        .properties(java.util.Map.of(    // Map.of requires Java 9 or later
            // Note the PascalCase here! These are CloudFormation identifiers
            "AnalyticsConfigurations", Arrays.asList(
                    java.util.Map.of("Id", "Config", // ...
                    ))))
        .build();
```

```
new CfnResource(this, "amzn-s3-demo-bucket", new CfnResourceProps
{
    Type = "AWS::S3::Bucket",
    Properties = new Dictionary<string, object>
    {   // Note the PascalCase here! These are CloudFormation identifiers
        ["AnalyticsConfigurations"] = new Dictionary<string, string>[]
        {
            new Dictionary<string, string> {
                ["Id"] = "Config"
            }
        }
    }
});
```

### L2 コンストラクトのエスケープハッチを開発する
<a name="develop-customize-escape-l2"></a>

L2 コンストラクトに機能がない場合や、問題を回避しようとしている場合は、L2 コンストラクト内にカプセル化されている L1 コンストラクトを変更できます。

すべての L2 コンストラクトは、対応する L1 コンストラクトを内包しています。たとえば、高レベルの `Bucket` コンストラクトは、低レベルの `CfnBucket` コンストラクトをラップしています。は AWS CloudFormation リソースに直接`CfnBucket`対応するため、 AWS CloudFormation で利用可能なすべての機能を公開します。

L1 コンストラクトにアクセスするための基本的なアプローチは、`construct.node.defaultChild` (Python: `default_child`) を使用し、(必要に応じて) 適切な型にそれをキャストし、そのプロパティを変更することです。ここでも、`Bucket` の例を見てみましょう。

**Example**  

```
// Get the CloudFormation resource
const cfnBucket = bucket.node.defaultChild as s3.CfnBucket;

// Change its properties
cfnBucket.analyticsConfiguration = [
  {
    id: 'Config',
    // ...
  }
];
```

```
// Get the CloudFormation resource
const cfnBucket = bucket.node.defaultChild;

// Change its properties
cfnBucket.analyticsConfiguration = [
  {
    id: 'Config'
    // ...
  }
];
```

```
# Get the CloudFormation resource
cfn_bucket = bucket.node.default_child

# Change its properties
cfn_bucket.analytics_configuration = [
    {
        "id": "Config",
        # ...
    }
]
```

```
// Get the CloudFormation resource
CfnBucket cfnBucket = (CfnBucket)bucket.getNode().getDefaultChild();

cfnBucket.setAnalyticsConfigurations(
        Arrays.asList(java.util.Map.of(    // Java 9 or later
            "Id", "Config", // ...
        ));
)
```

```
// Get the CloudFormation resource
var cfnBucket = (CfnBucket)bucket.Node.DefaultChild;

cfnBucket.AnalyticsConfigurations = new List<object> {
    new Dictionary<string, string>
    {
        ["Id"] = "Config",
        // ...
    }
};
```

このオブジェクトを使用して、 `Metadata`や などの AWS CloudFormation オプションを変更することもできます`UpdatePolicy`。

**Example**  

```
cfnBucket.cfnOptions.metadata = {
  MetadataKey: 'MetadataValue'
};
```

```
cfnBucket.cfnOptions.metadata = {
  MetadataKey: 'MetadataValue'
};
```

```
cfn_bucket.cfn_options.metadata = {
    "MetadataKey": "MetadataValue"
}
```

```
cfnBucket.getCfnOptions().setMetadata(java.util.Map.of(    // Java 9+
    "MetadataKey", "Metadatavalue"));
```

```
cfnBucket.CfnOptions.Metadata = new Dictionary<string, object>
{
    ["MetadataKey"] = "Metadatavalue"
};
```

## アンエスケープハッチを使用する
<a name="develop-customize-unescape"></a>

 AWS CDK は抽象化レベル*を上げる*機能も提供します。これは、「エスケープ解除」ハッチと呼ばれる場合があります。`CfnBucket` などの L1 コンストラクトがある場合は、新しい L2 コンストラクト (この場合は `Bucket`) を作成して、L1 コンストラクトをラップできます。

これは、L1 リソースを作成しつつ、L2 リソースを必要とするコンストラクトで使用する場合に便利です。

**ヒント**  
L1 コンストラクトでアクセス許可やその他の統合のみが必要な場合は、L2 にラップする必要はありません。代わりに、L1 で Grants クラスのような[ファサード](facades.md)を直接使用します。たとえば、 です`BucketGrants.fromBucket(cfnBucket).read(role)`。

より抽象度の高いレベルへの移行は、`.fromCfnXxxxx()` と呼ばれる L2 クラスの静的メソッドを使用します。例えば Amazon S3 バケットの場合は、`Bucket.fromCfnBucket()` を使用します。L1 リソースが唯一のパラメータです。

**Example**  

```
b1 = new s3.CfnBucket(this, "buck09", { ... });
b2 = s3.Bucket.fromCfnBucket(b1);
```

```
b1 = new s3.CfnBucket(this, "buck09", { ...} );
b2 = s3.Bucket.fromCfnBucket(b1);
```

```
b1 = s3.CfnBucket(self, "buck09", ...)
 b2 = s3.from_cfn_bucket(b1)
```

```
CfnBucket b1 = CfnBucket.Builder.create(this, "buck09")
								// ....
		                        .build();
IBucket b2 = Bucket.fromCfnBucket(b1);
```

```
var b1 = new CfnBucket(this, "buck09", new CfnBucketProps { ... });
var v2 = Bucket.FromCfnBucket(b1);
```

L1 コンストラクトから作成された L2 コンストラクトは、リソース名、ARNs、またはルックアップから作成されたものと同様に、L1 リソースを参照するプロキシオブジェクトです。これらのコンストラクトを変更しても、最終的な合成された AWS CloudFormation テンプレートには影響しません (L1 リソースがあるため、代わりに変更できます）。プロキシオブジェクトの詳細については、[「 AWS アカウントのリソースの参照](resources.md#resources-external)」を参照してください。

混乱を避けるため、同じ L1 コンストラクトを参照する複数の L2 コンストラクトを作成しないでください。例えば、[前のセクション](#develop-customize-escape-l2)の手法を使用して `Bucket` から `CfnBucket` を抽出する場合、その `CfnBucket` で `Bucket.fromCfnBucket()` を呼び出すことで 2 番目の `Bucket` インスタンスを作成することは避けてください。実際には期待どおりに機能しますが (合成される ` AWS::S3::Bucket` は 1 つだけです)、コードの保守が難しくなります。

## raw オーバーライドを使用する
<a name="develop-customize-override"></a>

L1 コンストラクトに欠落しているプロパティがある場合は、raw オーバーライドを使用してすべてのタイピングをバイパスできます。これにより、合成されたプロパティを削除することもできます。

以下の例に示すように、いずれかの `addOverride` メソッド (Python: `add_override`) を使用します。

**Example**  

```
// Get the CloudFormation resource
const cfnBucket = bucket.node.defaultChild as s3.CfnBucket;

// Use dot notation to address inside the resource template fragment
cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus');
cfnBucket.addDeletionOverride('Properties.VersioningConfiguration.Status');

// use index (0 here) to address an element of a list
cfnBucket.addOverride('Properties.Tags.0.Value', 'NewValue');
cfnBucket.addDeletionOverride('Properties.Tags.0');

// addPropertyOverride is a convenience function for paths starting with "Properties."
cfnBucket.addPropertyOverride('VersioningConfiguration.Status', 'NewStatus');
cfnBucket.addPropertyDeletionOverride('VersioningConfiguration.Status');
cfnBucket.addPropertyOverride('Tags.0.Value', 'NewValue');
cfnBucket.addPropertyDeletionOverride('Tags.0');
```

```
// Get the CloudFormation resource
const cfnBucket = bucket.node.defaultChild ;

// Use dot notation to address inside the resource template fragment
cfnBucket.addOverride('Properties.VersioningConfiguration.Status', 'NewStatus');
cfnBucket.addDeletionOverride('Properties.VersioningConfiguration.Status');

// use index (0 here) to address an element of a list
cfnBucket.addOverride('Properties.Tags.0.Value', 'NewValue');
cfnBucket.addDeletionOverride('Properties.Tags.0');

// addPropertyOverride is a convenience function for paths starting with "Properties."
cfnBucket.addPropertyOverride('VersioningConfiguration.Status', 'NewStatus');
cfnBucket.addPropertyDeletionOverride('VersioningConfiguration.Status');
cfnBucket.addPropertyOverride('Tags.0.Value', 'NewValue');
cfnBucket.addPropertyDeletionOverride('Tags.0');
```

```
# Get the CloudFormation resource
cfn_bucket = bucket.node.default_child

# Use dot notation to address inside the resource template fragment
cfn_bucket.add_override("Properties.VersioningConfiguration.Status", "NewStatus")
cfn_bucket.add_deletion_override("Properties.VersioningConfiguration.Status")

# use index (0 here) to address an element of a list
cfn_bucket.add_override("Properties.Tags.0.Value", "NewValue")
cfn_bucket.add_deletion_override("Properties.Tags.0")

# addPropertyOverride is a convenience function for paths starting with "Properties."
cfn_bucket.add_property_override("VersioningConfiguration.Status", "NewStatus")
cfn_bucket.add_property_deletion_override("VersioningConfiguration.Status")
cfn_bucket.add_property_override("Tags.0.Value", "NewValue")
cfn_bucket.add_property_deletion_override("Tags.0")
```

```
// Get the CloudFormation resource
CfnBucket cfnBucket = (CfnBucket)bucket.getNode().getDefaultChild();

// Use dot notation to address inside the resource template fragment
cfnBucket.addOverride("Properties.VersioningConfiguration.Status", "NewStatus");
cfnBucket.addDeletionOverride("Properties.VersioningConfiguration.Status");

// use index (0 here) to address an element of a list
cfnBucket.addOverride("Properties.Tags.0.Value", "NewValue");
cfnBucket.addDeletionOverride("Properties.Tags.0");

// addPropertyOverride is a convenience function for paths starting with "Properties."
cfnBucket.addPropertyOverride("VersioningConfiguration.Status", "NewStatus");
cfnBucket.addPropertyDeletionOverride("VersioningConfiguration.Status");
cfnBucket.addPropertyOverride("Tags.0.Value", "NewValue");
cfnBucket.addPropertyDeletionOverride("Tags.0");
```

```
// Get the CloudFormation resource
var cfnBucket = (CfnBucket)bucket.node.defaultChild;

// Use dot notation to address inside the resource template fragment
cfnBucket.AddOverride("Properties.VersioningConfiguration.Status", "NewStatus");
cfnBucket.AddDeletionOverride("Properties.VersioningConfiguration.Status");

// use index (0 here) to address an element of a list
cfnBucket.AddOverride("Properties.Tags.0.Value", "NewValue");
cfnBucket.AddDeletionOverride("Properties.Tags.0");

// addPropertyOverride is a convenience function for paths starting with "Properties."
cfnBucket.AddPropertyOverride("VersioningConfiguration.Status", "NewStatus");
cfnBucket.AddPropertyDeletionOverride("VersioningConfiguration.Status");
cfnBucket.AddPropertyOverride("Tags.0.Value", "NewValue");
cfnBucket.AddPropertyDeletionOverride("Tags.0");
```

## カスタムリソースを使用する
<a name="develop-customize-custom"></a>

この機能が AWS CloudFormation を通じてではなく、直接 API コールを通じてのみ利用できる場合は、必要な API コールを行うために AWS CloudFormation カスタムリソースを記述する必要があります。 AWS CDK を使用してカスタムリソースを記述し、通常のコンストラクトインターフェイスにラップできます。コンストラクトの利用者の観点から見ると、エクスペリエンスはネイティブに感じられます。

カスタムリソースを構築するには、リソースの `CREATE`、`UPDATE`、`DELETE` ライフサイクルイベントに応答する Lambda 関数を書き込む必要があります。カスタムリソースが API を呼び出せるのが 1 回だけである場合には、[AwsCustomResource](https://github.com/awslabs/aws-cdk/tree/master/packages/%40aws-cdk/custom-resources) の使用を検討してください。これにより、 AWS CloudFormation のデプロイ中に任意の SDK 呼び出しを実行できます。それ以外の場合は、必要な作業を実行するための独自の Lambda 関数を作成する必要があります。

テーマが広すぎてここで完全にカバーすることはできませんが、以下のリンクから初めてみてください。
+  [カスタムリソース](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/template-custom-resources.html) 
+  [カスタムリソースの例](https://github.com/aws-samples/aws-cdk-examples/tree/master/typescript/custom-resource/) 
+ より完全な例については、CDK 標準ライブラリの[「DnsValidatedCertificate」](https://github.com/awslabs/aws-cdk/blob/master/packages/@aws-cdk/aws-certificatemanager/lib/dns-validated-certificate.ts)クラスを参照してください。これはカスタムリソースとして実装されます。