Infrastructure as Code(IaC)は、AWSクラウドにインフラストラクチャをデプロイする標準的な方法となっています。AWS Cloud Development Kit(AWS CDK)は、開発者がYaml/JSONで宣言的なコードを記述するのではなく、お気に入りのプログラミング言語で必要なクラウドIaCを記述できる手段を提供します。
このブログでは、AWS CDKを活用する方法と、AWS CDKスタックでL1およびL2コンストラクトの力を活用してS3バケットを作成する方法について説明します。まず、これらの用語を定義することから始めましょう。
AWS CDKとは何ですか?
AWS CDKにより、開発者はC#、Python、TypeScriptなどの馴染みのあるプログラミング言語を使用してAWSクラウドインフラストラクチャを定義できます。多くの複雑さを抽象化する一方で、必要に応じて詳細な制御も提供します。AWS CDKを使用すると、ニーズに最適な抽象化レベルを選択する力があります。その仕組みは以下の通りです:
高水準言語であるC#は、.NET型をCDKランタイムに変換するためにJSIIランタイムが必要であることにご注意ください。CDKは、CDKアプリケーションをAWS CloudFormationテンプレートに合成し、その後組織のAWSアカウントでCloudFormationスタックとしてデプロイされる仕組みで動作します。
AWS CDKスタック
AWS CDKスタックは「コンストラクト」として知られるリソースの集合であり、リソースはAWSサービス、またはスタックで定義されたAWSサービスの利用を支援するコンポーネントです。
スタックには複数のコンストラクトを定義でき、各スタックはリソースから直接または間接的に参照されるスタックのインスタンスで表現できます。
L1およびL2コンストラクトの定義
コンストラクトは、スタックのリソースを詳細に定義するスタックの一部です。言い換えると、L1(レベル1)コンストラクトは、スタックのリソースの属性を定義するための低レベルで詳細な制御を可能にします。コンストラクトには、AWS CloudFormationテンプレートのメタデータ形式(JSON/Yaml)でクラウドコンポーネントを記述するために必要なすべての詳細が含まれています。
「コンストラクトは、Amazon Simple Storage Service(Amazon S3)バケットなどの単一のAWSリソースを表すことができます。コンストラクトは、複数の関連するAWSリソースで構成される高レベルの抽象化でもあります。このようなコンポーネントの例には、関連するコンピューティング容量を持つワーカーキュー、または監視リソースとダッシュボードを持つスケジュールされたジョブが含まれます。」*
*参考: AWS CDKコンストラクト
L1とL2コンストラクトの違い
L1とL2コンストラクトの違いを理解する鍵は「抽象化」と提供される抽象化のレベルです。
L1コンストラクトはTypeScriptで記述された低レベルのコンストラクトです。これは、TypeScriptがJSIIランタイムに最も隣接するレベルに適切に位置するためです。L2コンストラクトは、例えばCDK .NETフレームワーク用にC#で記述され、JSIIランタイムの上に抽象化レイヤーがあります。
この高レベルの抽象化には、純粋に構造的な制約が伴います。これは、.NET型を必要なJSIIランタイム型に変換または「マーシャル」する仲介クラスが必要になるためです。
これらの制約は仲介クラスの使用により生じることに注意することが重要です。これらのクラスは、.NET型を特定のJSIIランタイム型に変換する役割を果たし、AWSリソース構成に必要な詳細な制御レベルを示しています。
L2よりもL1コンストラクトを使用する場合
L2コンストラクトはシンプルさと使いやすさを提供し、L1コンストラクトはAWSリソースに対するより細かい制御を提供します。前述のように、.NETランタイムによって課される型制約のため、JSIIランタイムがAWS CloudFormationで必要な細かい粒度でそのような型、プロパティ、および/またはメソッドをマップすることが困難になります。これは、CloudFormationスタックには、記述されている特定のクラウドコンポーネントのベストプラクティス、セキュリティ、またはその他の関連する側面に従って完全に解決する必要があるメタデータが含まれているためです。
使用例:S3バケットにユーザーフレンドリーな名前を割り当てる
S3バケット名は一意である必要がありますが、いくつかのパターンがあります。したがって、デフォルトでバケット名に一意性要件を満たすためのハッシュのような値が含まれている場合、それはあまりユーザーフレンドリーではありません。そこで、明らかな解決策が提示されます – S3リソースを作成する際にバケット名をカスタマイズする必要があります。
ユーザーが読みやすいバケット名:
作成後にIBucketから継承するBucketクラスでL2レベルのコンストラクトに名前を割り当てようとすると、コンパイラは「プロパティまたはインデクサーBucket.bucketnameは割り当てできません – 読み取り専用です」というエラーメッセージを生成します。
解決策:CfnBucketクラスを使用する:
作成後にICfnBucketから継承するL1バケットに名前を割り当てようとすると、それは機能します。これは、L1コンストラクト(すべてのL1コンストラクトにはCloudFormationの略であるcfnが接頭辞として付けられます)が、コンストラクトクラスがCloudFormationテンプレートと直接マップすることを示すインジケーターであるためです。
これは、L2コンストラクトでは取得できない詳細な詳細の掘り下げが必要な可能性があるAWSリソースに適用されます。
選択と制御の力
このアプローチは他のAWSリソースにも拡張でき、IaCプロジェクトでシンプルさと制御のバランスを達成できます。
L1とL2コンストラクトの選択は、プロジェクトのニーズによって決まります。L2コンストラクトはシンプルさと利便性のために設計されており、L1コンストラクトは複雑なAWSリソース構成により多くの柔軟性と制御を提供します。