モジュールを使用したリソース構成のカプセル化と再利用 - AWS CloudFormation

モジュールを使用したリソース構成のカプセル化と再利用

モジュールは、スタックテンプレート全体に含めるリソース構成をパッケージ化する、透過的で管理しやすく、繰り返し可能な方法です。モジュールは、共通のサービス構成とベストプラクティスを、スタックテンプレートに含めるためのモジュール式のカスタマイズ可能なビルディングブロックとしてカプセル化できます。モジュールを使用すると、リソース実装の複雑さを深く理解することなく、ベストプラクティス、専門分野の知識、承認されたガイドライン (セキュリティ、コンプライアンス、ガバナンス、業界規制などの領域について) をテンプレートに含めることができます。

たとえば、ネットワークのドメイン専門家は、組み込みのセキュリティグループと、セキュリティガイドラインに準拠した入力/出力ルールを含むモジュールを作成できます。その後、そのモジュールをテンプレートに含めることで、VPC、サブネット、セキュリティグループ、ゲートウェイがどのように機能するかを考えるのに時間を費やすことなく、セキュアなネットワーキングインフラストラクチャをスタックにプロビジョニングできます。また、モジュールはバージョン管理されているため、セキュリティガイドラインが時間の経過とともに変更された場合、モジュールの作成者はそれらの変更を組み込んだ新しいバージョンのモジュールを作成できます。

テンプレートでモジュールを使用することの特徴は次のとおりです。

  • 予測可能性 – モジュールは CloudFormation レジストリに登録されているスキーマに準拠する必要があります。そのため、テンプレートにモジュールを含めると解決できるリソースがわかります。

  • 再利用性 – 複数のテンプレートとアカウントで同じモジュールを使用できます。

  • トレーサビリティ – CloudFormation では、スタック内のどのリソースがモジュールからプロビジョニングされたかを把握できるため、リソース変更のソースを簡単に把握できます。

  • 管理機能 – モジュールを登録すると、バージョニング、アカウント、リージョンの可用性など、CloudFormation レジストリを使用してモジュールを管理できます。

モジュールには次のものを含めることができます。

  • モジュールからプロビジョニングされる 1 つ以上のリソース、および出力や条件などの関連データ。

  • 任意のモジュールパラメータ。モジュールが使用されるたびにカスタム値を指定できます。

モジュールタイプの開発については、「CloudFormation コマンドラインインターフェースユーザーガイド」の「Developing module types」(モジュールタイプの開発) を参照してください。

テンプレートでのモジュールの使用

モジュールを使用するには、モジュールを使用する AWS アカウント とリージョンに登録されていることを確認してください。詳細については、「パブリック拡張とプライベート拡張」を参照してください。

CloudFormation レジストリのモジュールをプライベート拡張として登録します。次に、個々のリソースと同じように扱います。

  • それをテンプレートの Resources セクションに含めます。

  • モジュールに必要なプロパティを指定します。

スタックオペレーションを開始すると、CloudFormation は、含まれているモジュールを適切なリソースに解決する処理済みテンプレートを生成します。変更セットを使用して 、スタック操作を実際に実行する前に、追加または更新するリソースをプレビューします。詳細については、「変更セットを使用して CloudFormation スタックを更新する」を参照してください。

次の例を考えてみましょう。リソースとモジュールの両方を含むテンプレートがあります。テンプレートには、1 つの個別のリソース ResourceA とモジュール ModuleParent が含まれます。このモジュールには、ResourceB および ResourceC の 2 つのリソースと、ネストされたモジュール ModuleChild が含まれます。ModuleChild には、1 つのリソース ResourceD が含まれます。このテンプレートからスタックを作成すると、CloudFormation はテンプレートを処理し、モジュールを適切なリソースに解決します。結果のスタックには、ResourceAResourceBResourceCResourceD の 4 つのリソースがあります。

スタックオペレーション中、CloudFormation はスタックテンプレートに含まれている 2 つのモジュールを適切な 4 つのリソースに解決します。

CloudFormation は、スタック内のどのリソースがモジュールから作成されたかを追跡します。この情報は、特定のスタックの [Events] (イベント)、[Resources] (リソース)、および [Drifts] (ドリフト) タブに表示できます。また、変更セットのプレビューにも表示されます。

モジュールはテンプレート内のリソースと区別できます。これは、リソースで使用される一般的な 3 つのパート規則とは対照的に、次の 4 つの部分からなる命名規則に従っているためです。

organization::service::use-case::MODULE

パラメータを使用してモジュール値を指定する

モジュールには、モジュールパラメータを含めることができます。テンプレートパラメーターと同様に、モジュールパラメーターを使用すると、モジュールを含むテンプレート (またはモジュール) からモジュールにカスタム値を入力できます。モジュールはこれらの値を使用して、そのモジュールに含まれるリソースのプロパティを設定できます。

また、モジュールプロパティを設定するテンプレートパラメータを定義して、スタック操作時にモジュールに渡される値をユーザーが入力できるようにすることもできます。テンプレートのパラメータの定義に関する詳細は、「Parameters」を参照してください。

同様に、モジュールパラメータを含むネストされたモジュールがモジュールに含まれている場合、次のことができます。

  • ネストされたモジュールのパラメータの値を親モジュールで直接指定します。

  • 親モジュール内の対応するモジュールパラメータを定義して、ネストされたモジュールのパラメータを、親モジュールが含まれているテンプレート (またはモジュール) で設定できるようにします。

テンプレートパラメータを使用したモジュールパラメータ値の指定

次の例は、モジュールに値を渡すテンプレートパラメータを定義する方法を示しています。

ここで、BucketName を含むテンプレートは、スタック操作中にユーザーが S3 バケット名を指定できるようにするテンプレートパラメータ My::S3::SampleBucket::MODULE を定義します。

# Template containing My::S3::SampleBucket::MODULE { "Parameters": { "BucketName": { "Description": "Name for your sample bucket", "Type": "String" } }, "Resources": { "MyBucket": { "Type": "My::S3::SampleBucket::MODULE", "Properties": { "BucketName": { "Ref": "BucketName" } } } } }

親モジュールから子モジュール内のリソースのプロパティを指定する

次の例は、別のモジュール内にネストされているモジュールでパラメータ値を指定する方法を示しています。

この最初のモジュール My::S3::SampleBucketPrivate::MODULE は、子モジュールになります。これは、BucketNameAccessControl の 2 つのパラメータを定義します。これらのパラメータに指定された値は、モジュールに含まれる AWS::S3::Bucket リソースの BucketName およびAccessControl プロパティを指定するために使用されます。以下は My::S3::SampleBucketPrivate::MODULE のテンプレートフラグメントです。

# My::S3::SampleBucketPrivate::MODULE { "AWSTemplateFormatVersion": "2010-09-09", "Description": "A sample S3 Bucket with Versioning and DeletionPolicy.", "Parameters": { "BucketName": { "Description": "Name for the bucket", "Type": "String" }, "AccessControl": { "Description": "AccessControl for the bucket", "Type": "String" } }, "Resources": { "S3Bucket": { "Type": "AWS::S3::Bucket", "Properties": { "BucketName": { "Ref": "BucketName" }, "AccessControl": { "Ref": "AccessControl" }, "DeletionPolicy": "Retain", "VersioningConfiguration": { "Status": "Enabled" } } } } }

次に、前のモジュールは親モジュール My::S3::SampleBucket::MODULE 内にネストされます。親モジュール My::S3::SampleBucket::MODULE は、次の方法で子モジュールのパラメータを設定します。

  • My::S3::SampleBucketPrivate::MODULEAccessControl パラメータを Private に設定します。

  • BucketName では 、モジュールパラメータを定義します。これにより、My::S3::SampleBucket::MODULE を含むテンプレート (またはモジュール) でバケット名を指定できます 。

# My::S3::SampleBucket::MODULE { "AWSTemplateFormatVersion": "2010-09-09", "Description": "A sample S3 Bucket. With Private AccessControl.", "Parameters": { "BucketName": { "Description": "Name for your sample bucket", "Type": "String" } }, "Resources": { "MyBucket": { "Type": "My::S3::SampleBucketPrivate::MODULE", "Properties": { "BucketName": { "Ref": "BucketName" }, "AccessControl" : "Private" } } } }

モジュールパラメータの制約の指定

モジュールパラメータは、制約の適用をサポートしていません。モジュールパラメータに対して制約チェックを実行するには、必要な制約を持つテンプレートパラメータを作成します。その後、モジュールパラメータでそのテンプレートパラメータを参照します。テンプレートのパラメータの定義に関する詳細は、「Parameters」を参照してください。

モジュール内のリソースの参照

モジュール内のリソースは、論理名で参照できます。モジュールに含まれるリソースの完全修飾論理名は、次の組み合わせによって構築できます。

  • 包含テンプレート (または包含モジュール)) 内のモジュールに指定された論理名。

  • モジュールで指定された、リソースの論理名。

リソースの完全修飾論理名は、区切り文字としてピリオドを使用する場合であっても、使用しない場合であっても、指定することができます。例えば、以下の論理名は両方とも有効で、機能的には同等です。

  • ModuleLogicalName.ResourceLogicalName

  • ModuleLogicalNameResourceLogicalName

このようにして、GetAtt Ref および組み込み関数を使用して、モジュールリソースのプロパティ値にアクセスできます。

次の例では、テンプレートはモジュール内のプロパティを参照して、テンプレート自体のリソースに対応するプロパティを設定します。

My::S3::SampleBucket::MODULEモジュールに、S3Bucket の論理名を持つ AWS::S3::Bucket リソースが含まれているとします。Ref 組み込み関数を使用してこのリソースのバケット名を参照するには、テンプレート MyBucket 内のモジュールで指定された論理名とモジュール S3Bucket 内のリソースの論理名を組み合わせて、リソース MyBucket.S3Bucket または MyBucketS3Bucket の完全修飾論理名を取得します。

モジュールに含まれるリソースの論理名は、モジュールのスキーマで指定されます。このスキーマには、次の方法でアクセスできます。

  • CloudFormation レジストリ内のモジュールを見つけます。[Schema] タブにモジュールスキーマが表示されます。

  • DescribeType 操作を使用して、スキーマを含むモジュールの詳細を返します。

# Template that uses My::S3::SampleBucket::MODULE { "Parameters": { "BucketName": { "Description": "Name for your sample bucket", "Type": "String" } }, "Resources": { "MyBucket": { "Type": "My::S3::SampleBucket::MODULE", "Properties": { "BucketName": { "Ref": "BucketName" } } }, "exampleQueue": { "Type": "AWS::SQS::Queue", "Properties": { "QueueName": { "Ref": "MyBucket.S3Bucket" } } } }, "Outputs": { "BucketArn": { "Value": { "Fn::GetAtt": [ "MyBucket", "S3Bucket.Arn" ] } } } }
Parameters: BucketName: Description: Name for your sample bucket Type: String Resources: MyBucket: Type: My::S3::SampleBucket::MODULE Properties: BucketName: !Ref BucketName exampleQueue: Type: AWS::SQS::Queue Properties: QueueName: !Ref MyBucket.S3Bucket Outputs: BucketArn: Value: !GetAtt MyBucket.S3Bucket.Arn

モジュールを使用するときの考慮事項

  • モジュールは追加料金なしで使用できます。スタック内でそれらのモジュールが解決したリソースに対してのみお支払いいただきます。

  • CloudFormation クォータ (スタックで許可されるリソースの最大数、テンプレート本文の最大サイズなど) は、テンプレートに含まれるリソースがモジュールから取得されているかどうかにかかわらず、処理されたテンプレートに適用されます。詳細については、「CloudFormation クォータを理解する」を参照してください。

  • スタックレベルで指定するタグは、モジュールから派生した個々のリソースに割り当てられます。

  • モジュールレベルで指定されたヘルパースクリプトは、CloudFormation がテンプレートを処理するときに、モジュールに含まれる個々のリソースには伝達されません。

  • モジュールで指定された出力は、テンプレートレベルで出力に伝播されます。

    各出力には、モジュールで定義されたモジュールの論理名と出力名を連結した論理 ID が割り当てられます。詳細については、「デプロイされた CloudFormation スタックからエクスポートされた出力を取得する」を参照してください。

  • モジュールで指定されたパラメータは、テンプレートレベルのパラメータには伝達されません。

    ただし、モジュールレベルのパラメータを参照するテンプレートレベルのパラメータを作成できます。詳細については、「パラメータを使用してモジュール値を指定する」を参照してください。

モジュールの登録とバージョン管理

CloudFormation レジストリを使用して、アカウントとリージョンのモジュールを登録および管理します。詳細については、「CloudFormation レジストリによる拡張機能の管理」を参照してください。

特定のアカウントとリージョンに、同じモジュールの複数のバージョンを登録できます。次の考慮事項に注意が必要です。

  • モジュールを使用するアカウントとリージョンに、モジュールを登録する必要があります。

  • スタックオペレーション中、CloudFormation は、スタックオペレーションが実行されている AWS アカウント およびリージョンで、デフォルトバージョンとして現在登録されているモジュールの任意のバージョンを使用します。これには、他のモジュールにネストされているモジュールも含まれます。

    したがって、異なるアカウントまたはリージョンで、同じモジュールの異なるバージョンをデフォルトバージョンとして登録している場合、同じテンプレートを使用すると、異なる結果になる可能性があることに注意してください。

    詳細については、「AWS CLI を使用して使用するプライベート拡張のバージョンを指定する」を参照してください。

  • スタックオペレーション中、CloudFormation は、スタックオペレーションが実行されている AWS アカウント およびリージョンで、デフォルトバージョンとして現在登録されているリソースの任意のバージョンを使用します。これには、モジュールを含めることによって生成されたリソースが含まれます。

  • モジュールのデフォルトバージョンを変更しても、スタックの更新オペレーションは開始されません。ただし、次にそのモジュールを含むテンプレート (スタックの更新など) でスタックオペレーションを実行すると、CloudFormation は新しいデフォルトバージョンをオペレーションで使用します。

    これに関する例外の 1 つは、以下で説明するように、[use previous template] オプションを指定してスタックの更新を実行することです。

  • スタックの更新オペレーションで、[use previous template] (以前のテンプレートを使用) オプションを指定すると、CloudFormation はスタック更新のために以前に処理されたテンプレートを使用し、モジュールに加えた変更については再処理しません。

  • 一貫した結果を保証するために、スタックセットで使用するためにスタックテンプレートにモジュールを含める場合は、スタックインスタンスをデプロイする予定のすべてのアカウントとリージョンで、同じバージョンのモジュールがデフォルトバージョンとして設定されていることを確認する必要があります。これは、他のモジュールにネストされているモジュールの場合を含みます。詳細については、「StackSets を使用したアカウントとリージョン全体でのスタックの管理」を参照してください。

モジュールの新しいバージョンの登録、またはデフォルトバージョンの変更に関する詳細は、「CloudFormation レジストリによる拡張機能の管理」を参照してください。

アカウントで使用するためにパブリックモジュールをアクティベートする

アカウントとリージョンでパブリックモジュールを正常にアクティブ化するには、モジュールに含まれる各サードパーティのパブリック拡張 (リソースまたはモジュール) に対して以下が当てはまる必要があります。

  • アカウントとリージョンで拡張がすでにアクティブ化されている必要があります。

    モジュール内のエクステンションがタイプ名のエイリアスを使用する場合、エクステンションは同じタイプ名エイリアスを使用してアカウントとリージョンに登録する必要があります。詳細については、「拡張を参照するエイリアスを指定する」を参照してください。

  • 現在アクティブ化されているエクステンションのバージョンは、モジュールで指定されているエクステンションのサポートされているメジャーバージョンのいずれかである必要があります。詳細については、「CloudFormation CLI ユーザーガイド」の「Module requirements for publishing a public module」(パブリックモジュールを公開するためのモジュール要件) を参照してください。

適切なサードパーティのパブリック拡張と拡張のバージョンがアクティブ化されていない場合、CloudFormation はオペレーションに失敗し、モジュールを正常にアクティブ化する前にアクティブ化する必要がある拡張やバージョンをリストするエラーが表示されます。