From f8ab9b223379a756e28daeebbe9ad5236d5c4bfd Mon Sep 17 00:00:00 2001 From: Mickael Charneau <94433131+cmick-aws@users.noreply.github.com> Date: Fri, 24 Nov 2023 17:58:28 +0900 Subject: [PATCH 1/9] Catch-up on EN labs for Japanese translation. (#255) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Catch-up for Basics Lab for Japanese translation (#250) * Catch-up for Basics Lab for Japanese translation Reviewed by @ttymt * Catch-up for Advanced Lab for Japanese translation (#251) * Catch-up for Advanced Lab for Japanese translation Review by @ttymt * Added translation catchup for Intermediate in Japanese Translated by @hirakawad Review by @cmick-aws * Added Japanese translation for Intermediate section new labs Translated by @mwhiroya Review by @cmick-aws, @hirakawd * Remove trailing spaces * Propagated changes for Cross-Stack references lab in Japanese translation * Bump version: 3.2.1 → 3.3.0 --------- Co-authored-by: Franco Rezabek <43790446+rezabekf@users.noreply.github.com> --- .bumpversion.cfg | 2 +- .../modules/consume-example/index.ja.md | 2 +- .../modules/create-example/index.ja.md | 28 +- .../example-in-python/index.ja.md | 134 ++++ .../resource-types/prerequisites/index.ja.md | 2 +- .../operations/helper-scripts/index.ja.md | 161 ++-- .../multi-region-latest-ami/index.ja.md | 105 ++- .../operations/session-manager/index.ja.md | 6 +- .../index.ja.md | 102 ++- .../basics/operations/user-data/index.ja.md | 79 +- .../flipping-formats-and-cleanup/index.ja.md | 6 + .../templates/intrinsic-functions/index.ja.md | 125 ++- .../templates/linting-and-testing/index.ja.md | 6 + content/basics/templates/mappings/index.ja.md | 104 ++- content/basics/templates/outputs/index.ja.md | 154 +++- .../templates/pseudo-parameters/index.ja.md | 101 ++- .../resource-return-values/index.ja.md | 99 ++- .../basics/templates/resources/index.ja.md | 68 +- .../templates/template-anatomy/index.ja.md | 4 + .../templates/template-and-stack/index.ja.md | 109 ++- .../operations/drift-detection/index.ja.md | 726 +++++++++++++++--- .../operations/resource-importing/index.ja.md | 720 +++++++++++++---- .../index.ja.md | 176 +++-- .../operations/stacksets/index.ja.md | 349 +++++---- .../understanding-changesets/index.ja.md | 163 +++- .../index.ja.md | 186 +++-- .../architecting-templates/index.ja.md | 54 +- .../templates/conditions/index.ja.md | 184 +++-- .../templates/cross-stacks/index.ja.md | 192 +++-- .../templates/dynamic-references/index.ja.md | 365 ++++++--- .../templates/language-extensions/index.ja.md | 226 +++--- .../looping-over-collections/index.ja.md | 277 ++++--- .../templates/nested-stacks/index.ja.md | 364 ++++++--- .../templates/package-and-deploy/index.ja.md | 116 ++- .../policy-as-code-with-guard/index.ja.md | 32 +- .../resource-dependencies/index.ja.md | 123 ++- .../helper-scripts/az-update-1.ja.png | Bin 101798 -> 0 bytes .../stacksets/createstacksetcompletion.ja.png | Bin 0 -> 56188 bytes .../operations/stacksets/exports.ja.png | Bin 0 -> 58732 bytes .../stacksets/exportssecuritygroup.ja.png | Bin 0 -> 84373 bytes .../stacksets/stackinstances.ja.png | Bin 0 -> 128412 bytes .../stacksetsdeploymentoptions.ja.png | Bin 0 -> 120482 bytes 42 files changed, 4011 insertions(+), 1639 deletions(-) delete mode 100644 static/basics/operations/helper-scripts/az-update-1.ja.png create mode 100644 static/intermediate/operations/stacksets/createstacksetcompletion.ja.png create mode 100644 static/intermediate/operations/stacksets/exports.ja.png create mode 100644 static/intermediate/operations/stacksets/exportssecuritygroup.ja.png create mode 100644 static/intermediate/operations/stacksets/stackinstances.ja.png create mode 100644 static/intermediate/operations/stacksets/stacksetsdeploymentoptions.ja.png diff --git a/.bumpversion.cfg b/.bumpversion.cfg index da03603d5..8b68d7308 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,4 +1,4 @@ [bumpversion] -current_version = 3.2.1 +current_version = 3.3.0 commit = True tag = False diff --git a/content/advanced/modules/consume-example/index.ja.md b/content/advanced/modules/consume-example/index.ja.md index 759ea8461..c1c449117 100644 --- a/content/advanced/modules/consume-example/index.ja.md +++ b/content/advanced/modules/consume-example/index.ja.md @@ -15,7 +15,7 @@ AWS アカウントの、特定の AWS リージョンのプライベートレ touch use-module.yaml ::: -テキストエディターでこのファイルを開き、以下の CloudFormatoin YAML コードを貼り付けます。 +テキストエディターで `use-module.yaml` を開き、以下の CloudFormation の YAML コードを貼り付けます。 :::code{language=yaml showLineNumbers=false showCopyAction=true} diff --git a/content/advanced/modules/create-example/index.ja.md b/content/advanced/modules/create-example/index.ja.md index 93c8c8b39..40ae1effe 100644 --- a/content/advanced/modules/create-example/index.ja.md +++ b/content/advanced/modules/create-example/index.ja.md @@ -31,14 +31,16 @@ cfn init いくつかの質問に対し、回答を入力します。 - Initializing new project - Do you want to develop a new resource(r) or a module(m) or a hook(h)?. - >> m - What's the name of your module type? - (::::::MODULE) - >> CFNWORKSHOP::EC2::VPC::MODULE - Directory /home/user/cfn101-workshop/module/fragments Created - Initialized a new project in /home/user/cfn101-workshop/module +:::code{language=shell showLineNumbers=false showCopyAction=false} +Initializing new project +Do you want to develop a new resource(r) or a module(m) or a hook(h)?. +>> m +What's the name of your module type? +(::::::MODULE) +>> CFNWORKSHOP::EC2::VPC::MODULE +Directory /PATH-TO-YOUR-DIRECTORY/cfn101-workshop/module/fragments Created +Initialized a new project in /PATH-TO-YOUR-DIRECTORY/cfn101-workshop/module +::: コマンドを実行することで、ディレクトリ内に何が作成されたのかを見てみましょう。 @@ -64,10 +66,10 @@ CloudFormation モジュールは、このワークショップで既に作成 touch fragments/module.yaml ::: -テキストエディターでこのファイルを開き、以下の CloudFormation YAML コードを貼り付けます。 +テキストエディターで `module.yaml` を開き、以下の CloudFormation YAML コードを貼り付けます。 -:::code{language=yaml showLineNumbers=false showCopyAction=true} +:::code{language=yaml showLineNumbers=true showCopyAction=true} AWSTemplateFormatVersion: 2010-09-09 Description: A full VPC Stack @@ -242,13 +244,13 @@ cfn submit 次のような出力が表示されます。 -``` +:::code{language=shell showLineNumbers=false showCopyAction=false} Module fragment is valid. Successfully submitted type. Waiting for registration with token '{token}' to complete. Registration complete. {'ProgressStatus': 'COMPLETE', 'Description': 'Deployment is currently in DEPLOY_STAGE of status COMPLETED', ... -... -``` +...} +::: これで [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) にアクセスすると、レジストリのページの `アクティブ化済みの拡張機能` セクションに新しいモジュールが表示されるはずです。 diff --git a/content/advanced/resource-types/example-in-python/index.ja.md b/content/advanced/resource-types/example-in-python/index.ja.md index d285e6da4..05fa2f0dd 100644 --- a/content/advanced/resource-types/example-in-python/index.ja.md +++ b/content/advanced/resource-types/example-in-python/index.ja.md @@ -312,6 +312,140 @@ aws cloudformation deregister-type \ --type RESOURCE ::: +リソースタイプ、モジュール、フックなどの CloudFormation エクステンションを登録するために `cfn submit` コマンドを使用すると、CFN-CLI はご利用の AWS アカウントに 2 つの CloudFormation スタックを作成します。1 つはエクステンション (リソースタイプエクステンションやフックエクステンションのためなど) の実行ロールを作成するのもです。もう 1 つはエクステンションのインフラストラクチャーコンポーネントを持つものです。また、CFN-CLI は両方のスタックに削除保護を設定します。この 2 つのスタックとは、このラボ専用の `awssamples-ec2-importkeypair-role-stack` スタックと、このラボや、同じアカウントで CFN-CLI を使用し開発や登録をしているその他のエクステンションで共通使用されている `CloudFormationManagedUploadInfrastructure` スタックです。 + +次に示す手順に沿って、`awssamples-ec2-importkeypair-role-stack` スタックを削除します。まず、削除保護を解除します。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-termination-protection \ + --region us-east-1 \ + --no-enable-termination-protection \ + --stack-name awssamples-ec2-importkeypair-role-stack +::: + +次に `awssamples-ec2-importkeypair-role-stack` スタックを削除します。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ + --region us-east-1 \ + --stack-name awssamples-ec2-importkeypair-role-stack + +aws cloudformation wait stack-delete-complete \ + --region us-east-1 \ + --stack-name awssamples-ec2-importkeypair-role-stack +::: + +もう 1 つの `CloudFormationManagedUploadInfrastructure` スタックは、[AWS Key Management Service (AWS KMS)](https://aws.amazon.com/jp/kms/) のキーと 2 つの Amazon S3 バケットなどを作成します。バケットには、このラボを進める際に CFN-CLI がユーザーに代わって作成してアップロードしたリソースタイプの ZIP アーカイブなど、CloudFormation 拡張機能のレジストリに送信ために必要なデータを保持しています。この ZIP アーカイブを削除するには、まず S3 バケットの名前を特定することから始めます。スタック内で `ArtifactBucket` 論理 ID を持つバケットを以下の通りに取得します。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-resources \ + --region us-east-1 \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --query "StackResources[?LogicalResourceId=='ArtifactBucket'].PhysicalResourceId" \ + --output text +::: + +このコマンドが `ArtifactBucket` のバケット名 (例えば `cloudformationmanageduploadinfra-accesslogsbucket-[...省略...]`) を返します。メモにとってください。以下のコマンドでそのバケットの内容の一覧を取得します。コマンドのパラメータをメモにとったバケット名に書き換えてください。 + +:::code{language=shell showLineNumbers=false showCopyAction=false} +aws s3 ls s3://NAME-OF-YOUR-cloudformationmanageduploadinfrast-artifactbucket-[...] +::: + +このコマンドでは、リソースタイプの情報を持つ ZIP ファイルを `AWSSamples-EC2-ImportKeypair-YYYY-MM-ddthh-MM-SS.zip` のような形の名前で表示されるはずです。ファイル名をメモします。`ArtifactBucket` バケットはバージョニングが有効になっているため、上記の ZIP ファイルオブジェクトのバージョン ID に関する情報を収集する必要があります。以下のコマンドのパラメータをメモしたバケット名とファイル名に置き換えて実行します。 + +:::code{language=shell showLineNumbers=false showCopyAction=false} +aws s3api list-object-versions \ + --bucket YOUR-cloudformationmanageduploadinfrast-artifactbucket \ + --prefix awssamples-ec2-importkeypair-YYYY-MM-DDTHH-MM-SS.zip \ + --query "Versions[*].VersionId" --output text +::: + +ZIP ファイルのバージョン ID が `abcExampleAbCDExampleABCDExample` のように出力されるはずです。こちらもメモして、以下の通りにオブジェクトのバージョンを削除します。コマンドにメモしたバケット名、ファイル名、バージョン ID 情報を必ず置き換えてください。 + +:::code{language=shell showLineNumbers=false showCopyAction=false} +aws s3api delete-object \ + --bucket YOUR-artifactbucket-name \ + --key awssamples-ec2-importkeypair-YYYY-MM-DDTHH-MM-SS.zip \ + --version-id abcdEXAMPLEabcdEXAMPLEabcdEXAMPLE +::: + +このラボでリソースタイプを複数回レジストリに送信した場合、名前が `awssamples-ec2-importkeypair-` で始まるオブジェクトがバケット内に複数見つかる可能性があり、これらも上記と同じ方法で削除する必要があります。 + +::alert[`CloudFormationManagedUploadInfrastructure` スタックは、CloudFormation 拡張機能をアカウントのレジストリに送信するために使用されるリソースを管理します。**このラボを実施するために使用されているアカウントで、他のリソースタイプ、モジュール、フックなど、他に CloudFormation 拡張機能を作成している場合、`CloudFormationManagedUploadInfrastructure` スタックで管理している S3 バケットに、他のオブジェクトが見つかる場合があります。それらのオブジェクトを削除しない場合は、このクリーンアップセクションの残りの部分もスキップしてください**。他にオブジェクトがなかった場合は、次の手順に進んでください。]{type="warning"} + +次は、スタック内の論理 ID が `AccessLogsBucket` である S3 バケットのバケット名を特定します。次のコマンドでリソースから抽出します。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-resources \ + --region us-east-1 \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --query "StackResources[?LogicalResourceId=='AccessLogsBucket'].PhysicalResourceId" \ + --output text +::: + +上記のコマンドで `AccessLogsBucket` のバケット名を取得できるはずです。たとえば、`cloudformationmanageduploadinfra-accesslogsbucket-[...省略...]` のような形です。メモをします。このラボの実行の途中でこのバケットにオブジェクトが作成された場合があります。以下のコマンドを使用してその内容の一覧を表示します。コマンドのバケット名はメモしたバケット名で置き換えてください。 + +:::code{language=shell showLineNumbers=false showCopyAction=false} +aws s3 ls s3://NAME-OF-YOUR-cloudformationmanageduploadinfra-accesslogsbucket-[...] +::: + +この [ページ](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/ServerLogs.html#how-logs-delivered) で説明されているように、サーバーアクセスログを有効にすると Amazon S3 はバケット (この場合はログバケットを使用するアーティファクト用のバケット) のアクセスログを定期的に収集して統合し、そのログをターゲットのロギングバケットにアップロードします。現時点でログバケットにオブジェクトが表示されない場合でも、状況によっては、後でログバケットを削除しようとしたときにログが配信された可能性があります。オブジェクトを含むバケットは削除できません。その場合、ログバケットを作成したスタックを削除するとエラーが発生します。ログバケットのログファイルを削除する場合は、先ほどのアーティファクトバケット内のオブジェクトの対応方法と同様のプロセスを実施します。その後に再度ログバケット (または作成したスタック) の削除を試みことができます。以下の手順で実施できます。 + +`CloudFormationManagedUploadInfrastructure` スタックを削除する前に、`AccessLogsBucket` と `EncryptionKey` の `DeletionPolicy: Retain` と `UpdateReplacePolicy: Retain` を無効化する必要があります。テンプレートを取得して、`CloudFormationManagedUploadInfrastructure.template` に保存してください。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation get-template \ + --region us-east-1 \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --query TemplateBody \ + --output text > CloudFormationManagedUploadInfrastructure.template +::: + +テキストエディタで `CloudFormationManagedUploadInfrastructure.template` を開き、以下の通りに修正します。 +- 全ての `DeletionPolicy: Retain` を `DeletionPolicy: Delete` に書き換えます。 +- 全ての `UpdateReplacePolicy: Retain` を `UpdateReplacePolicy: Delete` に書き換えます。 + +修正済みテンプレートを保存して、スタックのアップデートに使います。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack \ + --region us-east-1 \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --template-body file://CloudFormationManagedUploadInfrastructure.template \ + --capabilities CAPABILITY_IAM + +aws cloudformation wait stack-update-complete \ + --region us-east-1 \ + --stack-name CloudFormationManagedUploadInfrastructure +::: + +不要となった修正済みテンプレートファイルを削除します。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +rm CloudFormationManagedUploadInfrastructure.template +::: + +`CloudFormationManagedUploadInfrastructure` スタックの削除保護を解除します。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-termination-protection \ + --region us-east-1 \ + --no-enable-termination-protection \ + --stack-name CloudFormationManagedUploadInfrastructure +::: + +`CloudFormationManagedUploadInfrastructure` スタックを削除します。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ + --region us-east-1 \ + --stack-name CloudFormationManagedUploadInfrastructure + +aws cloudformation wait stack-delete-complete \ + --region us-east-1 \ + --stack-name CloudFormationManagedUploadInfrastructure +::: + ### まとめ おめでとうございます! Python でのサンプルリソースタイプ実装を一通り実施し、リソースタイプを作成する際に留意すべき重要な概念、期待される事項、目的を学びました。 diff --git a/content/advanced/resource-types/prerequisites/index.ja.md b/content/advanced/resource-types/prerequisites/index.ja.md index ae5edda0d..972db3340 100644 --- a/content/advanced/resource-types/prerequisites/index.ja.md +++ b/content/advanced/resource-types/prerequisites/index.ja.md @@ -22,7 +22,7 @@ weight: 310 ::alert[CloudFormation CLI のバージョン 1.0 がすでにインストールされている場合は、バージョン 2.0 にアップグレードし、使用する言語プラグインもアップグレードすることをお勧めします。アップグレードには、前に示した `pip install` コマンドの `--upgrade` オプションを使用し、使用している、または、使用する予定の言語プラグインを含めることができます。詳細については、[ページ](https://docs.aws.amazon.com/ja_jp/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html#resource-type-setup) の下部にある *Upgrading to CFN-CLI 2.0* をご参照ください。]{type="info"} -* [Python での実装例](../example-in_python) ラボでは、サンプルアプリケーションのユニットテストを実行するために必要な以下のパッケージをインストールします。 +* [Python での実装例](../example-in-python) ラボでは、サンプルアプリケーションのユニットテストを実行するために必要な以下のパッケージをインストールします。 :::code{language=shell showLineNumbers=false showCopyAction=true} pip install pytest-cov cloudformation-cli-python-lib diff --git a/content/basics/operations/helper-scripts/index.ja.md b/content/basics/operations/helper-scripts/index.ja.md index 7acb46026..c9ac1790e 100644 --- a/content/basics/operations/helper-scripts/index.ja.md +++ b/content/basics/operations/helper-scripts/index.ja.md @@ -3,6 +3,10 @@ title: "ヘルパースクリプト" weight: 400 --- +_ラボ実施時間 : 15分程度_ + +--- + ### 概要 このラボでは、CloudFormation [ヘルパースクリプト](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-helper-scripts-reference.html) について学習します。前のラボで学んだことは素晴らしい出発点です。しかし、`UserData` から気づくかもしれませんが手続き型スクリプトは理想的ではありません。シンプルな PHP アプリケーションをデプロイしたが、ユーザーデータにより複雑なアプリを書こうとすることを想像してみてください。それは非常に難しいでしょう。 @@ -31,12 +35,12 @@ weight: 400 Amazon EC2 インスタンスのためにメタデータを指定するには、`AWS::CloudFormation::Init` タイプを使用する必要があります。テンプレートが `cfn-init` スクリプトを実行すると、スクリプトはメタデータセクション内のリソースを検索します。テンプレートにメタデータを追加しましょう。 -```yaml +:::code{language=yaml showLineNumbers=false showCopyAction=true} WebServerInstance: Type: AWS::EC2::Instance Metadata: AWS::CloudFormation::Init: -``` +::: #### 2. cfn-init の設定 @@ -56,7 +60,7 @@ Amazon EC2 インスタンスのためにメタデータを指定するには、 `packages` キーのコードをテンプレートに追加します。 -```yaml +:::code{language=yaml showLineNumbers=false showCopyAction=true} WebServerInstance: Type: AWS::EC2::Instance Metadata: @@ -65,8 +69,7 @@ WebServerInstance: packages: yum: httpd: [] - php: [] -``` +::: ##### 2. `index.php` ファイルの作成 @@ -74,7 +77,7 @@ WebServerInstance: `files` キーのコードをテンプレートに追加します。 -```yaml +:::code{language=yaml showLineNumbers=false showCopyAction=true} WebServerInstance: Type: AWS::EC2::Instance Metadata: @@ -105,7 +108,7 @@ WebServerInstance: mode: 000644 owner: apache group: apache -``` +::: ##### 3. Apache Web サーバーを有効にして起動する @@ -113,7 +116,7 @@ WebServerInstance: `services` キーのコードをテンプレートに追加します。 -```yaml +:::code{language=yaml showLineNumbers=false showCopyAction=true} WebServerInstance: Type: AWS::EC2::Instance Metadata: @@ -128,7 +131,7 @@ WebServerInstance: httpd: enabled: true ensureRunning: true -``` +::: ##### 4. `cfn-init` スクリプトの実行 @@ -138,7 +141,7 @@ WebServerInstance: `UserData` プロパティのコードをテンプレートに追加します。 -```yaml +:::code{language=yaml showLineNumbers=false showCopyAction=true} UserData: Fn::Base64: !Sub | @@ -147,7 +150,7 @@ UserData: yum install -y aws-cfn-bootstrap # Call cfn-init script to install files and packages /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region} -``` +::: ::alert[`!Sub` 組み込み関数は `${AWS::StackName}` と `${AWS::Region}` 変数の値を動的に置き換えます。]{type="info"} @@ -162,7 +165,7 @@ UserData: 1. 両方のファイルのコードをテンプレートにコピーします。 - ```yaml + :::code{language=yaml showLineNumbers=false showCopyAction=true} WebServerInstance: Type: AWS::EC2::Instance Metadata: @@ -191,13 +194,13 @@ UserData: runas=root services: {...} - ``` + ::: 1. テンプレートの `services` セクションで `cfn-hup` を有効にして起動します。 `services` キーのコードをテンプレートに追加します。 - ```yaml + :::code{language=yaml showLineNumbers=false showCopyAction=true} WebServerInstance: Type: AWS::EC2::Instance Metadata: @@ -223,7 +226,7 @@ UserData: files: - /etc/cfn/cfn-hup.conf - /etc/cfn/hooks.d/cfn-auto-reloader.conf - ``` + ::: #### 4. cfn-signal の設定と CreationPolicy 属性の追加 @@ -236,16 +239,16 @@ UserData: 1. `WebServerInstance` リソースに `CreationPolicy` プロパティを追加します。 - ```yaml + :::code{language=yaml showLineNumbers=false showCopyAction=true} CreationPolicy: ResourceSignal: Count: 1 Timeout: PT10M - ``` + ::: 1. `cfn-signal` を UserData パラメータに追加します。 - ```yaml + :::code{language=yaml showLineNumbers=false showCopyAction=true} UserData: Fn::Base64: !Sub | @@ -256,61 +259,50 @@ UserData: /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region} # Call cfn-signal script to send a signal with exit code /opt/aws/bin/cfn-signal --exit-code $? --stack ${AWS::StackName} --resource WebServerInstance --region ${AWS::Region} - ``` + ::: -#### 5. スタックの更新 +#### 5. スタックの作成 スタックを更新して `UserData` プロパティで行った変更を適用するには、EC2 インスタンスを置き換える必要があります。 [こちら](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html?shortFooter=true#aws-properties-ec2-instance-properties)で EC2 インスタンスの置き換えをトリガーする属性を確認できます。 -以下の例では、`AvailabilityZone` プロパティのパラメータを使用して置き換えをトリガーします。 - -1. テンプレートに `AvailabilityZone` パラメータを追加します。 - - ```yaml - Parameters: - AvailabilityZone: - Type: AWS::EC2::AvailabilityZone::Name - ``` - -1. EC2 リソースの **Properties** セクションに `AvailabilityZone` を追加し、上記で作成したパラメータを参照させます。 - - ```yaml - WebServerInstance: - Type: AWS::EC2::Instance - Metadata: - {..} - Properties: - AvailabilityZone: !Ref AvailabilityZone - ``` - -1. デプロイされている Web サーバーのインスタンスのアベイラビリティーゾーンを確認します。 - - + EC2 コンソールの **[インスタンス](https://console.aws.amazon.com/ec2#instances)** に移動 - + `-webserver` インスタンスを選択し、**アベイラビリティーゾーン** の値を書き留めておきます。たとえば、`eu-west-2a`。 - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body`、`--capabilities` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-helper-scripts \ +--template-body file://helper-scripts.yaml \ +--capabilities CAPABILITY_IAM +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-helper-scripts/96d87030-e809-11ed-a82c-0eb19aaeb30f" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +1. インスタンスが正常に作成されたことを確認するために、Web ブラウザで `WebsiteURL` を入力します (WebsiteURL は CloudFormation コンソールの _Outputs_ タブから取得できます)。 +:::: +::::tab{id="local" label="ローカル開発"} 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 -1. スタック名 (例: **cfn-workshop-ec2**) をクリックします。 -1. 画面右上の **更新** ボタンをクリックします。 -1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 -1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 -1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 -1. ステップ1で作成した `helper-scripts.yaml` を指定し、**次へ** をクリックします。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 +1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 +1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 +1. `helper-scripts.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **スタックの名前** (例: `cfn-workshop-helper-scripts`) を入力し、**次へ** をクリックします。 1. **Amazon Machine Image ID** はそのままにしてください。 -1. **AvailabilityZone** にはステップ 3 でメモを取ったアベイラビリティーゾーン以外のものを選択してください。例えば **eu-west-2b**。 - ![az-update](/static/basics/operations/helper-scripts/az-update-1.ja.png) -1. **EnvironmentType** は選択されている環境のままにします。 +1. **EnvironmentType** にはドロップダウンから環境の種類を選択します。例えば **Test** を選択して、**次へ** をクリックします。 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 -1. **レビュー <スタック名>** ページで、一番下までスクロールし、**AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。** チェックボックスをチェックし、**スタックの更新** をクリックします。 - - ::alert[**Change set preview** には、EC2 リソースの _Replacement_ 条件 が **True** になっています。したがって、既存の EC2 インスタンが終了され、新しいインスタンスが作成されます。]{type="info"} - -1. ステータスが **UPDATE_COMPLETE** になるまで、**リフレッシュ** ボタンを数回クリックします。 - -Web ブラウザで `WebsiteURL` を入力します (WebsiteURL は CloudFormation コンソールの _Outputs_ タブから取得できます)。 +1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。** の文言のチェックボックスにチェックを入れます。**送信** をクリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +1. インスタンスが正常に作成されたことを確認するために、Web ブラウザで `WebsiteURL` を入力します (WebsiteURL は CloudFormation コンソールの _Outputs_ タブから取得できます)。 +:::: +::::: #### チャレンジ -このチャレンジでは、スタックを更新したときに `cfn-hup` がアプリケーションを更新する方法を証明します。AMI ID を表示するように index.php ファイルを更新します。 +このチャレンジでは、スタックを更新したときに `cfn-hup` がアプリケーションを更新する方法を証明します。AMI ID を表示するように `index.php` ファイルを更新します。 ##### 1. `index.php` ファイルの変更 @@ -318,11 +310,11 @@ EC2 メタデータの _files_ セクションにある `/var/www/html/index.php 以下のコードを `<\?php {...} ?>` ブロックに追加します。 -```php +:::code{language=php showLineNumbers=false showCopyAction=true} # Get the instance AMI ID and store it in the $ami_id variable $url = "http://169.254.169.254/latest/meta-data/ami-id"; $ami_id = file_get_contents($url); -``` +::: 以下のコードを html `

` タグに追加してください。 @@ -332,21 +324,44 @@ $ami_id = file_get_contents($url); ##### 2. 新しいテンプレートでスタックを更新 -`cfn-hup` はメタデータセクションの変更を検出し、新しいバージョンを自動的にデプロイします。 +`cfn-hup` はメタデータセクションの変更を検出し、新しいバージョンを自動的にデプロイし、既存のインスタンスを更新します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを更新します。必要な `--stack-name`、`--template-body`、`--capabilities` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack --stack-name cfn-workshop-helper-scripts \ +--template-body file://helper-scripts.yaml \ +--capabilities CAPABILITY_IAM +::: +1. `update-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-helper-scripts/96d87030-e809-11ed-a82c-0eb19aaeb30f" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。新しい EC2 インスタンスが作成されないので、すぐ終わるはずです。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-helper-scripts/96d87030-e809-11ed-a82c-0eb19aaeb30f" +::: +:::: +::::tab{id="local" label="ローカル開発"} 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 -1. スタック名 (例: **cfn-workshop-ec2**) をクリックします。 +1. スタック名 (例: `cfn-workshop-helper-scripts`) をクリックします。 1. 画面右上の **更新** ボタンをクリックします。 1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 -1. ステップ1で作成した `helper-scripts.yaml` を指定し、**次へ** をクリックします。 +1. `helper-scripts.yaml` ファイルを指定し、**次へ** をクリックします。 1. **Amazon Machine Image ID** はそのままにしてください。 -1. **AvailabilityZone** はそのままのアベイラビリティーゾーンにしてください。 1. **EnvironmentType** は選択されている環境のままにします。 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 -1. **レビュー <スタック名>** ページで、一番下までスクロールし、**AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。** チェックボックスをチェックし、**スタックの更新** をクリックします。 -1. ステータスが **UPDATE_COMPLETE** になるまで、**リフレッシュ** ボタンを数回クリックします。 +1. **レビュー <スタック名>** ページで、一番下までスクロールし、**AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。** チェックボックスをチェックし、**送信** をクリックします。 +1. ステータスが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: ##### 3. 変更が正常に展開されたことを確認 @@ -358,10 +373,10 @@ $ami_id = file_get_contents($url); 作成したリソースをクリーンアップするには、次の手順を実施します。 -1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** で、このラボで作成したスタックを選択します。たとえば、`cfn-workshop-ec2`。 +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** で、このラボで作成したスタックを選択します (例: `cfn-workshop-helper-scripts`)。 1. 右上の **削除** をクリックします。 1. ポップアップウィンドウで、**削除** をクリックします。 -1. **DELETE_COMPLETE** というステータスが表示されるまで、**更新** ボタンを数回クリックします。 +1. **DELETE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 --- ### まとめ diff --git a/content/basics/operations/multi-region-latest-ami/index.ja.md b/content/basics/operations/multi-region-latest-ami/index.ja.md index 746562fe0..d1e10387d 100644 --- a/content/basics/operations/multi-region-latest-ami/index.ja.md +++ b/content/basics/operations/multi-region-latest-ami/index.ja.md @@ -3,6 +3,10 @@ title: "マルチリージョンの最新の AMI" weight: 100 --- +_ラボ実施時間 : 10分程度_ + +--- + ### 概要 現在のテンプレートをさまざまなリージョンにデプロイするユースケースを考えてみましょう。各 AWS リージョンの AMI ID と一致するために、 手動で `AmiId` を変更する必要があります。同じく、Amazon Machine Image にアップデートがある場合、最新のイメージを使用するために、同じ手動処理が発生します。 @@ -19,39 +23,100 @@ weight: 100 1. `multi-region-latest-ami.yaml` ファイルを開きます。 1. `AmiID` パラメータを次のように更新します。 -```yaml - AmiID: - Type: AWS::SSM::Parameter::Value - Description: The ID of the AMI. - Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' -``` +:::code{language=yaml showLineNumbers=false showCopyAction=true} +AmiID: + Type: AWS::SSM::Parameter::Value + Description: The ID of the AMI. + Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' +::: AWS コンソールに移動し、新しいテンプレートでスタックを更新します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-multi-region-latest-ami \ +--template-body file://multi-region-latest-ami.yaml +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-multi-region-latest-ami/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。 +:::: +::::tab{id="local" label="ローカル開発"} 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 -1. スタック名 (例: **cfn-workshop-ec2**) をクリックします。 -1. 画面右上の **更新** ボタンをクリックします。 -1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 -1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 -1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 -1. ステップ1で作成した `multi-region-latest-ami.yaml` を指定し、**次へ** をクリックします。 -1. **Amazon Machine Image ID** には `/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2` をコピーアンドペーストしてください。 -1. **EnvironmentType** には、リストされているものとは異なる環境を選択します。たとえば、**Dev** が選択されている場合は、**Test** を選択し、**次へ** をクリックします。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 +1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 +1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 +1. `multi-region-latest-ami.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **スタックの名前** (例: `cfn-workshop-multi-region-latest-ami`) を入力し、**次へ** をクリックします。 +1. **Amazon Machine Image ID** には `/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2` をコピーします。 +1. **EnvironmentType** にはドロップダウンから環境の種類を選択します。例えば **Test** を選択して、**次へ** をクリックします。 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**送信** をクリックします。 -1. ステータスが **UPDATE_COMPLETE** になるまで、**リフレッシュ** ボタンを数回クリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: ### チャレンジ 使用していたものとは別のAWSリージョンにテンプレートをデプロイします。 -::expand[コンソールの右上のリージョンをクリックして、別のリージョンを選択します。]{header="解決策を確認しますか?"} - +::::::expand{header="解決策を確認しますか?"} +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。`--region` パラメータは最初にスタックを作成したリージョン以外のリージョンを指定します。例えば、最初に `us-east-1` で作成されていたら、 `us-east-2` を指定します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-multi-region-latest-ami \ +--template-body file://multi-region-latest-ami.yaml \ +--region us-east-2 +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-2:123456789012:stack/cfn-workshop-multi-region-latest-ami/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. 画面右上のリージョン名 (例: **バージニア北部**) をクリックし、別のリージョンを選択します。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 +1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 +1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 +1. `multi-region-latest-ami.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **スタックの名前** (例: `cfn-workshop-multi-region-latest-ami`) を入力し、**次へ** をクリックします。 +1. **Amazon Machine Image ID** には `/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2` をコピペします。 +1. **EnvironmentType** にはドロップダウンから環境の種類を選択します。例えば **Test** を選択して、**次へ** をクリックします。 +1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 +1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**送信** をクリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: :::alert{type="info"} -AMI ID パラメータを更新する必要がなかったことに注意してください。クラウドフォーメーションとシステムとのインテグレーションを利用することで -Manager Parameter Store では、テンプレートがより汎用的で再利用可能になりました。 +AMI ID パラメータを更新する必要がなかったことに注意してください。Systems Manager Parameter Store を利用し CloudFormation をインテグレーションすることで、テンプレートがより汎用的で再利用可能になりました。 ::: +:::::: + +### クリーンアップ +以下の手順の通りに、このラボで作成した [スタックの削除](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-console-delete-stack.html) を行ってください。 + +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動します。 +1. CloudFormation の **スタック** ページで `cfn-workshop-multi-region-latest-ami` を選択します。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +1. CloudFormation のスタックを作成した全てのリージョンで上記の手順を切り返します。 --- ### まとめ -おめでとうございます!これで、最新の Amazon Linux AMI を使用するようにテンプレートが正常に更新できました。さらに、テンプレートは、AMI ID パラメータを追加しなくても、どのリージョンにもデプロイできるようになりました。 +おめでとうございます!これで、最新の Amazon Linux AMI を使用するようにテンプレートを正常に更新できました。さらに、テンプレートは、AMI ID パラメータを追加しなくても、どのリージョンにもデプロイできるようになりました。 diff --git a/content/basics/operations/session-manager/index.ja.md b/content/basics/operations/session-manager/index.ja.md index a0f18aebf..9702ad251 100644 --- a/content/basics/operations/session-manager/index.ja.md +++ b/content/basics/operations/session-manager/index.ja.md @@ -3,6 +3,10 @@ title: "Session Manager" weight: 200 --- +_ラボ実施時間 : 15分程度_ + +--- + ### 概要 [Session Manager](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/session-manager.html) はインタラクティブなワンクリックのブラウザベースのターミナルまたは AWS CLI を使用して Amazon EC2 インスタンスを管理できる AWS Systems Manager のフルマネージド機能です。 @@ -103,7 +107,7 @@ AWS コンソールに移動し、新しいテンプレートでスタックを 1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 -1. ステップ1で作成した `session-manager.yaml` を指定し、**次へ** をクリックします。 +1. `session-manager.yaml` ファイルを指定し、**次へ** をクリックします。 1. **Amazon Machine Image ID** はそのままにしてください。 1. **EnvironmentType** には、リストされているものとは異なる環境を選択します。たとえば、**Dev** が選択されている場合は、**Test** を選択し、**次へ** をクリックします。 :::alert{type="info"} diff --git a/content/basics/operations/troubleshooting-provisioning-errors/index.ja.md b/content/basics/operations/troubleshooting-provisioning-errors/index.ja.md index 5352ebc1c..50f4c8a95 100644 --- a/content/basics/operations/troubleshooting-provisioning-errors/index.ja.md +++ b/content/basics/operations/troubleshooting-provisioning-errors/index.ja.md @@ -3,6 +3,10 @@ title: "プロビジョニングエラーのトラブルシューティング" weight: 500 --- +_ラボ実施時間 : 25分程度_ + +--- + ### 概要 CloudFormation テンプレートの開発を繰り返す中で、CloudFormation [スタック](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacks.html) を作成することで、テンプレートに記述されているリソースのプロビジョニングを検証できます。テンプレート内のリソースの構成に誤ったプロパティ値を指定した場合、デフォルトではスタックは最後に確認された安定した状態にロールバックし、すべてのスタックのリソースはロールバックされます。 @@ -33,17 +37,39 @@ CloudFormation テンプレートの開発を繰り返す中で、CloudFormation 前述のエラーを含む `sqs-queues.yaml` テンプレートを使用してスタックのロールバックの一時停止機能を利用し、エラーを修正してスタックの作成を完了させます。 + +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} + + +1. **Cloud9 のターミナル** で `code/workspace/troubleshooting-provisioning-errors` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/troubleshooting-provisioning-errors +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-troubleshooting-provisioning-errors --template-body file://sqs-queues.yaml --disable-rollback +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-troubleshooting-provisioning-errors/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックのステータスが **CREATE_FAILED** ステータスであることを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動し、使用したい [AWS リージョン](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html) を選択します。 1. 画面の右上の **スタックの作成** プルダウンを開き、**新しいリソースを使用 (標準)** をクリックします。 1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 -1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。前述の `sqs-queues.yaml` テンプレートを選択し、**次** を選択します。 -1. スタック名を指定します (例: `troubleshoot-provisioning-errors-workshop`)。同じページで、`QueueNamePrefix` パラメーターのデフォルト値をそのまま使用し、**次** を選択します。 -1. **スタックの失敗オプション** で、**正常にプロビジョニングされたリソースの保持** を選択します。**次** を選択します。 -1. 次ののページで、ページの下部までスクロールし、**スタックの作成** をクリックします。 +1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。前述の `sqs-queues.yaml` テンプレートを選択し、**次へ** を選択します。 +1. スタック名を指定します (例: `cfn-workshop-troubleshooting-provisioning-errors`)。同じページで、`QueueNamePrefix` パラメーターのデフォルト値をそのまま使用し、**次へ** を選択します。 +1. **スタックの失敗オプション** で、**正常にプロビジョニングされたリソースの保持** を選択します。**次へ** を選択します。 +1. 次のページで、ページの下部までスクロールし、**送信** をクリックします。 1. スタックが `CREATE_FAILED` ステータスになるまで、スタック作成ページを更新します。 +:::: +::::: -前述のエラーが原因で、スタックの作成が失敗しました。リストからスタックの名前を選択します (例: `troubleshoot-provisioning-errors-workshop`)。**リソース** タブで、`DeadLetterQueue` リソースが`CREATE_COMPLETE` ステータスで、`SourceQueue` リソースが `CREATE_FAILED` ステータスの状態を確認出来ます。また、失敗した理ソールの `CREATE_FAILED` メッセージをクリックすると、関連エラーを確認出来ます。 +前述のエラーが原因で、スタックの作成が失敗しました。リストからスタックの名前を選択します (例: `cfn-workshop-troubleshooting-provisioning-errors`)。**リソース** タブで、`DeadLetterQueue` リソースが `CREATE_COMPLETE` ステータスで、`SourceQueue` リソースが `CREATE_FAILED` ステータスの状態を確認出来ます。また、失敗したリソースの `CREATE_FAILED` メッセージをクリックすると、関連エラーを確認出来ます。 同じスページには、次の図に示すように、次に行うステップを選択できるオプションも表示されます。 @@ -51,12 +77,32 @@ CloudFormation テンプレートの開発を繰り返す中で、CloudFormation 目標は、テンプレートのエラーをトラブルシューティングして修正し、プロビジョニングを再開して `SourceQueue` リソースを作成することです。このプロセスの一環として、先に正常に作成された `DeadLetterQueue` の状態を保持します。次のステップ: -1. テキストエディターで `sqs-queues.yaml` テンプレートを開き、`SourceQueue` リソースを探し、`FifoQueue: false` を `FifoQueue: true` に変更します。完了したら、変更を保存します。 +テキストエディターで `sqs-queues.yaml` テンプレートを開き、`SourceQueue` リソースを探し、`FifoQueue: false` を `FifoQueue: true` に変更します。完了したら、変更を保存します。 + +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace/troubleshooting-provisioning-errors` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/troubleshooting-provisioning-errors +::: +1. AWS CLI でスタックを更新します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack --stack-name cfn-workshop-troubleshooting-provisioning-errors --template-body file://sqs-queues.yaml --disable-rollback +::: +1. `update-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-troubleshooting-provisioning-errors/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::tab{id="local" label="ローカル開発"} 1. 前の図に示した **スタックのロールバックが一時停止されました** の枠の中の **更新** ボタンをクリックします。 -1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択し、更新したテンプレートを設定した上で **次** を選択します。 -1. **パラメータ** ページで **次** を選択します。 +1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択し、更新したテンプレートを設定した上で **次へ** を選択します。 +1. **パラメータ** ページで **次へ** を選択します。 1. **スタックオプションの設定** ページで、**スタックの失敗オプション** セクションを探します。スタックの作成時に選択した **正常にプロビジョニングされたリソースの保持** オプションは引き続き選択されているはずです。ページを下にスクロールして、**次へ** を選択します。 1. 次に、**送信** を選択します。 +:::: +::::: スタックが `UPDATE_COMPLETE` ステータスになるまでページを更新します。スタックの **リソース** タブでは、`SourceQueue` リソースが `CREATE_COMPLETE` ステータスになっているはずです。 @@ -101,16 +147,46 @@ CloudFormation テンプレートの開発を繰り返す中で、CloudFormation * この SQS リソースの[ドキュメントページ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html#aws-resource-sqs-queue-return-values)を開き、SQS キューの ARN を取得するために、`Fn::GetAtt` でどの戻り値を利用すべきかを判断してください。この情報に基づいて、先ほど貼り付けたスニペット内の関連する構成が想定どおりであるかどうかを確認します。 ::: -:::expand{header="解決策を確認しますか?"} +::::::expand{header="解決策を確認しますか?"} * テンプレートの中で、`SourceQueueParameter` リソースの `Value: !GetAtt 'SourceQueue.QueueName'` を `Value: !GetAtt 'SourceQueue.Arn'` に変更してください。 -* 更新されたテンプレートを使用して、[スタックの更新](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-direct.html)を行ってください。 + +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace/troubleshooting-provisioning-errors` に移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/troubleshooting-provisioning-errors + ::: +1. AWS CLI でスタックを更新します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation update-stack --stack-name cfn-workshop-troubleshooting-provisioning-errors --template-body file://sqs-queues.yaml --disable-rollback + ::: +1. `update-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-troubleshooting-provisioning-errors/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. スタック名 (例: `cfn-workshop-troubleshooting-provisioning-errors`) をクリックします。 +1. 画面右上の **更新** ボタンをクリックします。 +1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 +1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 +1. `sqs-queues.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 +1. **レビュー <スタック名>** ページで、一番下までスクロールし、**送信** をクリックします。 +1. ステータスが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: * 完全なソリューションを含むテンプレートは、`code/solutions/troubleshooting-provisioning-errors` ディレクトリにあります。 -::: +:::::: ### クリーンアップ このラボで作成したリソースのクリーンアップを行うために、以下の手順を実施してください。 -1. このラボで作成したスタック (例: `troubleshoot-provisioning-errors-workshop`) を選択します。 -1. **[削除]** を選択してスタックを削除し、ポップアップで **[削除]** を選択して確定します。 +1. このラボで作成したスタック (例: `cfn-workshop-troubleshooting-provisioning-errors`) を選択します。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +1. スタックが **DELETE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 --- ### まとめ diff --git a/content/basics/operations/user-data/index.ja.md b/content/basics/operations/user-data/index.ja.md index 10379849e..989b469a5 100644 --- a/content/basics/operations/user-data/index.ja.md +++ b/content/basics/operations/user-data/index.ja.md @@ -3,6 +3,10 @@ title: "ユーザーデータ" weight: 300 --- +_ラボ実施時間 : 10分程度_ + +--- + ### 概要 AWS CloudFormation を使用して、Amazon EC2 インスタンスにアプリケーションを自動的にインストール、設定、および起動できます。そうすることで、直接インスタンスに接続しなくても、デプロイメントの複製や既存のインストールの更新を簡単に行うことができます。時間と労力を大幅に節約できます。 @@ -29,16 +33,16 @@ AWS CloudFormation を使用して、Amazon EC2 インスタンスにアプリ まず、セキュリティグループを作成します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=75} WebServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: 'Enable HTTP access via port 80' -``` +::: Apache Web サーバーはポート 80 でコンテンツを提供するので、セキュリティグループの `SecurityGroupIngress` 属性にインターネットからのアクセスを許可するイングレスルールを作成する必要があります。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=79 highlightLines=83-87} WebServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: @@ -48,23 +52,23 @@ WebServerSecurityGroup: FromPort: 80 ToPort: 80 CidrIp: 0.0.0.0/0 -``` +::: 最後に、セキュリティグループを EC2 インスタンスに関連付けます。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=63 highlightLines=69-70} WebServerInstance: Type: AWS::EC2::Instance Properties: IamInstanceProfile: !Ref EC2InstanceProfile ImageId: !Ref AmiID - InstanceType: !FindInMap [Environment, InstanceType, !Ref EnvType] + InstanceType: !FindInMap [EnvironmentToInstanceType, !Ref EnvironmentType, InstanceType] SecurityGroupIds: - !Ref WebServerSecurityGroup Tags: - Key: Name Value: !Join [ '-', [ !Ref EnvironmentType, webserver ] ] -``` +::: :::alert{type="info"} _セキュリティグループ_ プロパティを変更したため、CloudFormation スタックに存在している EC2 インスタンスが _置換_ されます。[こちら](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html?shortFooter=true#aws-properties-ec2-instance-properties)で EC2 インスタンスの更新時に[置換](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-replacement)が必要になるプロパティを確認できます。 @@ -80,7 +84,7 @@ _セキュリティグループ_ プロパティを変更したため、CloudFor **UserData** は、CloudFormation から EC2 インスタンスに渡されるときに Base64 でエンコードされている必要があります。`Fn::Base64` 組み込み関数を使用して入力文字列をエンコードします。 ::: -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=74} UserData: Fn::Base64: | #!/bin/bash @@ -113,34 +117,56 @@ UserData: EOF -``` +::: #### 3. CloudFormation の _Outputs_ に **WebsiteURL** を追加 以下のコードをコピーして、CloudFormation テンプレートの _Outputs_ セクションに貼り付けます。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=132} WebsiteURL: Value: !Sub http://${WebServerEIP} Description: Application URL -``` +::: #### 4. スタックの更新 -前のラボと同様に、更新されたテンプレートでスタックを更新します。CloudFormation がスタックの更新を完了すると、スクリプトが EC2 インスタンスに Web サーバーをセットアップしたことを確認できます。 +前のラボと同様に、更新されたテンプレートでスタックを作成します。CloudFormation がスタックの作成を完了すると、スクリプトが EC2 インスタンスに Web サーバーをセットアップしたことを確認できます。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body`、`--capabilities` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ +--stack-name cfn-workshop-user-data \ +--template-body file://user-data.yaml \ +--capabilities CAPABILITY_IAM +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=json showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-user-data/96d87030-e809-11ed-a82c-0eb19aaeb30f" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::tab{id="local" label="ローカル開発"} 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 -1. スタック名 (例: **cfn-workshop-ec2**) をクリックします。 -1. 画面右上の **更新** ボタンをクリックします。 -1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 -1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 -1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 -1. ステップ1で作成した `user-data.yaml` を指定し、**次へ** をクリックします。 -1. **Amazon Machine Image ID** はそのままにしてください。 -1. **EnvironmentType** は選択されている環境のままにします。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 +1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 +1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 +1. `user-data.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **スタックの名前** (例: `cfn-workshop-user-data`) を入力し、**次へ** をクリックします。 +1. **Amazon Machine Image ID** はそのままにします。 +1. **EnvironmentType** は選択されている値をそのままにして、**次へ** をクリックします。 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 -1. **レビュー <スタック名>** ページで、一番下までスクロールし、**AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。** チェックボックスをチェックし、**スタックの更新** をクリックします。 -1. ステータスが **UPDATE_COMPLETE** になるまで、**リフレッシュ** ボタンを数回クリックします。 +1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。** の文言のチェックボックスにチェックを入れます。**送信** をクリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: Web ブラウザで `WebsiteURL` を入力します (WebsiteURL は CloudFormation コンソールの _Outputs_ タブから取得できます)。 @@ -150,6 +176,15 @@ Web ブラウザで `WebsiteURL` を入力します (WebsiteURL は CloudFormati ![php-page](/static/basics/operations/user-data/php.png) +### クリーンアップ + +以下の手順の通りに、作成したリソースのクリーンアップを実施してください。 + +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動します。 +1. CloudFormation の **スタック** ページで `cfn-workshop-user-data` を選択します。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +1. スタックが **DELETE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 + --- ### まとめ diff --git a/content/basics/templates/flipping-formats-and-cleanup/index.ja.md b/content/basics/templates/flipping-formats-and-cleanup/index.ja.md index 3c76a63d7..72b7e4f1e 100644 --- a/content/basics/templates/flipping-formats-and-cleanup/index.ja.md +++ b/content/basics/templates/flipping-formats-and-cleanup/index.ja.md @@ -3,6 +3,12 @@ title: "フォーマット変換とクリーンアップ" weight: 1000 --- +_ラボ実施時間 : 10分程度_ + +_チャレンジ : 15分程度_ + +--- + ### 概要 AWS CloudFormation [テンプレート](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-formats.html) は JSON 形式または YAML 形式で記述できます。好みに応じてどちらかを選択できます。詳細については、[AWS CloudFormation テンプレート形式](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-formats.html) を参照してください。 diff --git a/content/basics/templates/intrinsic-functions/index.ja.md b/content/basics/templates/intrinsic-functions/index.ja.md index 4ec706f19..8afdfaa58 100644 --- a/content/basics/templates/intrinsic-functions/index.ja.md +++ b/content/basics/templates/intrinsic-functions/index.ja.md @@ -3,6 +3,10 @@ title: "組み込み関数" weight: 400 --- +_ラボ実施時間 : 10分程度_ + +--- + ### 概要 このラボではテンプレートで **[組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html)** の使い方を紹介します。 @@ -70,24 +74,43 @@ AWS リソースの管理を容易にするため、任意にメタデータを Value: !Join [ '-', [ !Ref InstanceType, webserver ] ] ``` -#### EC2 スタックの更新 +#### EC2 スタックの作成 -それでは、スタックを更新しましょう。AWS コンソールを開き、CloudFormation スタックを更新してください。 +それでは、スタックを作成しましょう。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。`ParameterValue` の **MyAmiId** 値を先ほど `resources.yaml` で記載した値に置き換えます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-intrinsic-functions --template-body file://intrinsic-functions.yaml --parameters ParameterKey="AmiID",ParameterValue="MyAmiId" +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-intrinsic-functions/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::tab{id="local" label="ローカル開発"} 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 -1. スタック名 (例:**cfn-workshop-ec2**) をクリックします。 -1. 画面右上の **更新** ボタンをクリックします。 -1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 -1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 -1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 -1. ステップ 1 で作成した `intrinsic-functions.yaml` を指定し、**次へ** をクリックします。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 +1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 +1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 +1. `intrinsic-functions.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **スタックの名前** (例:`cfn-workshop-intrinsic-functions`) を入力し、**次へ** をクリックします。 1. **Type of EC2 Instance** はデフォルトの値をそのまま使います。 -1. **AmiID** では、`resources.yaml` ファイルにハードコードした AMI ID からコピーして貼り付けて、**次へ** をクリックします。 +1. **Amazon Machine Image ID** には、`resources.yaml` ファイルにハードコードした AMI ID からコピーして貼り付けて、**次へ** をクリックします。 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**送信** をクリックします。 -1. ステータスが **UPDATE_COMPLETE** になるまで、**リフレッシュ** ボタンを数回クリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: -**スタックの更新結果の確認方法** +**スタックの作成結果の確認方法** 1. **[AWS EC2 console](https://console.aws.amazon.com/ec2)** のリンクをブラウザの新しいタブで開きます。 1. 左側のメニューで、**インスタンス** をクリックします。 @@ -96,33 +119,73 @@ AWS リソースの管理を容易にするため、任意にメタデータを ![tags-png](/static/basics/templates/intrinsic-functions/tags.ja.png) ### チャレンジ -**Fn::Sub** 組み込み関数を使って、インスタンスタイプを `InstanceType` という名前のついたタグを追加してください。 +`Fn::Sub` 組み込み関数を使って、インスタンスタイプを `InstanceType` という名前のついたタグを追加してください。 -短縮形は `!Sub` です。 +`Fn::Sub` 組み込み関数の YAML の短縮形は `!Sub` です。 ::expand[**[Fn::Sub](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html)** 関数の AWS ドキュメントをご確認ください]{header="ヒントが必要ですか?"} -:::expand{header="解決策を確認しますか?"} -1. テンプレートに `InstanceType` タグを追加します。 +::::::expand{header="解決策を確認しますか?"} +テンプレートに `InstanceType` タグを追加します。 + +```yaml +Resources: + WebServerInstance: + Type: AWS::EC2::Instance + Properties: + ImageId: !Ref AmiID + InstanceType: !Ref InstanceType + Tags: + - Key: Name + Value: !Join [ '-', [ !Ref InstanceType, webserver ] ] + - Key: InstanceType + Value: !Sub ${InstanceType} +``` + +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを更新します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。`ParameterValue` の **MyAmiId** 値を先ほど `resources.yaml` で記載した値に置き換えます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack --stack-name cfn-workshop-intrinsic-functions --template-body file://intrinsic-functions.yaml --parameters ParameterKey="AmiID",ParameterValue="MyAmiId" +::: +1. `update-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-intrinsic-functions/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. スタック名 (例: `cfn-workshop-intrinsic-functions`) をクリックします。 +1. 画面右上の **更新** ボタンをクリックします。 +1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 +1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックし、作業用ディレクトリに移動します。 +1. `intrinsic-functions.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **Type of EC2 Instance** はデフォルトの値をそのまま使います。 +1. **Amazon Machine Image ID** には、`resources.yaml` ファイルにハードコードした AMI ID からコピーして貼り付けて、**次へ** をクリックします。 +1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 +1. **レビュー <スタック名>** ページで、一番下までスクロールし、**送信** をクリックします。 +1. スタックが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: +最後に、EC2 コンソールでインスタンスの **タグ** タブで `InstanceType` タグが作られていることを確認します。 +:::::: + +### クリーンアップ - ```yaml - Resources: - WebServerInstance: - Type: AWS::EC2::Instance - Properties: - ImageId: !Ref AmiID - InstanceType: !Ref InstanceType - Tags: - - Key: Name - Value: !Join [ '-', [ !Ref InstanceType, webserver ] ] - - Key: InstanceType - Value: !Sub ${InstanceType} - ``` +以下の手順の通りに、このラボで作成したリソースを削除します。 -1. AWS コンソールを開き、CloudFormation スタックを更新します。 -1. EC2 コンソールで、`InstanceType` タグが作られていることを確認します。 -::: +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動します。 +1. CloudFormation の **スタック** ページで作成したスタック (例: `cfn-workshop-intrinsic-functions`) を選択します。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +1. スタックが **DELETE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 --- + ### まとめ おめでとうございます!これで無事にテンプレートで組み込み関数を使うことができました。 diff --git a/content/basics/templates/linting-and-testing/index.ja.md b/content/basics/templates/linting-and-testing/index.ja.md index 91e0de749..ff69c5579 100644 --- a/content/basics/templates/linting-and-testing/index.ja.md +++ b/content/basics/templates/linting-and-testing/index.ja.md @@ -3,6 +3,12 @@ title: "静的解析とテスト" weight: 900 --- +_ラボ実施時間 : 15分程度_ + +_チャレンジ : 3分程度_ + +--- + ### 概要 ソフトウェア開発ライフサイクル (Software Development Life Cycle, SDLC) の早い段階において CloudFormation テンプレートの静的解析 (lint) とテストをしておくことはベストプラクティスです。まず、自身のワークステーションで lint とテストのアクションを実行します。次に、テンプレートの lint とテストをパイプラインの継続的インテグレーション (Continuous Integration, CI) のフェーズに組み込みます。CI フェーズをコードプロモーションの最初の導入口として使うのです。 diff --git a/content/basics/templates/mappings/index.ja.md b/content/basics/templates/mappings/index.ja.md index b09028116..e3c38de09 100644 --- a/content/basics/templates/mappings/index.ja.md +++ b/content/basics/templates/mappings/index.ja.md @@ -3,14 +3,18 @@ title: "マッピング" weight: 600 --- +_ラボ実施時間 : 10分程度_ + +--- + ### 概要 このラボでは、**[マッピング](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html)** を紹介します。_マッピング_セクションは、CloudFormation テンプレートのトップレベルセクションで、テンプレートで参照できるキーと値のマップを定義します。 ![マッピングセクションの構造図](/static/basics/templates/mappings/mapping.png) -マッピングセクションの簡単な例を以下に紹介します。`AnExampleMapping` という 1 つのマップが含まれています。\ -`AnExampleMapping` には、`TopLevelKey01`、`TopLevelKey02` と `TopLevelKey03` という 3 つのトップレベルキーが含まれています。\ +マッピングセクションの簡単な例を以下に紹介します。`AnExampleMap` という 1 つのマップが含まれています。\ +`AnExampleMap` には、`TopLevelKey01`、`TopLevelKey02` と `TopLevelKey03` という 3 つのトップレベルキーが含まれています。\ 各トップレベルキーには、1 つ以上の `Key: Value` ペアが含まれています。 :::code{language=yaml showLineNumbers=false showCopyAction=false} @@ -104,20 +108,38 @@ Tags: #### 5. 最後に、ソリューションをデプロイします -テンプレートにマッピングセクションを追加したので、AWS コンソールに移動して CloudFormation スタックを更新します。 +テンプレートにマッピングセクションを追加したので、AWS コンソールに移動して CloudFormation スタックを作成します。 -1. **[AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** を新しいタブで開き、必要に応じて AWS アカウントにログインします。 -1. スタック名 (例: **cfn-workshop-ec2**) を選択します。 -1. 画面右上の **更新** ボタンをクリックします。 -1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 -1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 -1. **ファイルの選択** ボタンをクリックし、ワークショップのディレクトリに移動します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。`ParameterValue` の **MyAmiId** 値を先ほど `resources.yaml` で記載した値に置き換えます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-mappings --template-body file://mappings.yaml --parameters ParameterKey="AmiID",ParameterValue="MyAmiId" +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-mappings/f5a16f40-eb42-11ed-8ce8-1246a18a4ddd" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 +1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 +1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 1. `mappings.yaml` ファイルを指定し、**次へ** をクリックします。 -1. **Amazon マシンイメージ ID** については、デフォルト値のままにしてください。 -1. **EnvironmentType** には、ドロップダウンリストから環境を選択し (例:**Test**)、**次へ**をクリックします。 +1. **スタックの名前** (例: `cfn-workshop-mappings`) を入力し、**次へ** をクリックします。 +1. **Amazon Machine Image ID** はそのままにしてください。 +1. **EnvironmentType** にはドロップダウンから環境の種類を選択します。例えば **Test** を選択して、**次へ** をクリックします。 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 -1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**変更セットのプレビュー** の内容が表示されることをしばらく待ち、**送信** をクリックします。 -1. ステータスが **UPDATE_COMPLETE** になるまで、**リフレッシュ** ボタンを数回クリックします。 +1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**送信** をクリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::::: ### チャレンジ @@ -126,14 +148,14 @@ Tags: `EnvironmentType` パラメータで許可される値のリストに `Dev` を追加することを忘れないでください。 :::expand{header="ヒントが必要ですか?"} -1. _Parameters_ セクションには - * `Dev` を `EnvironmentType` の AllowedValues リストに追加 +1. `Parameters` セクションには + * `Dev` を `EnvironmentType` の AllowedValues リストに追加 1. `Mappings` セクションには - * `Dev` のトップレベルキーを追加 - * 名前と値のペア `InstanceType: t2.nano` を追加 + * `Dev` のトップレベルキーを追加 + * 名前と値のペア `InstanceType: t2.nano` を追加 ::: -:::expand{header="解決策を確認しますか?"} +::::::expand{header="解決策を確認しますか?"} ```yaml Parameters: EnvironmentType: @@ -155,14 +177,56 @@ Mappings: Prod: InstanceType: t2.small ``` + 完全なソリューションは、`code/solutions/mappings.yaml` ファイルにあります。 -::: -ソリューションが機能することをテストするには、[5. 最後に、ソリューションをデプロイします](#5.) のステップで行ったようにスタックを更新し、`EnvironmentType` を **Dev** に変更してください。 +ソリューションの動作を確認するために、以下のステップを実施します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを更新します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。`ParameterValue` の **MyAmiId** 値を先ほど `resources.yaml` で記載した値に置き換えます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack --stack-name cfn-workshop-mappings --template-body file://mappings.yaml --parameters ParameterKey="AmiID",ParameterValue="MyAmiId" ParameterKey="EnvironmentType",ParameterValue="Dev" +::: +1. `update-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-mappings/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. スタック名 (例: `cfn-workshop-ec2`) をクリックします。 +1. 画面右上の **更新** ボタンをクリックします。 +1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 +1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックし、作業用ディレクトリに移動します。 +1. `mappings.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **Amazon Machine Image ID** はそのままにしてください。 +1. **EnvironmentType** にはプールダウンから **Dev** 環境を選択し、**次へ** をクリックします。 +1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 +1. **レビュー <スタック名>** ページで、一番下までスクロールし、**送信** をクリックします。 +1. スタックが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: ::alert[タイプを変更する前に EC2 インスタンスを停止する必要があるため、インスタンスタイプを変更するとダウンタイムが発生します。]{type="info"} +:::::: + +### クリーンアップ + +以下の手順で作成したリソースの削除を行います。 + +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動します。 +1. CloudFormation の **スタック** ページで `cfn-workshop-mappings` を選択します。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +1. スタックが **DELETE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 --- + ### まとめ 素晴らしいです!これで、マッピングを使用してより柔軟な CloudFormation テンプレートを作成する方法を学習できました。 diff --git a/content/basics/templates/outputs/index.ja.md b/content/basics/templates/outputs/index.ja.md index 0578842b0..90cd0af94 100644 --- a/content/basics/templates/outputs/index.ja.md +++ b/content/basics/templates/outputs/index.ja.md @@ -3,6 +3,10 @@ title: "出力" weight: 700 --- +_ラボ実施時間 : 10分程度_ + +--- + ### 概要 このラボでは、**[出力](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html)** について学びます。_出力_ はスタック内のリソースの情報にアクセス可能にするセクションです。例えば、作成された EC2 インスタンスのパブリック DNS 名を出力することができます。 @@ -38,18 +42,47 @@ Outputs: インスタンスの _PublicDnsName_ を取得するには、`Fn::GetAtt` 組み込み関数を使う必要があります。 1. まずは使用可能な属性について、[AWS ドキュメント](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#aws-properties-ec2-instance-return-values) を確認しましょう。_PublicDnsName_ は `Fn::GetAtt` で入手できるプロパティであることを確認できます。 -以下のセクションをテンプレートに追加してください。 - -```yaml -Outputs: - EC2PublicDNS: - Description: 'Public DNS of EC2 instance' - Value: !GetAtt WebServerInstance.PublicDnsName -``` - -5. AWS コンソールに移動し、新しいテンプレートでスタックを更新します。 - -6. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)の _出力_ タブから出力値を確認します。 + 以下のセクションをテンプレートに追加してください。 + ```yaml + Outputs: + EC2PublicDNS: + Description: 'Public DNS of EC2 instance' + Value: !GetAtt WebServerInstance.PublicDnsName + ``` + +1. この新しいテンプレートでスタックを作成します。 + + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **Cloud9 のターミナル** で `code/workspace` に移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace + ::: + 1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。`ParameterValue` の **MyAmiId** 値を先ほど `resources.yaml` で記載した値に置き換えます。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation create-stack --stack-name cfn-workshop-outputs --template-body file://outputs.yaml --parameters ParameterKey="AmiID",ParameterValue="MyAmiId" + ::: + 1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-outputs/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: + 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 + :::: + ::::tab{id="local" label="ローカル開発"} + 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 + 1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 + 1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 + 1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 + 1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 + 1. `outputs.yaml` ファイルを指定し、**次へ** をクリックします。 + 1. **スタックの名前** (例: `cfn-workshop-outputs`) を入力し、**次へ** をクリックします。 + 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 + 1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**送信** をクリックします。 + 1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 + :::: + ::::: + +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)の _出力_ タブから出力値を確認します。 ### チャレンジ @@ -62,36 +95,77 @@ Outputs: ::expand[[AWS::EC2::EIP リソース](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-eip.html) の AWS ドキュメントを確認してください。]{header="ヒントが必要ですか?"} -:::expand{header="解決策を確認しますか?"} -```yaml -Resources: - WebServerInstance: - Type: AWS::EC2::Instance - Properties: - ImageId: !Ref AmiID - InstanceType: !FindInMap [EnvironmentToInstanceType, !Ref EnvironmentType, InstanceType] - Tags: - - Key: Name - Value: !Join [ '-', [ !Ref EnvironmentType, webserver ] ] - - WebServerEIP: - Type: 'AWS::EC2::EIP' - Properties: - Domain: vpc - InstanceId: !Ref WebServerInstance - -Outputs: - WebServerPublicDNS: - Description: 'Public DNS of EC2 instance' - Value: !GetAtt WebServerInstance.PublicDnsName - - WebServerElasticIP: - Description: 'Elastic IP assigned to EC2' - Value: !Ref WebServerEIP -``` -::: +::::::expand{header="解決策を確認しますか?"} + ```yaml + Resources: + WebServerInstance: + Type: AWS::EC2::Instance + Properties: + ImageId: !Ref AmiID + InstanceType: !FindInMap [EnvironmentToInstanceType, !Ref EnvironmentType, InstanceType] + Tags: + - Key: Name + Value: !Join [ '-', [ !Ref EnvironmentType, webserver ] ] + + WebServerEIP: + Type: 'AWS::EC2::EIP' + Properties: + Domain: vpc + InstanceId: !Ref WebServerInstance + + Outputs: + WebServerPublicDNS: + Description: 'Public DNS of EC2 instance' + Value: !GetAtt WebServerInstance.PublicDnsName + + WebServerElasticIP: + Description: 'Elastic IP assigned to EC2' + Value: !Ref WebServerEIP + ``` +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace + ::: +1. AWS CLI でスタックを更新します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。`ParameterValue` の **MyAmiId** 値を先ほど `resources.yaml` で記載した値に置き換えます。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation update-stack --stack-name cfn-workshop-outputs --template-body file://outputs.yaml --parameters ParameterKey="AmiID",ParameterValue="MyAmiId" + ::: +1. `update-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-outputs/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)の _出力_ タブから出力値を確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. スタック名 (例: `cfn-workshop-outputs`) をクリックします。 +1. 画面右上の **更新** ボタンをクリックします。 +1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 +1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックし、作業用ディレクトリに移動します。 +1. `outputs.yaml` を指定し、**次へ** をクリックします。 +1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 +1. **レビュー <スタック名>** ページで、一番下までスクロールし、**送信** をクリックします。 +1. スタックが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)の _出力_ タブから出力値を確認します。 +:::: +::::: +:::::: + +### クリーンアップ + +以下の手順で作成したリソースの削除を行います。 + +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動します。 +1. CloudFormation の **スタック** ページで `cfn-workshop-outputs` を選択します。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +1. スタックが **DELETE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 --- + ### まとめ すばらしいです!これで CloudFormation テンプレートで **出力** を使う方法を学ぶことができました。 diff --git a/content/basics/templates/pseudo-parameters/index.ja.md b/content/basics/templates/pseudo-parameters/index.ja.md index 6b326ef80..21134d9c7 100644 --- a/content/basics/templates/pseudo-parameters/index.ja.md +++ b/content/basics/templates/pseudo-parameters/index.ja.md @@ -3,8 +3,12 @@ title: "擬似パラメータ" weight: 500 --- +_ラボ実施時間 : 15分程度_ + +--- + ### 概要 -このラボでは、[擬似パラメータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html)を使って再利用可能なテンプレートの作り方について学びます。 +このラボでは、**[擬似パラメータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html)** を使って再利用可能なテンプレートの作り方について学びます。 ### カバーされるトピック このラボの完了までに次のことができるようになります。 @@ -113,7 +117,7 @@ DemoRole: `DemoRole` の `Policies` セクションを特定し、`Resouce: *` を含むすべての行を次で置き換えてください。 ```yaml - Resource: !Sub 'arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${BasicParameter}' +Resource: !Sub 'arn:${AWS::Partition}:ssm:${AWS::Region}:${AWS::AccountId}:parameter/${BasicParameter}' ``` 最後に、`pseudo-parameters.yaml` テンプレートファイルの `Resources` セクションに以下のサンプルスニペットを追加します。このスニペットは、上記で定義した IAM ロールを使って、定義したばかりの SSM パラメータの読み取り権限を持つ Lambda 関数を定義しています。この Lambda 関数は `dbUsername` という SSM パラメータにアクセスできるかをテストするために、Lambda 関数を実行します。 @@ -127,25 +131,45 @@ DemoLambdaFunction: Code: ZipFile: | import boto3 - client = boto3.client('ssm') - def lambda_handler(event, context): response = client.get_parameter(Name='dbUsername') print(f'SSM dbUsername parameter value: {response["Parameter"]["Value"]}') ``` 上記の内容を使って、テンプレートを更新してください。次に [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation) を開き、このテンプレートを使ってスタックを作成してください。 -* 画面右上の **スタックの作成** をクリックし、_新しいリソースを使用 (標準)_ をクリックしてください。 -* **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 -* **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 -* **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 -* `pseudo-parameters.yaml` を指定し、**次へ** をクリックします。 -* **スタックの名前** (例: **cfn-workshop-pseudo-parameters**) を入力し、**次へ** をクリックします。 -* **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 -* **レビュー** のページで、ページの下部までスクロールし、*機能* セクションに **AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。** の文言のチェックボックスにチェックを入れます。 -* **送信** をクリックします。 作成されたスタックの進捗は CloudFormation コンソールで確認できます。 -* スタックの作成が完了するまで待ってください。ステータスが `CREATE_COMPLETE` になるまでコンソールの表示を更新してください。 + +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace/pseudo-parameters` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/pseudo-parameters +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body`、`--capabilities` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-pseudo-parameters --template-body file://pseudo-parameters.yaml --capabilities CAPABILITY_NAMED_IAM +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-pseudo-parameters/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 +1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 +1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 +1. `pseudo-parameters.yaml` を指定し、**次へ** をクリックします。 +1. **スタックの名前** (例: `cfn-workshop-pseudo-parameters`) を入力し、**次へ** をクリックします。 +1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 +1. **レビュー <スタック名>** ページで、一番下までスクロールし、**AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。** チェックボックスをチェックし、**送信** をクリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +:::::: + +CloudFormation コンソールのスタック画面で、リソースタブで作成されたリソースを確認できます。 ![resources-png](/static/basics/templates/pseudo-parameters/resources.ja.png) @@ -183,17 +207,16 @@ Lambda 関数の実行後、**実行結果**の下の _詳細_ を開くと、** - バケット名を組み立てるときは、このラボで `!Sub` 組み込み関数で擬似パラメータを参照したように、テンプレートパラメータを参照します。例えば、テンプレートパラメータが `S3BucketNamePrefix` の場合、`!Sub '${S3BucketNamePrefix}'` となるように `!Sub` 組み込み関数で参照します。 ::: -:::expand{header="解決策を確認しますか?"} +::::::expand{header="解決策を確認しますか?"} まず、_Parameters_ セクションに S3 バケットプレフィックスとして使うテンプレートパラメータ `S3BucketNamePrefix` を追加します。 ```yaml S3BucketNamePrefix: Description: The prefix to use for your S3 bucket Type: String - Default: my-demo-bucket - AllowedPattern: ^[0-9a-zA-Z]+([0-9a-zA-Z-]*[0-9a-zA-Z])*$ + Default: cfn-workshop + AllowedPattern: ^(?!(^xn--|.$))^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]$ ConstraintDescription: Bucket name prefix can include numbers, lowercase letters, uppercase letters, and hyphens (-). It cannot start or end with a hyphen (-). - MinLength: 3 ``` そして、`DemoBucket` リソースをテンプレートの _Resources_ セクションに追加します。 @@ -205,16 +228,50 @@ DemoBucket: BucketName: !Sub '${S3BucketNamePrefix}-${AWS::Region}-${AWS::AccountId}' ``` 完成した解答コードは、`code/solutions/pseudo-parameters/pseudo-parameters.yaml` を見てください。 -::: -動作が期待通りになることを確認するために、解答をテストしてください。まず、先程作成した[スタックの更新](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-direct.html)をします。スタック更新の際に内容を変更したテンプレートを選択します。スタックの更新が成功するまでしばらく待ち、S3 バケットが `YOUR_BUCKET_NAME_PREFIX-AWS_REGION-YOUR_ACCOUNT_ID` の形式を使っていることを確認してください。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace/pseudo-parameters` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/pseudo-parameters +::: +1. AWS CLI でスタックを更新します。必要な `--stack-name`、`--template-body`、`--capabilities` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack --stack-name cfn-workshop-pseudo-parameters --template-body file://pseudo-parameters.yaml --capabilities CAPABILITY_NAMED_IAM +::: +1. `update-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-pseudo-parameters/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +1. **[Amazon S3](https://console.aws.amazon.com/s3)** のコンソールを開いて、バケット名が `YOUR_BUCKET_NAME_PREFIX-AWS_REGION-YOUR_ACCOUNT_ID` の形になっていることを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. スタック名 (例: `cfn-workshop-pseudo-parameters`) をクリックします。 +1. 画面右上の **更新** ボタンをクリックします。 +1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 +1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックし、作業用ディレクトリに移動します。 +1. `pseudo-parameters.yaml` を指定し、**次へ** をクリックします。 +1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 +1. **レビュー <スタック名>** ページで、一番下までスクロールし、**AWS CloudFormation によって IAM リソースが作成される場合があることを承認します。** チェックボックスをチェックし、**送信** をクリックします。 +1. スタックが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +1. **[Amazon S3](https://console.aws.amazon.com/s3)** のコンソールを開いて、バケット名が `YOUR_BUCKET_NAME_PREFIX-AWS_REGION-YOUR_ACCOUNT_ID` の形になっていることを確認します。 +:::: +::::: +:::::: ### クリーンアップ + 次のステップに従って、作成したリソースを削除してください。 - * **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** で、このラボで作成したスタック (例: `cfn-workshop-pseudo-parameters`) を選択してください。 - * ラボで作ったスタックを削除するため **削除** をクリックし、ポップアップで **削除** をクリックしてください。 +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動します。 +1. CloudFormation の **スタック** ページで `cfn-workshop-pseudo-parameters` を選択します。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +1. スタックが **DELETE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 --- + ### まとめ すばらしいです!これでより再利用可能な CloudFormation テンプレートを作るために擬似パラメータの使い方について学びました。より詳しい情報については、[擬似パラメータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html)を参照してください。 diff --git a/content/basics/templates/resource-return-values/index.ja.md b/content/basics/templates/resource-return-values/index.ja.md index 0aad35469..f814822de 100644 --- a/content/basics/templates/resource-return-values/index.ja.md +++ b/content/basics/templates/resource-return-values/index.ja.md @@ -3,6 +3,10 @@ title: "戻り値の特定" weight: 800 --- +_ラボ実施時間 : 10分程度_ + +--- + ### 概要 [AWS CloudFormation](https://aws.amazon.com/jp/cloudformation/) を使って、テンプレートによってリソースをプログラムで表現することができます。そうした場合、リソースを構成するために、同じテンプレートで定義されている特定のリソースの戻り値の参照が必要な場合があります。 @@ -17,7 +21,7 @@ weight: 800 戻り値については、リソースタイプ毎に [AWS リソースおよびプロパティタイプのリファレンス](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)に記載されています。任意のリソースタイプをリストから選び、ページの右側の **Return values** から `Ref` や `Fn::GetAtt` の[組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html)でどの値が利用可能かを見ることができます。 -[Amazon Simple Storage Service](https://aws.amazon.com/jp/s3/) (Amazon S3) バケットのリソースタイプ `AWS::S3::Bucket` を例として見てみましょう。[AWS リソースおよびプロパティタイプのリファレンス](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)のリストから **Amazon S3** を選びます。次のページで **AWS::S3::Bucket** を選び、このリソースタイプのリファレンスドキュメントを見ます。ページ右側の **Return values** から `AWS::S3::Bucket` リソースタイプで使用可能な戻り値を見ることができます。 +[Amazon Simple Storage Service](https://aws.amazon.com/jp/s3/) (Amazon S3) バケットのリソースタイプ `AWS::S3::Bucket` を例として見てみましょう。[AWS リソースおよびプロパティタイプのリファレンス](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)のリストから **Amazon Simple Storage Service** を選びます。次のページで **AWS::S3::Bucket** を選び、このリソースタイプのリファレンスドキュメントを見ます。ページ右側の **Return values** から `AWS::S3::Bucket` リソースタイプで使用可能な戻り値を見ることができます。 ドキュメントにて、`Ref` や `Fn::GetAtt` の組み込み関数を使う場合に、どのような値が利用可能で返ってくるかを確認しましょう。例えば、バケット名を参照したい場合、バケットリソースの `Ref` に [論理 ID](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html) を指定することで参照できます。もしバケットの [Amazon リソースネーム](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference-arns.html) (ARN) を取得したい場合は、`Fn::GetAtt` を `Arn` 属性と一緒にすることで取得できます。 @@ -38,7 +42,7 @@ weight: 800 次のサンプルのテンプレートスニペットをコピーして `resource-return-values.yaml` ファイルに追記してください。 -```yaml +:::code{language=yaml showLineNumbers=false showCopyAction=true} Resources: S3Bucket: Type: AWS::S3::Bucket @@ -69,7 +73,7 @@ Outputs: S3BucketDomainName: Description: IPv4 DNS name of the bucket. Value: !GetAtt S3Bucket.DomainName -``` +::: テンプレートに貼り付けたテンプレートスニペットには Amazon S3 [バケット](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html) とバケット[ポリシー](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-policy.html)の 2 つのリソースがあります。次に解説します。 @@ -80,15 +84,37 @@ Outputs: それでは、`resource-return-values.yaml` テンプレートを使ってスタックを作成し、ここまで説明してきた動作を実際に見ていきます。 -1. **[AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動します。 -1. **スタックの作成** から、_新しいリソースを使用 (標準)_ をクリックします。 -1. **テンプレートの準備完了** を選びます。**テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。`resource-return-values.yaml` をアップロードし、**次へ** を選択します。 -1. **スタックの名前** (例: **resource-return-values**) を入力し、準備ができたら **次へ**を選択します。 -1. **スタックオプションの設定** はデフォルトの設定のままとし、ページの下部までスクロールし、**次へ** をクリックします。 -1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**スタックの作成** をクリックします。 - -スタックのステータスが `CREATE_COMPLETE` になるまで、ページをリフレッシュします。それでは、スタックイベントと出力値を見ていきます。スタックイベントは次の画像のようになっているはずです。 - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/resource-return-values +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-resource-return-values --template-body file://resource-return-values.yaml +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resource-return-values/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 +1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 +1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 +1. `resource-return-values.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **スタックの名前** (例: `cfn-workshop-resource-return-values`) を入力し、**次へ** をクリックします。 +1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 +1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**送信** をクリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: + +それでは、スタックイベントと出力値を見ていきます。スタックイベントは次の画像のようになっているはずです。 ![resource-return-values.png](/static/basics/templates/resource-return-values/resource-return-values.ja.png) スタックイベントを見ていると、バケットとバケットポリシーが無事に作られていることがわかります。ここで、スタックの**リソース**タブに移動して `S3Bucket` の物理 ID を見つけ、リンクをクリックしてください。[Amazon S3 コンソール](https://console.aws.amazon.com/s3/)のバケットの詳細ページに移動できます。次に、バケットのページで**アクセス許可**を選び**バケットポリシー**セクションのバケットポリシーを確認してください。バケットポリシーの `Resource` セクションで戻り値がどのように置換されているかを見てください。次に、AWS CloudFormation コンソールのスタックの**出力**タブに移動し、表示されているスタックで作成した Amazon S3 バケットの IPv4 DNS 名を確認してください。 @@ -112,11 +138,11 @@ Outputs: * Amazon EC2 インスタンスの[戻り値](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#aws-properties-ec2-instance-return-values) とセキュリティグループの[戻り値](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#aws-properties-ec2-security-group-return-values)を確認し、`Ref` や `Fn::GetAtt` の[組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html)でどのような値が返るかを見てください。 ::: -:::expand{header="解決策を確認しますか?"} +::::::expand{header="解決策を確認しますか?"} * `Ref` 組み込み関数を使って、インスタンスリソースの `SecurityGroups` プロパティにセキュリティグループの論理 ID をリストアイテムとして指定してください。 * Amazon EC2 インスタンスリソースを次の定義のように修正してください。 -```yaml +:::code{language=yaml showLineNumbers=false showCopyAction=true} Ec2Instance: Type: AWS::EC2::Instance Properties: @@ -127,13 +153,13 @@ Ec2Instance: Tags: - Key: Name Value: Resource-return-values-workshop -``` +::: * `Ref` 組み込み関数を使い、インスタンス ID を取得するために Amazon EC2 インスタンスリソースの論理 ID を渡してください。同様にインスタンスのパブリック IP を取得するために、Amazon EC2 インスタンスリソースの論理 ID と `PublicIp` 属性を `Fn::GetAtt` 関数に渡します。 * セキュリティグループの ID を取得するために、セキュリティグループリソースの論理 ID と `GroupId` 属性を `Fn::GetAtt` 関数に渡します。 * テンプレートの `Outputs` セクションを次のように修正します。 -```yaml +:::code{language=yaml showLineNumbers=false showCopyAction=true} Outputs: InstanceID: Description: The ID of the launched instance @@ -146,19 +172,52 @@ Outputs: SecurityGroupId: Description: ID of the security group created Value: !GetAtt InstanceSecurityGroup.GroupId -``` ::: +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace/resource-return-values` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/resource-return-values +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-resource-return-values-challenge --template-body file://resource-return-values-challenge.yaml +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resource-return-values-challenge/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +1. [AWS CloudFormation console](https://console.aws.amazon.com/cloudformation) の _出力_ タブで出力値を確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 +1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 +1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 +1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 +1. `resource-return-values-challenge.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **スタックの名前** (例: `cfn-workshop-resource-return-values-challenge`) を入力し、**次へ** をクリックします。 +1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 +1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**送信** をクリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +1. [AWS CloudFormation console](https://console.aws.amazon.com/cloudformation) の _出力_ タブで出力値を確認します。 +:::: +::::: +:::::: このチャレンジの完全な解答は `code/solutions/resource-return-values/resource-return-values-challenge.yaml` テンプレートにあります。 ### クリーンアップ + 次のステップに従って、このラボの各パートで作成した[スタックを削除](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-console-delete-stack.html)してください。 1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動してください。 -2. CloudFormation コンソールの **スタック**ページで、`resource-return-values` を選択してください。 -3. 詳細ページでスタックを削除するため **削除** を選択し、ポップアップで **削除** を選択してください。 -4. 同様の手順で `resource-return-values-challenge` スタックを削除してください。 +2. CloudFormation コンソールの **スタック**ページで、`cfn-workshop-resource-return-values` を選択してください。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +4. 同様の手順で `cfn-workshop-resource-return-values-challenge` スタックを削除してください。 --- + ### まとめ すばらしいです!これで特定のリソースの戻り値を見つける方法と、それらを他のリソースで `Ref`、`Fn::GetAtt`、`Fn::Sub` の[組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html)で使う方法を学びました。 diff --git a/content/basics/templates/resources/index.ja.md b/content/basics/templates/resources/index.ja.md index cb030122a..78b00b835 100644 --- a/content/basics/templates/resources/index.ja.md +++ b/content/basics/templates/resources/index.ja.md @@ -3,6 +3,10 @@ title: "リソース" weight: 300 --- +_ラボ実施時間 : 10分程度_ + +--- + ### 概要 このラボでは、CloudFormation の最上位の要素 (形式バージョン、説明、メタデータ、パラメータ、リソース) について学んでいきます。 @@ -33,7 +37,7 @@ AWSTemplateFormatVersion: "2010-09-09" _Description_ セクションには、テンプレートに関するコメントを含めることができます。 :::code{language=yaml showLineNumbers=false showCopyAction=true} -Description: AWS CloudFormation workshop - Resources (uksb-1q9p31idr). +Description: AWS CloudFormation workshop - Resources (uksb-1q9p31idr) (tag:resources). ::: #### メタデータ @@ -93,39 +97,57 @@ EC2 リソースタイプの唯一の必須プロパティは _ImageId_ です 1. **[AWS EC2 console](https://console.aws.amazon.com/ec2)** を開きます。 2. **インスタンス** -> **インスタンスを起動** をクリックします。 - 3. **Amazon Linux 2 AMI** `ami-xxxxxxxxx` の ID をコピーします。 - ::alert[x86 と Arm アーキテクチャを選択できるリージョンの場合、必ず **(x86)** AMI ID を使うようにしてください。]{type="info"} + 3. **Amazon Linux 2023 AMI** `ami-xxxxxxxxx` の ID をコピーします。 + ::alert[x86 と Arm アーキテクチャを選択できるリージョンの場合、必ず **64-bit (x86)** AMI ID を使うようにしてください。]{type="info"} 4. AMI ID が見つかったら、コピーして **ImageId** プロパティに貼り付けます。 -::alert[**London Region** の場合の解答について `code/solutions/resources.yaml` ファイルで見ることができます。]{type="info"} +::alert[**米国東部 (バージニア北部) リージョン** の場合の解答を `code/solutions/resources.yaml` ファイルで見ることができます。]{type="info"} -これで EC2 テンプレートをデプロイする準備が整いました。AWS コンソールに戻り、[Template and Stack](../templates/template-and-stack) で実施した時と同様の方法でデプロイを行います。 +これで EC2 テンプレートをデプロイする準備が整いました。[テンプレートとスタック](../template-and-stack) で実施した時と同様の方法でデプロイを行います。 :::alert{type="warning"} これ以降のラボを実施するためには、CloudFormation をデプロイするリージョンに **デフォルト VPC** が必要です。もしデフォルト VPC を削除していた場合、**[デフォルトの VPC を作成する](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/default-vpc.html#create-default-vpc)** の AWS ドキュメントに沿って新しいデフォルト VPC を作成できます。 ::: -1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** リンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 -1. 画面の右上の **スタックの作成** プルダウンを開き、_新しいリソースを使用 (標準)_ をクリックします。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** で `code/workspace` に移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace +::: +1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-resources --template-body file://resources.yaml +::: +1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resources/62df5090-e747-11ed-a22a-0e39ed6c0e49" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: + +::::tab{id="local" label="ローカル開発"} +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 +1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 -1. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 -1. ステップ1で作成した `resources.yaml` を指定します。 -1. **次へ** をクリックします。 -1. **スタックの名前** (例: **cfn-workshop-ec2**) を入力します。 +1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 +1. `resources.yaml` ファイルを指定し、**次へ** をクリックします。 +1. **スタックの名前** (例: `cfn-workshop-resources`) を入力します。 + _スタックの名前_ はスタックを識別します。スタックの目的がわかるような名前を使ってください。 - + **Type of EC2 Instance** には、お好みのインスタンスサイズ (例: **t2.micro**) を選択してください。 - + **次へ** をクリックします。 +1. **Type of EC2 Instance** には、お好みのインスタンスサイズ (例: **t2.micro**) を選択し、**次へ** をクリックします。 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 -1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**スタックの作成** をクリックします。 +1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**送信** をクリックします。 ::alert[これによりお使いのアカウントに EC2 インスタンスが作成されます。デプロイされたスタックのコストを確認するためには、レビューページの **予想コスト** をクリックして、ご確認ください。]{type="info"} -1. ステータスが **CREATE_COMPLETE** になるまで、**リフレッシュ** ボタンを数回クリックします。 +1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 +:::: +::::: ### チャレンジ この練習問題では、AWS CLI を使って、AWS Systems Manager パラメータストアから最新の Amazon Linux AMI ID を取得します。 -::alert[このチャレンジを完了するには、設定が完了された [AWS CLI](../../../prerequisites/awscli) が必要です。]{type="info"} +::alert[このチャレンジを完了するには、[AWS CLI](../../../prerequisites/local-development) が完了していることをご確認ください。Cloud9 環境には最初からインストールされています。]{type="info"} ::expand[[Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/query-for-the-latest-amazon-linux-ami-ids-using-aws-systems-manager-parameter-store/) を確認してみてください。]{header="ヒントが必要ですか?"} @@ -136,13 +158,21 @@ EC2 リソースタイプの唯一の必須プロパティは _ImageId_ です aws ssm get-parameters \ --names /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 \ --query "Parameters[].Value" \ - --region eu-west-2 \ + --region us-east-1 \ --output text ::: - -![ami-id-gif](/static/basics/templates/resources/ami-id.gif) :::: +### クリーンアップ + +以下の手順で作成したリソースの削除を行います。 + +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動します。 +1. CloudFormation の **スタック** ページで `cfn-workshop-resources` を選択します。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +1. スタックが **DELETE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 + --- + ### まとめ おめでとうございます!これで無事に CloudFormation を使って EC2 インスタンスをデプロイする方法について学習できました。 diff --git a/content/basics/templates/template-anatomy/index.ja.md b/content/basics/templates/template-anatomy/index.ja.md index ad10f4b96..ede2fbfc4 100644 --- a/content/basics/templates/template-anatomy/index.ja.md +++ b/content/basics/templates/template-anatomy/index.ja.md @@ -3,6 +3,10 @@ title: "テンプレートの構造" weight: 100 --- +_ラボ実施時間 : 10分程度_ + +--- + ### テンプレート **AWS CloudFormation テンプレート** は **スタック** を構成する AWS リソースの宣言です。テンプレートは JavaScript Object Notation (JSON) または YAML 形式のテキストファイルとして保存します。一般的なテキストファイルであるため、任意のテキストエディタでの作成や編集、他のソースコードと一緒にバージョン管理システムでの管理などが可能です。 diff --git a/content/basics/templates/template-and-stack/index.ja.md b/content/basics/templates/template-and-stack/index.ja.md index 764e0e8e6..bcdca5e49 100644 --- a/content/basics/templates/template-and-stack/index.ja.md +++ b/content/basics/templates/template-and-stack/index.ja.md @@ -3,8 +3,12 @@ title: "テンプレートとスタック" weight: 200 --- +_ラボ実施時間 : 10分程度_ + +--- + ### 概要 -このラボでは、1 つの S3 バケットの宣言を含む、Resources セクションだけで構成された最も基礎的なテンプレートから始めます。 +このラボでは、1 つの S3 バケットの宣言を含む、`Resources` セクションだけで構成された最も基礎的なテンプレートから始めます。 ### カバーするトピック このラボを完了すると、以下のことができるようになります。 @@ -26,30 +30,50 @@ weight: 200 - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 ``` -4. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、AWS アカウントにログインします。 -5. **スタックの作成** をクリックします。 (画面右上をクリックした場合、_新しいリソースを使用 (標準)_ をクリックしてください。) -6. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 -7. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 -8. **ファイルの選択** ボタンをクリックし、作業用ディレクトリに移動します。 -9. ステップ 1で作成した `template-and-stack.yaml` を指定します。 -10. **次へ** をクリックします。 -11. **スタックの名前** (例: **cfn-workshop-s3**) を入力します。 +4. 以下の手順の通りにスタックを作成します。 + + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **Cloud9 のターミナル** で `code/workspace` に移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace + ::: + 1. AWS CLI でスタックを作成します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation create-stack --stack-name cfn-workshop-template-and-stack --template-body file://template-and-stack.yaml + ::: + 1. `create-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-template-and-stack/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: + 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 + :::: + ::::tab{id="local" label="ローカル開発"} + 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のリンクを新しいタブで開き、必要に応じて AWS アカウントにログインします。 + 1. 画面右上の **スタックの作成** をクリックし、**新しいリソースを使用 (標準)** をクリックしてください。 + 1. **テンプレートの準備** では、**テンプレートの準備完了** を選びます。 + 1. **テンプレートの指定** では、**テンプレートファイルのアップロード** を選びます。 + 1. **ファイルの選択** をクリックして、作業ディレクトリに移動します。 + 1. `template-and-stack.yaml` ファイルを指定し、**次へ** をクリックします。 + 1. **スタックの名前** (例: `cfn-workshop-template-and-stack`) を入力します。 + _スタック名_ はスタックを識別します。スタックの目的がわかるような名前を使ってください。 + **次へ** をクリックします。 -12. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 -13. **レビュー <スタック名>** のページで、ページの下までスクロールし、**スタックの作成** をクリックします。 -14. ステータスが **CREATE_COMPLETE** になるまで、**リフレッシュ** ボタンを数回クリックできます。 + 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 + 1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**送信** をクリックします。 + 1. スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 + :::: + :::::: ### チャレンジ -この練習問題では、S3 バケットのバージョニングを有効にします。バージョニングを有効にすることにより、誤った削除や上書きを防止したり、アーカイブすることで以前のバージョンのオブジェクトを取得したりできるようになります。 +この練習問題では、S3 バケットのオブジェクトの誤った削除や上書きを防止したり、バージョニングを有効にします。アーカイブすることで以前のバージョンのオブジェクトを取得できるようになります。 -1. S3 リソースの `Properties` セクションに、 `VersioningConfiguration` プロパティを追加します。 +1. S3 リソースの `Properties` セクションに、`VersioningConfiguration` プロパティを追加します。 2. `Status` を `Enabled` に設定します。 3. テンプレートの変更を反映するために、スタックを更新します。 ::expand[ [AWS::S3::Bucket](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html) リソースの AWS ドキュメントをご確認ください。]{header="ヒントが必要ですか?"} -:::expand{header="解決策を確認しますか?"} +::::::expand{header="解決策を確認しますか?"} 1. 次のコードで、テンプレートのコードを置き換えてください。 ```yaml Resources: @@ -63,29 +87,48 @@ weight: 200 - ServerSideEncryptionByDefault: SSEAlgorithm: AES256 ``` -1. 次のデモのように、スタックを更新します。 - - 1. **[AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** を新しいタブで開き、必要に応じて AWS アカウントにログインします。 - 1. スタック名 (例: **cfn-workshop-s3**) を選択します。 - 1. 画面右上の **更新** ボタンをクリックします。 - 1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 - 1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 - 1. **ファイルの選択** ボタンをクリックし、ワークショップのディレクトリに移動します。 - 1. `code/workspace/template-and-stack.yaml` ファイルを指定し、**次へ** をクリックします。 - 1. **スタックの詳細を指定** では **次へ** をクリックします。 - 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 - 1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**変更セットのプレビュー** の内容が表示されることをしばらく待ち、**送信** をクリックします。 - 1. ステータスが **UPDATE_COMPLETE** になるまで、**リフレッシュ** ボタンを数回クリックします。 -::: +1. 次は、以下の手順の通りにスタックを更新します。 + + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **Cloud9 のターミナル** で `code/workspace` に移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace + ::: + 1. AWS CLI でスタックを更新します。必要な `--stack-name`、`--template-body` パラメータがあらかじめ設定されています。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation update-stack --stack-name cfn-workshop-template-and-stack --template-body file://template-and-stack.yaml + ::: + 1. `update-stack` コマンドが正常に送信されたら、CloudFormation が `StackId` を返します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-template-and-stack/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: + 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** のコンソールを新しいタブで開き、スタックが **CREATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 + :::: + ::::tab{id="local" label="ローカル開発"} + 1. **[AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** を新しいタブで開き、必要に応じて AWS アカウントにログインします。 + 1. スタック名 (例: `cfn-workshop-template-and-stack`) を選択します。 + 1. 画面右上の **更新** ボタンをクリックします。 + 1. **テンプレートの準備** で、**既存テンプレートを置き換える** を選択します。 + 1. **テンプレートの指定** で、 **テンプレートファイルのアップロード** を選びます。 + 1. **ファイルの選択** ボタンをクリックし、ワークショップのディレクトリに移動します。 + 1. `code/workspace/template-and-stack.yaml` ファイルを指定し、**次へ** をクリックします。 + 1. **スタックの詳細を指定** では **次へ** をクリックします。 + 1. **スタックオプションの設定** はデフォルトの設定のままとし、**次へ** をクリックします。 + 1. **レビュー <スタック名>** のページで、ページの下部までスクロールし、**変更セットのプレビュー** の内容が表示されることをしばらく待ち、**送信** をクリックします。 + 1. スタックが **UPDATE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 + :::: + ::::: +:::::: ### クリーンアップ 次のステップに従って、作成したリソースを削除してください。 -1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** で、このラボで作成したスタック (例: `cfn-workshop-s3`) を選択してください。 -1. 画面の右上から **削除** をクリックしてください。 -1. ポップアップウィンドウで、**削除** をクリックします。 -1. ステータスが **DELETE_COMPLETE** になるまで **リフレッシュ** ボタンを数回クリックできます。 +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** に移動します。 +1. CloudFormation の **スタック** ページで `cfn-workshop-template-and-stack` を選択します。 +1. スタックの詳細で **削除** を選択し、ポップアップ上で **削除** で確定します。 +1. スタックが **DELETE_COMPLETE** ステータスになるまで待ちます。必要に応じて、リフレッシュボタンをクリックします。 --- diff --git a/content/intermediate/operations/drift-detection/index.ja.md b/content/intermediate/operations/drift-detection/index.ja.md index 6d8c69532..a63f0c334 100644 --- a/content/intermediate/operations/drift-detection/index.ja.md +++ b/content/intermediate/operations/drift-detection/index.ja.md @@ -26,9 +26,8 @@ CloudFormation は[ドリフト検出](https://docs.aws.amazon.com/ja_jp/AWSClou 開始するには、次の手順に従います。 1. `code/workspace/drift-detection` ディレクトリに移動します。 -2. 以下のコードをコピーして `drift-detection-workshop.yaml` ファイルに追加し、ファイルを保存します。 - -```yaml +1. 以下のコードをコピーして `drift-detection-workshop.yaml` ファイルに追加し、ファイルを保存します。 +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=5} Resources: Table1: Type: AWS::DynamoDB::Table @@ -52,55 +51,152 @@ Resources: Type: AWS::SQS::Queue Properties: MessageRetentionPeriod: 345600 -``` +::: -3. テンプレート内のリソース例をよく確認した上で、実施してください。 +1. テンプレート内のリソース例をよく確認した上で、実施してください。 1. DynamoDB [テーブル](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-dynamodb-table.html) には、正常に作成するための `KeySchema` と `AttributeDefinitions` プロパティの最小限の定義があります。ワークショップ中は、テーブルにデータを保存したり、テーブルからデータを取得したりすることはありません。 - 2. SQS [キュー](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html) の `MessageRetentionPeriod` は 4 日間 (秒単位で表現) です。この値は [デフォルト](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html#cfn-sqs-queue-messageretentionperiod) ですが、CloudFormation はテンプレートで明示的に宣言したプロパティに対してのみドリフトを評価することに注意してください。このプロパティを含めない場合、CloudFormation は後でリソースの変更を報告しません。 - -次のステップでは、AWS CloudFormation コンソールを使用して、このテンプレートを使用して新しいスタックを作成します。 - -1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. **スタックの作成**から、**新しいリソースを使用 (標準)** を選択します。 -3. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。前述の`drift-detection-workshop.yaml` テンプレートを選択し、**次へ**をクリックします。 -4. スタック名を入力します。例えば、`drift-detection-workshop` と入力します。**次へ**をクリックします。 -5. **スタックオプションの設定**ページはデフォルト値のまま、**次へ**をクリックします。 -6. **送信**をクリックします。 -7. スタックが `CREATE_COMPLETE` 状態になるまで、スタック作成ページを更新します。 + 1. SQS [キュー](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html) の `MessageRetentionPeriod` は 4 日間 (秒単位で表現) です。この値は [デフォルト](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html#cfn-sqs-queue-messageretentionperiod) ですが、CloudFormation はテンプレートで明示的に宣言したプロパティに対してのみドリフトを評価することに注意してください。このプロパティを含めない場合、CloudFormation は後でリソースの変更を報告しません。 +1. 次のステップでは、このテンプレートを使用して新しいスタックを作成します。 + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **Cloud9 のターミナル** 上で `cfn101-workshop/code/workspace/drift-detection` ディレクトリに移動します: + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/drift-detection + ::: + 1. AWS CLI コマンドを使ってスタックを作成します。例えばスタック名を `cfn-workshop-drift-detection` と入力します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation create-stack \ +--stack-name cfn-workshop-drift-detection \ +--template-body file://drift-detection-workshop.yaml + ::: + 1. `create-stack` コマンドが成功すると CloudFormation は `StackId` を返却します。 + :::code{language=json showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: + 1. 新しいタブで **[AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** を開いてスタックが **CREATE_COMPLETE** 状態であることを確認します。 + :::: + ::::tab{id="local" label="ローカル開発"} + 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 + 1. **スタックの作成** から、 **新しいリソースを使用 (標準)** を選択します。 + 1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。前述の `drift-detection-workshop.yaml` テンプレートを選択し、 **次へ** をクリックします。 + 1. スタック名を入力します。例えば、`cfn-workshop-drift-detection-workshop` と入力します。 **次へ** をクリックします。 + 1. **スタックオプションの設定** ページはデフォルト値のまま、 **次へ** をクリックします。 + 1. **送信** をクリックします。 + 1. スタックが `CREATE_COMPLETE` 状態になるまで、スタック作成ページを更新します。 + :::: + ::::: ### リソースの変更によるドリフトの検出と修復 -次に、CloudFormation の外部で DynamoDB テーブルを直接変更します。 +次に、CloudFormation の外で DynamoDB テーブルを直接変更します。 1. [Amazon DynamoDB コンソール](https://console.aws.amazon.com/dynamodb/) に移動します。 -2. メニューの**テーブル**見出しの下で、**アクション**、**設定の更新**を選択します。 -3. **Table1** エントリを選択します (テーブル名の先頭にはスタックの名前が付きます)。 -4. **追加の設定**タブを選択します。 -5. **読み取り/書き込みキャパシティー**セクションで、**編集**を選択します。 -6. **オンデマンド**キャパシティモードを選択し、**変更を保存**を選択します。 +1. メニューの **テーブル** 見出しの下で、 **アクション** 、 **設定の更新** を選択します。 +1. **Table1** エントリを選択します (テーブル名の先頭にはスタックの名前が付きます)。 +1. **追加の設定** タブを選択します。 +1. **読み取り/書き込みキャパシティー** セクションで、 **編集** を選択します。 +1. **オンデマンド** キャパシティモードを選択し、 **変更を保存** を選択します。 このステップでは、CloudFormation ドリフト検出を使用して、元のテンプレートと比較して `Table1` リソースに加えられた変更を特定します。 -1. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。必要に応じて、**スタック**メニュー項目を選択してスタックを確認します。 -2. 前のステップで作成したスタック (例えば、`drift-detection-workshop`) を選択します。 -3. **スタックアクション**から、**ドリフトの検出**を選択します。 -4. **スタックの情報**タブに移動し、**ドリフトステータス**フィールドに `DRIFTED` と表示されるまでページを更新します。なお、ドリフト検出が完了するまでに少し時間がかかります。 -5. **スタックアクション**から、**ドリフト結果を表示**を選択します。 -6. ドリフトステータスページが表示されます。画面では、`Table1` が変更され、`Queue1` がテンプレートと同期されていることがわかります。 -7. **リソースのドリフトステータス**ビューから `Table1` を選択し、次に**ドリフトの詳細を表示**を選択します。 -8. 次に、`Table1` のドリフトの詳細を確認すると、3つの差分があります。コンソールで行った変更に応じて `BillingMode` プロパティが変更され、`ProvisionedThroughput` の値もその変更の一部として DynamoDB によって更新されました。**違い**ビューで各プロパティを選択すると、関連するテンプレートの違いが強調表示されます。 + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **ドリフト検出** を行うために `cfn-workshop-drift-detection` スタックに対して次のコマンドを実行します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation detect-stack-drift \ +--stack-name cfn-workshop-drift-detection + ::: + 1. CloudFormation は次の結果を返却します。 + :::code{language=json showLineNumbers=false showCopyAction=true} + "StackDriftDetectionId": "35768f30-f947-11ed-9dc9-0eb469d3b073" + ::: + 1. ドリフト検出操作の実行結果をステップ 2 で得られた `stack-drift-detection-id` を使って確認します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation describe-stack-drift-detection-status \ +--stack-drift-detection-id stack-drift-detection-id + ::: + 1. `describe-stack-drift-detect-status` コマンドが成功すると、CloudFormation は`"DetectionStatus":"DETECTION_COMPLETE"` と `"StackDriftStatus":"DRIFTED"` の情報を返却します。 + :::code{language=json showLineNumbers=true showCopyAction=false highlightLines=4-5} +{ + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/83fd7940-f945-11ed-ab77-12daf0c351ad", + "StackDriftDetectionId": "35768f30-f947-11ed-9dc9-0eb469d3b073", + "StackDriftStatus": "DRIFTED", + "DetectionStatus": "DETECTION_COMPLETE", + "DriftedStackResourceCount": 1, + "Timestamp": "2023-05-23T08:52:55.332000+00:00" +} + ::: + 1. ドリフトしたリソースの詳細を確認するため次のコマンドを実行します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation describe-stack-resource-drifts \ +--stack-name cfn-workshop-drift-detection + ::: + 1. `descibe-stack-resource-drifts` コマンドの出力結果に `Table1` リソースのドリフトした内容が `Property Differences` の中で示されています。 + :::code{language=json showLineNumbers=true showCopyAction=false highlightLines=21-34} +{ + "StackResourceDrifts": [ + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/83fd7940-f945-11ed-ab77-12daf0c351ad", + "LogicalResourceId": "Queue1", + "PhysicalResourceId": "https://sqs.us-east-1.amazonaws.com/123456789012/cfn-workshop-drift-detection-Queue1-LhZ9kuNmNV62", + "ResourceType": "AWS::SQS::Queue", + "ExpectedProperties": "{\"MessageRetentionPeriod\":345600}", + "ActualProperties": "{\"MessageRetentionPeriod\":345600}", + "PropertyDifferences": [], + "StackResourceDriftStatus": "IN_SYNC", + "Timestamp": "2023-05-23T08:42:44.951000+00:00" + }, + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/83fd7940-f945-11ed-ab77-12daf0c351ad", + "LogicalResourceId": "Table1", + "PhysicalResourceId": "cfn-workshop-drift-detection-Table1-173M9QVM1EZKE", + "ResourceType": "AWS::DynamoDB::Table", + "ExpectedProperties": "{\"BillingMode\":\"PROVISIONED\",\"ProvisionedThroughput\":{\"WriteCapacityUnits\":1,\"ReadCapacityUnits\":1},\"AttributeDefinitions\":[{\"AttributeType\":\"S\",\"AttributeName\":\"Album\"},{\"AttributeType\":\"S\",\"AttributeName\":\"Artist\"}],\"KeySchema\":[{\"KeyType\":\"HASH\",\"AttributeName\":\"Album\"},{\"KeyType\":\"RANGE\",\"AttributeName\":\"Artist\"}]}", + "ActualProperties": "{\"BillingMode\":\"PAY_PER_REQUEST\",\"AttributeDefinitions\":[{\"AttributeName\":\"Album\",\"AttributeType\":\"S\"},{\"AttributeName\":\"Artist\",\"AttributeType\":\"S\"}],\"KeySchema\":[{\"KeyType\":\"HASH\",\"AttributeName\":\"Album\"},{\"KeyType\":\"RANGE\",\"AttributeName\":\"Artist\"}]}", + "PropertyDifferences": [ + { + "PropertyPath": "/ProvisionedThroughput", + "ExpectedValue": "{\"ReadCapacityUnits\":1,\"WriteCapacityUnits\":1}", + "ActualValue": "null", + "DifferenceType": "REMOVE" + }, + { + "PropertyPath": "/BillingMode", + "ExpectedValue": "PROVISIONED", + "ActualValue": "PAY_PER_REQUEST", + "DifferenceType": "NOT_EQUAL" + } + ], + "StackResourceDriftStatus": "MODIFIED", + "Timestamp": "2023-05-23T09:31:32.470000+00:00" + } + ] +} + ::: + :::: + ::::tab{id="local" label="ローカル開発"} + 1. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。必要に応じて、 **スタック** メニュー項目を選択してスタックを確認します。 + 1. 前のステップで作成したスタック (例えば、`cfn-workshop-drift-detection-workshop`) を選択します。 + 1. **スタックアクション** から、 **ドリフトの検出** を選択します。 + 1. **スタックの情報** タブに移動し、 **ドリフトステータス** フィールドに `DRIFTED` と表示されるまでページを更新します。なお、ドリフト検出が完了するまでに少し時間がかかります。 + 1. **スタックアクション** から、 **ドリフト結果を表示** を選択します。 + 1. ドリフトステータスページが表示されます。画面では、`Table1` が変更され、`Queue1` がテンプレートと同期されていることがわかります。 + 1. **リソースのドリフトステータス** ビューから `Table1` を選択し、次に **ドリフトの詳細を表示** を選択します。 + 1. 次に、`Table1` のドリフトの詳細を確認すると、3 つの差分があります。コンソールで行った変更に応じて `BillingMode` プロパティが変更され、`ProvisionedThroughput` の値もその変更の一部として DynamoDB によって更新されました。 **違い** ビューで各プロパティを選択すると、関連するテンプレートの違いが強調表示されます。 + :::: + ::::: これで、構成ドリフトを修正するために必要な情報が揃い、希望する構成がテンプレートと再び一致するようになりました。以下の手順に従ってテーブル設定を更新してください。 1. [DynamoDB コンソール](https://console.aws.amazon.com/dynamodb) に戻り、以前と同じように **設定の更新** を選択します。 -2. **Table1** のエントリを選択し、**追加の設定**タブに移動します。 -3. **編集**を選択します。 -4. **プロビジョニング**キャパシティモードを選択します。 -5. **読み取りキャパシティー**と**書き込みキャパシティー**の両方で、**Auto Scaling** を**オフ**にします。 -6. 読み取りキャパシティーと書き込みキャパシティーの**プロビジョンドキャパシティーユニット**両方に `1` を入力します。 -7. **変更を保存**をクリックします。 +1. **Table1** のエントリを選択し、 **追加の設定** タブに移動します。 +1. **編集** を選択します。 +1. **プロビジョニング** キャパシティモードを選択します。 +1. **読み取りキャパシティー** と **書き込みキャパシティー** の両方で、 **Auto Scaling** を **オフ** にします。 +1. 読み取りキャパシティーと書き込みキャパシティーの **プロビジョンドキャパシティーユニット** 両方に `1` を入力します。 +1. **変更を保存** をクリックします。 -リソースはテンプレートと同期され、元の構成に復元されました。先ほど行ったようにスタックのドリフト検出を実行すると、**スタック情報**タブの**ドリフトステータス**フィールドに `IN_SYNC` と表示されるはずです。 +リソースはテンプレートと同期され、元の構成に復元されました。先ほど行ったようにスタックのドリフト検出を実行すると、 **スタック情報** タブの **ドリフトステータス** フィールドに `IN_SYNC` と表示されるはずです。 ### テンプレートの更新によるドリフトの検出と修復 @@ -108,41 +204,179 @@ Resources: 1. [Amazon SQS コンソール](https://console.aws.amazon.com/sqs/) に移動します。 -2. 必要に応じて、左側の折りたたまれたメニューを選択して展開し、**キュー**を選択します。 -3. スタックの名前で始まる名前のキュー (例: `drift-detection-workshop`) を見つけて選択します。 -4. **編集**を選択します。 -5. **メッセージ保持期間**を `4` ではなく `2` 日に変更し、ページの一番下にある**保存**をクリックします。 +1. 必要に応じて、左側の折りたたまれたメニューを選択して展開し、 **キュー** を選択します。 +1. スタックの名前で始まる名前のキュー (例: `cfn-workshop-drift-detection-workshop`) を見つけて選択します。 +1. **編集** を選択します。 +1. **メッセージ保持期間** を `4` ではなく `2` 日に変更し、ページの一番下にある **保存** をクリックします。 このステップでは、CloudFormation を使用してキューリソースのドリフトを検出します。 -1. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。必要な場合は、**スタック**メニュー項目を選択してスタックを確認してください。 -2. 前のステップで作成したスタック (例えば、`drift-detection-workshop`) を選択します。 -3. **スタックアクション**から、**ドリフトの検出**を選択します。 -4. ドリフト検出が完了するまで数秒待ってください。**ドリフトステータス**フィールドに `DRIFTED` と表示されるまで、スタック情報ページを更新します。 -5. **スタックアクション**から、**ドリフト結果を表示**を選択します。 -6. ドリフトステータスページが表示され、`Queue1` が変更されたことが示されます。 -7. `Queue1` を選択し、**ドリフトの詳細を表示**を選択します。 -8. `Queue1` のドリフトの詳細を確認します。差分が 1 つあることが確認できます。コンソールで行った変更に応じて、`MessageRetentionPeriod` プロパティが変更されました。 + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **ドリフト検出** を行うために `cfn-workshop-drift-detection` スタックに対して次のコマンドを実行します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation detect-stack-drift \ +--stack-name cfn-workshop-drift-detection + ::: + 1. CloudFormation は次の結果を返却します。 + :::code{language=json showLineNumbers=false showCopyAction=true} + "StackDriftDetectionId": "2c320c80-f954-11ed-9e69-0a031a01f375" + ::: + 1. ドリフト検出操作の実行結果をステップ 2 で得られた `stack-drift-detection-id` を使って確認します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation describe-stack-drift-detection-status \ +--stack-drift-detection-id stack-drift-detection-id + ::: + 1. `describe-stack-drift-detect-status` コマンドが成功すると、CloudFormation は`"DetectionStatus":"DETECTION_COMPLETE"` と `"StackDriftStatus":"DRIFTED"` の情報を返却します。 + :::code{language=json showLineNumbers=true showCopyAction=false highlightLines=4-5} +{ + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/2c320c80-f954-11ed-9e69-0a031a01f375", + "StackDriftDetectionId": "35768f30-f947-11ed-9dc9-0eb469d3b073", + "StackDriftStatus": "DRIFTED", + "DetectionStatus": "DETECTION_COMPLETE", + "DriftedStackResourceCount": 1, + "Timestamp": "2023-05-23T08:52:55.332000+00:00" +} + ::: + 1. ドリフトしたリソースの詳細を確認するため次のコマンドを実行します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation describe-stack-resource-drifts \ +--stack-name cfn-workshop-drift-detection + ::: + 1. `descibe-stack-resource-drifts` コマンドの出力結果に `Queue1` リソースのドリフトした内容が `Property Differences` の中で示されています。 + :::code{language=json showLineNumbers=true showCopyAction=false highlightLines=10-17} +{ + "StackResourceDrifts": [ + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/6a9d0720-f94c-11ed-8f4f-0e06081e3865", + "LogicalResourceId": "Queue1", + "PhysicalResourceId": "https://sqs.us-east-1.amazonaws.com/123456789012/cfn-workshop-drift-detection-Queue1-9vq6DP77LiCe", + "ResourceType": "AWS::SQS::Queue", + "ExpectedProperties": "{\"MessageRetentionPeriod\":345600}", + "ActualProperties": "{\"MessageRetentionPeriod\":172800}", + "PropertyDifferences": [ + { + "PropertyPath": "/MessageRetentionPeriod", + "ExpectedValue": "345600", + "ActualValue": "172800", + "DifferenceType": "NOT_EQUAL" + } + ], + "StackResourceDriftStatus": "MODIFIED", + "Timestamp": "2023-05-23T10:25:44.111000+00:00" + }, + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/6a9d0720-f94c-11ed-8f4f-0e06081e3865", + "LogicalResourceId": "Table1", + "PhysicalResourceId": "cfn-workshop-drift-detection-Table1-1VFN7I198DR33", + "ResourceType": "AWS::DynamoDB::Table", + "ExpectedProperties": "{\"BillingMode\":\"PROVISIONED\",\"ProvisionedThroughput\":{\"WriteCapacityUnits\":1,\"ReadCapacityUnits\":1},\"AttributeDefinitions\":[{\"AttributeType\":\"S\",\"AttributeName\":\"Album\"},{\"AttributeType\":\"S\",\"AttributeName\":\"Artist\"}],\"KeySchema\":[{\"KeyType\":\"HASH\",\"AttributeName\":\"Album\"},{\"KeyType\":\"RANGE\",\"AttributeName\":\"Artist\"}]}", + "ActualProperties": "{\"BillingMode\":\"PROVISIONED\",\"ProvisionedThroughput\":{\"ReadCapacityUnits\":1,\"WriteCapacityUnits\":1},\"AttributeDefinitions\":[{\"AttributeName\":\"Album\",\"AttributeType\":\"S\"},{\"AttributeName\":\"Artist\",\"AttributeType\":\"S\"}],\"KeySchema\":[{\"KeyType\":\"HASH\",\"AttributeName\":\"Album\"},{\"KeyType\":\"RANGE\",\"AttributeName\":\"Artist\"}]}", + "PropertyDifferences": [], + "StackResourceDriftStatus": "IN_SYNC", + "Timestamp": "2023-05-23T10:25:44.761000+00:00" + } + ] +} + ::: + :::: + ::::tab{id="local" label="ローカル開発"} + 1. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。必要な場合は、 **スタック** メニュー項目を選択してスタックを確認してください。 + 1. 前のステップで作成したスタック (例えば、`cfn-workshop-drift-detection-workshop`) を選択します。 + 1. **スタックアクション** から、 **ドリフトの検出** を選択します。 + 1. ドリフト検出が完了するまで数秒待ってください。 **ドリフトステータス** フィールドに `DRIFTED` と表示されるまで、スタック情報ページを更新します。 + 1. **スタックアクション** から、 **ドリフト結果を表示** を選択します。 + 1. ドリフトステータスページが表示され、`Queue1` が変更されたことが示されます。 + 1. `Queue1` を選択し、 **ドリフトの詳細を表示** を選択します。 + 1. `Queue1` のドリフトの詳細を確認します。差分が 1 つあることが確認できます。コンソールで行った変更に応じて、`MessageRetentionPeriod` プロパティが変更されました。 + :::: + ::::: 次に、リソースの新しい状態に合わせてテンプレートを更新し、スタックを同期し直します。 1. お好みのテキストエディターで、ワークショップのテンプレートファイルを開きます。 -2. `Queue1` の `MessageRetentionPeriod` を、前のステップで見たドリフト詳細ページの**現在の値** 列に表示された値と一致するように変更します。テンプレートの `MessageRetentionPeriod` の値を `172800` に設定します。これは `2` 日間の秒数です。 -3. テンプレートファイルを保存します。 -4. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -5. 前で実施した操作と同様に、スタックを選択します。 -6. **更新**を選択します。 -7. **既存テンプレートを置き換える**を選択し、**テンプレートファイルのアップロード**を選択します。 -8. **ファイルを選択**を使用して、更新されたテンプレートファイルを選択します。 -9. **次へ**をクリックします。 -10. スタックの詳細ページで、**次へ**をクリックします。 -11. スタックのオプションページで、**次へ**をクリックします。 -12. **送信**をクリックします。 -13. スタックの更新が完了するまでお待ちください。ページを更新して現在の状態を読み込みます。 -14. **スタックの情報**タブを選択します。 -15. **スタックアクション**から、**ドリフトの検出**を選択します。 -16. ドリフト検出が完了するまで数秒待ってください。 -17. これで、ドリフトステータスが `IN_SYNC` になり、テンプレートとリソースが一致していることがわかります。 +1. `Queue1` の `MessageRetentionPeriod` を、前のステップで見たドリフト詳細ページの **現在の値** 列に表示された値と一致するように変更します。テンプレートの `MessageRetentionPeriod` の値を `172800` に設定します。これは `2` 日間の秒数です。 +1. テンプレートファイルを保存します。 +1. 以下の手順でスタックを更新しましょう。 + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **Cloud9 のターミナル** 上で `cfn101-workshop/code/workspace/drift-detection` ディレクトリに移動します: + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/drift-detection + ::: + 1. AWS CLI コマンドを使って `cfn-workshop-drift-detection` スタックを更新します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation update-stack \ +--stack-name cfn-workshop-drift-detection \ +--template-body file://drift-detection-workshop.yaml + ::: + 1. `update-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 + :::code{language=json showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: + 1. 次のコマンドで `UPDATE` 操作が完了するまで待ちます。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation wait stack-update-complete \ +--stack-name cfn-workshop-drift-detection + ::: + 1. 確認のため、`cfn-workshop-drift-detection`スタックに対して **ドリフト検出** を行います。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation detect-stack-drift \ +--stack-name cfn-workshop-drift-detection + ::: + 1. ドリフトしたリソースの詳細を確認するため次のコマンドを実行します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation describe-stack-resource-drifts \ +--stack-name cfn-workshop-drift-detection + ::: + 1. ドリフトのステータスが`IN_SYNC`であることを確認できれば、テンプレートとリソースが一致しています。 + :::code{language=json showLineNumbers=true showCopyAction=false highlightLines=11,22} + { + "StackResourceDrifts": [ + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/6a9d0720-f94c-11ed-8f4f-0e06081e3865", + "LogicalResourceId": "Queue1", + "PhysicalResourceId": "https://sqs.us-east-1.amazonaws.com/123456789012/cfn-workshop-drift-detection-Queue1-9vq6DP77LiCe", + "ResourceType": "AWS::SQS::Queue", + "ExpectedProperties": "{\"MessageRetentionPeriod\":172800}", + "ActualProperties": "{\"MessageRetentionPeriod\":172800}", + "PropertyDifferences": [], + "StackResourceDriftStatus": "IN_SYNC", + "Timestamp": "2023-05-23T10:54:21.628000+00:00" + }, + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection/6a9d0720-f94c-11ed-8f4f-0e06081e3865", + "LogicalResourceId": "Table1", + "PhysicalResourceId": "cfn-workshop-drift-detection-Table1-1VFN7I198DR33", + "ResourceType": "AWS::DynamoDB::Table", + "ExpectedProperties": "{\"BillingMode\":\"PROVISIONED\",\"ProvisionedThroughput\":{\"WriteCapacityUnits\":1,\"ReadCapacityUnits\":1},\"AttributeDefinitions\":[{\"AttributeType\":\"S\",\"AttributeName\":\"Album\"},{\"AttributeType\":\"S\",\"AttributeName\":\"Artist\"}],\"KeySchema\":[{\"KeyType\":\"HASH\",\"AttributeName\":\"Album\"},{\"KeyType\":\"RANGE\",\"AttributeName\":\"Artist\"}]}", + "ActualProperties": "{\"BillingMode\":\"PROVISIONED\",\"ProvisionedThroughput\":{\"ReadCapacityUnits\":1,\"WriteCapacityUnits\":1},\"AttributeDefinitions\":[{\"AttributeName\":\"Album\",\"AttributeType\":\"S\"},{\"AttributeName\":\"Artist\",\"AttributeType\":\"S\"}],\"KeySchema\":[{\"KeyType\":\"HASH\",\"AttributeName\":\"Album\"},{\"KeyType\":\"RANGE\",\"AttributeName\":\"Artist\"}]}", + "PropertyDifferences": [], + "StackResourceDriftStatus": "IN_SYNC", + "Timestamp": "2023-05-23T10:54:22.168000+00:00" + } + ] + } + ::: + :::: + ::::tab{id="local" label="ローカル開発"} + 1. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 + 1. 前で実施した操作と同様に、スタックを選択します。 + 1. **更新** を選択します。 + 1. **既存テンプレートを置き換える** を選択し、 **テンプレートファイルのアップロード** を選択します。 + 1. **ファイルを選択** を使用して、更新されたテンプレートファイルを選択します。 + 1. **次へ** をクリックします。 + 1. スタックの詳細ページで、 **次へ** をクリックします。 + 1. スタックのオプションページで、 **次へ** をクリックします。 + 1. **送信** をクリックします。 + 1. スタックの更新が完了するまでお待ちください。ページを更新して現在の状態を読み込みます。 + 1. **スタックの情報** タブを選択します。 + 1. **スタックアクション** から、 **ドリフトの検出** を選択します。 + 1. ドリフト検出が完了するまで数秒待ってください。 + 1. これで、ドリフトステータスが `IN_SYNC` になり、テンプレートとリソースが一致していることがわかります。 + :::: + ::::: + おめでとうございます! リソースの新しい状態に一致するようにテンプレートを更新することで、スタックのずれを修復する方法を学びました。 @@ -153,9 +387,9 @@ Resources: はじめに、以下の手順に従ってください。 1. お気に入りのエディターで `drift-detection-challenge.yaml` ファイルを開きます。 -2. 以下の内容を `drift-detection-challenge.yaml` テンプレートに追加し、ファイルを保存します。このテンプレートは、最新の Amazon Linux 2 AMI を使用して [Amazon Elastic Compute Cloud](https://aws.amazon.com/ec2/) (Amazon EC2) インスタンスを起動し、初回起動時に `Hello World` と出力されるスクリプトを実行するように設定します。 +1. 以下の内容を `drift-detection-challenge.yaml` テンプレートに追加し、ファイルを保存します。このテンプレートは、最新の Amazon Linux 2 AMI を使用して [Amazon Elastic Compute Cloud](https://aws.amazon.com/ec2/) (Amazon EC2) インスタンスを起動し、初回起動時に `Hello World` と出力されるスクリプトを実行するように設定します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=5} Parameters: LatestAmiId: Type: AWS::SSM::Parameter::Value @@ -173,48 +407,157 @@ Resources: Bucket1: Type: AWS::S3::Bucket -``` - -::alert[この `UserData` スクリプトは、インスタンスの初回起動時にのみ実行されます。起動のたびにスクリプトを実行するために[設定を作成する](https://repost.aws/ja/knowledge-center/execute-user-data-ec2)のも良いですが、今回のワークショップではテンプレートの複雑さを低く抑えるため、このテンプレートでは簡単な内容だけを紹介します。] +::: +:::alert{type="info"} +この `UserData` スクリプトは、インスタンスの初回起動時にのみ実行されます。起動のたびにスクリプトを実行するために[設定を作成する](https://repost.aws/ja/knowledge-center/execute-user-data-ec2)のも良いですが、今回のワークショップではテンプレートの複雑さを低く抑えるため、このテンプレートでは簡単な内容だけを紹介します。 +::: +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 のターミナル** 上で `cfn101-workshop/code/workspace/drift-detection` ディレクトリに移動します: +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/drift-detection +::: +1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ +--stack-name cfn-workshop-drift-detection-challenge \ +--template-body file://drift-detection-challenge.yaml +::: +1. 次のコマンドで `CREATE` 操作が完了するまで待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-create-complete \ +--stack-name cfn-workshop-drift-detection-challenge +::: +1. 以下のコマンドを実行し `Instance1` の **物理 ID** を取得します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-resources \ +--stack-name cfn-workshop-drift-detection-challenge +::: +1. コマンドを実行すると CloudFormation は以下の結果を返却します。`Instance1` の **物理 ID** をメモしておきます。 +:::code{language=json showLineNumbers=true showCopyAction=false highlightLines=19} +{ + "StackResources": [ + { + "StackName": "cfn-workshop-drift-detection-challenge", + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection-challenge/30dbaeb0-f965-11ed-a54c-0ea8a8f21e33", + "LogicalResourceId": "Bucket1", + "PhysicalResourceId": "cfn-workshop-drift-detection-challenge-bucket1-1svpxjottevmx", + "ResourceType": "AWS::S3::Bucket", + "Timestamp": "2023-05-23T12:27:57.391000+00:00", + "ResourceStatus": "CREATE_COMPLETE", + "DriftInformation": { + "StackResourceDriftStatus": "NOT_CHECKED" + } + }, + { + "StackName": "cfn-workshop-drift-detection-challenge", + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection-challenge/30dbaeb0-f965-11ed-a54c-0ea8a8f21e33", + "LogicalResourceId": "Instance1", + "PhysicalResourceId": "i-1234567890abcdef0", + "ResourceType": "AWS::EC2::Instance", + "Timestamp": "2023-05-23T12:28:09.726000+00:00", + "ResourceStatus": "CREATE_COMPLETE", + "DriftInformation": { + "StackResourceDriftStatus": "NOT_CHECKED" + } + } + ] +} +::: +:::: +::::tab{id="local" label="ローカル開発"} 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. **スタックの作成**から、**新しいリソースを使用 (標準)** を選択します。 -3. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択し、`drift-detection-challenge.yaml` ファイルをアップロードして、**次へ**をクリックします。 -4. スタック名 (例えば、`drift-detection-challenge`) を入力し、**次へ**をクリックします。 -5. **スタックオプションの設定**ページで、**次へ**をクリックします。 -6. 次のページで、**送信**をクリックします。 -7. スタックが作成されたら、`drift-detection-challenge` スタックを選択し、**リソース**を選択します。例えば、`i-1234567890abcdef0` のような形式で記述された、`Instance1` の**物理 ID** をメモしておきます。 +1. **スタックの作成** から、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択し、`drift-detection-challenge.yaml` ファイルをアップロードして、 **次へ** をクリックします。 +1. スタック名 (例えば、`cfn-workshop-drift-detection-challenge`) を入力し、 **次へ** をクリックします。 +1. **スタックオプションの設定** ページで、 **次へ** をクリックします。 +1. 次のページで、 **送信** をクリックします。 +1. スタックが作成されたら、`cfn-workshop-drift-detection-challenge` スタックを選択し、 **リソース** を選択します。例えば、`i-1234567890abcdef0` のような形式で記述された、`Instance1` の **物理 ID** をメモしておきます。 +:::: +::::: 次に、ドリフトを導入した最初のラボと同様の方法でこのリソースを変更します。変更する `UserData` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-userdata) ではまずインスタンスを停止する必要があるため、この変更により中断が発生します。出力されるメッセージを `Hello Universe` に変更します。 1. [Amazon EC2 コンソール](https://console.aws.amazon.com/ec2/) に移動します。 -2. **インスタンス** セクションを見つけて、上に記録された ID のインスタンスを選択します。 -3. **インスタンスの状態**から、**インスタンスを停止**を選択し、**停止**ボタンをクリックします。 -4. インスタンスの状態が `停止済み` に変わるのを待ちます。必要に応じてページを更新してください。 -6. インスタンスの状態が `停止済み` になったら、必要に応じてインスタンスを再度選択し、**アクション**から**インスタンス設定**を選択し、**ユーザーデータを編集**を選択します。 -7. **新しいユーザーデータ**として、以下のように Hello World を Hello Universe に変更します。 - +1. **インスタンス** セクションを見つけて、上に記録された ID のインスタンスを選択します。 +1. **インスタンスの状態** から、 **インスタンスを停止** を選択し、 **停止** ボタンをクリックします。 +1. インスタンスの状態が `停止済み` に変わるのを待ちます。必要に応じてページを更新してください。 +1. インスタンスの状態が `停止済み` になったら、必要に応じてインスタンスを再度選択し、 **アクション** から **インスタンス設定** を選択し、 **ユーザーデータを編集** を選択します。 +1. **新しいユーザーデータ** として、以下のように Hello World を Hello Universe に変更します。 :::code{language=shell showLineNumbers=false showCopyAction=true} #!/usr/bin/env bash echo Hello Universe ::: - -8. **保存**をクリックします。 -9. インスタンスをもう一度選択し、**インスタンスの状態**から**インスタンスを開始**を選択します。 -10. インスタンスの状態が `実行中` に変わるのを待ちます。必要に応じてページを更新してください。 +1. **保存** をクリックします。 +1. インスタンスをもう一度選択し、 **インスタンスの状態** から **インスタンスを開始** を選択します。 +1. インスタンスの状態が `実行中` に変わるのを待ちます。必要に応じてページを更新してください。 このステップでは、CloudFormation ドリフト検出を使用して、元のテンプレートと比較して `Instance1` リソースに加えられた変更を特定します。 -1. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。必要な場合は、**スタック**メニュー項目を選択してください。 -2. 前のステップで作成したスタック (例えば、`drift-detection-challenge`) を選択します。 -3. **スタックアクション**から、**ドリフトの検出**を選択します。 -4. ドリフト検出が完了するまでに少し時間がかかります。**ドリフトステータス** フィールドに `Drifted` と表示されるまで、スタック情報ページを更新します。 -5. **スタックアクション**から、**ドリフト結果を表示**を選択します。 -6. ドリフトステータスページが表示され、`Instance1` が変更されたことが示されます。 -7. `Instance1` を選択し、**ドリフトの詳細を表示**を選択します。 -8. ドリフトの詳細は、`UserData` プロパティが変更されたことを示しています。`UserData` プロパティは Base64 エンコーディングを使用して保存されるため、行った正確な変更は画面上では分かりません。 - -::alert[ツールを使って Base64 のテキストをデコードし、それが表すシェルスクリプトを見ることができます。例えば、 Linux では、`base64` コマンドラインツールを使用して次のように処理できます。macOSなどの一部の実装では、`base64` コマンドのオプションとして `-d` の代わりに `-D` を使用していることに注意してください。] +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. `Instance1` の変更を特定しましょう。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation detect-stack-drift \ +--stack-name cfn-workshop-drift-detection-challenge +::: +1. 以下のコマンドを AWS CLI で実行して **ドリフトの検出結果** を確認します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-resource-drift \ +--stack-name cfn-workshop-drift-detection-challenge +::: +1. `descibe-stack-resource-drifts` コマンドの出力結果でリソースのドリフトした内容が `Property Differences` に示されています。 +:::code{language=json showLineNumbers=true showCopyAction=false highlightLines=21-28} +{ + "StackResourceDrifts": [ + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection-challenge/30dbaeb0-f965-11ed-a54c-0ea8a8f21e33", + "LogicalResourceId": "Bucket1", + "PhysicalResourceId": "cfn-workshop-drift-detection-challenge-bucket1-1svpxjottevmx", + "ResourceType": "AWS::S3::Bucket", + "ExpectedProperties": "{}", + "ActualProperties": "{}", + "PropertyDifferences": [], + "StackResourceDriftStatus": "IN_SYNC", + "Timestamp": "2023-05-23T12:52:07.616000+00:00" + }, + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection-challenge/30dbaeb0-f965-11ed-a54c-0ea8a8f21e33", + "LogicalResourceId": "Instance1", + "PhysicalResourceId": "i-0113f35b272b0f04e", + "ResourceType": "AWS::EC2::Instance", + "ExpectedProperties": "{\"ImageId\":\"ami-0d52ddcdf3a885741\",\"InstanceType\":\"t2.micro\",\"UserData\":\"IyEvdXNyL2Jpbi9lbnYgYmFzaAplY2hvIEhlbGxvIFdvcmxkCg==\"}", + "ActualProperties": "{\"ImageId\":\"ami-0d52ddcdf3a885741\",\"InstanceType\":\"t2.micro\",\"UserData\":\"IyEvdXNyL2Jpbi9lbnYgYmFzaAplY2hvIEhlbGxvIFVuaXZlcnNl\"}", + "PropertyDifferences": [ + { + "PropertyPath": "/UserData", + "ExpectedValue": "IyEvdXNyL2Jpbi9lbnYgYmFzaAplY2hvIEhlbGxvIFdvcmxkCg==", + "ActualValue": "IyEvdXNyL2Jpbi9lbnYgYmFzaAplY2hvIEhlbGxvIFVuaXZlcnNl", + "DifferenceType": "NOT_EQUAL" + } + ], + "StackResourceDriftStatus": "MODIFIED", + "Timestamp": "2023-05-23T12:52:08.421000+00:00" + } + ] +} +::: +:::: +::::tab{id="local" label="ローカル開発"} +1. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。必要な場合は、 **スタック** メニュー項目を選択してください。 +1. 前のステップで作成したスタック (例えば、`cfn-workshop-drift-detection-challenge`) を選択します。 +1. **スタックアクション** から、 **ドリフトの検出** を選択します。 +1. ドリフト検出が完了するまでに少し時間がかかります。 **ドリフトステータス** フィールドに `Drifted` と表示されるまで、スタック情報ページを更新します。 +1. **スタックアクション** から、 **ドリフト結果を表示** を選択します。 +1. ドリフトステータスページが表示され、`Instance1` が変更されたことが示されます。 +1. `Instance1` を選択し、 **ドリフトの詳細を表示** を選択します。 +1. ドリフトの詳細は、`UserData` プロパティが変更されたことを示しています。`UserData` プロパティは Base64 エンコーディングを使用して保存されるため、行った正確な変更は画面上では分かりません。 +:::: +::::: +:::alert{type="info"} +ツールを使って Base64 のテキストをデコードし、それが表すシェルスクリプトを見ることができます。例えば、 Linux では、`base64` コマンドラインツールを使用して次のように処理できます。macOS などの一部の実装では、`base64` コマンドのオプションとして `-d` の代わりに `-D` を使用していることに注意してください。 +::: 例えば、次のコマンドを実行すると、 @@ -223,32 +566,50 @@ echo "IyEvdXNyL2Jpbi9lbnYgYmFzaAplY2hvIEhlbGxvIFdvcmxkCg==" | base64 -d ::: 次の出力が表示されるはずです。 - :::code{language=shell showLineNumbers=false showCopyAction=false} #!/usr/bin/env bash echo Hello World ::: -::alert[UserData の base64 テキストを外部の Web サイトを使用してエンコードまたはデコードする場合、特に機密情報が含まれている可能性がある場合は注意が必要です。]{type="warning"} +:::alert{type="warning"} +UserData の base64 テキストを外部の Web サイトを使用してエンコードまたはデコードする場合、特に機密情報が含まれている可能性がある場合は注意が必要です。 +::: ここでのタスクは、それ以上中断することなく、スタックをリソースの新しい状態で更新することです。 :::expand{header= "ヒントが必要ですか?"} - * リソースをスタックからデタッチし、`UserData` を修正して再度インポートする必要があります。`UserData` を Base64 に変換する必要はありません。 * 詳細なガイダンスについては、[リソースインポート](/intermediate/operations/resource-importing.html) ラボを参照してください。 - ::: - -:::expand{header="解決策を確認しますか?"} - +::::::expand{header="解決策を確認しますか?"} 1. `drift-detection-challenge.yaml` テンプレートを更新して、値が `Retain` の `DeletionPolicy` 属性を `Instance1` リソースに追加し、ファイルを保存します。 -2. 更新された `drift-detection-challenge.yaml` テンプレートでスタックを更新します。これにより、CloudFormation は、テンプレートからリソースを削除しても、そのリソースは削除せず、管理を停止するだけとなります。 -3. スタックの更新が完了したら、テンプレートファイルをもう一度編集して Resources 宣言全体を削除し (関連する各行の先頭にある `#` 文字を使用してコメントアウトしても良いです)、ファイルを保存します。 -4. 更新されたテンプレートファイルでスタックを更新します。CloudFormation はインスタンスを終了せずにスタックから削除します。 -5. テンプレートファイルを編集してリソースを復元し、以前に行った変更と一致するように UserData を更新します。 - -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=10 highlightLines=12} +Resources: + Instance1: + DeletionPolicy: Retain + Type: AWS::EC2::Instance + Properties: + ImageId: !Ref LatestAmiId + InstanceType: t2.micro + UserData: !Base64 | + #!/usr/bin/env bash + echo Hello World +::: +1. 更新された `drift-detection-challenge.yaml` テンプレートでスタックを更新します。これにより、CloudFormation は、テンプレートからリソースを削除しても、そのリソースは削除せず、管理を停止するだけとなります。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack \ +--stack-name cfn-workshop-drift-detection-challenge \ +--template-body file://drift-detection-challenge.yaml +::: +1. スタックの更新が完了したら、テンプレートファイルをもう一度編集して Resources 宣言全体を削除し (関連する各行の先頭にある `#` 文字を使用してコメントアウトしても良いです)、ファイルを保存します。 +1. 更新されたテンプレートファイルでスタックを更新します。CloudFormation はインスタンスを終了せずにスタックから削除します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack \ +--stack-name cfn-workshop-drift-detection-challenge \ +--template-body file://drift-detection-challenge.yaml +::: +1. テンプレートファイルを編集してリソースを復元し、以前に行った変更と一致するように UserData を更新します。 +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=10 highlightLines=19} Resources: Instance1: DeletionPolicy: Retain @@ -259,32 +620,145 @@ Resources: UserData: !Base64 | #!/usr/bin/env bash echo Hello Universe -``` - -6. CloudFormation コンソールでスタックを選択し、**スタックアクション**から**スタックへのリソースのインポート**を選択します。 -7. **次へ**をクリックします。 -8. テンプレートファイルをアップロードします。 -9. インスタンスの物理 ID を入力し、**次へ** をクリックします。 -10. **スタックの詳細を指定**で、**次へ**をクリックします。 -11. **リソースをインポート**を選択します。 -12. スタックの操作が完了し、リソースがインポートされたら、ドリフト検出を実行して、インスタンスがスタックテンプレートと同期していることを確認できます。 - ::: - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. IMPORT 操作のためにリソースを記述するテキストファイルを作成します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +touch resources-import.txt +::: +1. 以下のコードをコピーして `resources-import.txt` にペーストします。[**識別子**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview)の値はこのパートの前に、メモをしたインスンスの **物理 ID** に置き換えます。 +:::code{language=json showLineNumbers=false showCopyAction=true} +[ + { + "ResourceType":"AWS::EC2::Instance", + "LogicalResourceId":"Instance1", + "ResourceIdentifier": { + "InstanceId":"i-12345abcd6789" + } + } +] +::: +1. リソースのインポートを行うために、次のコマンドを使って `cfn-workshop-drift-detection-challenge` スタックを更新します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-change-set \ +--stack-name cfn-workshop-drift-detection-challenge \ +--change-set-name drift-challenge --change-set-type IMPORT \ +--resources-to-import file://resources-import.txt \ +--template-body file://drift-detection-challenge.yaml +::: +1. 次のコマンドを使って変更セットを実行します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation execute-change-set \ +--stack-name cfn-workshop-drift-detection-challenge \ +--change-set-name drift-challenge +::: +1. 次のコマンドで `IMPORT` 操作が完了するのを待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-import-complete \ +--stack-name cfn-workshop-drift-detection-challenge +::: +1. `cfn-workshop-drift-detection-challenge` スタックのドリフト検出を確認します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation detect-stack-drift \ +--stack-name cfn-workshop-drift-detection-challenge +::: +1. `descibe-stack-resource-drifts`コマンドの実行結果を確認すると、ドリフトの詳細で `Instance1` インスタンスの状態がスタックと同じであることが確認できます。 +:::code{language=json showLineNumbers=true showCopyAction=false highlightLines=11,22} +{ + "StackResourceDrifts": [ + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-drift-detection-challenge/30dbaeb0-f965-11ed-a54c-0ea8a8f21e33", + "LogicalResourceId": "Bucket1", + "PhysicalResourceId": "cfn-workshop-drift-detection-challenge-bucket1-1svpxjottevmx", + "ResourceType": "AWS::S3::Bucket", + "ExpectedProperties": "{}", + "ActualProperties": "{}", + "PropertyDifferences": [], + "StackResourceDriftStatus": "IN_SYNC", + "Timestamp": "2023-05-23T17:29:29.338000+00:00" + }, + { + "StackId": "arn:aws:cloudformation:us-east-1:402198065244:stack/cfn-workshop-drift-detection-challenge/30dbaeb0-f965-11ed-a54c-0ea8a8f21e33", + "LogicalResourceId": "Instance1", + "PhysicalResourceId": "i-0113f35b272b0f04e", + "ResourceType": "AWS::EC2::Instance", + "ExpectedProperties": "{\"ImageId\":\"ami-0d52ddcdf3a885741\",\"InstanceType\":\"t2.micro\",\"UserData\":\"IyEvdXNyL2Jpbi9lbnYgYmFzaAplY2hvIEhlbGxvIFdvcmxkCg==\"}", + "ActualProperties": "{\"ImageId\":\"ami-0d52ddcdf3a885741\",\"InstanceType\":\"t2.micro\",\"UserData\":\"IyEvdXNyL2Jpbi9lbnYgYmFzaAplY2hvIEhlbGxvIFdvcmxkCg==\"}", + "PropertyDifferences": [], + "StackResourceDriftStatus": "IN_SYNC", + "Timestamp": "2023-05-23T17:29:30.015000+00:00" + } + ] +} +::: +:::: +::::tab{id="local" label="ローカル開発"} +1. CloudFormation コンソールでスタックを選択し、 **スタックアクション** から **スタックへのリソースのインポート** を選択します。 +1. **次へ** をクリックします。 +1. テンプレートファイルをアップロードします。 +1. インスタンスの物理 ID を入力し、 **次へ** をクリックします。 +1. **スタックの詳細を指定** で、 **次へ** をクリックします。 +1. **リソースをインポート** を選択します。 +1. スタックの操作が完了し、リソースがインポートされたら、ドリフト検出を実行して、インスタンスがスタックテンプレートと同期していることを確認できます。 +:::: +::::: ソリューションのテンプレートは `code/solutions/drift-detection/drift-detection-workshop.yaml` にあります。 おめでとうございます! これで、リソースを削除して再インポートすることで、影響なしにドリフトを修復する方法がわかりました。 +:::::: ### クリーンアップ 次に示す手順に従って、このワークショップで作成したリソースをクリーンアップしてください。 - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. AWS CLI を使って S3 バケットを削除します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +aws s3 rb s3://drift-detection-challenge-AWS_ACCOUNT_ID --force +::: +1. `cfn-workshoop-drift-detection-workshop` スタックを削除します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ +--stack-name cfn-workshop-drift-detection-workshop +::: +1. `cfn-workshop-drift-detection-challenge` スタックの `DeletionPolicy` を `Delete` に変更するため、テンプレートファイルを編集します。 +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=10 highlightLines=12} +Resources: + Instance1: + DeletionPolicy: Delete + Type: AWS::EC2::Instance + Properties: + ImageId: !Ref LatestAmiId + InstanceType: t2.micro + UserData: !Base64 | + #!/usr/bin/env bash + echo Hello Universe +::: +1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack \ +--stack-name cfn-workshop-drift-detection-challenge \ +--template-body file://drift-detection-challenge.yaml +::: +1. スタックの更新が完了した後に、スタックの削除を行います。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ +--stack-name cfn-workshop-drift-detection-challenge +::: +:::: +::::tab{id="local" label="ローカル開発"} 1. CloudFormation コンソールに移動します。 -2. 最初のラボで作成したスタック (例えば、`drift-detection-workshop`) を選択します。 -3. **削除**を選択し、**削除**をクリックします。 -4. `drift-detection-challenge` スタックの場合は、テンプレートファイルを編集して `DeletionPolicy` を `Delete` に変更します。 -5. スタックを選択して**更新**を選択します。次に**既存テンプレートを置き換える**を選択し、更新されたファイルをアップロードすることでスタックを更新します。**次へ**を 3 回選択し、最後に**送信**をクリックします。スタックの更新が完了するまでお待ちください。 -6. `drift-detection-challenge` スタックを選択し、**削除**を選択後、**削除**ボタンをクリックします。 +1. 最初のラボで作成したスタック (例えば、`cfn-workshop-drift-detection-workshop`) を選択します。 +1. **削除** を選択し、 **削除** をクリックします。 +1. `cfn-workshop-drift-detection-challenge` スタックのために使ったテンプレートファイルを編集して `DeletionPolicy` を `Delete` に変更します。 +1. スタックを選択して **更新** を選択します。次に **既存テンプレートを置き換える** を選択し、更新されたファイルをアップロードすることでスタックを更新します。 **次へ** を 3 回選択し、最後に **送信** をクリックします。スタックの更新が完了するまでお待ちください。 +1. `cfn-workshop-drift-detection-challenge` スタックを選択し、 **削除** を選択後、 **削除** ボタンをクリックします。 +:::: +::::: + +--- + ### まとめ diff --git a/content/intermediate/operations/resource-importing/index.ja.md b/content/intermediate/operations/resource-importing/index.ja.md index dc178d799..6f311156f 100644 --- a/content/intermediate/operations/resource-importing/index.ja.md +++ b/content/intermediate/operations/resource-importing/index.ja.md @@ -11,7 +11,6 @@ weight: 400 ::alert[インポート操作でサポートされるリソースの詳細については、 [インポートおよびドリフト検出オペレーションをサポートするリソース](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import-supported-resources.html) をご参照ください。]{type="info"} - ### 取り上げるトピック このラボを修了すると、次のことができるようになります。 @@ -19,11 +18,8 @@ weight: 400 * リソースをスタックにインポートする方法を学びます。 * リソースインポートのさまざまなユースケースに関する重要な考慮事項を学び、実践します。 - - ### ラボを開始 - -* ディレクトリを `code/workspace/resource-importing` に変更します。 +* `code/workspace/resource-importing` ディレクトリに移動します。 * `resource-importing.yaml`ファイルを開きます。 * このラボの手順に従って、テンプレートのコンテンツを更新します。 @@ -33,11 +29,11 @@ weight: 400 開始するには、次に示す手順に従ってください。 -1. [Amazon SNS コンソール](https://console.aws.amazon.com/sns/) に移動し、**トピック**を選択します。次に、**トピックの作成**を選択します。 -2. **タイプ**セクションで、`スタンダード`を選択します。 -3. トピックの**名前** (`Topic1` など) を指定します。 -4. 準備ができたら、**トピックの作成**を選択します。 -5. トピックが正常に作成されたら、`Topic1` の**詳細**セクションの下にある [Amazon リソースネーム (ARN)](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference-arns.html) をメモします。この ARN 値は、このラボの後半で使用します。Amazon SNS トピックの ARN パターンの例は `arn:aws:sns:us-east-1:123456789012:MyTopic` です。 +1. [Amazon SNS コンソール](https://console.aws.amazon.com/sns/) に移動し、 **トピック** を選択します。次に、 **トピックの作成** を選択します。 +1. **タイプ** セクションで、`スタンダード`を選択します。 +1. トピックの **名前** (`Topic1` など) を指定します。 +1. 準備ができたら、 **トピックの作成** を選択します。 +1. トピックが正常に作成されたら、`Topic1` の **詳細** セクションの下にある [Amazon リソースネーム (ARN)](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference-arns.html) をメモします。この ARN 値は、このラボの後半で使用します。Amazon SNS トピックの ARN パターンの例は `arn:aws:sns:us-east-1:123456789012:MyTopic` です。 次に、リソースのインポート機能を使用して、新しく作成したトピックを、これから作成する新しいスタックにインポートします。そのためには、CloudFormation テンプレートを使用して、既存のトピックを `AWS::SNS::Topic` [リソース](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sns-topic.html) で次のように記述します。 @@ -45,142 +41,488 @@ weight: 400 * インポートする各リソースには、`DeletionPolicy` [属性](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html) が記述されている必要があります。トピックにはこの属性を指定し、属性値には `Retain` を指定します。`DeletionPolicy` 属性に `Retain` 値を使用するときは、スタックからリソースを削除するとき、またはスタックを削除するときにリソースを保持するように指定します。 * 以下のコードをコピーして `resource-importing.yaml` ファイルに追加し、ファイルを保存します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=11} Parameters: Topic1Name: Type: String Default: Topic1 Description: Name of the first Amazon SNS topic you created with the Amazon SNS console. + Resources: SNSTopic1: DeletionPolicy: Retain Type: AWS::SNS::Topic Properties: TopicName: !Ref Topic1Name -``` +::: ::alert[インポート操作を成功させるには、インポートするすべてのリソースのテンプレートの記述に [DeletionPolicy](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html) 属性が設定されている必要があります。詳しい情報については、[インポートオペレーション中の考慮事項](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-considerations) をご参照ください。]{type="info"} この次のステップでは、AWS CloudFormation コンソールを使用して、`resource-importing.yaml` テンプレートを使用して [スタックを作成](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import-new-stack.html) します。 - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. `IMPORT` 操作のためリソースを記述するテキストファイルを作成します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +touch resources-import.txt +::: +1. 次のコードを `resources-import.txt` ファイルにコピーペーストして保存してください。[**識別子の値**](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、`Topic1` を作成した後にメモしたトピック ARN の値を指定します。 +:::code{language=json showLineNumbers=false showCopyAction=true} +[ + { + "ResourceType":"AWS::SNS::Topic", + "LogicalResourceId":"SNSTopic1", + "ResourceIdentifier": { + "TopicArn":"arn:aws:sns:us-east-1:123456789012:Topic1" + } + } +] +::: +1. 次のコマンドを実行してリソースインポートのためのテンプレートから `IMPORT` タイプの変更セットを作成しましょう。テンプレートは `Topic1Name` を入力パラメータとして必要とします。例えばスタック名を `cfn-workshop-resource-importing` とし変更セットを `cfn-workshop-resource-import-change-set` として `Topic1Name` の値を `Topic1` とします。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-change-set \ +--stack-name cfn-workshop-resource-importing \ +--change-set-name cfn-workshop-resource-import-change-set \ +--change-set-type IMPORT \ +--resources-to-import file://resources-import.txt \ +--template-body file://resource-importing.yaml \ +--parameters ParameterKey=Topic1Name,ParameterValue=Topic1 +::: +1. 変更セットから正しいリソースがインポートされることを確認します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-change-set \ +--stack-name cfn-workshop-resource-importing \ +--change-set-name cfn-workshop-resource-import-change-set +::: +1. リソースをインポートするために変更セットを実行します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation execute-change-set \ +--stack-name cfn-workshop-resource-importing \ +--change-set-name cfn-workshop-resource-import-change-set +::: +1. [wait stack-import-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-import-complete.html) コマンドを使って `IMPORT` 操作が完了するまで待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-import-complete \ +--stack-name cfn-workshop-resource-importing +::: +1. [describe-stacks](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html) コマンドを使ってインポートが完了していることを確認します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stacks --stack-name cfn-workshop-resource-importing +::: +1. `describe-stacks` コマンドを実行すると、17 行目で示されるように CloudFormation は `"StackStatus": "IMPORT_COMPLETE"` を返却します。 +:::code{language=json showLineNumbers=true showCopyAction=false highlightLines=17} +{ + "Stacks": [ + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resource-importing/43d74040-f44e-11ed-9921-0a4da8431f6d", + "StackName": "cfn-workshop-resource-importing", + "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/cfn-workshop-resource-import-change-set/3f86b48d-a0bf-434b-96de-2ec316a04134", + "Description": "AWS CloudFormation workshop - Resource Importing.", + "Parameters": [ + { + "ParameterKey": "Topic1Name", + "ParameterValue": "Topic1" + } + ], + "CreationTime": "2023-05-17T01:00:50.284000+00:00", + "LastUpdatedTime": "2023-05-17T01:05:31.414000+00:00", + "RollbackConfiguration": {}, + "StackStatus": "IMPORT_COMPLETE", + "DisableRollback": false, + "NotificationARNs": [], + "Tags": [], + "EnableTerminationProtection": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + } + } + ] +} +::: +:::: +::::tab{id="local" label="ローカル開発"} 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. **スタックの作成**から、**既存のリソースを使用 (リソースをインポート)** を選択します。 -3. **必要なもの**を読み、**次へ**をクリックします。 -4. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**をクリックします。`resource-importing.yaml` テンプレートをアップロードし、**次へ**をクリックします。 -5. [識別子の値](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、`Topic1` を作成した後にメモしたトピック ARN の値を指定します。 -6. **スタックの名前**を入力します。例えば、`resource-importing` と指定します。`Topic1Name` パラメータ値には必ず `Topic1` を指定します。 -7. 次のページで、**リソースをインポート**をクリックします。 +1. **スタックの作成** から、 **既存のリソースを使用 (リソースをインポート)** を選択します。 +1. **必要なもの** を読み、 **次へ** をクリックします。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** をクリックします。`resource-importing.yaml` テンプレートをアップロードし、 **次へ** をクリックします。 +1. [**識別子の値**](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、`Topic1` を作成した後にメモしたトピック ARN の値を指定します。 +1. **スタックの名前** を入力します。例えば、`cfn-workshop-resource-importing` と指定します。`Topic1Name` パラメータ値には必ず `Topic1` を指定します。 +1. 次のページで、 **リソースをインポート** をクリックします。 Amazon SNS トピックがスタックに正常にインポートされると、スタックのステータスに `IMPORT_COMPLETE` と表示されます。 -おめでとうございます! Amazon SNS コンソールで以前に作成したリソースを、新しいスタックにインポートしました。 [AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-welcome.html) を使用して既存のリソースを新しいスタックにインポートする方法については、[AWS CLI を使用した既存のリソースからのスタックの作成](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import-new-stack.html#resource-import-new-stack-cli) をご参照ください。 +既存のリソースを新しいスタックにインポートする方法の関する詳しい説明は、[AWS CLI を使用した既存のリソースからのスタックの作成](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import-new-stack.html#resource-import-new-stack-cli) をご参照ください。 +:::: +::::: + +おめでとうございます! Amazon SNS コンソールで以前に作成したリソースを、新しいスタックにインポートしました。 ### ラボパート 2 このラボでは、リソースを既存のスタックにインポートする方法を学びます。開始するには、以下の手順に従ってください。 -1. [Amazon SNS コンソール](https://console.aws.amazon.com/sns/) に移動して 2 つ目のトピックを作成します。ラボパート1で使用した手順に従い、新しいトピックの名前として **Topic2** を指定します。 -2. トピックが正常に作成されたら、`Topic2` の**詳細**セクションの下にある [Amazon リソースネーム (ARN)](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference-arns.html) をメモします。この情報は、後でこのラボで使用します (ARN パターンの例: `arn:aws:sns:us-east-1:123456789012:MyTopic`)。 -3. 以下の例をコピーして、前のラボで使用した `resource-importing.yaml` テンプレートの `Parameters` セクションに追加します。 - -```yaml +1. [Amazon SNS コンソール](https://console.aws.amazon.com/sns/) に移動して 2 つ目のトピックを作成します。ラボパート 1 で使用した手順に従い、新しいトピックの名前として **Topic2** を指定します。 +1. トピックが正常に作成されたら、`Topic2` の **詳細** セクションの下にある [Amazon リソースネーム (ARN)](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/reference-arns.html) をメモします。この情報は、後でこのラボで使用します (ARN パターンの例: `arn:aws:sns:us-east-1:123456789012:MyTopic`)。 +1. 以下の例をコピーして、前のラボで使用した `resource-importing.yaml` テンプレートの `Parameters` セクションに追加します。 +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=17} Topic2Name: Type: String Default: Topic2 Description: Name of the second Amazon SNS topic you created with the Amazon SNS console. -``` - -4. 次に、以下の例をコピーして、`resource-importing.yaml` テンプレートの `Resources` セクションに追加します。完了したら、テンプレートファイルを保存します。 - -```yaml +::: +1. 次に、以下の例をコピーして、`resource-importing.yaml` テンプレートの `Resources` セクションに追加します。完了したら、テンプレートファイルを保存します。 +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=29} SNSTopic2: DeletionPolicy: Retain Type: AWS::SNS::Topic Properties: TopicName: !Ref Topic2Name -``` - -5. 先ほど更新した `resource-importing.yaml` テンプレートには、2 つのパラメータ (`Topic1Name` と `Topic2Name`) と 2 つのリソース (`SNSTopic1` と `SNSTopic2`) が含まれるようになりました。新しいトピックを既存のスタックにインポートしましょう! -6. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -7. `resource-importing` という名前のスタックを選択し、**スタックアクション** から**リソースへのスタックのインポート** を選択します。 -8. **必要なもの**を読み、**次へ**をクリックします。 -9. **テンプレートの指定**から、**テンプレートファイルのアップロード**を選択します。このラボパートで更新した `resource-importing.yaml` テンプレートをアップロードし、**次へ**をクリックします。 -10. [識別子の値](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、`Topic2` を作成した後に書き留めたトピックの ARN 値を指定します。 -11. パラメータについては、必ず `Topic1Name` に `Topic1` を指定し、`Topic2Name` に `Topic2` を指定します。**次へ**をクリックします。 -12. 次のページで、**リソースをインポート**をクリックします。 - -Amazon SNS トピックがスタックに正常にインポートされると、スタックのステータス `IMPORT_COMPLETE` と表示されます。 +::: +1. 先ほど更新した `resource-importing.yaml` テンプレートには、2 つのパラメータ (`Topic1Name` と `Topic2Name`) と 2 つのリソース (`SNSTopic1` と `SNSTopic2`) が含まれるようになりました。新しいトピックを既存のスタックにインポートしましょう! + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. 次のコードを `resources-import.txt` ファイルにコピーペーストして保存してください。[**識別子の値**](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、`Topic2` を作成した後にメモしたトピック ARN の値を指定します。 + :::code{language=json showLineNumbers=false showCopyAction=true} + [ + { + "ResourceType":"AWS::SNS::Topic", + "LogicalResourceId":"SNSTopic2", + "ResourceIdentifier": { + "TopicArn":"arn:aws:sns:us-east-1:123456789012:Topic2" + } + } +] + ::: + 1. 次のコマンドを実行してリソースインポートのためのテンプレートから `IMPORT` タイプの変更セットを作成します。パラメータを `Topic1Name` を `Topic1` 、`Topic2Name` を `Topic2` とします。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation create-change-set \ +--stack-name cfn-workshop-resource-importing \ +--change-set-name cfn-workshop-resource-import-change-set \ +--change-set-type IMPORT \ +--resources-to-import file://resources-import.txt \ +--template-body file://resource-importing.yaml \ +--parameters ParameterKey=Topic1Name,ParameterValue=Topic1 ParameterKey=Topic2Name,ParameterValue=Topic2 + ::: + 1. 変更セットから正しいリソースがインポートされることを確認します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation describe-change-set \ +--stack-name cfn-workshop-resource-importing \ +--change-set-name cfn-workshop-resource-import-change-set + ::: + 1. リソースをインポートするために変更セットを実行します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation execute-change-set \ +--stack-name cfn-workshop-resource-importing \ +--change-set-name cfn-workshop-resource-import-change-set + ::: + 1. [wait stack-import-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-import-complete.html) コマンドを使って `IMPORT` 操作が完了するまで待ちます。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation wait stack-import-complete \ +--stack-name cfn-workshop-resource-importing + ::: + 1. [describe-stacks](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html) コマンドを使ってインポートが完了していることを確認します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation describe-stacks --stack-name cfn-workshop-resource-importing + ::: + 1. `describe-stacks` コマンドを実行すると、21 行目で示されるように CloudFormation は `"StackStatus": "IMPORT_COMPLETE"` を返却します。 + :::code{language=json showLineNumbers=true showCopyAction=false highlightLines=21} + { + "Stacks": [ + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resource-importing/43d74040-f44e-11ed-9921-0a4da8431f6d", + "StackName": "cfn-workshop-resource-importing", + "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/cfn-workshop-resource-import-change-set/b45266b6-01c9-4c23-99d6-d65731fc575c", + "Description": "AWS CloudFormation workshop - Resource Importing (uksb-1q9p31idr).", + "Parameters": [ + { + "ParameterKey": "Topic2Name", + "ParameterValue": "Topic2" + }, + { + "ParameterKey": "Topic1Name", + "ParameterValue": "Topic1" + } + ], + "CreationTime": "2023-05-17T01:00:50.284000+00:00", + "LastUpdatedTime": "2023-05-17T01:35:38.408000+00:00", + "RollbackConfiguration": {}, + "StackStatus": "IMPORT_COMPLETE", + "DisableRollback": false, + "NotificationARNs": [], + "Tags": [], + "EnableTerminationProtection": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + } + } + ] +} + ::: + :::: + ::::tab{id="local" label="ローカル開発"} + 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 + 1. `cfn-workshop-resource-importing` という名前のスタックを選択し、 **スタックアクション** から **リソースへのスタックのインポート** を選択します。 + 1. **必要なもの** を読み、 **次へ** をクリックします。 + 1. **テンプレートの指定** から、 **テンプレートファイルのアップロード** を選択します。このラボパートで更新した `resource-importing.yaml` テンプレートをアップロードし、 **次へ** をクリックします。 + 1. [**識別子の値**](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、`Topic2` を作成した後に書き留めたトピックの ARN 値を指定します。 + 1. パラメータについては、必ず `Topic1Name` に `Topic1` を指定し、`Topic2Name` に `Topic2` を指定します。 **次へ** をクリックします。 + 1. 次のページで、 **リソースをインポート** をクリックします。 + + Amazon SNS トピックがスタックに正常にインポートされると、スタックのステータス `IMPORT_COMPLETE` と表示されます。 + :::: + ::::: おめでとうございます! これで、リソースを既存のスタックにインポートする方法がわかりました。 追加の情報については、[AWS CLI を使用した既存のリソースのスタックへのインポート](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import-existing-stack.html#resource-import-existing-stack-cli) をご参照ください。 - ### ラボパート 3 -ラボのこの部分では、[スタック間でリソースを移動する](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/refactor-stacks.html) 方法を学びます。`SNSTopic1` リソースを `resource-importing` スタックから削除し、新しいリソースにインポートします。`SNSTopic1` の `DeletionPolicy` 属性に `Retain` を指定したので、スタックを更新しても `SNSTopic1` リソースは削除されないことに注意します。さっそく始めましょう。 - +ラボのこの部分では、[スタック間でリソースを移動する](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/refactor-stacks.html) 方法を学びます。`SNSTopic1` リソースを `cfn-workshop-resource-importing` スタックから削除し、新しいリソースにインポートします。`SNSTopic1` の `DeletionPolicy` 属性に `Retain` を指定したので、スタックを更新しても `SNSTopic1` リソースは削除されないことに注意します。さっそく始めましょう。 1. ラボパート 2 で使用した `resource-importing.yaml` テンプレートの **Parameters** セクションから以下のコードを削除します。 - -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=12} Topic1Name: Type: String Default: Topic1 Description: Name of the first Amazon SNS topic you created with the Amazon SNS console. -``` - -2. `resource-importing.yaml` テンプレートの **Resources** セクションから以下のコードを削除し、テンプレートファイルを保存します。 - -```yaml +::: +1. `resource-importing.yaml` テンプレートの **Resources** セクションから以下のコードを削除し、テンプレートファイルを保存します。 +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=23} SNSTopic1: DeletionPolicy: Retain Type: AWS::SNS::Topic Properties: TopicName: !Ref Topic1Name -``` - -3. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -4. `resource-importing`という名前のスタックを選択し、**更新**を選択します。 -5. **既存テンプレートを置き換える**を選択し、`resource-importing.yaml` テンプレートをアップロードします。**次へ**をクリックします。 -6. パラメータセクションで、`Topic2Name` のパラメータ値を `Topic2` のままにします。**次へ**をクリックします。 -7. **スタックオプションの設定**ページでデフォルト値のまま、**次へ**をクリックします。 -8. 次のページで**送信**をクリックします。 -9. スタックからの `SNSTopic1` リソースの削除を確認するには、`resource-importing` スタックを選択し、**リソース**を選択します。表示されるリソースは `SNSTopic2` のみです。 - - +::: +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. 次のコマンドを実行してスタックから `SNSTopic1` リソースを削除するための `UPDATE` タイプの変更セットを作成しましょう。スタック名を `cfn-workshop-resource-importing` とし、変更セット名を `cfn-workshop-resource-import-change-set` とし `Topic2Name` パラメータの値を `Topic2` にします。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-change-set \ +--stack-name cfn-workshop-resource-importing \ +--change-set-name cfn-workshop-resource-import-change-set \ +--change-set-type UPDATE \ +--template-body file://resource-importing.yaml \ +--parameters ParameterKey=Topic2Name,ParameterValue=Topic2 +::: +1. 変更セットから正しいリソースが削除されることを確認してください。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-change-set \ +--stack-name cfn-workshop-resource-importing \ +--change-set-name cfn-workshop-resource-import-change-set +::: +1. リソースをインポートするために変更セットを実行します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation execute-change-set \ +--stack-name cfn-workshop-resource-importing \ +--change-set-name cfn-workshop-resource-import-change-set +::: +1. [wait stack-import-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-import-complete.html) コマンドを使って `UPDATE` 操作が完了するまで待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-update-complete \ +--stack-name cfn-workshop-resource-importing +::: +1. [describe-stacks](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html) コマンドを使ってインポートが完了していることを確認します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stacks --stack-name cfn-workshop-resource-importing +::: +1. `describe-stacks` コマンドを実行すると、17 行目で示されるように CloudFormation は `"StackStatus": "IMPORT_COMPLETE"` を返却します。 +:::code{language=json showLineNumbers=true showCopyAction=false highlightLines=17} +{ + "Stacks": [ + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resource-importing/43d74040-f44e-11ed-9921-0a4da8431f6d", + "StackName": "cfn-workshop-resource-importing", + "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/cfn-workshop-resource-import-change-set/11e65a07-b12b-4430-ba7a-d06edf53d2d5", + "Description": "AWS CloudFormation workshop - Resource Importing (uksb-1q9p31idr).", + "Parameters": [ + { + "ParameterKey": "Topic2Name", + "ParameterValue": "Topic2" + } + ], + "CreationTime": "2023-05-17T01:00:50.284000+00:00", + "LastUpdatedTime": "2023-05-17T02:00:46.392000+00:00", + "RollbackConfiguration": {}, + "StackStatus": "UPDATE_COMPLETE", + "DisableRollback": false, + "NotificationARNs": [], + "Tags": [], + "EnableTerminationProtection": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + } + } + ] +} +::: +1. [describe-stack-resources](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stack-resources.html) コマンドを使って更新が完了していることを確認します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-resources --stack-name cfn-workshop-resource-importing +::: +1. `describe-stack-resources` コマンドを実行すると、CloudFormation は `SNSTopic2` リソースの情報のみを返却します。 +:::code{language=json showLineNumbers=true showCopyAction=false} +{ + "StackResources": [ + { + "StackName": "cfn-workshop-resource-importing", + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resource-importing/43d74040-f44e-11ed-9921-0a4da8431f6d", + "LogicalResourceId": "SNSTopic2", + "PhysicalResourceId": "arn:aws:sns:us-east-1:123456789012:Topic2a.fifo", + "ResourceType": "AWS::SNS::Topic", + "Timestamp": "2023-05-17T01:35:50.535000+00:00", + "ResourceStatus": "UPDATE_COMPLETE", + "DriftInformation": { + "StackResourceDriftStatus": "NOT_CHECKED" + } + } + ] +} +::: +:::: +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +1. `cfn-workshop-resource-importing`という名前のスタックを選択し、 **更新** を選択します。 +1. **既存テンプレートを置き換える** を選択し、`resource-importing.yaml` テンプレートをアップロードします。 **次へ** をクリックします。 +1. パラメータセクションで、`Topic2Name` のパラメータ値を `Topic2` のままにします。 **次へ** をクリックします。 +1. **スタックオプションの設定** ページでデフォルト値のまま、 **次へ** をクリックします。 +1. 次のページで **送信** をクリックします。 +1. スタックからの `SNSTopic1` リソースの削除を確認するには、`cfn-workshop-resource-importing` スタックを選択し、 **リソース** を選択します。表示されるリソースは `SNSTopic2` のみです。 +:::: +::::: `SNSTopic1` リソースを新しいスタックにインポートします。 1. `code/workspace/resource-importing` ディレクトリにいることを確認します。 -2. お好みのテキストエディタで `moving-resources.yaml` テンプレートファイルを開きます。 -3. 以下の例を `moving-resources.yaml` テンプレートに追加して保存します。 - -```yaml +1. お好みのテキストエディタで `moving-resources.yaml` テンプレートファイルを開きます。 +1. 以下の例を `moving-resources.yaml` テンプレートに追加して保存します。 +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=11} Parameters: Topic1Name: Type: String Default: Topic1 Description: Name of the first Amazon SNS topic you created with the Amazon SNS console. + Resources: SNSTopic1: DeletionPolicy: Retain Type: AWS::SNS::Topic Properties: TopicName: !Ref Topic1Name -``` - -4. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -5. **スタックの作成**から、**既存のリソースを使用 (リソースをインポート)** を選択します。 -6. **概要をインポート**を読み、**次へ**をクリックします。 -7. **テンプレートの指定**セクションで、**テンプレートファイルをアップロード**を選択します。`moving-resources.yaml` テンプレートをアップロードし、**次へ**をクリックします。 -8. [識別子の値](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、`Topic1` を作成した後にメモしたトピック ARN 値を指定します。 -9. **スタック名**を入力します。例えば、`moving-resources` と指定します。`Topic1Name` パラメータには必ず `Topic1` を指定します。 -10. 次のページで**リソースをインポート**をクリックします。 +::: +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. 以下のコードをコピーして `resources-import.txt` ファイルの内容を置き換えてください。 +:::code{language=json showLineNumbers=false showCopyAction=true} +[ + { + "ResourceType":"AWS::SNS::Topic", + "LogicalResourceId":"SNSTopic1", + "ResourceIdentifier": { + "TopicArn":"arn:aws:sns:us-east-1:123456789012:Topic1" + } + } +] +::: +1. [**識別子の値**](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、 **ラボ 1** で `Topic1` を作成した後にメモしたトピック ARN の値を指定します。 +1. 次のコマンドを実行してリソースをインポートするために `IMPORT` タイプの変更セットを作成しましょう。スタック名は `cfn-workshop-moving-resources` とし、変更セット名は `cfn-workshop-moving-resources` として `Topic1Name` パラメータの値を `Topic1` とします。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-change-set \ +--stack-name cfn-workshop-moving-resources \ +--change-set-name cfn-workshop-moving-resources-change-set \ +--change-set-type IMPORT \ +--resources-to-import file://resources-import.txt \ +--template-body file://moving-resources.yaml \ +--parameters ParameterKey=Topic1Name,ParameterValue=Topic1 +::: +1. 変更セットから正しいリソースがインポートされることを確認してください。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-change-set \ +--stack-name cfn-workshop-moving-resources \ +--change-set-name cfn-workshop-moving-resources-change-set +::: +1. リソースをインポートするために変更セットを実行します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation execute-change-set \ +--stack-name cfn-workshop-moving-resources \ +--change-set-name cfn-workshop-moving-resources-change-set +::: +1. [wait stack-import-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-import-complete.html) コマンドを使って `IMPORT` 操作が完了するまで待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-import-complete \ +--stack-name cfn-workshop-moving-resources +::: +1. [describe-stacks](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stacks.html) コマンドを使ってインポートが完了していることを確認します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stacks --stack-name cfn-workshop-moving-resources +::: +1. `describe-stacks` コマンドを実行すると、17 行目で示されるように CloudFormation は `"StackStatus": "IMPORT_COMPLETE"` を返却します。 +:::code{language=json showLineNumbers=true showCopyAction=false highlightLines=17} +{ + "Stacks": [ + { + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-moving-resources/70f207d0-f459-11ed-9c39-123ae332d1a1", + "StackName": "cfn-workshop-moving-resources", + "ChangeSetId": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/cfn-workshop-moving-resources-change-set/695b51cd-6d16-49e8-99f7-7b93a932f1fe", + "Description": "AWS CloudFormation workshop - Resource Importing (uksb-1q9p31idr).", + "Parameters": [ + { + "ParameterKey": "Topic1Name", + "ParameterValue": "Topic1" + } + ], + "CreationTime": "2023-05-17T02:20:50.451000+00:00", + "LastUpdatedTime": "2023-05-17T02:21:03.424000+00:00", + "RollbackConfiguration": {}, + "StackStatus": "IMPORT_COMPLETE", + "DisableRollback": false, + "NotificationARNs": [], + "Tags": [], + "EnableTerminationProtection": false, + "DriftInformation": { + "StackDriftStatus": "NOT_CHECKED" + } + } + ] +} +::: +1. [describe-stack-resources](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/describe-stack-resources.html) コマンドを使って更新が完了していることを確認します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-resources --stack-name cfn-workshop-moving-resources +::: +1. `describe-stack-resources` コマンドを実行すると、CloudFormation は `SNSTopic1` リソースの情報のみを返却します。 +:::code{language=json showLineNumbers=true showCopyAction=false} +{ + "StackResources": [ + { + "StackName": "cfn-workshop-moving-resources", + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-moving-resources/70f207d0-f459-11ed-9c39-123ae332d1a1", + "LogicalResourceId": "SNSTopic1", + "PhysicalResourceId": "arn:aws:sns:us-east-1:123456789012:Topic1.fifo", + "ResourceType": "AWS::SNS::Topic", + "Timestamp": "2023-05-17T02:21:15.205000+00:00", + "ResourceStatus": "UPDATE_COMPLETE", + "DriftInformation": { + "StackResourceDriftStatus": "NOT_CHECKED" + } + } + ] +} +::: +:::: +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +1. **スタックの作成** から、 **既存のリソースを使用 (リソースをインポート)** を選択します。 +1. **概要をインポート** を読み、 **次へ** をクリックします。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルをアップロード** を選択します。`moving-resources.yaml` テンプレートをアップロードし、 **次へ** をクリックします。 +1. [**識別子の値**](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、`Topic1` を作成した後にメモしたトピック ARN 値を指定し、**次へ** をクリックします。 +1. **スタック名** を入力します。例えば、`cfn-workshop-moving-resources` と指定します。`Topic1Name` パラメータには必ず `Topic1` を指定します。 +1. 次のページで **リソースをインポート** をクリックします。 Amazon SNS トピックがスタックに正常にインポートされると、スタックのステータスには `IMPORT_COMPLETE` と表示されます。 +:::: +::::: おめでとうございます! スタック間でリソースを移動する方法を学習しました。 - ::alert[特定のリソースのインポート操作を元に戻すには、まずテンプレート内のリソースの `DeletionPolicy` を `Retain` に設定し、次にスタックを更新して変更を適用します。次に、テンプレートからリソースを削除し、スタックを再度更新します。その際、スタックからリソースを削除しますが、リソースはそのまま残ります。]{type="info"} ### **リソースをインポートする際のベストプラクティス** @@ -200,17 +542,17 @@ aws ec2 describe-instances --instance-ids i-1234567890abcdef0 ### チャレンジ -この演習では、ラボパート1、2、3で得た知識を使用して、提供されたタスクを完了する必要があります。CloudFormation テンプレートのリソースの 1 つである EC2 インスタンスに、人為的ミスの結果として CloudFormation の外部で変更されたプロパティ値が存在する問題を解決する必要があります。この問題のトラブルシューティングと解決を行い、CloudFormation で希望するリソース構成を引き続き維持できるようにします。 +この演習では、ラボパート 1、2、3 で得た知識を使用して、提供されたタスクを完了する必要があります。CloudFormation テンプレートのリソースの 1 つである EC2 インスタンスに、人為的ミスの結果として CloudFormation の外部で変更されたプロパティ値が存在する問題を解決する必要があります。この問題のトラブルシューティングと解決を行い、CloudFormation で希望するリソース構成を引き続き維持できるようにします。 EC2 インスタンスと Amazon S3 バケットを定義するサンプルテンプレートから始めましょう。 はじめに、以下の手順に従ってください。 1. `code/workspace/resource-importing` というディレクトリにいることを確認します。 -2. `resource-import-challenge.yaml` ファイルを開きます。 -3. 以下の例を `resource-import-challenge.yaml` テンプレートに追加し、ファイルを保存します。 +1. `resource-import-challenge.yaml` ファイルを開きます。 +1. 以下の例を `resource-import-challenge.yaml` テンプレートに追加し、ファイルを保存します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=11} Parameters: LatestAmiId: Description: Fetching the latest AMI ID for Amazon Linux @@ -223,6 +565,7 @@ Parameters: - t2.nano - t2.micro - t2.small + Resources: S3Bucket: Type: AWS::S3::Bucket @@ -234,45 +577,71 @@ Resources: Tags: - Key: Name Value: InstanceImport -``` - -4. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -5. **スタックの作成**から、**新しいリソースを使用 (標準)** を選択します。 -6. **テンプレートを指定**セクションで、**テンプレートファイルのアップロード**を選択します。`resource-import-challenge.yaml` テンプレートをアップロードし、**次へ**をクリックします。 -7. **スタックの名前**を入力します。例えば、`resource-import-challenge` と指定します。`InstanceType` には `t2.nano` を指定します。[**次へ**]をクリックします。 -8. **スタックオプションの設定**ページはデフォルト値のまま、**次へ**をクリックします。 -9. 次のページで、**送信**を選択します。 -10. スタックを作成したら、`resource-import-challenge` スタックを選択し、**リソース**を確認します。`i-12345abcd6789` という形式の `インスタンス`の**物理 ID** をメモしておきましょう。 +::: +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. 次のコマンドを実行して **スタックの作成** を行いましょう。 **スタック名** は `cfn-workshop-resource-import-challenge` とし `InstanceType` パラメータの値は `t2.nano` とします。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ +--stack-name cfn-workshop-resource-import-challenge \ +--template-body file://resource-import-challenge.yaml \ +--parameters ParameterKey=InstanceType,ParameterValue=t2.nano +::: +1. 次のコマンドを実行して `CREATE_COMPLETE` になるまで待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-create-complete \ +--stack-name cfn-workshop-resource-import-challenge +::: +:::: +::::tab{id="LocalDevelopment" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +1. **スタックの作成** から、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートを指定** セクションで、 **テンプレートファイルのアップロード** を選択します。`resource-import-challenge.yaml` テンプレートをアップロードし、 **次へ** をクリックします。 +1. **スタックの名前** を入力します。例えば、`cfn-workshop-resource-import-challenge` と指定します。`InstanceType` には `t2.nano` を指定します。[**次へ**]をクリックします。 +1. **スタックオプションの設定** ページはデフォルト値のまま、 **次へ** をクリックします。 +1. 次のページで、 **送信** を選択します。 +:::: +::::: +スタックを作成したら、`cfn-workshop-resource-import-challenge` スタックを選択し、 **リソース** を確認します。`i-12345abcd6789` という形式の `インスタンス`の **物理 ID** をメモしておきましょう。 次に、スタックの管理範囲外でインスタンスタイプを変更して、ヒューマンエラーを再現してみましょう。以下の手順に従って [既存の EBS-backed インスタンスのインスタンスタイプを変更](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-resize.html#change-instance-type-of-ebs-backed-instance) を実行します。 1. [Amazon EC2 コンソール](https://console.aws.amazon.com/ec2/) に移動します。 -2. **インスタンス**セクションを見つけて、`InstanceImport` という名前のインスタンスを選択し、**インスタンスの状態**、**インスタンスを停止**を選択します。 -3. 同じインスタンスで、インスタンスが**停止**状態になったことを確認したら、**アクション**、**インスタンスの設定**、**インスタンスタイプを変更**を選択します。 -4. `t2.micro` を選択し、**適用**を選択します。 -5. `InstanceImport` インスタンスを再度選択し、**インスタンスの状態**、**インスタンスを開始**を選択します。 +1. **インスタンス** セクションを見つけて、`InstanceImport` という名前のインスタンスを選択し、 **インスタンスの状態** 、 **インスタンスを停止** を選択します。 +1. 同じインスタンスで、インスタンスが **停止** 状態になったことを確認したら、 **アクション** 、 **インスタンスの設定** 、 **インスタンスタイプを変更** を選択します。 +1. `t2.micro` を選択し、 **適用** を選択します。 +1. `InstanceImport` インスタンスを再度選択し、 **インスタンスの状態** 、 **インスタンスを開始** を選択します。 最初に Amazon EC2 インスタンスをスタックで作成しました。ヒューマンエラーを再現するために、テンプレートの [InstanceType](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-instancetype) プロパティを使用する代わりに、(CloudFormation を使用せずに) インスタンスを更新し、次にスタックを更新しました。 -::alert[インスタンスタイプを変更すると、インスタンスが停止して再起動するなど、 [一時的な中断を伴う更新](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-some-interrupt) が発生します。インスタンスのサイズ変更の詳細については、[インスタンスタイプを変更する](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-resize.html) をご参照ください。]{type="info"} - +:::alert{type="info"} +インスタンスタイプを変更すると、インスタンスが停止して再起動するなど、 [一時的な中断を伴う更新](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-some-interrupt) が発生します。インスタンスのサイズ変更の詳細については、[インスタンスタイプを変更する](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/ec2-instance-resize.html) をご参照ください。 +::: 今回のタスクは、スタックを更新するときに `InstanceType` プロパティに追加の変更を加えることなく、スタック内で現在 `t2.nano` に設定されているインスタンスタイプ値を、CloudFormation 以外の方法で設定された新しいインスタンス設定である `t2.micro` と一致させることです。 -::expand[* ラボパート 3 で学んだ概念の利用を検討します。]{header="ヒントが必要ですか?"} +:::expand{header="ヒントが必要ですか?"} +ラボパート 3 で学んだ概念の利用を検討します。 +::: -:::expand{header= "解決策を確認しますか?"} +:::::::expand{header= "解決策を確認しますか?"} 1. `resource-import-challenge.yaml` テンプレートを更新します。`Instance` リソースに、値が `Retain` の `DeletionPolicy` 属性を追加し、ファイルを保存します。 +1. パラメータ値を変更せずに、更新された `resource-import-challenge.yaml` テンプレートを使用してスタックを更新します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack \ +--stack-name cfn-workshop-resource-import-challenge \ +--template-body file://resource-import-challenge.yaml \ +--parameters ParameterKey=InstanceType,ParameterValue=t2.nano +::: -2. パラメータ値を変更せずに、更新された `resource-import-challenge.yaml` テンプレートを使用してスタックを更新します。 -3. スタックを更新し、インスタンスの `DeletionPolicy` 属性が `Retain` に設定されたら、インスタンスリソース定義と Parameters セクションにある関連パラメータをテンプレートから削除します。今回の例では、書くべきパラメーターが特に存在しないため、`Parameters` セクション自体を削除します。具体的には、`resource-import-challenge.yaml` テンプレートから次の 2 つのコードブロックを削除します。 - -```yaml +1. スタックを更新し、インスタンスの `DeletionPolicy` 属性が `Retain` に設定されたら、インスタンスリソース定義と Parameters セクションにある関連パラメータをテンプレートから削除します。今回の例では、書くべきパラメーターが特に存在しないため、`Parameters` セクション自体を削除します。具体的には、`resource-import-challenge.yaml` テンプレートから次の 2 つのコードブロックを削除します。 +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=11 highlightLines=11-15,17-23} Parameters: LatestAmiId: Description: Fetching the latest AMI ID for Amazon Linux Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 + InstanceType: Description: Select the type of the EC2 instance. Type: String @@ -280,58 +649,131 @@ Parameters: - t2.nano - t2.micro - t2.small -``` - -```yaml - Instance: - DeletionPolicy: Retain - Type: AWS::EC2::Instance - Properties: - ImageId: !Ref LatestAmiId - InstanceType: !Ref InstanceType - Tags: - - Key: Name - Value: InstanceImport -``` - -4. テンプレートファイルを保存します。更新された `resource-import-challenge.yaml` テンプレートを使用してスタックを再度更新します。このテンプレートにはパラメータセクションもインスタンスリソース定義もありません。このアクションはスタックからインスタンスを削除しますが、`Retain` に設定された `DeletionPolicy` 属性を記述して適用したため、インスタンスは削除されません。 -5. このスタックの更新後、ステップ 3 で削除した 2 つのコードブロックを `resource-import-challenge.yaml` テンプレートに追加して保存します。 -6. `resource-import-challenge`という名前のスタックを選択し、**スタックアクション**から**スタックへのリソースのインポート**を選択します。 -7. **必要なもの**を読み、**次へ**を選択してください。 -8. **テンプレートを指定**から、**テンプレートファイルのアップロード**を選択します。更新した`resource-import-challenge.yaml` テンプレートをアップロードし、**次へ**をクリックします。 -9. [識別子の値](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、このチャレンジの一部として先ほど書き留めたインスタンスの**物理 ID** を指定します。 -10. インスタンスタイプパラメータとして `t2.micro` を選択します。ここでは、実際のインスタンスタイプ設定である `t2.micro` と一致しています。 -11. 次のページで、**リソースをインポート**をクリックします。 ::: - - + :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=30 highlightLines=31} + Instance: + DeletionPolicy: Retain + Type: AWS::EC2::Instance + Properties: + ImageId: !Ref LatestAmiId + InstanceType: !Ref InstanceType + Tags: + - Key: Name + Value: InstanceImport + ::: +1. 更新された `resource-import-challenge.yaml` テンプレートファイルを使ってスタックを更新します。テンプレートファイルにはパラメータとインスタンスリソースの定義もありません。この操作によりスタックからインスタンスが取り除かれますが、リソースとしては削除されません。これは以前に `DeletionPolicy` の属性を `Retain` に適用したためです。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack \ +--stack-name cfn-workshop-resource-import-challenge \ +--template-body file://resource-import-challenge.yaml +::: +1. スタックを更新したあと、ステップ 3 で 2 つの削除したコードブロックを `resource-import-challenge.yaml` に追加して保存します。 +1. **スタックにリソースをインポート** しましょう + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. 以下のコードをコピーして `resources-import.txt` にペーストします。[**識別子**](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview)の値はこのパートの前に、メモをしたインスンスの **物理 ID** に置き換えます。 + :::code{language=json showLineNumbers=false showCopyAction=true} + [ + { + "ResourceType":"AWS::EC2::Instance", + "LogicalResourceId":"Instance", + "ResourceIdentifier": { + "InstanceId":"i-12345abcd6789" + } + } +] + ::: + 1. 以下のコマンドを実行して **リソースのインポート** のために `cfn-workshop-resource-import-challenge` スタックを更新します。`InstanceType` パラメータは `t2.micro` を指定します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation create-change-set \ +--stack-name cfn-workshop-resource-import-challenge \ +--change-set-name import-challenge --change-set-type IMPORT \ +--resources-to-import file://resources-import.txt \ +--template-body file://resource-import-challenge.yaml \ +--parameters ParameterKey=InstanceType,ParameterValue=t2.micro + ::: + 1. 変更セットを実行します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation execute-change-set \ +--stack-name cfn-workshop-resource-import-challenge \ +--change-set-name import-challenge + ::: + 1. AWS CLI の [wait stack-import-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-import-complete.html) コマンドを使って `IMPORT` 操作が完了するまで待ちます。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation wait stack-import-complete \ +--stack-name cfn-workshop-resource-import-challenge + ::: + :::: + ::::tab{id="LocalDevelopment" label="ローカル開発"} + 1. `cfn-workshop-resource-import-challenge`という名前のスタックを選択し、 **スタックアクション** から **スタックへのリソースのインポート** を選択します。 + 1. **必要なもの** を読み、 **次へ** を選択してください。 + 1. **テンプレートを指定** から、 **テンプレートファイルのアップロード** を選択します。更新した `resource-import-challenge.yaml` テンプレートをアップロードし、 **次へ** をクリックします。 + 1. [**識別子の値**](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import.html#resource-import-overview) には、このチャレンジの一部として先ほど書き留めたインスタンスの **物理 ID** を指定し、 **次へ** をクリックします。 + 1. インスタンスタイプパラメータとして `t2.micro` を選択します。ここでは、実際のインスタンスタイプ設定である `t2.micro` と一致しています。 + 1. 次のページで、 **リソースをインポート** をクリックします。 + :::: + ::::: ソリューションのテンプレートは、`code/solutions/resource-import/resource-import-challenge-solution.yaml` サンプルテンプレートにあります。 +::::::: 以上で、CloudFormation 以外の方法で変更があった場合に CloudFormation スタック構成をリソースの実際の設定と一致させる方法を学習しました。 **リソースインポートのユースケース** 1. 以前に AWS マネジメントコンソールや AWS CLI などを使用して AWS リソース (Amazon S3 バケットなど) を作成していて、CloudFormation を使用してリソースを管理したい。 -2. ライフサイクルと所有権ごとにリソースを 1 つのスタックに再編成して管理しやすくしたい (セキュリティグループのリソースなど)。 -3. 既存のスタックを既存のスタックにネストしたい。詳しい情報については、[既存のスタックのネスト化](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import-nested-stacks.html) をご参照ください。 -4. CloudFormation 以外の方法で更新されたリソースの CloudFormation 設定と一致させたい。 +1. ライフサイクルと所有権ごとにリソースを 1 つのスタックに再編成して管理しやすくしたい (セキュリティグループのリソースなど)。 +1. 既存のスタックを既存のスタックにネストしたい。詳しい情報については、[既存のスタックのネスト化](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resource-import-nested-stacks.html) をご参照ください。 +1. CloudFormation 以外の方法で更新されたリソースの CloudFormation 設定と一致させたい。 ### クリーンアップ このラボで作成したリソースをクリーンアップするには、次に示すクリーンアップ手順に従ってください。 1. `code/workspace/resource-importing` というディレクトリにいることを確認します。 -2. `resource-importing.yaml` テンプレートファイルを更新して、`SNSTopic2` リソース定義から `deletionPolicy: Retain` 行を削除し、テンプレートを保存します。 -3. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -4. `resource-importing` という名前のスタックを選択し、**更新**を選択します。 -5. **現在テンプレートを置き換える**を選択し、`resource-importing.yaml` テンプレートをアップロードします。**次へ**をクリックします。 -6. パラメータセクションで、既存のパラメータ値を受け入れることを選択します。**次へ**をクリックします。 -7. **スタックオプションの設定**ページでデフォルトのまま、**次へ**をクリックします。 -8. 次のページで**送信**を選択します。 -9. スタックの更新が完了したら、`resource-importing` スタックを選択し、**削除** を選択します。 -10. `moving-resources.yaml` テンプレートを更新して `SNSTopic1` リソース定義から `deletionPolicy: Retain` 行を削除し、スタックを更新します。正常に更新されたら、手順2~9を繰り返し、スタックを削除します。スタックの更新時には、既存のパラメータ値を受け入れます。 -11. `resource-import-challenge.yaml` テンプレートを更新して `Instance` リソース定義から `DeletionPolicy: Retain` 行を削除し、スタックを更新します。正常に更新されたらスタック `resource-import-challenge` について上記のステップ (2~9) を繰り返し、スタック削除します。 スタックの更新時には、既存のパラメータ値を受け入れます。 +1. `resource-importing.yaml` テンプレートファイルを更新して、`SNSTopic2` リソース定義から `deletionPolicy: Retain` 行を削除し、テンプレートを保存します。 + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. 次のコマンドを実行して **スタック** を更新します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation update-stack \ +--stack-name cfn-workshop-resource-importing \ +--template-body file://resource-importing.yaml + ::: + 1. 次のコマンドを実行して `UPDATE` 操作が完了するまで。待ちます。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation wait stack-update-complete \ +--stack-name cfn-workshop-resource-importing + ::: + 1. 次のコマンドを実行してスタックを削除します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation delete-stack \ + --stack-name cfn-workshop-resource-importing + ::: + 1. スタック `cfn-workshop-moving-resources` に対して上記の手順 (1-3) を繰り返します。これには、`moving-resources.yaml` テンプレートを更新して、`SNSTopic1` リソース定義から `DeletionPolicy: Retain` 行を削除します。スタックを更新し、更新が成功した後にスタックを削除します。スタックを更新するときに、既存のパラメーター値を受け入れることを選択します。 + 1. `resource-import-challenge.yaml` テンプレートを更新して `Instance` リソース定義の `DeletionPolicy: Retain` の行を削除し、スタックを更新します。次のコマンドを実行してスタックを更新しましょう。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation update-stack \ +--stack-name cfn-workshop-resource-import-challenge \ +--template-body file://resource-import-challenge.yaml \ +--parameters ParameterKey=InstanceType,ParameterValue=t2.micro + ::: + 1. `cfn-workshop-resource-import-challenge` に対して上記の手順 (2-3) を繰り返してスタックを削除します。 + :::: + ::::tab{id="LocalDevelopment" label="ローカル開発"} + 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 + 1. `cfn-workshop-resource-importing` という名前のスタックを選択し、 **更新** を選択します。 + 1. **現在テンプレートを置き換える** を選択し、`resource-importing.yaml` テンプレートをアップロードします。 **次へ** をクリックします。 + 1. パラメータセクションで、既存のパラメータ値を受け入れることを選択します。 **次へ** をクリックします。 + 1. **スタックオプションの設定** ページでデフォルトのまま、 **次へ** をクリックします。 + 1. 次のページで **送信** を選択します。 + 1. スタックの更新が完了したら、`cfn-workshop-resource-importing` スタックを選択し、 **削除** を選択します。 + 1. `moving-resources.yaml` テンプレートを更新して `SNSTopic1` リソース定義から `deletionPolicy: Retain` 行を削除し、`cfn-workshop-moving-resources` スタックを更新します。正常に更新されたら、手順 2 ~ 9 を繰り返し、`cfn-workshop-moving-resources` スタックを削除します。スタックの更新時には、既存のパラメータ値をそのままにします。 + 1. `resource-import-challenge.yaml` テンプレートを更新して `Instance` リソース定義から `DeletionPolicy: Retain` 行を削除し、スタックを更新します。正常に更新されたらスタック `cfn-workshop-resource-import-challenge` について上記のステップ (2 ~ 9) を繰り返し、スタック削除します。 スタックの更新時には、既存のパラメータ値をそのままにします。 + :::: + ::::: + +--- ### まとめ diff --git a/content/intermediate/operations/stack-policy-and-prevention-controls/index.ja.md b/content/intermediate/operations/stack-policy-and-prevention-controls/index.ja.md index 4f8ae3c58..3e53c139a 100644 --- a/content/intermediate/operations/stack-policy-and-prevention-controls/index.ja.md +++ b/content/intermediate/operations/stack-policy-and-prevention-controls/index.ja.md @@ -15,8 +15,6 @@ weight: 300 * [削除保護](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-protect-stacks.html) を有効にしてスタックの削除を防ぐ方法を学びます。 * [DeletionPolicy](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html) 属性を使用して、スタックからリソースを削除するとき、またはスタックを削除するときに、スタックに記述したリソースを保持 (場合によってはバックアップ) する方法について学びます。 - - ### ラボを開始 * `code/workspace/stack-policy-and-prevention-controls` ディレクトリに移動します。 @@ -33,7 +31,7 @@ weight: 300 * 以下のコードをコピーして `stack-policy-lab.yaml` ファイルに追加し、ファイルを保存します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=11} Parameters: SNSTopicTagValue: Description: Tag value for your Amazon SNS topic @@ -41,6 +39,7 @@ Parameters: Default: Topic-Tag-1 MinLength: 1 MaxLength: 256 + Resources: SNSTopic: Type: AWS::SNS::Topic @@ -49,17 +48,68 @@ Resources: Tags: - Key: TagSNS Value: !Ref SNSTopicTagValue -``` +::: -この次のステップでは、AWS CloudFormation コンソールを使用して `stack-policy-lab.yaml` テンプレートファイルを使用してスタックを作成します。次の手順に沿って進んでください。 +この次のステップでは、`stack-policy-lab.yaml` テンプレートファイルを使用してスタックを作成します。次の手順に沿って進んでください。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +次の手順でスタックを作成します。 +1. **Cloud9 のターミナル** で `code/workspace/stack-policy-and-prevention-controls` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/stack-policy-and-prevention-controls +::: +1. スタックポリシーを記述するため新しい JSON ファイルを作成します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +touch policy-body.json +::: +1. Cloud9 のエディタでこのファイルを開き、次の JSON をペーストします。 +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "Statement" : [ + { + "Effect" : "Deny", + "Principal" : "*", + "Action" : "Update:Modify", + "Resource" : "LogicalResourceId/SNSTopic" + }, + { + "Effect" : "Allow", + "Principal" : "*", + "Action" : "Update:*", + "Resource" : "*" + } + ] +} +::: +1. テンプレートは入力パラメータとして `SNSTopicTagValue` を必要とします。例えば `Topic-Tag-1` と入力します。 +1. 次のコマンドを実行してスタックを作成しましょう。(ここでは例として `us-east-1` リージョンを利用します。必要に応じてリージョンを変更してください。): +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ +--region us-east-1 \ +--stack-name cfn-workshop-stack-policy \ +--template-body file://stack-policy-lab.yaml \ +--stack-policy-body file://policy-body.json \ +--parameters ParameterKey=SNSTopicTagValue,ParameterValue=Topic-Tag-1 \ +--enable-termination-protection +::: +1. CloudFormation は次の結果を返却します。 +:::code{language=json showLineNumbers=false showCopyAction=false} +"StackId" : "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-stack-policy/330b0120-1771-11e4-af37-50ba1b98bea6" +::: +1. `cfn-workshop-stack-policy` が作成されるまで、CloudFormation コンソールで待機するか AWS CLI の [stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) コマンドを使って待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-create-complete \ +--stack-name cfn-workshop-stack-policy +::: +:::: +::::tab{id="local" label="ローカル開発"} 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. **スタックの作成**から、**新しいリソースを使用 (標準)** を選択します。 -3. **テンプレートの指定**セクションで、**テンプレートファイルをアップロード**を選択します。`stack-policy-lab.yaml` テンプレートをアップロードし、**次へ**をクリックします。 -4. スタック名を入力します。例えば、`stack-policy-lab` と入力します。パラメータセクションで、`SnStopicTagValue` のパラメータ値を `Topic-Tag-1` とします。**次へ**をクリックします。 -5. **スタックオプションの設定**ページの**スタックポリシー**セクションで、**スタックポリシーを入力する**を選択し、スタックポリシーに次のコードを貼り付けます。**スタック作成オプション**で、**削除保護**を**有効**とし、**次へ**をクリックします。 - -```json +1. **スタックの作成** から、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルをアップロード** を選択します。`stack-policy-lab.yaml` テンプレートをアップロードし、 **次へ** をクリックします。 +1. スタック名を入力します。例えば、`cfn-workshop-stack-policy` と入力します。パラメータセクションで、`SnStopicTagValue` のパラメータ値を `Topic-Tag-1` とします。 **次へ** をクリックします。 +1. **スタックオプションの設定** ページの **スタックポリシー** セクションで、 **スタックポリシーを入力する** を選択し、スタックポリシーに次のコードを貼り付けます。 **スタック作成オプション** で、 **削除保護** を **有効** とし、 **次へ** をクリックします。 +:::code{language=json showLineNumbers=false showCopyAction=true} { "Statement" : [ { @@ -76,34 +126,51 @@ Resources: } ] } -``` - -6. 次のページで、**送信**をクリックします。 +::: +1. 次のページで、 **送信** をクリックします。 +:::: +::::: ::alert[スタックポリシーをスタックに適用すると、そのスタック内のすべてのリソースがデフォルトで保護されます。従って、他のすべてのリソースを更新できるようにするには、スタックポリシーに明示的な `Allow` ステートメントを指定する必要があります。] -上記で `stack-policy-lab` スタックに設定したスタックポリシーは、[論理 ID](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html#resources-section-structure-resource-fields) が `SNSTopic` であるリソースの更新を拒否します。 +上記で `cfn-workshop-stack-policy` スタックに設定したスタックポリシーは、[論理 ID](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html#resources-section-structure-resource-fields) が `SNSTopic` であるリソースの更新を拒否します。 それでは、作成したスタックを更新して、適用したスタックポリシーをテストしてみましょう。 - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +次のコマンドを使って `SNSTopicTagValue` の値を `Topic-Tag-1` から `Topic-Tag-2` に更新します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack \ +--stack-name cfn-workshop-stack-policy \ +--use-previous-template \ +--parameters ParameterKey=SNSTopicTagValue,ParameterValue=Topic-Tag-2 +::: +CloudFormation は次の結果を返却します。 +:::code{language=json showLineNumbers=false showCopyAction=false} +"StackId" : "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-stack-policy/330b0120-1771-11e4-af37-50ba1b98bea6" +::: +:::: +::::tab{id="local" label="ローカル開発"} 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. `stack-policy-lab` という名前のスタックを選択し、**更新**を選択します。 -3. 次のページで、**現在のテンプレートの使用**を選択します。**次へ**をクリックします。 -4. パラメーターセクションで、`SNSTopicTagValue` の値を `Topic-Tag-1` から `Topic-Tag-2` に更新します。**次へ**をクリックします。 -5. **スタックオプションの設定**ページでデフォルト値のまま、**次へ**をクリックします。 -6. 次のページで**送信**をクリックします。 +1. `cfn-workshop-stack-policy` という名前のスタックを選択し、 **更新** を選択します。 +1. 次のページで、 **現在のテンプレートの使用** を選択します。 **次へ** をクリックします。 +1. パラメーターセクションで、`SNSTopicTagValue` の値を `Topic-Tag-1` から `Topic-Tag-2` に更新します。 **次へ** をクリックします。 +1. **スタックオプションの設定** ページでデフォルト値のまま、 **次へ** をクリックします。 +1. 次のページで **送信** をクリックします。 +:::: +::::: -スタックの更新は失敗します。スタックの**イベント**ペインを見ると、[論理 ID](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html#resources-section-structure-resource-fields) が `SNSTopic` であるリソースの `Action denied by stack policy` というエラーが表示されます。 +スタックの更新は失敗します。[AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)でスタックの **イベント** ペインを見ると、[論理 ID](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html#resources-section-structure-resource-fields) が `SNSTopic` であるリソースの `Action denied by stack policy` というエラーが表示されます。 -それでは、`stack-policy-lab` スタックで有効にした削除保護機能をテストしてみましょう。 +それでは、`cfn-workshop-stack-policy` スタックで有効にした削除保護機能をテストしてみましょう。 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. `stack-policy-lab` という名前のスタックを選択し、**削除**を選択します。 +1. `cfn-workshop-stack-policy` という名前のスタックを選択し、 **削除** を選択します。 -スタックで**削除保護**が有効になっていることを知らせるメッセージウィンドウが表示されます。スタックを削除する前に無効にする必要があります。 +スタックで **削除保護** が有効になっていることを知らせるメッセージウィンドウが表示されます。スタックを削除する前に無効にする必要があります。 **キャンセル** を選択してください。 -おめでとうございます! これで、CloudFormation スタック内のリソースの更新操作を定義し、スタックが削除されないようにする方法を学習しました。[AWS Command Line Interface](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-welcome.html) を使用してスタックポリシーを適用する方法については、[スタックポリシーの設定](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html#protect-stack-resources-protecting)をご参照ください。AWS Command Line Interface を使用して削除保護を有効または無効にするには、[update-termination-protection](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/update-termination-protection.html) コマンドを使用します。 +おめでとうございます! これで、CloudFormation スタック内のリソースの更新操作を定義し、スタックが削除されないようにする方法を学習しました。 ### **ラボパート 2 - DeletionPolicy** @@ -117,34 +184,44 @@ Resources: * `code/workspace/stack-policy-and-prevention-controls` ディレクトリにいることを確認します。 * 以下のコードをコピーして `deletion-policy-lab.yaml` ファイルに追加し、ファイルを保存します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=11} Resources: SNSTopic: DeletionPolicy: Retain Type: AWS::SNS::Topic Properties: TopicName: Topic-2 -``` - +::: +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +**スタックの作成** を行うためにターミナルで次のコマンドを実行します +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ +--stack-name cfn-workshop-stack-policy-deletion \ +--template-body file://deletion-policy-lab.yaml +::: +:::: +::::tab{id="local" label="ローカル開発"} 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. **スタックの作成**から、**新しいリソースを使用 (標準)** を選択します。 -3. **テンプレートの指定**セクションで、**テンプレートファイルをアップロード**を選択します。`deletion-policy-lab.yaml` テンプレートをアップロードし、**次へ**をクリックします。 -4. スタック名を入力します。例えば、`deletion-policy-lab` と入力します。**次へ**をクリックします。 -5. **スタックオプションの設定ページ**でデフォルト値のまま、ページの一番下までスクロールして**次へ**をクリックします。 -6. 次のページで、**送信**をクリックします。 +1. **スタックの作成** から、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルをアップロード** を選択します。`deletion-policy-lab.yaml` テンプレートをアップロードし、 **次へ** をクリックします。 +1. スタック名を入力します。例えば、`deletion-policy-lab` と入力します。 **次へ** をクリックします。 +1. **スタックオプションの設定ページ** でデフォルト値のまま、ページの一番下までスクロールして **次へ** をクリックします。 +1. 次のページで、 **送信** をクリックします。 +:::: +::::: `DeletionPolicy` 属性に `Retain` 値を使用するときは、スタックからリソースを削除するとき、またはスタックを削除するときにリソースを保持するように指定します。 スタックが作成されたら、リソースに設定した `DeletionPolicy` をテストしてみましょう。 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. `deletion-policy-lab` という名前のスタックを選択し、**削除**を選択します。次に、**削除**を選択して確定します。 +1. `cfn-workshop-deletion-policy` という名前のスタックを選択し、 **削除** を選択します。次に、 **削除** を選択して確定します。 スタックイベントペインで、論理 ID が `SNSTopic` のリソースが削除をスキップしたことがわかります。リソースが保持されていることを確認するには、以下の手順に従います。 - -1. [Amazon SNS コンソール](https://console.aws.amazon.com/sns/) に移動し、**トピック** を選択します。 -2. スタックで作成したトピック `Topic-2` がまだ存在していることから、スタックの削除中に削除されなかったことが分かります。 +1. [Amazon SNS コンソール](https://console.aws.amazon.com/sns/) に移動し、 **トピック** を選択します。 +1. スタックで作成したトピック `Topic-2` がまだ存在していることから、スタックの削除中に削除されなかったことが分かります。 おめでとうございます! これで、リソースに `DeletionPolicy` リソース属性を定義して、スタックの削除時にそのリソースを保持する方法を学習しました。詳しい情報については、[`DeletionPolicy` 属性](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html) と [`DeletionPolicy` オプション](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html#aws-attribute-deletionpolicy-options)をご参照ください。 @@ -155,18 +232,14 @@ Resources: これで、[論理 ID](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html#resources-section-structure-resource-fields) に基づいてリソースの更新を拒否するスタックポリシーを作成する方法がわかりました。この演習では、特定のタイプのリソースに適用されるスタックポリシーを作成します。タスクは、`AWS::RDS::DBInstance` リソースタイプへのすべての更新アクションを拒否するスタックポリシーを作成することです。 :::expand{header= "ヒントが必要ですか?"} - - [Condition](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/protect-stack-resources.html#stack-policy-reference) キーを使用して `ResourceType` を定義します。 - すべての更新アクションを含めるには、 `Action` をどのように指定しますか? - `Resource` にはどの値を指定すべきですか? - ::: -:::expand{header= "解決策を確認しますか?"} - +::::expand{header= "解決策を確認しますか?"} `"Effect" : "Deny"` に対して、次に示すように `Action`、`Resource`、`Condition` ブロックを含むスタックポリシーを作成します。 - -```json +:::code{language=json showLineNumbers=false showCopyAction=true} { "Statement" : [ { @@ -188,24 +261,21 @@ Resources: } ] } -``` - ::: +:::: これで、特定のリソースタイプの更新を拒否するスタックポリシーを作成する方法がわかりました。 ### クリーンアップ - 次に示す手順に従って、このラボで作成したリソースをクリーンアップしてください。 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. `stack-policy-lab` という名前のスタックを選択し、**削除**を選択します。 -3. メッセージウィンドウで、**削除保護を編集する**を選択し、**削除保護**を**無効**とします。**保存する**をクリックします。 -4. `stack-policy-lab` という名前のスタックを選択し、**削除** を選択し、**削除** を選択して確定します。 -5. [Amazon SNS コンソール](https://console.aws.amazon.com/sns/) に移動し、**トピック** を選択します。次に、トピック `Topic-2` を選択し、**削除**を選択します。メッセージペインに `これを削除` と入力し、**削除** を選択して確定します。 +1. `cfn-workshop-stack-policy` という名前のスタックを選択し、 **削除** を選択します。 +1. メッセージウィンドウで、 **削除保護を編集する** を選択し、 **削除保護** を **無効** とします。 **保存する** をクリックします。 +1. `cfn-workshop-stack-policy` という名前のスタックを選択し、 **削除** を選択し、 **削除** を選択して確定します。 +1. [Amazon SNS コンソール](https://console.aws.amazon.com/sns/) に移動し、 **トピック** を選択します。次に、トピック `Topic-2` を選択し、 **削除** を選択します。メッセージペインに `これを削除` と入力し、 **削除** を選択して確定します。 -* * * +___ ### まとめ - おめでとうございます! これで、意図しない更新を防ぎ、スタックが削除されないように保護し、意図せずにスタックが削除された場合にリソースを保存する方法を学習しました。 diff --git a/content/intermediate/operations/stacksets/index.ja.md b/content/intermediate/operations/stacksets/index.ja.md index 2aa6e6a0d..bffd8f801 100644 --- a/content/intermediate/operations/stacksets/index.ja.md +++ b/content/intermediate/operations/stacksets/index.ja.md @@ -1,228 +1,225 @@ --- -title: "Orchestrating with StackSets" +title: "スタックセットによるオーケストレーション" weight: 700 --- -::alert[日本語翻訳準備中]{type="info"} - -_Lab Duration: ~45 minutes_ +_ラボ実施時間 : 45分程度_ --- -### Overview +### 概要 -You can deploy the same infrastructure in multiple AWS [Regions](https://aws.amazon.com/about-aws/global-infrastructure/regions_az/) and/or multiple AWS accounts using [AWS CloudFormation StackSets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html). With CloudFormation StackSets, you can create, update, or delete stacks across multiple accounts and AWS regions with a single operation. From an administrator account, you can define and manage a CloudFormation template, and use the template as a basis for provisioning stacks into target accounts or regions of your choice. You can also share parameters between stack sets by [exporting and importing output values](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html), and establish dependencies in your stack sets. +[AWS CloudFormation StackSets](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html) を使用して、同じインフラストラクチャを複数の AWS [リージョン](https://aws.amazon.com/jp/about-aws/global-infrastructure/regions_az/)または複数の AWS アカウントにデプロイできます。CloudFormation StackSets を使用すると、1 回の操作で複数のアカウントや AWS リージョンにまたがるスタックを作成、更新、削除できます。管理アカウントから CloudFormation テンプレートを定義および管理し、そのテンプレートを基にして任意のターゲットアカウントまたはリージョンにスタックをプロビジョニングできます。[出力値のエクスポートとインポート](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html)によってスタックセットの間でパラメータを共有したり、スタックセットに依存関係を設定したりすることもできます。 -Although you can use StackSets to deploy across multiple AWS accounts and regions, in this lab you will focus on learning how to deploy across regions using one account. An architecture diagram of the target state is shown next: +StackSets を使用して複数の AWS アカウントやリージョンにデプロイすることもできますが、このラボでは、1 つのアカウントを使用して複数のリージョンにデプロイする方法を学習することに重点を置きます。最終的な状態のアーキテクチャ図を以下に示します。 ![StackSetsOverview](/static/intermediate/operations/stacksets/stacksetsoverview.png) -### Topics Covered +### 取り上げるトピック -By the end of this lab, you will be able to: +このラボを修了すると、次のことができるようになります。 -* Leverage CloudFormation StackSets to provision resources in one account and across multiple regions using a single operation. -* Understand how you can export output parameters from a stack set instance, and import them into another stack set instance. +* CloudFormation StackSets を活用して、1 つのアカウントでリソースをプロビジョニングし、1 回の操作で複数のリージョンにまたがってリソースをプロビジョニングします。 +* スタックセットのインスタンスから出力パラメータをエクスポートし、別のスタックセットのインスタンスにインポートする方法を理解します。 -### Start Lab +### ラボを開始 -### Prerequisites +#### 事前準備 -Specific permissions are required by AWS CloudFormation StackSets to deploy stacks in multiple AWS accounts - and across multiple AWS Regions. You will need an administrator role to perform StackSets operations, and an execution role to deploy the actual stacks in target account(s). These roles require specific naming conventions: **AWSCloudFormationStackSetAdministrationRole** for the administrator role, and **AWSCloudFormationStackSetExecutionRole** for the execution role. StackSets execution will fail if these roles are missing. +AWS CloudFormation StackSets が複数の AWS アカウントにスタックをデプロイしたり、複数の AWS リージョンにスタックをデプロイしたりするには、特定の権限が必要です。StackSets の操作を実行するには管理ロールが必要で、ターゲットアカウントに実際のスタックをデプロイするには実行ロールが必要です。これらのロールには特定の命名規則が必要です。管理者ロールには**AWSCloudFormationStackSetAdministrationRole**、実行ロールには**AWSCloudFormationStackSetExecutionRole** となります。これらのロールがないと、StackSets の実行は失敗します。 -::alert[Note that, on cross-account deployments, the **AWSCloudFormationStackSetAdministrationRole** should be created in the account where you are creating the stack set (the Administrator account). The **AWSCloudFormationStackSetExecutionRole** should be created in each target account where you wish to deploy the stack. Learn more about [granting self-managed permissions](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-prereqs-self-managed.html) for CloudFormation StackSets. If your accounts are managed using AWS Organizations, you can [enable trusted access](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacksets-orgs-enable-trusted-access.html), and CloudFormation will take care of provisioning all the necessary roles across the accounts.]{type="info"} +::alert[クロスアカウントデプロイでは、スタックセットを作成するアカウント(管理アカウント)に**AWSCloudFormationStackSetAdministrationRole** を作成する必要があることに注意してください。**AWSCloudFormationStackSetExecutionRole** は、スタックをデプロイしたい各ターゲットアカウントで作成する必要があります。CloudFormation スタックセットの[セルフマネージド型のアクセス許可を付与する](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-prereqs-self-managed.html) で詳細をご覧ください。アカウントが AWS Organizations を使用して管理されている場合は、[信頼できるアクセスを有効にする](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/stacksets-orgs-activate-trusted-access.html)を実行すると、CloudFormation が全てのアカウントに必要なロールのプロビジョニングを行います。]{type="info"} -To get started with this lab, use CloudFormation to create the administrator and execution roles: +このラボを開始するには、CloudFormation を使用して管理者ロールと実行者ロールを作成します。 -1. Download the administrator role CloudFormation template: https://s3.amazonaws.com/cloudformation-stackset-sample-templates-us-east-1/AWSCloudFormationStackSetAdministrationRole.yml -2. Navigate to the [AWS CloudFormation console](https://console.aws.amazon.com/cloudformation), and make sure you are in the **US East (N. Virginia)** region. -3. Choose **Create Stack**, and select **With new resources**. -4. Leave the **Prepare template** setting as is. - 1. For **Template source**, select **Upload a template file**. - 2. Select **Choose file**, and supply the CloudFormation template you downloaded: *AWSCloudFormationStackSetAdministrationRole.yml*. Choose **Next**. -5. For **Stack name**, use `StackSetAdministratorRole`. Choose **Next**. -6. In **Configure stack options** you may choose to configure tags, which are key-value pairs, that can help you identify your stacks and the resources they create. For example, enter *Owner* in the left column which is the tag key, and your email address in the right column which is the tag value. Accept default values for the other settings in the page. Choose **Next**. -7. Under **Review,** review the contents of the page. At the bottom of the page, select **I acknowledge that AWS CloudFormation might create IAM resources with custom names**. -8. Choose **Submit**. +1. 管理者ロール CloudFormation テンプレートをダウンロードします: https://s3.amazonaws.com/cloudformation-stackset-sample-templates-us-east-1/AWSCloudFormationStackSetAdministrationRole.yml +2. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation) に移動し、**米国東部 (バージニア北部)** リージョンにいることを確認します。 +3. **スタックの作成** を選択し、**新しいリソースを使用 (標準)** を選択します。 +4. **テンプレートを作成** 設定は以下のように設定します。 + 1. **テンプレートソース** では、**テンプレートファイルをアップロード** を選択します。 + 2. **ファイルを選択**を選択し、ダウンロードした CloudFormation テンプレート (*AWSCloudFormationStackSetAdministrationRole.yml*)を指定します。**次へ** を選択します。 +5. **スタック名** には、`StackSetAdministratorRole` を使用してください。**次へ** を選択します。 +6. **スタックオプションの設定** では、キーとバリューのペアであるタグを設定できます。タグは、スタックとスタックによって作成されるリソースを識別するのに役立ちます。例えば、左側の列にタグキーである *Owner* を入力し、右側の列にタグ値である電子メールアドレスを入力します。ページの他の設定はデフォルト値をそのまま使用します。**次へ** を選択します。 +7. **レビュー** でページの内容を確認します。ページの下部で、**AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。** にチェックを入れます。 +8. **送信** を選択します。 -Wait until the stack creation completes with a `CREATE_COMPLETE` **Status**. +スタックの作成の **ステータス** が `CREATE_COMPLETE` になるまで待ってください。 -You created the administrator role for StackSets; next, you will create the execution role. +StackSets の管理者ロールを作成しました。次に実行ロールを作成します。 -1. Download the execution role CloudFormation template: https://s3.amazonaws.com/cloudformation-stackset-sample-templates-us-east-1/AWSCloudFormationStackSetExecutionRole.yml -2. In the [AWS CloudFormation console](https://console.aws.amazon.com/cloudformation), select **Create Stack** and choose **With new resources**. -3. Leave the **Prepare template** setting as is. - 1. For **Template source**, select **Upload a template file**. - 2. Select **Choose file**, and supply the CloudFormation template you downloaded: *AWSCloudFormationStackSetExecutionRole.yml*. Choose **Next**. -4. In the **Specify stack details** page: for **Stack name**, use `StackSetExecutionRole`. -5. In **Parameters**, enter the 12-digit account ID for the AWS account you are using for this lab. Choose **Next**. -6. For **Configure stack options** you may choose to configure tags, as mentioned earlier. For example, enter *Owner* for the tag key, and your email address for the tag value. Accept default values for the other settings in the page. Choose **Next**. -7. Under **Review**, review the contents of the page. At the bottom of the page, select **I acknowledge that AWS CloudFormation might create IAM resources with custom names**. -8. Select **Submit**. +1. 実行ロール CloudFormation テンプレートをダウンロードします: https://s3.amazonaws.com/cloudformation-stackset-sample-templates-us-east-1/AWSCloudFormationStackSetExecutionRole.yml +2. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)で、**スタックの作成** を選択し、**新しいリソースを使用 (標準)** を選択します。 +3. **テンプレートを作成** 設定は、以下のように設定します。 + 1. **テンプレートソース** では、**テンプレートファイルをアップロード** を選択します。 + 2. **ファイルを選択** を選択し、ダウンロードした CloudFormation テンプレート (*AWSCloudFormationStackSetExecutionRole.yml*) を指定します。**次へ** を選択します。 +4. **スタックの詳細を指定** ページで、**スタック名** には `StackSetExecutionRole` を使用してください。 +5. **パラメータ** に、このラボで使用している AWS アカウントの 12 桁のアカウント ID を入力します。**次へ** を選択します。 +6. **スタックオプションの設定** では、前述のようにタグを設定することができます。例えば、タグキーには *Owner* と入力し、タグ値にはメールアドレスを入力します。ページの他の設定はデフォルト値をそのまま使用します。**次へ** を選択します。 +7. **レビュー** で、ページの内容を確認します。ページの下部で、**AWS CloudFormation によって IAM リソースがカスタム名で作成される場合があることを承認します。** を選択します。 +8. **送信** を選択します。 -Wait until the stack creation completes with a `CREATE_COMPLETE` **Status**. +スタックの作成の **ステータス** が `CREATE_COMPLETE` になるまで待ってください。 -Now that you created necessary permissions, you will proceed with Part 1 of the lab. +必要な権限を作成したので、ラボのパート 1 に進みます。 -#### Part 1 +#### ラボパート 1 -In part 1 of this lab, you'll use an example CloudFormation template, `example_network.yaml`, to create stacks in two Regions of the same account using StackSets. In part 2 of this lab, you'll use another example CloudFormation template, `example_securitygroup.yaml`, and create a security group for each network you created with the previous stack set. The architecture diagram of resources you'll describe with `example_network.yaml` is shown next: +このラボのパート 1 では、サンプルの CloudFormation テンプレート `example_network.yaml` を使用して、StackSets 機能で同じアカウントの 2 つのリージョンにスタックを作成します。このラボのパート 2 では、別のサンプル CloudFormation テンプレート `example_securitygroup.yaml` を使用して、前のスタックセットで作成したネットワークごとにセキュリティグループを作成します。`example_network.yaml` で記述するリソースのアーキテクチャ図を以下に示します。 ![StackSetsNetworkStack](/static/intermediate/operations/stacksets/stacksetsnetworkstack.png) -To get started, follow steps shown next: +開始するには、以下の手順に従ってく進んでださい。 -1. Navigate to the `code/workspace/stacksets` directory. -1. Open the `example_network.yaml` CloudFormation template in the text editor of your choice. -1. Familiarize with the configuration for the example resources in the template. In the example, your intents are to: - 1. create an [Amazon Virtual Private Cloud](https://aws.amazon.com/vpc/), Internet Gateway, two public subnets, route table, and two routes to the Internet: you will choose to deploy these resources in multiple regions using a single create operation via CloudFormation StackSets; - 1. [export](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html) the VPC ID and Subnet IDs outputs. Exports are region-specific. +1. `code/workspace/stacksets` ディレクトリに移動します。 +2. お好みのテキストエディターで `example_network.yaml` CloudFormation テンプレートを開きます。 +3. テンプレート内のサンプルリソースの設定を確認しておいてください。この例では以下のことを意図しています。 + 1. [Amazon Virtual Private Cloud](https://aws.amazon.com/jp/vpc/)、インターネットゲートウェイ、2 つのパブリックサブネット、ルートテーブル、およびインターネットへの 2 つのルートを作成します。CloudFormation StackSets で 1 回の作成オペレーションで、これらのリソースを複数のリージョンにデプロイできるようにします。 + 2. VPC ID とサブネット ID を[エクスポート](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html)に出力します。エクスポートはリージョンによって異なります。 -You will use the `example_network.yaml` template, that contains the network resources mentioned earlier, to deploy the template in two regions (`us-east-1` and `us-west-2`) of the same account. +前述のネットワークリソースを含む `example_network.yaml` テンプレートを使用して、同じアカウントの 2 つのリージョン(`us-east-1` と `us-west-2`) にテンプレートをデプロイします。 -In this next step, you will use the AWS CloudFormation Console to create a stack set from the `example_network.yaml` template: +次のステップでは、AWS CloudFormation コンソールを使用して `example_network.yaml` テンプレートからスタックセットを作成します。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -1. Let's **Create StackSets** by using the following AWS CLI command. +1. 次の AWS CLI コマンドを使用して、**Create StackSet** をしてみましょう。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack-set \ --stack-set-name cfn-workshop-network \ --template-body file://example_network.yaml ::: -1. Create stack instances to your stackset by using the following AWS CLI command. This command requires you specify the 12-digit AWS Account ID for the account you are using for this Lab. You can find this value by choosing the user/role drop-down menu in the top-right corner.For regions, choose to deploy in US East (N. Virginia) and US West (Oregon). +1. 次の AWS CLI コマンドを使用して、スタックセットにスタックインスタンスを作成します。このコマンドでは、このラボで使用するアカウントの 12 桁の AWS アカウント ID を指定する必要があります。AWS アカウント ID は、画面の右上の ユーザ/ロール ドロップダウンメニューを選択すると確認できます。リージョンには、米国東部 (バージニア北部) と米国西部 (オレゴン) の両方にデプロイすることを選択します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack-instances \ --stack-set-name cfn-workshop-network \ --accounts 123456789012 \ --regions us-east-1 us-west-2 ::: -1. CloudFormation returns the following output. +1. CloudFormation は次の出力を返却します。 :::code{language=json showLineNumbers=false showCopyAction=false} "OperationId": "d7995c31-83c2-xmpl-a3d4-e9ca2811563f" ::: -1. Verify that the stack instances were created successfully. Run `DescribeStackSetOperation` with the `operation-id` that is returned as part of the output of step 3. +1. スタックインスタンスが正常に作成されたことを確認します。ステップ 3 の出力の一部として返された `operation-id` を使用して `DescribeStackSetOperation` を実行します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation describe-stack-set-operation \ --stack-set-name cfn-workshop-network \ --operation-id operation_ID ::: -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). From the panel on the left of the page, select the **StackSets** tab. -1. Select `cfn-workshop-network`,Under **Stack instances**, you should see two stacks deployed. One in `us-east-1` and another in `us-west-2` +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。ページの左側にあるパネルから、**StackSets** タブを選択します。 +1. `cfn-workshop-network` を選択すると、**スタックインスタンス** の下に 2 つのスタックがデプロイされているはずです。1 つは `us-east-1` にあり、もう 1 つは `us-west-2` にあります。 :::: -::::tab{id="local" label="Local development"} -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. From the panel on the left of the page, select the **StackSets** tab. Choose **Create StackSets**. -1. In the **Permissions** section: choose **Self-service permissions**; leave the value for **IAM Admin role ARN** empty; set **IAM execution role name** to **AWSCloudFormationStackSetsExecutionRole**. -1. From the **Prerequisite**-**Prepare template** section, choose **Template is ready**. -1. Under **Specify template**, select **Template source** and choose **Upload a template file**. Select **Choose file** and supply the CloudFormation template `example_network.yaml` mentioned earlier, and then choose **Next**. -1. In **Specify StackSet details** page, provide name, description, and set parameters: - 1. Specify a **StackSet** name. For example, choose `cfn-workshop-network`. - 2. Provide a **StackSet description**. For example, choose `Provisions VPC, internet gateway, two public subnets, and two routes to the Internet`. - 3. Accept default values for **Parameters**. Choose **Next**. -1. On **Configure StackSet options**, leave **Execution configuration** as is. Choose **Next**. -1. In **Set deployment options** page, in **Add stacks to stack set** section, choose to **Deploy new stacks**. -1. Under **Accounts**, choose **Deploy stacks in accounts**. -1. In the **Account numbers** text box, enter the 12-digit AWS account ID for the account you are using for this lab. You can find this value by choosing the user/role drop-down menu in the top-right corner. -![StackSetsDeploymentOptions](/static/intermediate/operations/stacksets/stacksetsdeploymentoptions.png) -1. For **Specify regions**, choose to deploy in **US East (N. Virginia)** and **US West (Oregon)**. -1. Accept default values for **Deployment options**, and choose **Next**. -1. On the **Review** page, review the contents of the page and choose **Submit**. -1. Refresh the StackSet creation page until you see **CREATE** status as `SUCCEEDED`. -![StackSetCompletion](/static/intermediate/operations/stacksets/createstacksetcompletion.png) -1. Under **Stack instances**, you should see two stacks deployed. One in `us-east-1` and another in `us-west-2`. -![StackInstances](/static/intermediate/operations/stacksets/stackinstances.png) +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +1. ページの左側のパネルから、**StackSets** タブを選択します。**StackSet の作成** を選択します。 +1. **アクセス許可** セクションで、**IAM 管理ロール ARN** の値は空白のままにし、**IAM 実行ロール名** を**AWSCloudFormationStackSetExecutionRole** に設定します。 +1. **前提条件 - テンプレートの準備** セクションから、**テンプレートの準備完了** を選択します。 +1. **テンプレートを指定** セクションで、**テンプレートソース** で **テンプレートファイルのアップロード** を選択します。**ファイル名の選択** を選択し、前述の CloudFormation テンプレート `example_network.yaml` を指定して、**次へ** を選択します。 +1. **StackSet の詳細を指定** ページで、名前、説明、設定パラメータを指定します。 + 1. **StackSet 名** を指定します。例えば、`cfn-workshop-network` を入力します。 + 1. **StackSet の説明**を入力します。例えば、`Provisions VPC, internet gateway, two public subnets, and two routes to the Internet` を入力します。 + 1. **パラメータ** はデフォルト値をそのまま使用してください。**次へ** を選択します。 +1. **StackSet オプションの設定** では、**実行設定** はそのままにします。**次へ** を選択します。 +1. **デプロイオプションの設定** ページの **スタックセットにスタックを追加** セクションで、**新しいスタックのデプロイ** を選択します。 +1. **アカウント** で、**スタックをアカウントにデプロイ** を選択します。 +1. **アカウント番号** テキストボックスに、このラボで使用しているアカウントの 12 桁のアカウント ID を入力します。この値は、画面の右上にある ユーザ/ロール ドロップダウンメニューを選択すると確認できます。 +![StackSetsDeploymentOptions](/static/intermediate/operations/stacksets/stacksetsdeploymentoptions.ja.png) +1. **リージョンの指定** では、**米国東部 (バージニア北部)** と **米国西部 (オレゴン)** にデプロイすることを選択します。 +1. **デプロイオプション** はデフォルト値をそのまま使用し、**次へ** を選択します。 +1. **レビュー** ページで、ページの内容を確認し、**送信** を選択します。 +1. **CREATE** ステータスが `SUCCEEDED` になるまで StackSet 作成ページを更新します。 +![StackSetCompletion](/static/intermediate/operations/stacksets/createstacksetcompletion.ja.png) +1. **スタックインスタンス** タブで、2 つのスタックがデプロイされているはずです。1 つは `us-east-1` にあり、もう 1 つは `us-west-2` にあります。 +![StackInstances](/static/intermediate/operations/stacksets/stackinstances.ja.png) :::: ::::: -Navigate to **Exports**. You should see 3 exports named `AWS-CloudFormationWorkshop-SubnetId1`, `AWS-CloudFormationWorkshop-SubnetId2,` and `AWS-CloudFormationWorkshop-VpcId`. These exports are created in each region where you deployed your stack sets (`us-east-1` and `us-west-2`). +左のパネルで **エクスポート** を選択します。`AWS-CloudFormationWorkshop-SubnetId1`、`AWS-CloudFormationWorkshop-SubnetId2`、`AWS-CloudFormationWOrkshop-VPCID` という名前の 3 つのエクスポートが表示されるはずです。これらのエクスポートは、スタックセットをデプロイした各リージョン (`us-east-1` と `us-west-2`) で作成されます。 -![StackSetExports](/static/intermediate/operations/stacksets/exports.png) +![StackSetExports](/static/intermediate/operations/stacksets/exports.ja.png) -Congratulations! You have deployed your infrastructure to multiple AWS Regions using a single operation. +おめでとうございます! 1 回のオペレーションでインフラストラクチャを複数のリージョンにデプロイできました。 -#### Part 2 +#### ラボパート 2 -In this part of the lab, you will use a new CloudFormation template, `example_securitygroup.yaml`, describing a security group that you will associate to the VPC you created earlier in a given region. You will also export the output for the **Security Group ID**, so that you can consume it later in the *Challenge* portion of this workshop lab. The architecture diagram highlighting the security group resource you will describe with the `example_securitygroup.yaml` template is shown next: +ラボのこのパートでは、新しい CloudFormation テンプレート `example_securitygroup.yaml` を使用して、特定のリージョンで以前作成した VPC に関連付けるセキュリティグループを記述します。また、**セキュリティグループ ID** の出力をエクスポートして、このワークショップラボの *チャレンジ* の部分で後で使用できるようにします。`example_securitygroup.yaml` テンプレートで記述するセキュリティグループリソースを表現したアーキテクチャ図を以下に示します。 ![StackSetsSecurityGroup](/static/intermediate/operations/stacksets/stacksetsecuritygroup.png) -Let’s get started: +それでは、始めましょう。 -1. Navigate to the `code/workspace/stacksets` directory. -1. Open the `example_securitygroup.yaml` template in your favorite text editor. -1. Familiarize with the configuration for the example security group in the template. In the example, your intents are to: - 1. create a security group for the VPC you created earlier in each of the two regions with a single create operation using CloudFormation StackSets. You will reference the VPC ID using the `Fn::ImportValue` [intrinsic function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html); - 2. export the `SecurityGroupId` output. Exports are region-specific +1. `code/workspace/stacksets` ディレクトリに移動します。 +2. `example_securitygroup.yaml` テンプレートをお好みのテキストエディタで開きます。 +3. テンプレート内のサンプルセキュリティグループの設定を確認してください。この例では、以下のことを意図しています。 + 1. CloudFormation StackSets を使用して 1 回の作成操作で、2 つのリージョンのそれぞれで先に作成した VPC にセキュリティグループを作成します。VPC ID は `Fn::ImportValue` [組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html) を使用して参照します。 + 2. `SecurityGroupID` の出力をエクスポートします。エクスポートはリージョンによって異なります。 -In this next step, you will use the AWS CloudFormation console to create a stack set from the `example_securitygroup.yaml` template: +次のステップでは、AWS CloudFormation コンソールを使用して `example_securitygroup.yaml` テンプレートからスタックセットを作成します。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -1. Let's **Create StackSets** by using the following AWS CLI command. +1. 次の AWS CLI コマンドを使用して、**Create StackSet** を実行しましょう。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack-set \ --stack-set-name cfn-workshop-security \ --template-body file://example_securitygroup.yaml ::: -1. Create stack instances to your stackset by using the following AWS CLI command. This command requires you specify the 12-digit AWS Account ID for the account you are using for this Lab. You can find this value by choosing the user/role drop-down menu in the top-right corner. For regions, choose to deploy in US East (N. Virginia) and US West (Oregon). +1. 次の AWS CLI コマンドを使用して、スタックセットにスタックインスタンスを作成します。このコマンドでは、ラボで使用するアカウントの 12 桁の AWS アカウント ID を指定する必要があります。この値は、画面の右上にある ユーザー/ロール ドロップダウンメニューを選択すると確認できます。リージョンの場合には、米国東部 (バージニア北部) と米国西部 (オレゴン) の両方にデプロイすることを選択します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack-instances \ --stack-set-name cfn-workshop-security \ --accounts 123456789012 \ --regions us-east-1 us-west-2 ::: -1. CloudFormation returns the following output. +1. CloudFormation は次の出力を返却します。 :::code{language=json showLineNumbers=false showCopyAction=false} "OperationId": "d7995c31-83c2-xmpl-a3d4-e9ca2811563f" ::: -1. Verify that the stack instances were created successfully. Run `DescribeStackSetOperation` with the `operation-id` that is returned as part of the output of step 3. +1. スタックインスタンスが正常に作成されたことを確認します。ステップ 3 の出力の一部として返却された `operation-id` を使用して `DescribeStackSetOperation` を実行します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation describe-stack-set-operation \ --stack-set-name cfn-workshop-security \ --operation-id operation_ID ::: -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). From the panel on the left of the page, select the **StackSets** tab. -1. Select `cfn-workshop-security`,Under **Stack instances**, you should see two stacks deployed. One in `us-east-1` and another in `us-west-2` +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。左側のパネルから、**StackSets** を選択します。 +2. `cfn-workshop-security` を選択すると、**スタックインスタンス** の下に 2 つのスタックがデプロイされているはずです。1 つは `us-east-1` にあり、もう 1 つは `us-west-2` にあります。 :::: -::::tab{id="local" label="Local development"} -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. Select the **StackSets** tab. Choose **Create StackSets**. -1. In the **Permissions** section: choose **Self-service permissions**; for **IAM Admin role ARN**, select **IAM role name** from the drop-down menu, and set it to **AWSCloudFormationStackSetAdministrationRole**; set **IAM execution role name** to **AWSCloudFormationStackSetsExecutionRole**. -1. From **Prepare template**, choose **Template is ready**. -1. For **Template source**, choose **Upload a template file**. Select **Choose file** and supply the CloudFormation template `example_securitygroup.yaml` mentioned earlier, and then choose **Next**. -1. In **Specify StackSet details** page, provide name, description, and set parameters: - 1. Specify a **StackSet name**. For example, choose `cfn-workshop-security`. - 1. Provide a **StackSet description**. For example, choose `Provisions a security group, and associates it to the existing VPC`. - 1. Accept default values for **Parameters**. Choose **Next**. -1. On **Configure StackSet options**, leave **Execution Configuration** as is. Choose **Next**. -1. In **Set deployment options** page, in **Add stacks to stack set** section, choose to **Deploy new stacks**. - 1. Under **Accounts**, choose **Deploy stacks in accounts** option. - 1. From **Add stacks to stackset**, choose **Deploy new stacks**. - 1. In the **Account numbers** text box, enter the 12-digit AWS account ID for the account you are using for this lab. - 1. For **Specify regions**, choose to deploy in **US East (N. Virginia)** and **US West (Oregon)**. - 1. Accept default values for **Deployment options**. Ensure **Maximum concurrent accounts** is set to **1**, **Failure tolerance** to **0** and **Region Concurrency** to **Sequential**. Choose **Next**. - 1. On the **Review** page, review the contents of the page, and choose **Submit**. - 1. Refresh the StackSet creation page until you see the **Status** of the **CREATE** operation as `SUCCEEDED`. - 1. Under **Stack instances**, you should see two stacks deployed. One in `us-east-1` and another in `us-west-2`. +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +1. ページの左側のパネルから、**StackSets** タブを選択します。**StackSet の作成** を選択します。 +1. **アクセス許可** セクションで、**IAM 管理ロール ARN** 配下には、ドロップダウンから **IAM ロール名** を選択し、隣のドロップダウンから **AWSCloudFormationStackSetAdministrationRole** を選択します。**IAM 実行ロール名** を **AWSCloudFormationStackSetExecutionRole** に設定します。 +1. **前提条件 - テンプレートの準備** セクションから、**テンプレートの準備完了** を選択します。 +1. **テンプレートを指定** セクションで、**テンプレートソース** で **テンプレートファイルのアップロード** を選択します。**ファイル名の選択** を選択し、前述の CloudFormation テンプレート `example_securitygroup.yaml `を指定して、**次へ** を選択します。 +1. **StackSet の詳細を指定** ページで、名前、説明、設定パラメータを指定します。 + 1. **StackSet 名**を指定します。例えば、`cfn-workshop-security`を選択します。 + 1. **StackSet の説明**を入力します。例えば、`Provisions a security group, and associates it to the existing VPC` を入力します。 + 1. **パラメータ** はデフォルト値をそのまま使用してください。**次へ** を選択します。 +1. **StackSet オプションの設定** では、**実行設定** はそのままにします。**次へ** を選択します。 +1. **デプロイオプションの設定** ページの **スタックセットにスタックを追加** セクションで、**新しいスタックのデプロイ** を選択します。 +1. **アカウント** で、**アカウントにスタックをデプロイ** オプションを選択します。 +1. **アカウント番号** テキストボックスに、このラボで使用しているアカウントの 12 桁の AWS アカウント ID を入力します。 +1. **リージョンの指定** では、**米国東部 (バージニア北部)** と **米国西部 (オレゴン)** にデプロイすることを選択します。 +1. **デプロイオプション** はデフォルト値をそのまま使用します。**同時アカウントの最大数** は **1** で、**障害耐性** は **0** で、**リージョンの同時実行** を **順次** であることを確認してください。**次へ** を選択します。 +1. **レビュー** ページで、内容を確認し、**送信** を選択します。 +1. **CREATE** ステータスが `SUCCEEDED` になるまで StackSet 作成ページを更新します。 +1. **スタックインスタンス** タブで、2 つのスタックがデプロイされているはずです。1 つは `us-east-1` にあり、もう 1 つは `us-west-2` にあります。 :::: ::::: -Navigate to **Exports**. You should see a new export named `AWS-CloudFormationWorkshop-SecurityGroupId`. +左のパネルで **エクスポート** に移動します。「AWS-CloudFormationWorkshop-SecurityGroupId」という名前の新しいエクスポートが表示されるはずです。 -![StackSetsSecurityGroupExports](/static/intermediate/operations/stacksets/exportssecuritygroup.png) +![StackSetsSecurityGroupExports](/static/intermediate/operations/stacksets/exportssecuritygroup.ja.png) -Congratulations! You have learned how export an output value from a stack set instance, and import it into another stack set instance. +おめでとうございます!スタックセットインスタンスから出力値をエクスポートし、別のスタックセットインスタンスにインポートする方法を学びました。 -### Challenge +### チャレンジ -In this exercise, you will use the knowledge gained from earlier parts of this lab. Your task is to create a new `cfn-workshop-ec2instance` stack set that will provision an [Amazon Elastic Compute Cloud (Amazon EC2)](https://docs.aws.amazon.com/ec2/?id=docs_gateway) instance in the existing VPC, and attach the security group you created earlier. Your task is also to update the `example_ec2instance.yaml` template to import the value for `SubnetId1` that you exported as part of Part 1 of this lab. When you create the stack set, choose to deploy StackSets operations in **Parallel**. The architecture diagram highlighting the EC2 instance you will describe as part of this challenge is shown next: +この演習では、ラボの前半で得た知識を使用します。あなたのタスクは、既存の VPC に [Amazon Elastic Compute Cloud (Amazon EC2)](https://docs.aws.amazon.com/ja_jp/ec2/) インスタンスをプロビジョニングする新しい `cfn-workshop-ec2instance` スタックセットを作成し、先ほど作成したセキュリティグループをアタッチすることです。また、このラボのパート 1 でエクスポートした `SubnetId1` の値をインポートするように `example_ec2instance.yaml` テンプレートを更新することも課題です。スタックセットを作成する時は、StackSets オペレーションを **並行** にデプロイするようにしてください。このチャレンジで定義する EC2 インスタンスを表すアーキテクチャ図を以下に示します。 ![StackSetsEc2instance](/static/intermediate/operations/stacksets/stacksetsec2instance.png) -::::expand{header="Need a hint?"} -* Make sure you are in the directory named `code/workspace/stacksets`. -* Open the `example_ec2instance.yaml` CloudFormation template in the text editor of your choice. +::::expand{header="ヒントが必要ですか?"} +* `code/workspace/stacksets` ディレクトリに移動していることを確認してください。 +* お好みのテキストエディターで `example_ec2instance.yaml` CloudFormation テンプレートを開きます。 :::alert{type="info"} -[Amazon Machine Image (AMI)](https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html) resources are unique in each region. To use region-specific AMI IDs, you use the following code snippet in the `Parameters` section of your template to query the ID of the latest AMI for a given region; you also reference `LatestAmiId` in the **Resources** section of your template in `ImageId`. +[Amazon Machine Image (AMI)](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIs.html) リソースはリージョンごとに異なります。リージョン固有の AMI ID を使用するには、テンプレートの `Parameter` セクションにある次のコードスニペットを使用して、特定のリージョンの最新の AMI ID を取得します。また、テンプレートの **Resources** セクションで `ImageId` で `LatestAmId` を参照します。 ::: :::code{language=yaml showLineNumbers=false showCopyAction=false} LatestAmiId: @@ -230,23 +227,23 @@ LatestAmiId: Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 ::: -* Edit the `Resources` section of the template to import the value for `SubnetId1` that you exported in Part 1. You can import the parameter of your choice the same way you imported the ID of the VPC, from `example_network.yaml` to `example_securitygroup.yaml`. +* テンプレートの `Resources` セクションを編集して、第 1 回でエクスポートした `SubnetId1` の値をインポートします。VPC ID をインポートしたのと同じ方法で、`example_network.yaml` から `example_securitygroup.yaml` に任意のパラメータをインポートできます。 :::: -::::::expand{header="Want to see the solution?"} -You can find the full solution in the `code/solutions/stacksets/example_ec2instance.yaml` template. +::::::expand{header="解決策を確認しますか?"} +ソリューションの全文は `code/solutions/stacksets/example_ec2instance.yaml` テンプレートにあります。 -Append the following to the EC2 instance properties: `SubnetId: !ImportValue AWS-CloudFormationWorkshop-SubnetId1`. +EC2 インスタンスのプロパティにこのコードを追加します: `SubnetId: !ImportValue AWS-CloudFormationWorkshop-SubnetId1` :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -1. Change the directory to `cfn101-workshop/code/solutions/stacksets`. -1. Use the updated template, and create a new **StackSet** using the following AWS CLI command. +1. ディレクトリを `cfn101-workshop/code/solutions/stacksets` に変更します。 +2. 更新したテンプレートを使用し、次の AWS CLI コマンドを使用して新しい **StackSet** を作成します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack-set \ --stack-set-name cfn-workshop-ec2instance \ --template-body file://example_ec2instance.yaml ::: -1. Create stack instances to your stackset by using the following AWS CLI command. To deploy StackSets operations in parallel, choose **Parallel** for `RegionalConcurrencyType` from `--operation-preferrences`. +1. 次の AWS CLI コマンドを使用して、スタックセットにスタックインスタンスを作成します。StackSet のオペレーションを並行してデプロイするには、`--operation-preferences` の `RegionConcurrencyType` を **PARALLEL** に指定します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack-instances \ --stack-set-name cfn-workshop-ec2instance \ @@ -255,19 +252,19 @@ aws cloudformation create-stack-instances \ --operation-preferences RegionConcurrencyType=PARALLEL ::: :::: -::::tab{id="local" label="Local development"} -Use the updated template, and create a new `cfn-workshop-ec2instance` stack set to deploy the EC2 instance resources in the 2 regions you chose earlier. To deploy StackSets operations in parallel, from **Deployment Options** choose **Parallel**. This will deploy StackSets operations in both regions in parallel, thus saving time. +::::tab{id="local" label="ローカル開発"} +更新したテンプレートを使用して、新しい `cfn-workshop-ec2instance` スタックセットを作成して、先に選択した 2 つのリージョンに EC2 インスタンスリソースをデプロイします。StackSets のオペレーションを並行してデプロイするには、**リージョンの同時実行** を **並行** に設定します。これにより、StackSets のオペレーションを両方のリージョンに並行してデプロイできるため、時間を節約できます。 :::: ::::: :::::: -### Cleanup +### クリーンアップ -You will now tear down the resources you created. To delete a stack set, you will first delete its stack set instances, and then delete the empty stack set. +最後に、作成したリソースを削除します。スタックセットを削除するには、まずスタックインスタンスを削除し、次に空のスタックセットを削除します。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -1. Delete the **StackSet** Instances before you delete the StackSets from AWS CLI. +1. AWS CLI からスタックセットを削除する前に、**StackSet** のスタックインスタンスを削除してください。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation delete-stack-instances \ --stack-set-name cfn-workshop-ec2instance \ @@ -275,55 +272,55 @@ aws cloudformation delete-stack-instances \ --regions us-east-1 us-west-2 \ --no-retain-stacks ::: -1. Wait for `DELETE-STACK-INSTANCE` operation to complete and run the following command to delete the **StackSets** +1. `DELETE-STACK-INSTANCE` 操作が完了するのを待ってから、次のコマンドを実行して **StackSet** を削除します :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation delete-stack-set \ --stack-set-name cfn-workshop-ec2instance ::: -1. Follow the steps 1-2 for other two stack sets, and in the following order: `cfn-workshop-security`, and `cfn-workshop-network`. -1. Delete the IAM Roles that you created during this lab by running the following AWS CLI command +1. 他の 2 つのスタックセットについては、`cfn-workshop-security` と `cfn-workshop-network` の順序で、ステップ 1 〜 2 を実行します。 +1. 次の AWS CLI コマンドを実行して、このラボで作成した IAM ロールを削除します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation delete-stack \ --stack-set-name StackSetAdministratorRole ::: -1. Repeat the step 4 to **Delete** the execution role stack `StackSetAdministratorRole`. +1. ステップ 4 を繰り返して、実行ロールスタック `StackSetAdministratorRole` を **削除** します。 :::: -::::tab{id="local" label="Local development"} - -**How to delete AWS CloudFormation stacks within stack set** - -1. Navigate to the [AWS CloudFormation StackSets console.](https://console.aws.amazon.com/cloudformation/home#/stacksets) -1. Select the CloudFormation stack set you want to delete the stacks from. Choose the last stack set you created, i.e., `cfn-workshop-ec2instance`. -1. From top-right section of the page, select **Actions**, and choose **Delete stacks from StackSet**. -1. Under **Accounts**, select **Deploy stacks in accounts** under **Deployment locations**. -1. Under **Account numbers** enter the 12-digit AWS account ID for the account you are using for this lab. -1. For **Specify regions** select **Add all regions**. This will automatically select the AWS Regions that the StackSet deployed stacks into. Choose **Next**. -1. On the **Review** page, review the contents of the page, and choose **Submit**. -1. The **Status** changes to `PENDING`. -1. Refresh until the **Status** changes to `SUCCEEDED`. -1. Follow steps 2 through 8 for the other two stack sets, and in the following order: `cfn-workshop-security`, and `cfn-workshop-network`. - -Now that you have deleted stacks within each StackSet, you will now choose to delete the empty StackSet. - -**How to delete an AWS CloudFormation stack set** - -1. Navigate to [AWS CloudFormation StackSets console](https://console.aws.amazon.com/cloudformation/home#/stacksets). -1. Select the stack set you wish to delete. -1. Choose **Actions**, and then **Delete**. -1. In the popup that appears, confirm you want to delete this stack set by choosing **Delete StackSet**. -1. On refresh, your StackSet should no longer be listed. -1. Follow steps 2 through 5 for the two other stack sets. - -**How to delete an AWS CloudFormation stacks** - -1. Navigate to [AWS CloudFormation Stacks console](https://console.aws.amazon.com/cloudformation/home#/stacks). -1. Select the stack `StackSetAdministratorRole`, choose **Delete**. -1. In the popup that appears, confirm you want to delete this stack set by choosing **Delete**. -1. On refresh, your stack `StackSetAdministratorRole` should no longer be listed. -1. Follow steps 2 through 4 for the other stack `StackSetExecutionRole` that you created during this lab . +::::tab{id="local" label="ローカル開発"} + +**スタックセット内の AWS CloudFormation スタックを削除する方法** + +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +2. 削除したいスタックから CloudFormation スタックセットを選択します。最後に作成したスタックセット、つまり `cfn-workshop-ec2instance` を選択します。 +3. ページの右上のセクションから**アクション**を選択し、**StackSet からスタックを削除**を選択します。 +4. **アカウント**で、**デプロイロケーション**で**アカウントにスタックをデプロイ**を選択します。 +5. **アカウント番号**に、このラボで使用しているアカウントの 12 桁の AWS アカウント IDを入力します。 +6. **リージョンを指定**では、**全てのリージョンを追加**を選択します。これにより、StackSet がデプロイされた AWS リージョンが自動的に選択されます。 **次へ**を選択します。 +7. **レビュー**ページで、ページの内容を確認し、**送信**を選択します。 +8. **ステータス**が `Pending`に変わります。 +9. **ステータス**が `SUCCEEDED` になるまで更新します。 +10. 他の 2 つのスタックセットについては、`cfn-workshop-security` と `cfn-workshop-network` の順番で、ステップ 2 〜 8 を実行します。 + +各 StackSet 内のスタックを削除したので、次は空の StackSet を削除することを選択します。 + +**AWS CloudFormation スタックセットを削除する方法** + +1. [AWS CloudFormation StackSets コンソール](https://console.aws.amazon.com/cloudformation/home#/stacksets) に移動します。 +2. 削除するスタックセットを選択します。 +3. **アクション** を選択し、**StackSet の削除** を選択します。 +4. 表示されるポップアップで、**削除** を選択して、このスタックセットの削除を確定します。 +5. 画面を更新すると、StackSet は表示されなくなります。 +6. 他の 2 つのスタックセットについては、ステップ 2 〜 5 を実行します。 + +**AWS CloudFormation スタックを削除する方法** + +1. [AWS CloudFormation スタック コンソール](https://console.aws.amazon.com/cloudformation/home#/stacksets) に移動します。 +2. スタック `StackSetAdministratorRole` を選択し、**削除** を選択します。 +3. 示されるポップアップで、**削除** を選択してこのスタックの削除を確定します。 +4. 画面を更新すると、スタック `StackSetAdministratorRole` は表示されなくなります。 +5. このラボで作成したもう 1 つの `StackSetExecutionRole` スタックに対しても、ステップ 2 ~ 4 を実行します。 :::: ::::: -### Conclusion +### まとめ -Great work! You learned how you can use CloudFormation StackSets to deploy templates in multiple AWS Regions using a single operation, and how to export output parameters from one stack set instance and import them into another stack set instance. +CloudFormation StackSets を使用して 1 回のオペレーションで複数の AWS リージョンにテンプレートをデプロイする方法と、あるスタックセットのスタックインスタンスから出力パラメータをエクスポートして別のスタックセットのスタックインスタンスにインポートする方法を学びました。 diff --git a/content/intermediate/operations/understanding-changesets/index.ja.md b/content/intermediate/operations/understanding-changesets/index.ja.md index aec1f2391..0c869265b 100644 --- a/content/intermediate/operations/understanding-changesets/index.ja.md +++ b/content/intermediate/operations/understanding-changesets/index.ja.md @@ -3,6 +3,10 @@ title: "変更セットの理解" weight: 200 --- +_ラボ実施時間 : 20分程度_ + +--- + ### 概要 [AWS CloudFormation](https://aws.amazon.com/jp/cloudformation/) スタックを更新すると、そのスタック内の 1 つ以上のリソースを目的の新しい状態に更新します。リソースの依存関係、[スタックリソースの更新動作](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html)、またはユーザーエラーなどの要因により、特定の状態と実際の新しい状態との間に違いが生じる可能性があります。 @@ -21,44 +25,107 @@ weight: 200 サンプルテンプレートを使用して、CloudFormation スタックを作成します。次に、このスタックに 2 つの異なる変更セットを作成します。1 つはテンプレートの編集によるもので、もう 1 つはパラメータ値の変更によるものです。 それでは、始めましょう。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/understanding-changesets` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/understanding-changesets +::: +1. `Cloud9` エディターで `bucket.yaml` CloudFormation テンプレートを開き、サンプルテンプレートの内容をよく理解してください。 +1. 次の手順に従ってスタックを作成します。 + 1. このテンプレートでは、`BucketName` 入力パラメータに一意の値を指定する必要があります。詳細については、 [バケットの名前付け](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html)を参照してください。 + 1. 次のコマンドを使用してテンプレートからスタックを作成しましょう (この例では AWS リージョンに `us-east-1` を使用しています。必要に応じてこの値を変更してください)。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation create-stack \ +--region us-east-1 \ +--stack-name cfn-workshop-understanding-changesets \ +--template-body file://bucket.yaml \ +--parameters ParameterKey=BucketName,ParameterValue='YOUR_UNIQUE_BUCKET_NAME-HERE' + ::: + 1. CloudFormation は次の出力を返します。 + :::code{language=json showLineNumbers=false showCopyAction=false} + "StackId" : "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-understanding-changesets/330b0120-1771-11e4-af37-50ba1b98bea6" + ::: + 1. CloudFormation コンソールまたは [wait stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) コマンドを使用して `cfn-workshop-understanding-changesets` スタックが作成されるまでお待ちください。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation wait stack-create-complete \ +--stack-name cfn-workshop-understanding-changesets + ::: + :::: +::::tab{id="local" label="ローカル開発"} 1. `code/workspace/understanding-changesets` ディレクトリに移動します。 -2. お好みのテキストエディタで `bucket.yaml` CloudFormation テンプレートを開き、サンプルテンプレートの内容をご確認ください。 -3. 以下の手順に従ってスタックを作成します。 +1. お好みのテキストエディタで `bucket.yaml` CloudFormation テンプレートを開き、サンプルテンプレートの内容をご確認ください。 +1. 以下の手順に従ってスタックを作成します。 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 - 2. **スタックの作成**から、**新しいリソースを使用 (標準)** を選択します。 - 3. **テンプレートの準備**セクションで、**テンプレート準備完了**を選択します。 - 4. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。`bucket.yaml` テンプレートファイルを選択し、**次へ**をクリックします。 - 5. スタック名を指定します (例: `changesets-workshop`)。 - 6. `BucketName` パラメータには必ず一意の値を指定します。詳細については、[バケットの名前付け](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html) をご参照ください。**次へ**をクリックします。 - 7. 次のページで、すべてのオプションをデフォルト値のままにし、**次へ**をクリックします。 - 8. レビューページで、**送信**をクリックします。 - 9. スタックのステータスが `CREATE_COMPLETE` になるまで、スタックの作成ページを更新します。 + 1. **スタックの作成** から、 **新しいリソースを使用 (標準)** を選択します。 + 1. **テンプレートの準備** セクションで、 **テンプレート準備完了** を選択します。 + 1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。`bucket.yaml` テンプレートファイルを選択し、 **次へ** をクリックします。 + 1. スタック名を指定します (例: `cfn-workshop-understanding-changesets`)。 + 1. `BucketName` パラメータには必ず一意の値を指定します。詳細については、[バケットの名前付け](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html) をご参照ください。 **次へ** をクリックします。 + 1. 次のページで、すべてのオプションをデフォルト値のままにし、 **次へ** をクリックします。 + 1. レビューページで、 **送信** をクリックします。 + 1. スタックのステータスが `CREATE_COMPLETE` になるまで、スタックの作成ページを更新します。 +:::: +::::: ### ラボパート 1 ラボのこの部分では、特定のリソースタイプについて、スタックの更新時に [中断を伴わない更新](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt) を必要とするプロパティを指定します。次に、変更セットを作成して変更をプレビューし、変更セット操作の出力を確認します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +`Cloud9` エディタで `bucket.yaml` CloudFormation テンプレートを開き、以下に示すように `VersioningConfiguration` を追加します。ファイルを保存します。 +:::code{language=yaml showLineNumbers=false showCopyAction=true} +MyS3Bucket: + Type: AWS::S3::Bucket + Properties: + BucketName: !Ref BucketName + VersioningConfiguration: + Status: Enabled +::: +次に、最初の変更セットを作成します。 +1. ターミナルから以下のコマンドを **変更セットの作成** に対して実行し、変更セットの名前を指定します (例:`bucket-versioning-update`)。次に、上の例で選択した `bucketName` パラメーターを指定します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-change-set \ +--stack-name cfn-workshop-understanding-changesets \ +--change-set-name bucket-versioning-update \ +--template-body file://bucket.yaml \ +--parameters ParameterKey=BucketName,ParameterValue='TYPE_UNIQUE_BUCKET_NAME-HERE' +::: +1. CloudFormation は AWS CLI の以下の出力を返します。 +:::code{language=json showLineNumbers=false showCopyAction=false} +"StackId" : "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-understanding-changesets/330b0120-1771-11e4-af37-50ba1b98bea6", +"Id": "arn:aws:cloudformation:us-east-1:123456789012:changeSet/bucket-versioning-update/a470cff7-cb2c-4cba-bf27-2b3b9ccc1333" +::: +:::: +::::tab{id="local" label="ローカル開発"} + お好みのテキストエディタで `bucket.yaml` CloudFormation テンプレートを開き、以下に示すように `VersioningConfiguration` を追加し、ファイルを保存します。 -```yaml +:::code{language=yaml showLineNumbers=false showCopyAction=true} MyS3Bucket: Type: AWS::S3::Bucket Properties: BucketName: !Ref BucketName VersioningConfiguration: Status: Enabled -``` +::: 次に、最初の変更セットを作成します。 -1. CloudFormation コンソールで `changesets-workshop` スタックを選択し、**スタックアクション** から **既存スタックの変更セットを作成** を選択します。 -2. **テンプレートの準備**セクションで、**既存テンプレートを置き換える**を選択します。**テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択し、更新した `bucket.yaml` テンプレートを選択し、**次へ**をクリックします。 -3. **スタックの詳細を指定**ページと**スタックオプションの設定**ページの両方で **次へ**を**選択**し、**変更セットの作成**をクリックします。 -4. 変更セットの名前を指定します (例: `bucket-versioning-update`)。また、`MyS3Bucket のバケットバージョニングを有効にする`などの説明を指定し、**変更セットの作成** をクリックします。 -5. 変更セットのステータスが `CREATE_COMPLETE` になるまでページを更新します。 -6. ページの下部に、予想される変更の概要が表示されます。詳細については **JSON の変更**タブに移動します。以下のようになっているはずです。 +1. CloudFormation コンソールで `cfn-workshop-understanding-changesets` スタックを選択し、 **スタックアクション** から **既存スタックの変更セットを作成** を選択します。 +1. **テンプレートの準備** セクションで、 **既存テンプレートを置き換える** を選択します。 **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択し、更新した `bucket.yaml` テンプレートを選択し、 **次へ** をクリックします。 +1. **スタックの詳細を指定** ページと **スタックオプションの設定** ページの両方で **次へ** を **選択** し、 **変更セットの作成** をクリックします。 +1. 変更セットの名前を指定します (例: `bucket-versioning-update`)。また、`MyS3Bucket のバケットバージョニングを有効にする`などの説明を指定し、 **送信** をクリックします。 +1. 変更セットのステータスが `CREATE_COMPLETE` になるまでページを更新します。 +:::: +::::: + +1. [AWS CloudFormation](https://console.aws.amazon.com/cloudformation/) コンソールで、このワークショップで作成したスタックを選択します。たとえば、 `cfn-workshop-understanding-changesets` などです。 +1. **変更セット** タブから、 **bucket-versioning-update** を選択します。 +1. **JSON の変更** タブに移動すると詳細が表示されます。このタブは次のようになっているはずです。 -```json +:::code{language=json showLineNumbers=false showCopyAction=false} [ { "resourceChange": { @@ -89,7 +156,7 @@ MyS3Bucket: "type": "Resource" } ] -``` +::: `resourceChange` 構造では、リソースの論理 ID、CloudFormation が実行するアクション、リソースの物理 ID、リソースのタイプ、および CloudFormation がリソースを置き換えるかどうかが表示されます。`details` 構造では、CloudFormation は、[バージョニング設定](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html#aws-properties-s3-bucket-properties)プロパティを更新しても中断を必要としないため、バケットを再作成 (replacement) する必要がない直接的な変更としてラベル付けしています。 @@ -100,14 +167,28 @@ MyS3Bucket: それでは、始めましょう。 -1. CloudFormation コンソールで `changesets-workshop` スタックを選択し、**スタックアクション**から**既存スタックの変更セットを作成**を選択します。 -2. **テンプレートの準備**セクションで、**現在のテンプレートの使用**を選択し、**次へ**をクリックします。 -3. 新しい一意の[バケット名](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html)を指定して `BucketName` パラメータの値を変更し、前の手順に従って変更セットの作成を完了します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. ターミナルから次のコマンドで **変更セットの作成** を実行し、新しい固有の[バケット名](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html)を指定して `bucketName` パラメータの値を変更し、前と同じように残りのプロセスを実行して変更セットの作成を完了します。 -この変更セットの **JSON の変更**は次のようになります。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-change-set \ +--stack-name cfn-workshop-understanding-changesets \ +--change-set-name replace-change-set \ +--template-body file://bucket.yaml \ +--parameters ParameterKey=BucketName,ParameterValue='YOUR-NEW-UNIQUE-BUCKET-NAME-HERE' +::: +:::: +::::tab{id="local" label="ローカル開発"} +1. CloudFormation コンソールで `cfn-workshop-understanding-changesets` スタックを選択し、 **スタックアクション** から **既存スタックの変更セットを作成** を選択します。 +1. **テンプレートの準備** セクションで、 **現在のテンプレートの使用** を選択し、 **次へ** をクリックします。 +1. 新しい一意の[バケット名](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/bucketnamingrules.html)を指定して `BucketName` パラメータの値を変更し、前の手順に従って変更セットの作成を完了します。 +:::: +::::: +この変更セットの **JSON の変更** は次のようになります。 -```json +:::code{language=json showLineNumbers=false showCopyAction=false} [ { "resourceChange": { @@ -148,7 +229,7 @@ MyS3Bucket: "type": "Resource" } ] -``` +::: 前の例とは 2 つの重要な違いがあることがわかります。まず、`resourceChange` 構造の `replacement` プロパティの値が `True` に設定されています。次に、`detail` 構造の下に `Static` と `Dynamic` の 2 つの評価が表示されます。これらの点について詳しく説明しましょう。 @@ -167,16 +248,18 @@ CloudFormation では、変更セットを実行した後に初めて値を決 ### チャレンジ お好みのテキストエディタで、`code/workspace/understanding-changesets` ディレクトリにある `changeset-challenge.yaml` という名前のテンプレートファイルを開きます。このファイルは、以前に使用した `bucket.yaml` テンプレートの修正版です。`MyS3Bucket` ではなく `NewS3Bucket` の Amazon S3 バケットリソースの論理 ID を書き留めてください。テンプレートには、`MySqsQueue` 論理 ID を持つ [Amazon Simple Queue Service](https://aws.amazon.com/jp/sqs/) (SQS) [queue](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html#aws-resource-sqs-queue-properties) という新しいリソースも記述されていることに注意してください。 -`changeset-challenge.yaml` ファイルを使用して `changesets-workshop` スタックの新しい変更セットを作成したらどうなると思いますか? リソースはいくつ追加されますか? リソースは削除されますか? 変更セットの **JSON の変更**からキューの物理 ID を取得できますか? +`changeset-challenge.yaml` ファイルを使用して `cfn-workshop-understanding-changesets` スタックの新しい変更セットを作成したらどうなると思いますか? リソースはいくつ追加されますか? リソースは削除されますか? 変更セットの **JSON の変更** からキューの物理 ID を取得できますか? このファイルを使用して変更セットを作成し、提案された変更を正しく判断できたかどうかを確認してください。 -:::expand[* テンプレート内のリソースの論理 ID を変更し、更新したテンプレートでスタックを更新すると、CloudFormation はリソースを置き換えようとします。]{header="ヒントが必要ですか?"} +:::expand{header="ヒントが必要ですか?"} +テンプレート内のリソースの論理 ID を変更し、更新したテンプレートでスタックを更新すると、CloudFormation はリソースを置き換えようとします。 ::: -:::expand{header= "解決策を確認しますか?"} -* CloudFormation は、新しい `MySqsQueue` キューリソースを追加することに加えて、`NewS3Bucket` 論理 ID を使用して新しいバケットを作成し、`MyS3Bucket` を削除しようとします。新しいリソースの物理 ID は作成されるまで使用できません。**JSON の変更**は次のようになるはずです。 -```json +::::expand{header= "解決策を確認しますか?"} +* CloudFormation は、新しい `MySqsQueue` キューリソースを追加することに加えて、`NewS3Bucket` 論理 ID を使用して新しいバケットを作成し、`MyS3Bucket` を削除しようとします。新しいリソースの物理 ID は作成されるまで使用できません。 **JSON の変更** は次のようになるはずです。 + +:::code{language=json showLineNumbers=false showCopyAction=false} [ { "resourceChange": { @@ -224,14 +307,26 @@ CloudFormation では、変更セットを実行した後に初めて値を決 "type": "Resource" } ] -``` ::: +:::: + ### クリーンアップ このラボで作成したリソースをクリーンアップするには -1. CloudFormation コンソールから、`changesets-workshop` という名前のスタックを選択します。 -2. **削除**を選択し、次に**削除**を選択してスタックと、スタック用に作成した変更セットを削除します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +ターミナルから次の AWS CLI コマンドを実行して、作成したスタックを削除します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ +--stack-name cfn-workshop-understanding-changesets +::: +:::: +::::tab{id="local" label="ローカル開発"} +1. CloudFormation コンソールから、`cfn-workshop-understanding-changesets` という名前のスタックを選択します。 +1. **削除** を選択し、次に **削除** を選択してスタックと、スタック用に作成した変更セットを削除します。 +:::: +::::: --- diff --git a/content/intermediate/operations/update-behaviors-of-stack-resources/index.ja.md b/content/intermediate/operations/update-behaviors-of-stack-resources/index.ja.md index b11901a0b..f07c42400 100644 --- a/content/intermediate/operations/update-behaviors-of-stack-resources/index.ja.md +++ b/content/intermediate/operations/update-behaviors-of-stack-resources/index.ja.md @@ -6,7 +6,7 @@ weight: 100 ### 概要 このラボでは、インフラストラクチャの設計および更新への対応方法に関する重要なポイントを学びます。アプリケーションと環境が進化するにつれて、テンプレートに記述されているリソース構成に更新を適用します。 -CloudFormation は、変更が適用されたテンプレートと、以前のバージョンのテンプレートで記述したリソース構成との変更を比較することによってリソースを更新します。変更されていないリソース構成は、更新プロセス中も影響を受けません。それ以外の場合、CloudFormation は次のいずれかの[更新動作](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html)を使用します。**中断を伴わない更新**、**一時的な中断を伴う更新**、**置換**の各更新動作は、特定の[リソースタイプ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)に従い、テンプレートに追加する新しいプロパティや、変更するプロパティ値によって決まります。 +CloudFormation は、変更が適用されたテンプレートと、以前のバージョンのテンプレートで記述したリソース構成との変更を比較することによってリソースを更新します。変更されていないリソース構成は、更新プロセス中も影響を受けません。それ以外の場合、CloudFormation は次のいずれかの[更新動作](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html)を使用します。 **中断を伴わない更新** 、 **一時的な中断を伴う更新** 、 **置換** の各更新動作は、特定の[リソースタイプ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html)に従い、テンプレートに追加する新しいプロパティや、変更するプロパティ値によって決まります。 ### 対象トピック このラボを修了すると、次のことができるようになります。 @@ -21,7 +21,7 @@ CloudFormation は、変更が適用されたテンプレートと、以前の テンプレートに [Amazon Elastic Compute Cloud](https://aws.amazon.com/jp/ec2/)(Amazon EC2) インスタンスを記述することから始めましょう。`update-behaviors-of-stack-resources.yaml` テンプレートに以下の `Paramaters` セクションをコピーして追加します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=5} Parameters: InstanceType: Description: WebServer EC2 instance type @@ -29,14 +29,15 @@ Parameters: Default: t2.micro AllowedValues: [t2.micro, t2.small, t2.medium] ConstraintDescription: must be a valid EC2 instance type. + LatestAmiId: Type: AWS::SSM::Parameter::Value Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 -``` +::: 次に、`Resources` セクションと Amazon EC2 インスタンス定義をコピーしてテンプレートに追加します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=17} Resources: EC2Instance: Type: AWS::EC2::Instance @@ -46,42 +47,60 @@ Resources: Tags: - Key: Name Value: cfn-workshop -``` +::: 変更をファイルに保存します。次に、`update-behaviors-of-stack-resources.yaml` テンプレートを使用してスタックを作成します。 -1. [AWS CloudFormationコンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 -2. 使用したい[リージョン](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)を選択します。 -3. **スタックの作成**、**新しいリソースを使用 (標準)** を選択します。 -4. **テンプレートの準備**セクションで、**テンプレートの準備完了**を選択します。 -5. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。前述の`update-behaviors-of-stack-resources.yaml` テンプレートを選択し、**次へ**をクリックします。 -6. スタック名を指定します。例えば、`cfn-workshop-update-behaviors-of-stack-resources` と入力します。`InstanceType` パラメータと `LatestAmiID` パラメータのデフォルト値をそのまま使用し、**次へ**をクリックします。 -7. **スタックオプションの設定**ページはデフォルト値のまま、**次へ**をクリックします。 -8. **レビュー**ページで一番下までスクロールし、**送信**をクリックします。 -9. スタックの作成が完了するまでお待ちください。スタックのステータスが `CREATE_COMPLETE` になるまで、コンソールのビューを更新します。 - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/update-behaviors-of-stack-resources` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd code/workspace/update-behaviors-of-stack-resources +::: +1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-update-behaviors-of-stack-resources --template-body file://update-behaviors-of-stack-resources.yaml +::: +1. `create-stack` コマンドが正常に送信されると、CloudFormation は `StackID` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-update-behaviors-of-stack-resources/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +1. 使用したい[リージョン](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)を選択します。 +1. **スタックの作成** 、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートの準備** セクションで、 **テンプレートの準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。前述の `update-behaviors-of-stack-resources.yaml` テンプレートを選択し、 **次へ** をクリックします。 +1. スタック名を指定します。例えば、`cfn-workshop-update-behaviors-of-stack-resources` と入力します。`InstanceType` パラメータと `LatestAmiID` パラメータのデフォルト値をそのまま使用し、 **次へ** をクリックします。 +1. **スタックオプションの設定** ページはデフォルト値のまま、 **次へ** をクリックします。 +1. **レビュー** ページで一番下までスクロールし、 **送信** をクリックします。 +1. スタックの作成が完了するまでお待ちください。スタックのステータスが `CREATE_COMPLETE` になるまで、コンソールのビューを更新します。 +:::: +::::: **置換** -ここまで、スタックを使用して Amazon EC2 インスタンスを作成しました。インスタンスの [Amazon Machine Image](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIs.html) (AMI) には、このラボで最新の `x86-64` Amazon Linux 2 AMI を使用しました。次に、Amazon EC2 インスタンスに別の AMI を使用する必要があるシナリオを考えてみましょう。このラボでは、前に作成した CloudFormation スタック`cfn-workshop-update-behaviors-of-stack-resources` を更新し、`LatestAmiId` のパラメータ値を `/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs` でオーバーライドします。 +ここまで、スタックを使用して Amazon EC2 インスタンスを作成しました。インスタンスの [Amazon Machine Image](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIs.html) (AMI) には、このラボで最新の `x86-64` Amazon Linux 2 AMI を使用しました。次に、Amazon EC2 インスタンスに別の AMI を使用する必要があるシナリオを考えてみましょう。このラボでは、前に作成した CloudFormation スタック `cfn-workshop-update-behaviors-of-stack-resources` を更新し、`LatestAmiId` のパラメータ値を `/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs` でオーバーライドします。 ::alert[リソースのプロパティ値を変更するときは、必ずドキュメント内の特定のリソースプロパティの [Update requires](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-imageid)の値を確認してください。この場合、`ImageID` プロパティの値を更新すると、リソース[置換 (Replacement)](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-replacement) 動作が実行されます。]{type="info"} いよいよスタックを更新しましょう![AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動し、`cfn-workshop-update-behaviors-of-stack-resources` スタックを更新します。 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 -2. `cfn-workshop-update-behaviors-of-stack-resources` スタックを作成した[リージョン](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)を必ず選択してください。 -3. 先ほど作成したスタック (例えば、`cfn-workshop-update-behaviors-of-stack-resources`) を選択します。 -4. **更新**を選択します。 -5. **テンプレートの準備**で**現在のテンプレートの使用**を選択し、**次へ**をクリックします。 -6. **パラメータ**ページで、`InstanceType`のデフォルト値をそのまま使用し、`LatestAmiID` パラメータの既存の値を `/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-ebs` という新しい値に置き換えます。準備ができたら、**次へ**をクリックします。 -7. **スタックオプションの設定**ページでデフォルト値のまま、**次へ**をクリックします。 -8. **レビュー**ページで一番下までスクロールし、**送信**を選択します。 +1. `cfn-workshop-update-behaviors-of-stack-resources` スタックを作成した[リージョン](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)を必ず選択してください。 +1. 先ほど作成したスタック (例えば、`cfn-workshop-update-behaviors-of-stack-resources`) を選択します。 +1. **更新** を選択します。 +1. **テンプレートの準備** で **現在のテンプレートの使用** を選択し、 **次へ** をクリックします。 +1. **パラメータ** ページで、`InstanceType` のデフォルト値をそのまま使用し、`LatestAmiID` パラメータの既存の値を `/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-ebs` という新しい値に置き換えます。準備ができたら、 **次へ** をクリックします。 +1. **スタックオプションの設定** ページでデフォルト値のまま、 **次へ** をクリックします。 +1. **レビュー** ページで一番下までスクロールし、 **送信** を選択します。 -スタックの更新中に、[Amazon EC2 コンソール](https://console.aws.amazon.com/ec2/)に移動し、**インスタンス**を選択します。新しいインスタンスが起動され、このラボで以前に作成したインスタンスが終了することを確認できます。上記で行った AMI の変更によるスタック更新を実施すると、CloudFormation は最初に新しいインスタンスを作成し、前のインスタンスを削除しました。この例では、**置換**動作を示しています。 +スタックの更新中に、[Amazon EC2 コンソール](https://console.aws.amazon.com/ec2/)に移動し、 **インスタンス** を選択します。新しいインスタンスが起動され、このラボで以前に作成したインスタンスが終了することを確認できます。上記で行った AMI の変更によるスタック更新を実施すると、CloudFormation は最初に新しいインスタンスを作成し、前のインスタンスを削除しました。この例では、 **置換** 動作を示しています。 -おめでとうございます! **置換**動作を学習しました。 +おめでとうございます! **置換** 動作を学習しました。 **一時的な中断を伴う更新** @@ -89,27 +108,28 @@ Resources: ワークロードの要件が変わり、CPU とメモリの要件に合わせて新しい [Amazon EC2](https://aws.amazon.com/jp/ec2/instance-types/) インスタンスタイプが必要だと判断した例を見てみましょう。例えば、`cfn-workshop-update-behaviors-of-stack-resources` スタックで管理するインスタンスのタイプを、`t2.micro` から `t2.small` に変更します。 -::alert[インスタンスの `InstanceType` プロパティ値を変更する場合、まず [Update requires](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-instancetype) で説明されている動作を確認し、スタックを更新するとどうなるのかを理解する必要があります。]{type="info"} +:::alert{type="info"} +インスタンスの `InstanceType` プロパティ値を変更する場合、まず [Update requires](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-instancetype) で説明されている動作を確認し、スタックを更新するとどうなるのかを理解する必要があります。 +::: さっそくスタックを更新しましょう: 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 -2. `cfn-workshop-update-behaviors-of-stack-resources` スタックを作成した[リージョン](https://docs.aws.amazon.com/awsconsolehelpdocs/latest/gsg/select-region.html)を必ず選択してください。 -3. 先ほど作成したスタック (例えば、`cfn-workshop-update-behaviors-of-stack-resources`) を選択します。 -4. **更新**を選択します。 -5. **テンプレートの準備**で**現在のテンプレートの使用**を選択し、**次へ**をクリックします。 -6. 次のページで、`LatestAmiId` パラメータのデフォルト値をそのまま使用し、`InstanceType` パラメータ値として `t2.small` を選択します。**次へ**をクリックします。 -7. **スタックオプションの設定**ページでデフォルト値のまま、**次へ**をクリックします。 -8. **レビュー**ページで一番下までスクロールし、**送信**をクリックします。 +1. `cfn-workshop-update-behaviors-of-stack-resources` スタックを作成した[リージョン](https://docs.aws.amazon.com/awsconsolehelpdocs/latest/gsg/select-region.html)を必ず選択してください。 +1. 先ほど作成したスタック (例えば、`cfn-workshop-update-behaviors-of-stack-resources`) を選択します。 +1. **更新** を選択します。 +1. **テンプレートの準備** で **現在のテンプレートの使用** を選択し、 **次へ** をクリックします。 +1. 次のページで、`LatestAmiId` パラメータのデフォルト値をそのまま使用し、`InstanceType` パラメータ値として `t2.small` を選択します。 **次へ** をクリックします。 +1. **スタックオプションの設定** ページでデフォルト値のまま、 **次へ** をクリックします。 +1. **レビュー** ページで一番下までスクロールし、 **送信** をクリックします。 -スタックの更新中に、[Amazon EC2 コンソール](https://console.aws.amazon.com/ec2/)に移動し、**インスタンス**を選択します。インスタンスは最初に停止されるため、一時的に使用できなくなります。インスタンスタイプが `t2.small` に変更されると、まもなく running ステータスになることを確認できます。この例は、**一時的な中断を伴う更新**の動作を示しています。 +スタックの更新中に、[Amazon EC2 コンソール](https://console.aws.amazon.com/ec2/)に移動し、 **インスタンス** を選択します。インスタンスは最初に停止されるため、一時的に使用できなくなります。インスタンスタイプが `t2.small` に変更されると、まもなく running ステータスになることを確認できます。この例は、 **一時的な中断を伴う更新** の動作を示しています。 -おめでとうございます!**一時的な中断を伴う更新**動作について学習しました。 +おめでとうございます! **一時的な中断を伴う更新** 動作について学習しました。 **中断を伴わない更新** - 前の例を続けてみましょう。インスタンスは現在、[基本モニタリング](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-cloudwatch-new.html)を使用しており、インスタンスのメトリクスデータが 5 分間隔で[Amazon CloudWatch](https://aws.amazon.com/jp/cloudwatch/) に送信されます。ワークロードのメトリクスデータを 1 分間隔で利用できるようにする必要があり、インスタンスの[詳細モニタリング](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/using-cloudwatch-new.html)を有効にします。 次に、`update-behaviors-of-stack-resources.yaml` テンプレートに記載したインスタンスに `Monitoring` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-monitoring)を `true` に設定して追加します。 @@ -118,7 +138,7 @@ Resources: 既存の `update-behaviors-of-stack-resources.yaml` テンプレートを更新し、`EC2Instance` の定義に `Monitoring` プロパティを指定します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=17 highlightLines=22} EC2Instance: Type: AWS::EC2::Instance Properties: @@ -128,32 +148,53 @@ EC2Instance: Tags: - Key: Name Value: cfn-workshop -``` +::: 変更をファイルに保存します。次に、スタックを更新します。 -1. [AWS CloudFormationコンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 -2. `cfn-workshop-update-behaviors-of-stack-resources` スタックを作成した[リージョン](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)を選択してください。 -3. 先ほど作成したスタック (例えば、`cfn-workshop-update-behaviors-of-stack-resources`) を選択します。 -4. **更新**を選択します。 -5. **テンプレートの準備**セクションで**既存テンプレートを置き換える**を選択し、**テンプレートの指定**セクションの**テンプレートファイルのアップロード**で、`update-behaviors-of-stack-resources.yaml` テンプレートファイルを選択します。準備ができたら、**次へ**をクリックします。 -6. パラメータページで、`LatestAmiId` パラメータと `InstanceType` パラメータのデフォルト値をそのまま使用し、**次へ**をクリックします。 -7. **スタックオプションの設定**ページでデフォルト値のまま、**次へ**をクリックします。 -8. **レビュー**ページで一番下までスクロールし、**送信**をクリックします。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/update-behaviors-of-stack-resources` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd code/workspace/update-behaviors-of-stack-resources +::: +1. AWS CLI を使用してスタックを更新します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack --stack-name update-behaviors-of-stack-resources --template-body file://update-behaviors-of-stack-resources.yaml +::: +1. `update-stack` が正常に送信された場合、CloudFormation は `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/drift-detection-workshop/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **UPDATE_COMPLETE** になっているかどうかを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +1. `cfn-workshop-update-behaviors-of-stack-resources` スタックを作成した[リージョン](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)を選択してください。 +1. 先ほど作成したスタック (例えば、`cfn-workshop-update-behaviors-of-stack-resources`) を選択します。 +1. **更新** を選択します。 +1. **テンプレートの準備** セクションで **既存テンプレートを置き換える** を選択し、 **テンプレートの指定** セクションの **テンプレートファイルのアップロード** で、`update-behaviors-of-stack-resources.yaml` テンプレートファイルを選択します。準備ができたら、 **次へ** をクリックします。 +1. パラメータページで、`LatestAmiId` パラメータと `InstanceType` パラメータのデフォルト値をそのまま使用し、 **次へ** をクリックします。 +1. **スタックオプションの設定** ページでデフォルト値のまま、 **次へ** をクリックします。 +1. **レビュー** ページで一番下までスクロールし、 **送信** をクリックします。 +:::: +::::: -[Amazon EC2 コンソール](https://console.aws.amazon.com/ec2/)に移動し、**インスタンス**を選択します。スタックが更新されている間、インスタンスは実行中の状態のままであることに注意してください。これは、**中断を伴わない更新**の動作を示しています。 +[Amazon EC2 コンソール](https://console.aws.amazon.com/ec2/)に移動し、 **インスタンス** を選択します。スタックが更新されている間、インスタンスは実行中の状態のままであることに注意してください。これは、 **中断を伴わない更新** の動作を示しています。 -おめでとうございます! **中断を伴わない更新**の動作を学習しました。 +おめでとうございます! **中断を伴わない更新** の動作を学習しました。 ### チャレンジ -このラボで使用したテンプレートの `EC2Instance` の `Name` タグキーの `Value` を更新する任務があります。この情報をインスタンスの `Tags` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-tags)に記述します。`update-behaviors-of-stack-resources.yaml` テンプレートで、`Name` タグの `Value` に `cfn-workshop-new-value` を指定します。スタックを更新するときに、3つの更新動作のうちどれが適用されるかわかりますか? +このラボで使用したテンプレートの `EC2Instance` の `Name` タグキーの `Value` を更新する任務があります。この情報をインスタンスの `Tags` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-tags)に記述します。`update-behaviors-of-stack-resources.yaml` テンプレートで、`Name` タグの `Value` に `cfn-workshop-new-value` を指定します。スタックを更新するときに、3 つの更新動作のうちどれが適用されるかわかりますか? -::expand[* CloudFormation ドキュメントのどこで、特定のリソースタイプ (この場合 `AWS::EC2::Instance` [リソース](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html))について、特定のリソースプロパティの更新動作について知ることができますか?]{header="ヒントが必要ですか?"} +:::expand{header="ヒントが必要ですか?"} +* CloudFormation ドキュメントのどこで、特定のリソースタイプ (この場合 `AWS::EC2::Instance` [リソース](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html))について、特定のリソースプロパティの更新動作について知ることができますか? +::: -:::expand{header="解決策を確認しますか?"} -次に示すように、テンプレートの `Value` 情報を更新します。 +::::::expand{header="解決策を確認しますか?"} +次に示すように、テンプレートの `Name` タグの `Value` の情報を更新します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=17 highlightLines=25} EC2Instance: Type: AWS::EC2::Instance Properties: @@ -163,27 +204,46 @@ EC2Instance: Tags: - Key: Name Value: cfn-workshop-new-value -``` +::: 変更内容を `update-behaviors-of-stack-resources.yaml` テンプレートに保存します。更新したテンプレートでスタックを更新する前に、`Tags` プロパティの **Update requires** [セクション](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-tags)を参照してください。この場合、[中断を伴わない更新](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-updating-stacks-update-behaviors.html#update-no-interrupt)になります。 スタックの更新: -1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 -2. `cfn-workshop-update-behaviors-of-stack-resources` スタックを作成した[リージョン](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)を選択してください。 -3. 先ほど作成したスタック (例えば、`cfn-workshop-update-behaviors-of-stack-resources`) を選択します。 -4. **更新**を選択します。 -5. **テンプレートの準備**セクションで**既存テンプレートを置き換える**を選択し、次に `update-behaviors-of-stack-resources.yaml` テンプレートを選択します。準備ができたら、**次へ**をクリックします。 -6. 次のページで、`LatestAmiId` と `InstanceType` パラメータのデフォルト値をそのまま使用し、**次へ**をクリックします。 -7. **スタックオプションの設定**ページでデフォルト値のまま、**次へ**をクリックします。 -8. **レビュー**ページで一番下までスクロールし、**送信**をクリックします。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/update-behaviors-of-stack-resources` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd code/workspace/update-behaviors-of-stack-resources +::: +1. AWS CLI を使用してスタックを更新します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack --stack-name update-behaviors-of-stack-resources --template-body file://update-behaviors-of-stack-resources.yaml ::: +1. `update-stack` が正常に送信された場合、CloudFormation は `StackId` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/drift-detection-workshop/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **UPDATE_COMPLETE** になっているかどうかを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +1. `cfn-workshop-update-behaviors-of-stack-resources` スタックを作成した[リージョン](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)を選択してください。 +1. 先ほど作成したスタック (例えば、`cfn-workshop-update-behaviors-of-stack-resources`) を選択します。 +1. **更新** を選択します。 +1. **テンプレートの準備** セクションで **既存テンプレートを置き換える** を選択し、次に `update-behaviors-of-stack-resources.yaml` テンプレートを選択します。準備ができたら、 **次へ** をクリックします。 +1. 次のページで、`LatestAmiId` と `InstanceType` パラメータのデフォルト値をそのまま使用し、 **次へ** をクリックします。 +1. **スタックオプションの設定** ページでデフォルト値のまま、 **次へ** をクリックします。 +1. **レビュー** ページで一番下までスクロールし、 **送信** をクリックします。 +:::: +::::: +:::::: ### クリーンアップ 次に示す手順に従って、このラボで作成したリソースをクリーンアップしてください。 * CloudFormation コンソールで、このラボで作成した `cfn-workshop-update-behaviors-of-stack-resources` スタックを選択します。 -* **削除**を選択した後、**削除**を押して確定します。 +* **削除** を選択した後、 **削除** を押して確定します。 --- diff --git a/content/intermediate/templates/architecting-templates/index.ja.md b/content/intermediate/templates/architecting-templates/index.ja.md index a20960d20..73e79b79b 100644 --- a/content/intermediate/templates/architecting-templates/index.ja.md +++ b/content/intermediate/templates/architecting-templates/index.ja.md @@ -50,17 +50,15 @@ weight: 650 -### 前提条件のインストール +### 前提条件 -まだ、以下の手順が実行できていない場合、前提条件に従い、次のものを自分のワークステーションにインストールします (Cloud9 はこのラボで後ほど使用しますが、最初にワークステーションを使用することから始めます)。 +このラボでは後で Cloud9 を使用しますが、最初はワークステーションで作業します。まず、CloudFormation Workshop コードリポジトリのコンテンツをワークステーションに取り込みます。そのためには、次の 2 つのオプションから選択できます。 -1. [Git をインストール](/prerequisites/git)。 -2. [ラボリソースを取得](/prerequisites/lab-resources): ラボリポジトリのクローンを作成します。本作業を実施すると、リポジトリがワークステーションの `cfn101-workshop` ディレクトリにクローンされます。 - - -次に、クローンを作成したリポジトリの `cfn101-workshop/code/workspace/architecting-templates` ディレクトリに移動します。まずは、`base-network.template` ファイルと `cloud9.template` ファイルを使用して、ベースインフラストラクチャと Cloud9 環境をそれぞれ作成します。 +- オプション 1 (簡単、ワークステーションにツールをインストールする必要がない): [GitHub の CloudFormation Workshop リポジトリページ](https://github.com/aws-samples/cfn101-workshop) を開き、 **Code** ボタンを探して、ドロップダウンメニューから **Download ZIP** を選択します。このアクションにより、リポジトリの `main` ブランチにあるワークショップの内容を含む `cfn101-workshop-main.zip` ファイルが作成されます。このファイルをダウンロードしてワークステーションの任意のディレクトリに展開します。 +- オプション 2: [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) を使用して CloudFormation Workshop リポジトリのクローンを作成します。そのためには、ワークステーションに `git` がインストールされていることを確認するか、任意の方法でインストールしてください。準備ができたら、[ローカル開発の設定](/prerequisites/local-development) の **git を使ってラボのリソースをクローン** セクションに従って、ラボリポジトリをクローンしてください。これにより、リポジトリがワークステーションの `cfn101-workshop` ディレクトリにクローンされます。 +次に、ZIP ファイルから展開した、またはクローンしたリポジトリの `cfn101-workshop/code/workspace/architecting-templates` ディレクトリを開きます。`base-network.template` ファイルと `cloud9.template` ファイルを見つけます。まず、これらを使用してベースインフラストラクチャと Cloud9 環境をそれぞれ作成します。 ### VPC スタックの作成 @@ -69,13 +67,13 @@ weight: 650 `base-network.template` ファイルを使用して新しいスタックを作成します。 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 -2. ページ上部のリージョンセレクターから、*バージニア北部* (`us-east-1`) などのリージョンを選択します。 -3. **スタックの作成**から、**新しいリソースを使用 (標準)** を選択します。 -4. **テンプレートの準備**セクションで、**テンプレート準備完了**を選択します。 -5. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。前述の `base-network.template` ファイルを選択し、**次へ** をクリックします。 -6. スタック名を指定します。例えば、`cloudformation-workshop-dev-base-network` と入力します。デフォルトのパラメータ値のまま、**次へ** をクリックします。 -7. 次のページで、**次へ**をクリックします。 -8. 次のページで、**送信**をクリックします。 +1. ページ上部のリージョンセレクターから、*バージニア北部* (`us-east-1`) などのリージョンを選択します。 +1. **スタックの作成** から、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートの準備** セクションで、 **テンプレート準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。前述の `base-network.template` ファイルを選択し、 **次へ** をクリックします。 +1. スタック名を指定します。例えば、`cloudformation-workshop-dev-base-network` と入力します。デフォルトのパラメータ値のまま、 **次へ** をクリックします。 +1. 次のページで、 **次へ** をクリックします。 +1. 次のページで、 **送信** をクリックします。 スタックの作成が開始されます。最後に、スタックのステータスが `CREATE_COMPLETE` になります。スタックの作成が進むにつれて、ワークステーションの任意のテキストエディタで `base-network.template` ファイルを開きます。次の点を確認してください。 @@ -91,14 +89,14 @@ weight: 650 Cloud9 の環境を作ってみましょう! [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) を使用します。 1. 先ほど選択したリージョンと同一のリージョン (*バージニア北部* (`us-east-1`)など) であることを確認してください。 -2. **スタックの作成**から、**新しいリソースを使用 (標準)** を選択します。 -3. **テンプレートの準備**セクションで、**テンプレート準備完了**を選択します。 -4. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。`cloud9.template` ファイルを選択し、**次へ**をクリックします。 -5. スタック名を指定します。例えば、`cloudformation-workshop-dev-cloud9` と入力します。デフォルトのパラメータ値のまま、**次へ** をクリックします。 -6. 次のページで、**次へ**をクリックします。 -7. 次のページで、**送信**をクリックします。 -8. スタックのステータスが `CREATE_COMPLETE` になるまで、スタックの作成ページを更新します。名前のプレフィックスが `aws-cloud9-aws-cloudformation-workshop-` となっている別のスタックも作成されることに注意してください。このスタックは、Cloud9 環境のセキュリティグループと EC2 インスタンスを作成します。 -9. 準備ができたら、Cloud9 環境を開きます。[AWS Cloud9 コンソール](https://console.aws.amazon.com/cloud9/home) に移動し、`aws-cloudformation-workshop` 環境を見つけて、**Open IDE** を選択します。これで、環境が別のウィンドウで開かれるはずです。 +1. **スタックの作成** から、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートの準備** セクションで、 **テンプレート準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。`cloud9.template` ファイルを選択し、 **次へ** をクリックします。 +1. スタック名を指定します。例えば、`cloudformation-workshop-dev-cloud9` と入力します。デフォルトのパラメータ値のまま、 **次へ** をクリックします。 +1. 次のページで、 **次へ** をクリックします。 +1. 次のページで、 **送信** をクリックします。 +1. スタックのステータスが `CREATE_COMPLETE` になるまで、スタックの作成ページを更新します。名前のプレフィックスが `aws-cloud9-aws-cloudformation-workshop-` となっている別のスタックも作成されることに注意してください。このスタックは、Cloud9 環境のセキュリティグループと EC2 インスタンスを作成します。 +1. 準備ができたら、Cloud9 環境を開きます。[AWS Cloud9 コンソール](https://console.aws.amazon.com/cloud9/home) に移動し、`aws-cloudformation-workshop` 環境を見つけて、 **Open IDE** を選択します。これで、環境が別のウィンドウで開かれるはずです。 @@ -155,7 +153,7 @@ cd cfn101-workshop/code/workspace/architecting-templates/ cfn-lint *.template ::: -上記のコマンドの出力は表示されないはずです。つまり、エラーがないということを示しています。このコマンドを実行することで、テンプレートが前述のリソースタイプの仕様に準拠していることを確認できました。このラボでは、テンプレートアーキテクチャの例を示すことと、ワークスペースを準備するという2つの理由のために、VPC と Cloud9 環境のリソースをデプロイしました。ベストプラクティスの一環として、リソースをデプロイしたり、テンプレートをリポジトリに追加したりする前に `cfn-lint` を実行して、プロセスの早い段階で変更を加えます。 +上記のコマンドの出力は表示されないはずです。つまり、エラーがないということを示しています。このコマンドを実行することで、テンプレートが前述のリソースタイプの仕様に準拠していることを確認できました。このラボでは、テンプレートアーキテクチャの例を示すことと、ワークスペースを準備するという 2 つの理由のために、VPC と Cloud9 環境のリソースをデプロイしました。ベストプラクティスの一環として、リソースをデプロイしたり、テンプレートをリポジトリに追加したりする前に `cfn-lint` を実行して、プロセスの早い段階で変更を加えます。 `cfn-lint` の機能の例を説明するために、Cloud9 の左側にある *Environment* ナビゲーションタブを使用して `aws-cloudformation-workshop -> cfn101-workshop-> code -> workspace -> architecting-templates` ディレクトリの `hosted-zone.template` ファイルを開きます。 `Name: !Ref 'HostedZoneName'` の行を、一時的に `Names: !Ref 'HostedZoneName'` に変更します (`Name` プロパティを一時的に `Names` に変更します)。次に、先ほど行ったように `cfn-lint` を実行すると、次のようなエラーが表示されるはずです。 @@ -201,7 +199,7 @@ aws cloudformation wait stack-create-complete \ --region us-east-1 ::: -スタックの作成が完了すると、Route 53 のプライベートホストゾーンが作成されます。スタックの作成に使用したデフォルトのテンプレートパラメータを見てください。ホストゾーンの名前は `my-example-domain.com` です。[Route 53 Console](https://console.aws.amazon.com/route53/home) に移動し、**ホストゾーン**から、作成したホストゾーンを選択すると、詳細ページに `NS` と `SOA` の 2 つの DNS レコードタイプが既にあることがわかります。後で CloudFormation を使用してロードバランサー用のエイリアスレコードを作成します。そのレコードも詳細ページに表示されるはずです。 +スタックの作成が完了すると、Route 53 のプライベートホストゾーンが作成されます。スタックの作成に使用したデフォルトのテンプレートパラメータを見てください。ホストゾーンの名前は `my-example-domain.com` です。[Route 53 Console](https://console.aws.amazon.com/route53/home) に移動し、 **ホストゾーン** から、作成したホストゾーンを選択すると、詳細ページに `NS` と `SOA` の 2 つの DNS レコードタイプが既にあることがわかります。後で CloudFormation を使用してロードバランサー用のエイリアスレコードを作成します。そのレコードも詳細ページに表示されるはずです。 @@ -295,7 +293,7 @@ curl http://my-example-domain.com この課題では、再利用とモジュール性に関連する主要な概念を思い出して適用し、それらをデプロイメントのオーケストレーションの観点から拡張します。あなたは、(Cloud9 のワークスペースにある)`application.template` ファイルを `application-blue-green.template` という名前の新しいファイルにコピーし、この新しいファイルを更新して、blue / green のデプロイパターンのコンテキストで 2 つのスタックで使用できるようにします。[Amazon Route 53 DNS ルーティングの更新](https://docs.aws.amazon.com/ja_jp/whitepapers/latest/blue-green-deployments/update-dns-routing-with-amazon-route-53.html)をご参照ください。このチャレンジの要件は次の通りでです。 -* 2つのスタックを用意します。作成した既存の `cloudformation-workshop-dev-application` を更新し、`cloudformation-workshop-dev-application-v2` という名前の新しいスタックを作成して、それぞれ `Hello world!` の代わりに `Blue` と `Green` を出力として表示します。両方のスタックをそれぞれ *Blue* と *Green* と呼び、両方のスタックに新しい `application-blue-green.template` ファイルを使用します。 +* 2 つのスタックを用意します。作成した既存の `cloudformation-workshop-dev-application` を更新し、`cloudformation-workshop-dev-application-v2` という名前の新しいスタックを作成して、それぞれ `Hello world!` の代わりに `Blue` と `Green` を出力として表示します。両方のスタックをそれぞれ *Blue* と *Green* と呼び、両方のスタックに新しい `application-blue-green.template` ファイルを使用します。 * 各スタックは、前に使用したものと同じ `名前` (ホストゾーン名) を持つ新しいエイリアスレコードを作成する必要があります。ただし、これらのレコードは両方とも [加重セット](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/resource-record-sets-values-weighted.html#rrsets-values-weighted-weight) である必要があります。これにより、Route 53 は、[特定のリソースの合計に対する重みの比率](https://docs.aws.amazon.com/ja_jp/Route53/latest/DeveloperGuide/routing-policy-weighted.html) に基づいてユーザーが発行したクエリに応答します。最初に、 *Blue* スタックに重み `255` (大きい重み) を割り当て、*Green* スタックに重み `1` (少ない重み) を割り当てます。この方法では、*Blue* は最初にトラフィックの 255 / 256、*Green* はトラフィックの 1 / 256 に割り当てられます。 * 必ず、テンプレート内の _set identifier_ を更新し、同じテンプレートを使用する 2 つのスタックで値が一意となるようにします。 @@ -391,9 +389,9 @@ curl http://my-example-domain.com ワークステーションの CloudFormation コンソールに移動します。このラボで作成したスタックを次の順序で削除します。クロススタック参照を使用していくつかのスタックを参照しているため、値をエクスポートするスタックが利用側スタックで使用されている場合は削除できない点に注意してください。 1. `cloudformation-workshop-dev-application-v2` と `cloudformation-workshop-dev-application` は互いに依存していないため、それぞれが削除されるのを待たずに削除可能です。両方のスタックが削除されたら、次のステップに進みます。 -2. `cloudformation-workshop-dev-security-groups` と `cloudformation-workshop-dev-hosted-zone` は、それぞれが削除されるのを待たずに削除可能です。次のステップに進みます。 -3. `cloudformation-workshop-dev-cloud9` を削除します。このスタックを削除すると、開始した削除アクションによって、名前が `aws-cloud9-aws-cloudformation-workshop-` で始まるスタックも削除されます。両方のスタックが削除されたら、最後のステップに進みます。 -4. `cloudformation-workshop-dev-base-network` スタックを削除します。 +1. `cloudformation-workshop-dev-security-groups` と `cloudformation-workshop-dev-hosted-zone` は、それぞれが削除されるのを待たずに削除可能です。次のステップに進みます。 +1. `cloudformation-workshop-dev-cloud9` を削除します。このスタックを削除すると、開始した削除アクションによって、名前が `aws-cloud9-aws-cloudformation-workshop-` で始まるスタックも削除されます。両方のスタックが削除されたら、最後のステップに進みます。 +1. `cloudformation-workshop-dev-base-network` スタックを削除します。 ### まとめ diff --git a/content/intermediate/templates/conditions/index.ja.md b/content/intermediate/templates/conditions/index.ja.md index b29b8920b..a52d5fbfc 100644 --- a/content/intermediate/templates/conditions/index.ja.md +++ b/content/intermediate/templates/conditions/index.ja.md @@ -3,6 +3,10 @@ title: "条件" weight: 100 --- +_ラボ実施時間 : 20分程度_ + +--- + ### 概要 [AWS CloudFormation](https://aws.amazon.com/jp/cloudformation/) を使用してインフラストラクチャを記述する場合、CloudFormation テンプレートでリソースとリソースプロパティを宣言します。リソースを作成したり、条件に基づいてリソースプロパティ値を指定するようなユースケースで利用します。 @@ -41,7 +45,7 @@ CloudFormation は、スタックの作成時またはスタックの更新時 それでは、始めましょう! -まず、テンプレートを再利用可能にすることに集中しましょう。テンプレートに、ライフサイクル環境の入力パラメータを含む `Parameters` セクションを追加します。`EnvType` パラメータを呼び出し、使用可能な入力値として `test` と `prod` という2つの環境名の例を記述します。使用する [Amazon Machine Image](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIs.html) (AMI) の入力パラメータを定義します。この例では、[AWS Systems Manager](https://aws.amazon.com/jp/systems-manager/) [Paramater Store](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html) を使用して、使用可能な最新の Amazon Linux AMI を参照し、`LatestAmiId` というパラメータを呼び出しています。 +まず、テンプレートを再利用可能にすることに集中しましょう。テンプレートに、ライフサイクル環境の入力パラメータを含む `Parameters` セクションを追加します。`EnvType` パラメータを呼び出し、使用可能な入力値として `test` と `prod` という 2 つの環境名の例を記述します。使用する [Amazon Machine Image](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIs.html) (AMI) の入力パラメータを定義します。この例では、[AWS Systems Manager](https://aws.amazon.com/jp/systems-manager/) [Paramater Store](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html) を使用して、使用可能な最新の Amazon Linux AMI を参照し、`LatestAmiId` というパラメータを呼び出しています。 ::alert[詳細については、[AWS Systems Manager Parameter Store を使用して最新の Amazon Linux AMI ID を取得する](https://aws.amazon.com/jp/blogs/news/query-for-the-latest-amazon-linux-ami-ids-using-aws-systems-manager-parameter-store/)をご参照ください。]{type="info"} @@ -105,33 +109,75 @@ Resources: スタックを作成する時に、`test` を `EnvType` の値として渡すと、CloudFormation によって EC2 インスタンスリソースのみがプロビジョニングされることがわかります。更新したテンプレートを保存します。次に、AWS CloudFormation [コンソール](https://console.aws.amazon.com/cloudformation) に移動し、スタックを作成します。 -* CloudFormation コンソールで、**スタックの作成**、**新しいリソースを使用 (標準)** を選択します。 -* **テンプレートの準備**セクションで、**テンプレートの準備完了**を選択します。 -* **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -* `condition-resource.yaml` テンプレートを選択します。 -* **スタックの名前**を入力します。例えば、`cfn-workshop-condition-test` と入力します。 -* `EnvType` パラメータの値として `test` を選択します。**次へ**をクリックします。 -* **スタックオプションの設定**ページはデフォルト値のまま**次へ**をクリックします。 -* レビューページで、**送信**をクリックします。CloudFormation コンソールで作成中のスタックの進行状況を確認できます。 -* スタックの作成が完了するまでお待ちください。スタックのステータスが `CREATE_COMPLETE` になるまで、コンソールのビューを更新します。 - -スタックが `CREATE_COMPLETE` ステータスになったら、スタックの**リソース**タブに移動します。`EnvType` に渡した `test` 値と、テンプレート内の他の2つのリソースに追加して関連付けた条件に基づき作成したロジックをベースに、プロビジョニングされているリソースがEC2インスタンスだけであることを確認します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/conditions` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/conditions +::: +1. AWS CLI を使用してスタックを作成します。必要なパラメータはあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-condition-test \ +--template-body file://condition-resource.yaml \ +--parameters ParameterKey="EnvType",ParameterValue="test" +::: +1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-condition-test/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. CloudFormation コンソールで、 **スタックの作成** 、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートの準備** セクションで、 **テンプレートの準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. `condition-resource.yaml` テンプレートを選択します。 +1. **スタックの名前** を入力します。例えば、`cfn-workshop-condition-test` と入力します。 +1. `EnvType` パラメータの値として `test` を選択します。 **次へ** をクリックします。 +1. **スタックオプションの設定** ページはデフォルト値のまま **次へ** をクリックします。 +1. レビューページで、 **送信** をクリックします。CloudFormation コンソールで作成中のスタックの進行状況を確認できます。 +1. スタックの作成が完了するまでお待ちください。スタックのステータスが `CREATE_COMPLETE` になるまで、コンソールのビューを更新します。 +:::: +::::: + +スタックが `CREATE_COMPLETE` ステータスになったら、スタックの **リソース** タブに移動します。`EnvType` に渡した `test` 値と、テンプレート内の他の 2 つのリソースに追加して関連付けた条件に基づき作成したロジックをベースに、プロビジョニングされているリソースが EC2 インスタンスだけであることを確認します。 ![condition-test](/static/intermediate/templates/conditions/condition-test.ja.png) 次のステップでは、同じテンプレートを使用して新しいスタックを作成します。今回は、`envType` パラメータの値として `prod` を渡し、`Volume` と `MountPoint` リソースもプロビジョニングされることを確認します。AWS CloudFormation [コンソール](https://console.aws.amazon.com/cloudformation)に移動し、既存のテンプレートを使用してスタックを作成します。 -* CloudFormation コンソールで、**スタックの作成**、**新しいリソースを使用 (標準)** を選択します。 -* **テンプレートの準備**セクションで、**テンプレートの準備完了**を選択します。 -* **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -* `condition-resource.yaml` テンプレートを選択します。 -* **スタックの名前**を入力します。例えば、`cfn-workshop-condition-prod` と入力します。 -* `EnvType` パラメータの値として `prod` を選択します。**次へ**をクリックします。 -* **スタックオプションの設定**ページはデフォルト値のまま**次へ**をクリックします。 -* レビューページで、**送信**をクリックします。CloudFormation コンソールで作成中のスタックの進行状況を確認できます。 -* スタックの作成が完了するまでお待ちください。スタックのステータスが `CREATE_COMPLETE` になるまで、コンソールのビューを更新します。 - -今回は `IsProduction` 条件が満たされます。スタックの**リソース**タブに移動し、EC2インスタンスリソースと共に、`Volume` および `MountPoint` リソースもプロビジョニングされていることを確認します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/conditions` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/conditions +::: +1. AWS CLI を使用してスタックを作成します。必要なパラメータはあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-condition-prod \ +--template-body file://condition-resource.yaml \ +--parameters ParameterKey="EnvType",ParameterValue="prod" +::: +1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-condition-prod/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. CloudFormation コンソールで、 **スタックの作成** 、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートの準備** セクションで、 **テンプレートの準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. `condition-resource.yaml` テンプレートを選択します。 +1. **スタックの名前** を入力します。例えば、`cfn-workshop-condition-prod` と入力します。 +1. `EnvType` パラメータの値として `prod` を選択します。 **次へ** をクリックします。 +1. **スタックオプションの設定** ページはデフォルト値のまま **次へ** をクリックします。 +1. レビューページで、 **送信** をクリックします。CloudFormation コンソールで作成中のスタックの進行状況を確認できます。 +1. スタックの作成が完了するまでお待ちください。スタックのステータスが `CREATE_COMPLETE` になるまで、コンソールのビューを更新します。 +:::: +::::: + +今回は `IsProduction` 条件が満たされます。スタックの **リソース** タブに移動し、EC2 インスタンスリソースと共に、`Volume` および `MountPoint` リソースもプロビジョニングされていることを確認します。 ![condition-prod](/static/intermediate/templates/conditions/condition-prod.ja.png) @@ -145,8 +191,8 @@ Resources: まず、条件を設計します。例えば、`EnvType` パラメータの入力パラメータとして `prod` を指定した場合、条件は満たされます。次に、条件を EC2 インスタンスに関連付け、希望する動作を次のように記述します。条件が当てはまる場合、インスタンスはインスタンスタイプとして `t2.small` を使用し、それ以外の場合は `t2.micro` を使用します。次の例で、これがどのように機能するか見てみましょう。 1. `code/workspace/conditions` ディレクトリにいることを確認します。 -2. `condition-resource-property.yaml` ファイルを開きます。 -3. ラボの手順に従ってテンプレートの内容を更新します。 +1. `condition-resource-property.yaml` ファイルを開きます。 +1. ラボの手順に従ってテンプレートの内容を更新します。 それでは、始めましょう!この例では、前の例と同様に、`EnvType` パラメータと `IsProduction` 条件を定義して、渡したパラメータ値に基づいてリソースを作成します。以下に示すコンテンツをコピーし、`condition-resource-property.yaml` ファイルに貼り付けます。 @@ -186,17 +232,38 @@ Resources: このセクションでは、`EnvType` パラメータの値として `test` を指定、EC2 インスタンスのタイプが `t2.micro` であることを確認します。AWS CloudFormation [コンソール](https://console.aws.amazon.com/cloudformation)に移動し、次のテンプレートを使用してスタックを作成します。 -* CloudFormation コンソールで、**スタックの作成**、**新しいリソースを使用 (標準)** を選択します。 -* **テンプレートの準備**セクションで、**テンプレートの準備完了**を選択します。 -* **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -* `condition-resource-property.yaml` テンプレートを選択します。 -* **スタックの名前**を入力します。例えば、`cfn-workshop-condition-property-test` と入力します。 -* `EnvType` パラメータの値として `test` を渡します。**次へ**をクリックします。 -* **スタックオプションの設定**ページはデフォルト値のまま**次へ**をクリックします。 -* レビューページで、**送信**をクリックします。CloudFormation コンソールで作成中のスタックの進行状況を確認できます。 -* スタックの作成が完了するまでお待ちください。スタックのステータスが `CREATE_COMPLETE` になるまで、コンソールのビューを更新します。 - -スタックのステータスが `CREATE_COMPLETE` になったら、スタックの**リソース**タブに移動し、スタックで作成した EC2 インスタンスを探します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/conditions` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/conditions +::: +1. AWS CLI を使用してスタックを作成します。必須パラメータはあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-condition-property-test \ +--template-body file://condition-resource-property.yaml \ +--parameters ParameterKey="EnvType",ParameterValue="test" +::: +1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-condition-property-test/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. CloudFormation コンソールで、 **スタックの作成** 、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレートの準備** セクションで、 **テンプレートの準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. `condition-resource-property.yaml` テンプレートを選択します。 +1. **スタックの名前** を入力します。例えば、`cfn-workshop-condition-property-test` と入力します。 +1. `EnvType` パラメータの値として `test` を渡します。 **次へ** をクリックします。 +1. **スタックオプションの設定** ページはデフォルト値のまま **次へ** をクリックします。 +1. レビューページで、 **送信** をクリックします。CloudFormation コンソールで作成中のスタックの進行状況を確認できます。 +1. スタックの作成が完了するまでお待ちください。スタックのステータスが `CREATE_COMPLETE` になるまで、コンソールのビューを更新します。 +:::: +::::: + +スタックのステータスが `CREATE_COMPLETE` になったら、スタックの **リソース** タブに移動し、スタックで作成した EC2 インスタンスを探します。 次に、インスタンスタイプが想定通りであることを確認します。インスタンスの物理 ID のリンクをクリックして、Amazon EC2 コンソールでインスタンスを表示します。 ![condition-test-property](/static/intermediate/templates/conditions/condition-test-property.ja.png) @@ -212,14 +279,14 @@ Resources: ここまで、CloudFormation テンプレート内のリソースとプロパティ値で条件を使用する方法を学んできました。このチャレンジでは、`condition-resource.yaml` CloudFormation テンプレートの [Outputs](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html) セクションに条件付きで出力を作成します。 -**タスク:** `condition-resource.yaml` テンプレートに [Outputs](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html) セクションを記述してください。出力の論理IDとして `VolumeId` を指定し、`Ref` 組み込み関数を使用して [VolumeID を返します](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#aws-resource-ec2-volume-return-values)。このチャレンジのゴールは、`IsProduction` 条件が満たされた場合にのみ出力を作成することです。チャレンジのゴールに向けて、どのようにテンプレートに反映させますか?準備ができたら、更新したテンプレートで既存の `cfn-workshop-condition-prod` スタックを更新し、変更によって期待どおりの出力が作成されたことを確認します。 +**タスク** `condition-resource.yaml` テンプレートに [Outputs](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html) セクションを記述してください。出力の論理 ID として `VolumeId` を指定し、`Ref` 組み込み関数を使用して [VolumeID を返します](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-volume.html#aws-resource-ec2-volume-return-values)。このチャレンジのゴールは、`IsProduction` 条件が満たされた場合にのみ出力を作成することです。チャレンジのゴールに向けて、どのようにテンプレートに反映させますか?準備ができたら、更新したテンプレートで既存の `cfn-workshop-condition-prod` スタックを更新し、変更によって期待どおりの出力が作成されたことを確認します。 :::expand{header="ヒントが必要ですか?"} * [スタック出力](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html#outputs-section-structure-examples)のドキュメントを参照し、テンプレートで `VolumeId` 出力を定義してください。 * [条件](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/conditions-section-structure.html)と[条件の関連付け](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-conditions.html#associating-a-condition)のドキュメントを確認してください。どのように条件付きで出力を作成しますか? ::: -:::expand{header="解決策を確認しますか?"} +::::::expand{header="解決策を確認しますか?"} `condition-resource.yaml` ファイルに次の内容を追加します。 ```yaml @@ -231,19 +298,38 @@ Outputs: 次に、AWS CloudFormation [コンソール](https://console.aws.amazon.com/cloudformation)に移動して、`cfn-workshop-condition-prod` スタックの更新を選択します。 -* CloudFormation コンソールで、**更新**をクリックします。 -* **テンプレートの準備**セクションで、**既存のテンプレート置き換える**を選択します。 -* **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -* `condition-resource.yaml` テンプレートを選択します。 -* `EnvType` は既に `prod` に設定されているはずです。**次へ**をクリックします。 -* **スタックオプションの設定**ページはデフォルト値のまま**次へ**をクリックします。 -* レビューページで、**送信**をクリックします。CloudFormation コンソールで作成中のスタックの進行状況を確認できます。 -* スタックの作成が完了するまでお待ちください。スタックのステータスが `UPDATE_COMPLETE` になるまで、コンソールのビューを更新します。 - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/conditions` ディレクトリに移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/conditions + ::: +1. AWS CLI を使用してスタックを更新します。必要なパラメータはあらかじめ入力されています。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation update-stack --stack-name cfn-workshop-condition-prod \ +--template-body file://condition-resource.yaml \ +--parameters ParameterKey="EnvType",ParameterValue="prod"``` + ::: +1. `update-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-condition-prod/739fafa0-e4d7-11ed-a000-12d9009553ff" +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **UPDATE_COMPLETE** になっているかどうかを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. CloudFormation コンソールで、 **更新** をクリックします。 +1. **テンプレートの準備** セクションで、 **既存のテンプレート置き換える** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. `condition-resource.yaml` テンプレートを選択します。 +1. `EnvType` は既に `prod` に設定されているはずです。 **次へ** をクリックします。 +1. **スタックオプションの設定** ページはデフォルト値のまま **次へ** をクリックします。 +1. レビューページで、 **送信** をクリックします。CloudFormation コンソールで作成中のスタックの進行状況を確認できます。 +1. スタックの作成が完了するまでお待ちください。スタックのステータスが `UPDATE_COMPLETE` になるまで、コンソールのビューを更新します。 +:::: +::::: スタックの`出力`セクションに移動し、`VolumeId` の出力が存在することを確認します。 ![condition-prod-update](/static/intermediate/templates/conditions/condition-prod-update.ja.png) -::: +:::::: 解決策は、`code/solutions/conditions/condition-output.yaml` テンプレートファイルでも入手できます。 @@ -252,7 +338,7 @@ Outputs: 次に示す手順に従って、このラボで作成したリソースをクリーンアップしてください。 * CloudFormation コンソールで、このラボで作成した `cfn-workshop-condition-test` スタックを選択します。 -* このラボで作成したスタックの**削除**を選択した後、**スタックの削除**をクリックして確定します。 +* このラボで作成したスタックの **削除** を選択した後、 **スタックの削除** をクリックして確定します。 このラボで作成した他のスタック `cfn-workshop-condition-prod`、`cfn-workshop-condition-property-test` に対して、上記と同じクリーンアップ手順を実行します。 diff --git a/content/intermediate/templates/cross-stacks/index.ja.md b/content/intermediate/templates/cross-stacks/index.ja.md index 616026875..1aad5e8a4 100644 --- a/content/intermediate/templates/cross-stacks/index.ja.md +++ b/content/intermediate/templates/cross-stacks/index.ja.md @@ -1,28 +1,32 @@ --- -title: "階層化されたスタック" +title: "クロススタック参照" weight: 500 --- +_ラボ実施時間 : 25分程度_ + +--- + ### 概要 前のラボでは、`Outputs` セクションと `Fn::GetAtt` 関数を使って子スタックから親スタックへ値を渡す方法について学びました。そして、再利用可能なテンプレートを作成することができるようになりました。例えば、ネストされたスタックを利用すると、VPC と IAM ロール専用のテンプレートを用意することができます。 -しかし、**スタック** を再利用したい場合はどうでしょうか? +しかし、 **スタック** を再利用したい場合はどうでしょうか? 例えば、多数のテンプレートを使用して多数のワークロードをデプロイする計画があったとします。すべての EC2 インスタンスが Systems Manager Session Manager によるすべての EC2 インスタンスへのアクセスを有効にする必要があります。 同様に、1 つのスタックで VPC をデプロイし、それを将来、複数のスタックやワークロードで使用したい場合があります。 このような一対多の関係は、ネストされたスタックのシナリオでは実現できません。 -ここで階層化されたスタックの出番です。 +ここでクロススタック参照の出番です。 -私たちは [Export](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html) を使用し、任意の CloudFormation スタックに [Import](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html) できるグローバル変数を作成します。 +私たちは [Export](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html) を使用し、同じ AWS アカウントと同じリージョンの任意の CloudFormation スタックに [Import](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html) できるグローバル変数を作成します。 ### 取り上げるトピック このラボでは、以下を作成します。 -1. **VPC スタック**: 前のラボで使用したものと同じシンプルな VPC テンプレートが含まれていますが、出力に Export が追加されています。 -2. **IAM インスタンスロールスタック**: 前のラボで使用したのと同じ IAM インスタンスロールが含まれていますが、出力に Export が追加されています。 -3. **EC2 スタック**: 前のラボで定義した EC2 インスタンスが含まれていますが、ここでは Fn::ImportValue 関数を使用します。 +1. **VPC スタック** : 前のラボで使用したものと同じシンプルな VPC テンプレートが含まれていますが、出力に Export が追加されています。 +1. **IAM インスタンスロールスタック** : 前のラボで使用したのと同じ IAM インスタンスロールが含まれていますが、出力に Export が追加されています。 +1. **EC2 スタック** : 前のラボで定義した EC2 インスタンスが含まれていますが、ここでは Fn::ImportValue 関数を使用します。 -> 階層化されたスタックの階層を示す図 +> クロススタック参照の関係を示す図 ![cross-stack-hierarchy.png](/static/intermediate/templates/cross-stacks/cross-stack-hierarchy.ja.png) @@ -45,7 +49,7 @@ VPC テンプレートは既に作成されており、タイトルは `vpc.yaml 以下の [4-5、9-10、14-15] 行目をテンプレートファイルに追加します。 -```yaml {hl_lines=[4,5,9,10,14,15]} +:::code{language=yaml showLineNumbers=true showCopyAction=true highlightLines=4-5,9-10,14-15} Outputs: VpcId: Value: !Ref VPC @@ -61,58 +65,93 @@ Outputs: Value: !Ref VPCPublicSubnet2 Export: Name: cfn-workshop-PublicSubnet2 -``` +::: ##### 2. VPC スタックのデプロイ -1. コンソールで CloudFormation に移動し、**新しいリソースを使用 (標準)** をクリックします。 -2. **テンプレートの準備**セクションで、**テンプレート準備完了**を選択します。 -3. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -4. `vpc.yaml` ファイルを選択します。 -5. **スタック名**を入力します。例えば、`cfn-workshop-vpc` と入力します。 -6. **AvaliabilityZone** パラメータには、**2 つの AZ** を選択します。 -7. 残りのパラメータは**デフォルト**のままとします。 -8. すべてデフォルトのままウィザード内を移動します。 -9. レビューページで一番下までスクロールし、**送信**をクリックします。 - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `cfn101-workshop/code/workspace/cross-stacks` ディレクトリに移動します。 +1. **スタックを作成** は、次の AWS CLI コマンドを使用して行います。このテンプレートでは、 `AvailabilityZones` パラメータの値を指定する必要があります。たとえば、 `us-east-1a` と `us-east-1b` は以下で使用されます。利用しているリージョンの 2 つのアベイラビリティーゾーンを選択してください。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ +--stack-name cfn-workshop-cross-stacks-vpc \ +--template-body file://vpc.yaml \ +--parameters ParameterKey=AvailabilityZones,ParameterValue=us-east-1a\\,us-east-1b +::: +1. 次の AWS CLI コマンドを実行して、スタックの作成が完了するまで待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-create-complete \ +--stack-name cfn-workshop-cross-stacks-vpc +::: +:::: +::::tab{id="local" label="ローカル開発"} +1. コンソールで CloudFormation に移動し、 **新しいリソースを使用 (標準)** をクリックします。 +1. **テンプレートの準備** セクションで、 **テンプレート準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. `vpc.yaml` ファイルを選択します。 +1. **スタック名** を入力します。例えば、`cfn-workshop-cross-stacks-vpc` と入力します。 +1. **AvaliabilityZone** パラメータには、 **2 つの AZ** を選択します。 +1. 残りのパラメータは **デフォルト** のままとします。 +1. すべてデフォルトのままウィザード内を移動します。 +1. レビューページで一番下までスクロールし、 **送信** をクリックします。 +:::: +::::: #### IAM スタックの作成 ##### 1. IAM ロールテンプレートの準備 1. `iam.yaml` ファイルを開きます。 -2. 以下の [4~5] 行目をテンプレートの **Outputs** セクションにコピーします。 - ```yaml {hl_lines=[4,5]} +1. 以下の [4 ~ 5] 行目をテンプレートの **Outputs** セクションにコピーします。 +:::code{language=yaml showLineNumbers=true showCopyAction=true highlightLines=4-5} Outputs: WebServerInstanceProfile: Value: !Ref WebServerInstanceProfile Export: Name: cfn-workshop-WebServerInstanceProfile - ``` +::: ##### 2. IAM スタックのデプロイ - -1. コンソールで CloudFormation に移動し、**新しいリソースを使用 (標準)** をクリックします。 -2. **テンプレートの準備**セクションで、**テンプレート準備完了**を選択します。 -3. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -4. `iam.yaml` ファイルを選択します。 -5. **スタック名**を入力します。例えば、`cfn-workshop-iam` と入力します。 -6. **次へ**をクリックします。 -7. すべてデフォルトのままウィザード内を移動します。 -8. **Acknowledge IAM capabilities** をクリックし、**送信**をクリックします。 - -#### EC2 階層化されたスタックの作成 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. 次の AWS CLI コマンドを使用して、 **スタックを作成** してみましょう。このテンプレートでは、IAM リソースを作成するための `CAPABILITY_IAM` 機能を指定する必要があります。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ +--stack-name cfn-workshop-cross-stacks-iam \ +--template-body file://iam.yaml \ +--capabilities CAPABILITY_IAM +::: +1. 次の AWS CLI コマンドを実行して、スタックの作成が完了するまで待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-create-complete \ +--stack-name cfn-workshop-cross-stacks-iam +::: +:::: +::::tab{id="local" label="ローカル開発"} +1. コンソールで CloudFormation に移動し、 **新しいリソースを使用 (標準)** をクリックします。 +1. **テンプレートの準備** セクションで、 **テンプレート準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. `iam.yaml` ファイルを選択します。 +1. **スタック名** を入力します。例えば、`cfn-workshop-cross-stacks-iam` と入力します。 +1. **次へ** をクリックします。 +1. すべてデフォルトのままウィザード内を移動します。 +1. **Acknowledge IAM capabilities** をクリックし、 **送信** をクリックします。 +:::: +::::: + +#### EC2 クロススタックの作成 ##### 1. EC2 テンプレートの準備 -**階層化された Stack** のコンセプトは、**Paramaters** を使用する代わりに、組み込み関数を使用して、以前にエクスポートされた値をインポートすることです。 +**クロススタック** のコンセプトは、 **Paramaters** を使用する代わりに、組み込み関数を使用して、以前にエクスポートされた値をインポートすることです。 従って、`ec2.yaml` に最初に加えるべき変更は、今後使用されなくなる `SubnetId`、`VpcID`、`WebServerInstanceProfile` のパラメータを削除することです。 ##### 2. Parameters セクションの更新 -次の例のような形で、**Parameters** セクションを更新します。 -つまり、**Parameters** セクションから、`VpcId`、`SubnetId`、`WebServerInstanceProfile` の項目を削除します。 +次の例のような形で、 **Parameters** セクションを更新します。 +つまり、 **Parameters** セクションから、`VpcId`、`SubnetId`、`WebServerInstanceProfile` の項目を削除します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} Parameters: EnvironmentType: Description: 'Specify the Environment type of the stack.' @@ -128,7 +167,7 @@ Parameters: Type: AWS::SSM::Parameter::Value Description: 'The ID of the AMI.' Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2 -``` +::: ##### 3. WebServerInstance リソースの更新 @@ -137,7 +176,7 @@ Parameters: `ec2.yaml` テンプレートのリソースセクションにある WebServerInstance リソースを更新します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true highlightLines=5-8} WebServerInstance: Type: AWS::EC2::Instance {...} @@ -147,12 +186,12 @@ WebServerInstance: ImageId: !Ref AmiID InstanceType: !FindInMap [EnvironmentToInstanceType, !Ref EnvironmentType, InstanceType] {...} -``` +::: ##### 4. セキュリティグループの更新 最後に、セキュリティグループリソースを更新します。`ec2.yaml` テンプレートの **Resources** セクション `WebServerSecurityGroup` リソース [19] 行目を更新します。 -```yaml {hl_lines=[19]} +:::code{language=yaml showLineNumbers=true showCopyAction=true highlightLines=19} WebServerSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: @@ -172,24 +211,41 @@ WebServerSecurityGroup: ToPort: 443 CidrIp: 0.0.0.0/0 VpcId: !ImportValue cfn-workshop-VpcId -``` +::: ##### 5. EC2 スタックのデプロイ -1. コンソールで CloudFormation に移動し、**新しいリソースを使用 (標準)** をクリックします。 -2. **テンプレートの準備**セクションで、**テンプレート準備完了**を選択します。 -3. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -4. `ec2.yaml` ファイルを選択します。 -5. **スタック名**を入力します。例えば、`cfn-workshop-ec2`と入力します。 -6. 残りのパラメータは **デフォルト** のままとします。 -7. すべてデフォルトのままウィザード内を移動します。 -8. **レビュー**ページで一番下までスクロールし、**送信**をクリックします。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. 次の AWS CLI コマンドを使用して、 **スタックを作成** してみましょう。このテンプレートでは、IAM リソースを作成するための `CAPABILITY_IAM` 機能を指定する必要があります。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ +--stack-name cfn-workshop-cross-stacks-ec2 \ +--template-body file://ec2.yaml +::: +1. 次の AWS CLI コマンドを実行して、スタックの作成が完了するまで待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-create-complete \ +--stack-name cfn-workshop-cross-stacks-ec2 +::: +:::: +::::tab{id="local" label="ローカル開発"} +1. コンソールで CloudFormation に移動し、 **新しいリソースを使用 (標準)** をクリックします。 +1. **テンプレートの準備** セクションで、 **テンプレート準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. `ec2.yaml` ファイルを選択します。 +1. **スタック名** を入力します。例えば、`cfn-workshop-cross-stacks-ec2`と入力します。 +1. 残りのパラメータは **デフォルト** のままとします。 +1. すべてデフォルトのままウィザード内を移動します。 +1. **レビュー** ページで一番下までスクロールし、 **送信** をクリックします。 +:::: +::::: #### 7. デプロイメントのテスト ##### 1.アプリケーションが正常にデプロイされたことを確認 -プライベートモードで新しいブラウザウィンドウを開き、`websiteURL` を入力します (WebsiteURL は CloudFormation コンソールの EC2 スタックの**出力**タブから取得できます)。 +プライベートモードで新しいブラウザウィンドウを開き、`websiteURL` を入力します (WebsiteURL は CloudFormation コンソールの EC2 スタックの **出力** タブから取得できます)。 下の図のような、いくつかのインスタンスメタデータが表示されます。 ![ami-id](/static/intermediate/templates/cross-stacks/ami-id-1.ja.png) @@ -204,16 +260,32 @@ Session Manager を使用してインスタンスにログインできること ::alert[スタックが出力値をインポートした後は、出力値をエクスポートしているスタックを削除したり、エクスポートされた出力値を変更したりすることはできません。エクスポートするスタックを削除したり、出力値を変更したりする前に、すべてのインポートを削除する必要があります。]{type="info"} -例えば、**EC2 スタック**を削除する前に **VPC スタック**を削除することはできません。次のエラーメッセージが表示されます。 +例えば、 **EC2 スタック** を削除する前に **VPC スタック** を削除することはできません。次のエラーメッセージが表示されます。 ![delete-export-before-import.png](/static/intermediate/templates/cross-stacks/delete-export-before-import.ja.png) - -1. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation) で、**EC2 スタック** を選択します (例: `cfn-workshop-ec2`)。 -2. 右上の**削除**をクリックします。 -3. ポップアップウィンドウで、**スタックの削除**をクリックします。 -4. **DELETE_COMPLETE** のステータスが表示されるまで、**更新**ボタンを数回クリックします。 -5. 依存関係がなくなったため、**IAM** と **VPC** スタックが削除できます。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **スタックを削除** するために次の AWS CLI コマンドを実行してください +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ +--stack-name cfn-workshop-cross-stacks-ec2 +::: +1. 次の AWS CLI コマンドを使用して、スタックが削除されるまで待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-delete-complete \ +--stack-name cfn-workshop-cross-stacks-ec2 +::: +1. `cfn-workshop-cross-stacks-iam` と `cfn-workshop-cross-stacks-vpc` スタックについて、上記のステップ (1-2) を繰り返します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. [CloudFormation コンソール](https://console.aws.amazon.com/cloudformation) で、 **EC2 スタック** を選択します (例: `cfn-workshop-cross-stacks-ec2`)。 +1. 右上の **削除** をクリックします。 +1. ポップアップウィンドウで、 **スタックの削除** をクリックします。 +1. **DELETE_COMPLETE** のステータスが表示されるまで、 **更新** ボタンを数回クリックします。 +1. 依存関係がなくなったため、 **IAM** と **VPC** スタックが削除できます。 +:::: +::::: --- ### まとめ -**階層化されたスタック**では、複数のスタックで繰り返し使用できるリソースを作成できます。利用する全てのスタックで、**Export** で指定した名前を知る必要があります。この機能を利用することで、役割と責任を分けることができます。例えば、ネットワークチームは、承認された VPC デザインをテンプレートとして作成して提供できます。必要に応じて、VPCスタックの Export を参照すれば良いです。同様に、セキュリティチームは IAM ロールや EC2 セキュリティグループについても同じ操作を行うことができます。 +**クロススタック参照** では、複数のスタックで繰り返し使用できるリソースを作成できます。利用する全てのスタックで、 **Export** で指定した名前を知る必要があります。この機能を利用することで、役割と責任を分けることができます。例えば、ネットワークチームは、承認された VPC デザインをテンプレートとして作成して提供できます。必要に応じて、VPC スタックの Export を参照すれば良いです。同様に、セキュリティチームは IAM ロールや EC2 セキュリティグループについても同じ操作を行うことができます。 diff --git a/content/intermediate/templates/dynamic-references/index.ja.md b/content/intermediate/templates/dynamic-references/index.ja.md index 3706018d3..9e86cc26e 100644 --- a/content/intermediate/templates/dynamic-references/index.ja.md +++ b/content/intermediate/templates/dynamic-references/index.ja.md @@ -3,6 +3,10 @@ title: "動的参照" weight: 300 --- +_ラボ実施時間 : 30分程度_ + +--- + ### 概要 このモジュールでは、CloudFormation テンプレートの[動的な参照](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/dynamic-references.html)を使用して、[AWS Systems Manager](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/what-is-systems-manager.html) (SSM)、[Parameter Store](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html)、[AWS Secrets Manager](https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/intro.html) を含む AWS サービスに保存されている外部値を参照する方法を学びます。 @@ -18,7 +22,7 @@ weight: 300 * CloudFormation テンプレートの外部値にアクセスするための*動的参照文字列*を作成 * 特定のバージョン、または*最新*バージョンの Parameter Store パラメータを取得 * Secrets Manager シークレットの特定のバージョンを取得 - * JSON データ形式を使用するシークレットから特定のキーの値を抽出 +* JSON データ形式を使用するシークレットから特定のキーの値を抽出 ### ラボを開始 @@ -27,62 +31,94 @@ weight: 300 あなた (または組織のチーム) がカスタム AMI を作成したら、Parameter Store を使用して AMI の識別子を保存することができます。これにより、EC2 インスタンスを起動するときに使用する AMI をプログラムで指定しやすくなり、設定ミスの可能性が低くなります。 -このラボでは、AMI ID を永続化する Parameter Store パラメータを作成します。カスタム AMI の代わりに、選択したリージョンで利用できる最新の _Amazon Linux 2 AMI, 64-bit x86_ を使用します。次に、テンプレートに記述した EC2 インスタンスの `ImageId` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-imageid)でパラメータを参照します。 +このラボでは、AMI ID を永続化する Parameter Store パラメータを作成します。カスタム AMI の代わりに、選択したリージョンで利用できる最新の _Amazon Linux 2023 AMI, 64-bit x86_ を使用します。次に、テンプレートに記述した EC2 インスタンスの `ImageId` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-instance.html#cfn-ec2-instance-imageid)でパラメータを参照します。 -それでは、始めましょう!次に示す手順に従って選択してください: +それでは、始めましょう! -1. Amazon EC2 [コンソール](https://us-east-1.console.aws.amazon.com/ec2/v2/home?region=us-east-1#LaunchInstances:)に移動し、使用する[リージョンを選択](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)します。次に、最新の *Amazon Linux 2 AMI, (64-bit x86)* を探し、AMI ID (例: `ami-abcd1234`) をメモします。この値は次のステップで使用します。 +:::alert{type="info"} +ワークショップの _AWS リージョン_ には **us-east-1 (バージニア北部)** を使用することをお勧めします。 +::: + +1. Amazon EC2 [コンソール](https://us-east-1.console.aws.amazon.com/ec2/home?region=us-east-1#LaunchInstances:)の _インスタンスを起動_ に移動し、使用する[リージョンを選択](https://docs.aws.amazon.com/ja_jp/awsconsolehelpdocs/latest/gsg/select-region.html)します。次に、最新の *Amazon Linux 2023 AMI (64 ビット x86)* を探し、AMI ID (例:`ami-abcd1234`) を書き留めます。この値は次のステップで使用します。 ![ec2](/static/intermediate/templates/dynamic-references/ec2-console-ami-picker.ja.png) -2. [AWS Command Line Interface](https://aws.amazon.com/jp/cli/) (CLI) を使用してパラメータを作成します。以下に示すコマンドを実行するときは、必ず `YOUR_AMI_ID` と `YOUR_REGION` のプレースホルダーを必要な値に置き換えてください。必要値の入力時には、特定の AWS リージョンを指定します。リージョンの詳細については、[リージョンエンドポイント](https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html#regional-endpoints) の表の**コード**をご参照ください。また、必ず、前のステップで AMI を選択したときのリージョンと同一のリージョンを使用してください。 +2. [AWS Command Line Interface](https://aws.amazon.com/jp/cli/) (CLI) を使用してパラメータを作成します。以下に示すコマンドを実行するときは、必ず `YOUR_AMI_ID` と `YOUR_REGION` のプレースホルダーを必要な値に置き換えてください。必要値の入力時には、特定の AWS リージョンを指定します。リージョンの詳細については、[リージョンエンドポイント](https://docs.aws.amazon.com/ja_jp/general/latest/gr/rande.html#regional-endpoints) の表の **コード** をご参照ください。また、必ず、前のステップで AMI を選択したときのリージョンと同一のリージョンを使用してください。 - :::code{language=shell showLineNumbers=false showCopyAction=true} - aws ssm put-parameter \ - --name "/golden-images/amazon-linux-2" \ - --value YOUR_AMI_ID \ - --type "String" \ - --region YOUR_REGION - ::: +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws ssm put-parameter \ + --name "/golden-images/amazon-linux-2" \ + --value YOUR_AMI_ID \ + --type "String" \ + --region YOUR_REGION +::: ::alert[CloudFormation を使用して、`String` または `StringList` タイプの Paramater Store パラメータを作成可能です。詳細については、[AWS::SSM::Parameter](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html) のドキュメントをご覧ください。]{type="info"} -3. 次の手順に従って、テンプレートに記述した EC2 インスタンスのパラメータへの動的参照を作成します。 +3. `put-parameter` コマンドが成功すると、SSM は `Version` と `Tier` を返します。 +:::code{language=json showLineNumbers=false showCopyAction=false} +"Version": 1, +"Tier": "Standard" +::: - 1. `code/workspace/dynamic-references` ディレクトリに移動します。 - 2. お好みのテキストエディタで `ec2-instance.yaml` CloudFormation テンプレートを開きます。 - 3. テンプレート内の `AWS::EC2::Instance` リソースタイプブロックを探し、`Properties` セクションのプロパティに `ImageId` プロパティとパラメータへの動的参照を追加してテンプレートを更新します。 +4. 次の手順に従って、テンプレートに記述した EC2 インスタンスのパラメータへの動的参照を作成します。 + 1. `code/workspace/dynamic-references` ディレクトリに移動します。 + 1. お好みのテキストエディタで `ec2-instance.yaml` CloudFormation テンプレートを開きます。 + 1. テンプレート内の `AWS::EC2::Instance` リソースタイプブロックを探し、`Properties` セクションのプロパティに `ImageId` プロパティとパラメータへの動的参照を追加してテンプレートを更新します。 :::code{language=yaml showLineNumbers=false showCopyAction=true} ImageId: '{{resolve:ssm:/golden-images/amazon-linux-2}}' ::: 上記の動的参照を使って、スタックの実行時に `/golden-images/amazon-linux-2` パラメータの `LATEST` バージョンの値を解決します。 -::alert[CloudFormationは、[動的参照](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-ssm)による[パブリックパラメータ](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/parameter-store-finding-public-parameters.html)をサポートしていません。[SSM パラメータタイプ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#aws-ssm-parameter-types)を使用してパブリックパラメータの値を取得することができます。]{type="info"} - -4. いよいよスタックを作成しましょう! 以下の手順に従ってください。 - - 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動し、**新しいリソースを使用 (標準)** を選択します。 - 2. **テンプレートの準備**セクションで、**テンプレート準備完了**を選択します。 - 3. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 - 4. ファイル `ec2_instance.yaml` を選択します。 - 5. スタック名を入力します。例えば、`cfn-workshop-ec2-stack` を入力します。 - 6. **スタックオプションの設定**ページはデフォルト値のまま、**次へ**をクリックします。 - 7. スタックの**レビュー**ページで、一番下までスクロールし、**送信**をクリックします。 - 8. スタックの作成ページを更新することで、CloudFormation コンソールでスタックの作成の進行状況を確認できます。 - 9. スタックの `CREATE_COMPLETE` ステータスが表示されるまでページを更新してください。 - -::alert[SSM パラメータへの動的参照を使用して、特定のパラメータバージョンを指すこともできます。例えば、CloudFormation にパラメータのバージョン `1` を解決させるには、`ImageId: '{{resolve:ssm:/golden-images/amazon-linux-2:1}}'` を使用します。特定のバージョンへの動的参照をロックすると、スタックの更新時にリソースが意図せず更新されることを防止するのに役立ちます。]{type="info"} - -5. EC2 インスタンスに使用したイメージの ID が、Parameter Store パラメータに保存したイメージ ID と一致することを確認します。まず、CloudFormation コンソールの**リソース** タブに移動して EC2 インスタンス ID を確認します。EC2 インスタンスの物理 ID を探し、その値を書き留めます。次に、以下のコマンドを実行します (コマンドを実行する前に、`YOUR_INSTANCE_ID` と `YOUR_REGION` プレースホルダーを置き換えてください)。 +::alert[CloudFormation は、[動的参照](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-ssm)による[パブリックパラメータ](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/parameter-store-finding-public-parameters.html)をサポートしていません。[SSM パラメータタイプ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html#aws-ssm-parameter-types)を使用してパブリックパラメータの値を取得することができます。]{type="info"} +5. いよいよスタックを作成しましょう! 以下の手順に従ってください。 + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **Cloud9 ターミナル** で `code/workspace/dynamic-references` ディレクトリに移動します + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/dynamic-references + ::: + 2. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。 :::code{language=shell showLineNumbers=false showCopyAction=true} - aws ec2 describe-instances \ - --instance-ids YOUR_INSTANCE_ID \ - --region YOUR_REGION \ - --query 'Reservations[0].Instances[0].ImageId' + aws cloudformation create-stack \ +--stack-name cfn-workshop-dynamic-references-ec2 \ +--template-body file://ec2-instance.yaml ::: + 1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-dynamic-references-ec2/3fabc340-e74e-11ed-9b33-0a550dedb7a1" + ::: + 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。 + :::: + ::::tab{id="local" label="ローカル開発"} + 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移 し **新しいリソースを使用 (標準)** を選択します。 + 1. **テンプレートの準備** セクションで、 **テンプレート準備完了** を選択します。 + 1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 + 1. ファイル `ec2-instance.yaml` を選択します。 + 1. スタック名を入力します。例えば、`cfn-workshop-dynamic-references-ec2` を入力します。 + 1. **スタックオプションの設定** ページはデフォルト値のまま、 **次へ** をクリックします。 + 1. スタックの **レビュー <スタック名>** ページで、一番下までスクロールし、 **送信** をクリックします。 + 1. スタックの **CREATE_COMPLETE** ステータスが表示されるまでページを更新してください。 + :::: + ::::: + + ::alert[SSM パラメータへの動的参照を使用して、特定のパラメータバージョンを指すこともできます。例えば、CloudFormation にパラメータのバージョン `1` を解決させるには、`ImageId: '{{resolve:ssm:/golden-images/amazon-linux-2:1}}'` を使用します。特定のバージョンへの動的参照をロックすると、スタックの更新時にリソースが意図せず更新されることを防止するのに役立ちます。]{type="info"} + +6. EC2 インスタンスに使用したイメージの ID が、Parameter Store パラメータに保存したイメージ ID と一致することを確認します。まず、CloudFormation コンソールの _リソース_ タブに移動して EC2 インスタンス ID を確認します。EC2 インスタンスの物理 ID を探し、その値を書き留めます。次に、以下のコマンドを実行します (コマンドを実行する前に、`YOUR_INSTANCE_ID` と `YOUR_REGION` プレースホルダーを置き換えてください)。 + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws ec2 describe-instances \ +--instance-ids YOUR_INSTANCE_ID \ +--region YOUR_REGION \ +--query 'Reservations[0].Instances[0].ImageId' +::: +7. `describe-instances` コマンドが正常に送信された場合、EC2 は `ImageID` を返します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"ami-02396cdd13e9a1257" +::: おめでとうございます!Parameter Store を使用して、動的参照の利用方法の例を学習しました。 @@ -95,131 +131,206 @@ weight: 300 1. Amazon RDS データベースを作成し、接続情報を AWS Secrets Manager にシークレットとして保存します。 1. `code/workspace/dynamic-references` ディレクトリにいることを確認します。 - 2. お好みのテキストエディタで `database.yaml` CloudFormationテンプレートを開きます。 - 3. テンプレート内の次のリソースに注意してください。 - 1. `AWS::RDS::DBInstance` タイプのリソース。本リソースを使用して Amazon RDSインスタンスを記述します。 - 2. `AWS::SecretsManager::Secret` タイプのリソース。データベース接続パラメータをJSONキーと値のペアとして、`DatabaseConnParams` という名前のシークレットに保存します。 - ```json - { - "RDS_HOSTNAME": "${Database.Endpoint.Address}", - "RDS_PORT": "${Database.Endpoint.Port}", - "RDS_USERNAME": "${DBUsername}", - "RDS_PASSWORD": "${DBPassword}" - } - ``` + 1. お好みのテキストエディタで `database.yaml` CloudFormation テンプレートを開きます。 + 1. テンプレート内の次のリソースに注意してください。 + 1. `AWS::RDS::DBInstance` タイプのリソース。本リソースを使用して Amazon RDS インスタンスを記述します。 + :::alert{type="info"} + `AWS::RDS::DBInstance`タイプのリソースで (このラボの例のように) `DBClusterIdentifier` プロパティを指定していない場合、[削除ポリシー](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html)が明示的に定義されていない場合、削除ポリシーはデフォルトで `Snapshot` になり、CloudFormation はリソースを削除する前にリソースのスナップショットを作成します。このラボでは、リソースの `DeletionPolicy` を `Delete` に設定して、削除時にスナップショットの作成をスキップします。 + ::: + 1. `AWS::SecretsManager::Secret` タイプのリソース。データベース接続パラメータを JSON キーと値のペアとして、`DatabaseConnParams` という名前のシークレットに保存します。 + :::code{language=json showLineNumbers=true showCopyAction=false lineNumberStart=47} + { + "RDS_HOSTNAME": "${Database.Endpoint.Address}", + "RDS_PORT": "${Database.Endpoint.Port}", + "RDS_USERNAME": "${DBUsername}", + "RDS_PASSWORD": "${DBPassword}" +} + ::: 2. データベーススタックをデプロイするには、以下の手順に従います。 - 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動し、**新しいリソースを使用 (標準)** を選択します。 - 2. **テンプレートの準備**セクションで、**テンプレートの準備完了**を選択します。 - 3. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 - 4. ファイル `database.yaml` を選択します。 - 5. スタック名を入力します。例えば、`cfn-workshop-database-stack` と入力します。 - 6. `DBUserName` には、DB インスタンスのプライマリユーザー名を指定します。 - 7. `DBPassword` には、プライマリユーザーのパスワードを指定します。 - 8. **スタックオプションの設定**ページはデフォルト値のまま、**次へ**をクリックします。 - 9. スタックの**レビュー**ページで、一番下までスクロールして、**送信**をクリックします。 - 10. スタックの作成ページを更新することで、CloudFormation コンソールでスタックの作成の進行状況を確認できます。 - 11. スタックの `CREATE_COMPLETE` ステータスが表示されるまでページを更新してください。 - -3. 次に、AWS Lambda 関数を作成し、以前に作成した Secrets Manager シークレットへの動的参照を使用して、いくつかのデータベース接続パラメータを[環境変数](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-envvars.html)として Lambda 関数に読み取ります。 - 1. `code/workspace/dynamic-references` ディレクトリにいることを確認します。 - 2. お好みのテキストエディタで `lambda-function.yaml` CloudFormation テンプレートを開きます。 - 3. テンプレートには `AWS::Lambda::Function` リソースタイプが記述されています。`Properties` セクションに `Environment` プロパティを追加し、先ほど作成した AWS Secret Manager シークレットへの動的参照を使用する変数を追加してテンプレートを更新します。 - ```yaml - Environment: - Variables: - RDS_HOSTNAME: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_HOSTNAME}}' - RDS_PORT: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_PORT}}' - ``` -4. Lambda スタックをデプロイするには、以下の手順に従います。 - 1. [AWS CloudFormationコンソール](https://console.aws.amazon.com/cloudformation/) に移動し、**新しいリソースを使用 (標準)** を選択します。 - 2. **テンプレートの準備**セクションで、**テンプレートの準備完了**を選択します。 - 3. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**をクリックします。 - 4. ファイル `lambda_function.yaml` を選択します。 - 5. スタック名を入力します。例えば、`cfn-workshop-lambda-stack` と入力し、**次へ**をクリックします。 - 6. **スタックオプションの設定**ページはデフォルト値のまま、**次へ**をクリックします。 - 7. スタックの**レビュー**ページで、一番下までスクロールし、次の例に示すように IAM Capabilities チェックボックスを選択します。 - ![Acknowledge IAM Capability](/static/intermediate/templates/dynamic-references/iam-capability.ja.png) - 8. **送信**を選択します。スタックのステータスが `CREATE_COMPLETE` になるまでページを更新します。 - - 先ほど使用したテンプレートでは、データベース接続パラメーターはスタックの実行時に動的文字列を使用して取得されます。`RDS_HOSTNAME` などの特定のキーの値を、`'{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_HOSTNAME}}'` で取得しました。なお、`DatabaseConnParams` はシークレット ID を示しています。 - - ::alert[AWS Secrets Manager のシークレットには、暗号化されたシークレット値のコピーを保持する [*versions*](https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/getting-started.html#term_version) があります。シークレットの値を変更すると、Secrets Manager は新しいバージョンを作成します。シークレットには常に、現在のシークレット値であるステージングラベル `AWSCURRENT` のバージョンがあります。必要に応じて、*バージョンステージ*または*バージョン ID* を指定して、この文字列を次のように変更できます: `'{{resolve:secretsmanager:prod-DatabaseConnParams:SecretString:RDS_HOSTNAME::}}'`。バージョンを指定しない場合、CloudFormation はステージ `AWSCURRENT` に関連するシークレットをデフォルトで解決します。]{type="info"} - -5. 作成したサンプルの Lambda 関数を呼び出すと、関数は `RDS_HOSTNAME` と `RDS_PORT` 環境変数をフェッチし、それらの値を出力します。まず、CloudFormation コンソールの**リソース** タブに移動し、Lambda 関数名を見つけます。Lambda 関数の物理 ID を探し、その値を書き留めます。次に、次のコマンドを使用し、データベース接続パラメーターを Lambda 関数に渡していることを確認します (`YOUR_FUNCTION_NAME` を Lambda 関数名に、`YOUR_REGION` を必要な値に置き換えてください)。 + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **Cloud9 ターミナル** で `code/workspace/dynamic-references` ディレクトリに移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/dynamic-references + ::: + 1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。`DBUsername` パラメータと `DBPassword` パラメータの値を入力します。 :::code{language=shell showLineNumbers=false showCopyAction=true} - aws lambda invoke \ - --function-name YOUR_FUNCTION_NAME \ - --region YOUR_REGION \ - output.json + aws cloudformation create-stack \ +--stack-name cfn-workshop-dynamic-references-database \ +--template-body file://database.yaml \ +--parameters ParameterKey=DBUsername,ParameterValue='admin' \ +ParameterKey=DBPassword,ParameterValue='wjznf74irj831o9' + ::: + 1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-dynamic-references-database/5b6b44f0-e750-11ed-af8c-12a600715c03" + ::: + 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。最新のスタックステータスを確認するには、定期的に更新を選択する必要があります。 + :::: + ::::tab{id="local" label="ローカル開発"} + 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移し、 **新しいリソースを使用 (標準)** を選択します。 + 1. **テンプレートの準備** セクションで、 **テンプレートの準備完了** を選択します。 + 1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 + 1. ファイル `database.yaml` を選択します。 + 1. スタック名を入力します。例えば、`cfn-workshop-database-stack` と入力します。 + 1. `DBUserName` には、DB インスタンスのプライマリユーザー名を指定します。 + 1. `DBPassword` には、プライマリユーザーのパスワードを指定します。 + :::alert{type="info"} + 入力したユーザー名またはパスワードが無効な場合は、テンプレートのパラメーターの詳細を確認してください。 ::: + 1. **スタックオプションの設定** ページはデフォルト値のまま、 **次へ** をクリックします。 + 1. スタックの **レビュー <スタック名>** ページで、一番下までスクロールして、 **送信** をクリックします。 + 1. スタックの `CREATE_COMPLETE` ステータスが表示されるまでページを更新してください。 + :::: + ::::: - 次のコマンドを使用して、上記コマンドの出力を表示します。 +1. 次に、AWS Lambda 関数を作成し、以前に作成した Secrets Manager シークレットへの動的参照を使用して、いくつかのデータベース接続パラメータを[環境変数](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/configuration-envvars.html)として Lambda 関数に読み取ります。 + 1. `code/workspace/dynamic-references` ディレクトリにいることを確認します。 + 1. お好みのテキストエディタで `lambda-function.yaml` CloudFormation テンプレートを開きます。 + 1. テンプレートには `AWS::Lambda::Function` リソースタイプが記述されています。`Properties` セクションに `Environment` プロパティを追加し、先ほど作成した AWS Secret Manager シークレットへの動的参照を使用する変数を追加してテンプレートを更新します。 + :::code{language=yaml showLineNumbers=false showCopyAction=true} + Environment: + Variables: + RDS_HOSTNAME: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_HOSTNAME}}' + RDS_PORT: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_PORT}}' + ::: +1. Lambda スタックをデプロイするには、以下の手順に従います。 + :::::tabs{variant="container"} + ::::tab{id="cloud9" label="Cloud9"} + 1. **Cloud9 ターミナル** で `code/workspace/dynamic-references` ディレクトリに移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/dynamic-references + ::: + 1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` と `--capabilities` はあらかじめ入力されています。 :::code{language=shell showLineNumbers=false showCopyAction=true} - cat output.json - "Database: db.us-east-1.rds.amazonaws.com:3306" + aws cloudformation create-stack \ +--stack-name cfn-workshop-dynamic-references-lambda \ +--template-body file://lambda-function.yaml \ +--capabilities CAPABILITY_IAM + ::: + 1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-dynamic-references-lambda/7e465860-e751-11ed-aa31-0a674dce3c49" ::: + 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。最新のスタックステータスを確認するには、定期的に更新を選択する必要があります。 + :::: + ::::tab{id="local" label="ローカル開発"} + 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動し **新しいリソースを使用 (標準)** を選択します。 + 1. **テンプレートの準備** セクションで、 **テンプレートの準備完了** を選択します。 + 1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** をクリックします。 + 1. ファイル `lambda_function.yaml` を選択します。 + 1. スタック名を入力します。例えば、`cfn-workshop-lambda-stack` と入力し、 **次へ** をクリックします。 + 1. **スタックオプションの設定** ページはデフォルト値のまま、 **次へ** をクリックします。 + 1. **レビュー <スタック名>** ページで、一番下までスクロールし、 **AWS CloudFormation が IAM リソースを作成する可能性があることを認識しています** チェックボックスをチェックし、 **送信** をクリックします。 + 1. スタックのステータスが `CREATE_COMPLETE` になるまでページを更新します。 + :::: + ::::: + +先ほど使用したテンプレートでは、データベース接続パラメーターはスタックの実行時に動的文字列を使用して取得されます。`RDS_HOSTNAME` などの特定のキーの値を、`'{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_HOSTNAME}}'` で取得しました。なお、`DatabaseConnParams` はシークレット ID を示しています。 + +::alert[AWS Secrets Manager のシークレットには、暗号化されたシークレット値のコピーを保持する [*versions*](https://docs.aws.amazon.com/ja_jp/secretsmanager/latest/userguide/getting-started.html#term_version) があります。シークレットの値を変更すると、Secrets Manager は新しいバージョンを作成します。シークレットには常に、現在のシークレット値であるステージングラベル `AWSCURRENT` のバージョンがあります。必要に応じて、*バージョンステージ*または*バージョン  ID* を指定して、この文字列を次のように変更できます: `'{{resolve:secretsmanager:prod-DatabaseConnParams:SecretString:RDS_HOSTNAME::}}'`。バージョンを指定しない場合、CloudFormation はステージ `AWSCURRENT` に関連するシークレットをデフォルトで解決します。]{type="info"} + +5. 作成したサンプルの Lambda 関数を呼び出すと、関数は `RDS_HOSTNAME` と `RDS_PORT` 環境変数をフェッチし、それらの値を出力します。まず、CloudFormation コンソールの _リソース_ タブに移動し、Lambda 関数名を見つけます。Lambda 関数の物理 ID を探し、その値を書き留めます。次に、次のコマンドを使用し、データベース接続パラメーターを Lambda 関数に渡していることを確認します (`YOUR_FUNCTION_NAME` を Lambda 関数名に、`YOUR_REGION` を必要な値に置き換えてください)。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws lambda invoke \ + --function-name YOUR_FUNCTION_NAME \ + --region YOUR_REGION \ + output.json +::: + +次のコマンドを使用して、上記コマンドの出力を表示します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cat output.json +::: + +output.json の内容が出力されます。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"Database: cfn-workshop-dynamic-references-database-database-rrxa105iggu0.csxwxntvtkdn.us-east-1.rds.amazonaws.com:3306" +::: おめでとうございます! AWS Secrets Manager で動的参照を使用する方法を学びました。 ### チャレンジ - この演習では、*動的参照*についての理解を深めます。 -AWS Lambda では、`MemorySize` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-memorysize)で、[関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)のメモリ構成をサポートします。ここでのタスクは、AWS CLI でParamater Store パラメータを作成することです。ここで、`Lambda_memory_size.yaml` テンプレートに記述する Lambda 関数に使用するメモリサイズを設定します。次に、作成したパラメーターのバージョン `1` への動的参照を作成し、テンプレートを使用してスタックを作成してビルドした内容が機能することを確認します。`cfn-workshop-lambda-memory-size-stack` スタックを呼び出します。Parameter Store パラメータは、スタックの作成時に選択したものと同じ AWS リージョンに作成します。 +AWS Lambda では、`MemorySize` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-memorysize)で、[関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)のメモリ構成をサポートします。ここでのタスクは、AWS CLI で Paramater Store パラメータを作成することです。ここで、`Lambda_memory_size.yaml` テンプレートに記述する Lambda 関数に使用するメモリサイズを設定します。次に、作成したパラメーターのバージョン `1` への動的参照を作成し、テンプレートを使用してスタックを作成してビルドした内容が機能することを確認します。`cfn-workshop-dynamic-references-lambda-memory` スタックを呼び出します。Parameter Store パラメータは、スタックの作成時に選択したものと同じ AWS リージョンに作成します。 :::expand{header= "ヒントが必要ですか?"} -* CloudFormation [ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-memorysize) を参照し、Lambda 関数の `MemorySize` 設定を指定する方法を理解してください。 -* 特定のバージョンの Parameter Store パラメータへの動的参照文字列を作成する方法については、CloudFormation [ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-ssm-pattern)をご参照ください。 +1. CloudFormation [ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-memorysize) を参照し、Lambda 関数の `MemorySize` 設定を指定する方法を理解してください。 +1. 特定のバージョンの Parameter Store パラメータへの動的参照文字列を作成する方法については、CloudFormation [ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-ssm-pattern)をご参照ください。 ::: ::::expand{header="解決策を確認しますか?"} -* 以下のコマンドを使用して、必要なメモリ設定を指定する Parameter Store パラメータを作成します (この例では `us-east-1` リージョンを使用しています。この値を適宜更新してください)。 - -:::code{language=yaml showLineNumbers=false showCopyAction=true} +1. 以下のコマンドを使用して、必要なメモリ設定を指定する Parameter Store パラメータを作成します (`YOUR_REGION`を必要な値に置き換えてください)。 +:::code{language=shell showLineNumbers=false showCopyAction=true} aws ssm put-parameter \ - --name "/lambda/memory-size" \ - --value "256" \ - --type "String" \ - --region YOUR_REGION +--name "/lambda/memory-size" \ +--value "256" \ +--type "String" \ +--region YOUR_REGION ::: - -* お好みのテキストエディタで `code/workspace/dynamic-references/lambda-memory-size.yaml` テンプレートを開きます。パラメータへの動的参照を使用して `MemorySize` プロパティを含む以下の例を `Resources` セクションに追加して、テンプレートを更新します。 -```yaml +1. お好みのテキストエディタで `code/workspace/dynamic-references/lambda-memory-size.yaml` テンプレートを開きます。パラメータへの動的参照を使用して `MemorySize` プロパティを含む以下の例を `Resources` セクションに追加して、テンプレートを更新します。 +:::code{language=yaml showLineNumbers=false showCopyAction=true} HelloWorldFunction: Type: AWS::Lambda::Function Properties: Role: !GetAtt FunctionExecutionRole.Arn Handler: index.handler - Runtime: python3.7 + Runtime: python3.9 MemorySize: '{{resolve:ssm:/lambda/memory-size:1}}' Code: ZipFile: | import os def handler(event, context): return "Hello World!" -``` - -テンプレートで説明および更新したリソースをプロビジョニングするには、`cfn-workshop-lambda-memory-size-stack` CloudFormation スタックを作成します。 +::: +1. 以前の Lambda 関数と同様に、`cfn-workshop-dynamic-references-lambda-memory` CloudFormation スタックを作成して、テンプレートに記述して更新したリソースをプロビジョニングします。 +1. [AWS コマンドラインインターフェイス](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/gettingstarted-awscli.html)(CLI) を実行して、MemorySize の SSM パラメータ値を使用して Lambda 関数が作成されたことを確認します。`--query` パラメータはすでに入力されています (`YOUR_REGION` を必要な値に置き換えてください)。 +:::code{language=yaml showLineNumbers=false showCopyAction=true} +aws lambda list-functions --query 'Functions[*].[FunctionName,MemorySize,Environment]' --region YOUR_REGION +::: +1. 成功すると、`aws lambda list-functions` には少なくとも 2 つの関数の詳細が表示されるはずです。1 つは RDS 環境変数を使用して作成したもので、もう 1 つは `MemorySize` を 256 に設定したものです。 +:::code{language=json showLineNumbers=false showCopyAction=false} +[ + [ + "cfn-workshop-dynamic-references-HelloWorldFunction-xhsdJOc49hhX", + 256, + null + ], + [ + "cfn-workshop-dynamic-references-l-DatabaseFunction-XO1tBoIQL3xT", + 128, + { + "Variables": { + "RDS_HOSTNAME": "cfn-workshop-dynamic-references-database-database-eyffmthgvwih.csxwxntvtkdn.us-east-1.rds.amazonaws.com", + "RDS_PORT": "3306" + } + } + ] +] +::: 解決策は、`code/solutions/dynamic-references/lambda-memory-size.yaml` サンプルテンプレートにあります。 :::: ### クリーンアップ -1. `cfn-workshop-lambda-stack` と `cfn-workshop-lambda-memory-size-stack` で作成した Lambda 関数に関連付けられた CloudWatch ロググループを削除します (チャレンジセクションの Lambda 関数を呼び出した場合は、関連するロググループが存在しているはずです)。スタックごとに、CloudFormation コンソールの**リソース**タブに移動して Lambda 関数名を検索し、Lambda 関数の物理 ID を探して、その値を書き留めます。次に、作成した各 Lambda 関数に対して以下のコマンドを使用します (`YOUR_FUNCTION_NAME` を Lambda 関数名に置き換え、`YOUR_REGION` を必要な値に置き換えてください)。 - :::code{language=shell showLineNumbers=false showCopyAction=true} - aws logs delete-log-group \ - --log-group-name /aws/lambda/YOUR_FUNCTION_NAME \ - --region YOUR_REGION - ::: -2. 次のコマンドを使用して、AMI ID と `MemorySize` 設定を保存するために作成した 2 つの Parameter Store パラメータを削除します (`YOUR_REGION` は必要な値に置き換えてください)。 - :::code{language=shell showLineNumbers=false showCopyAction=true} - aws ssm delete-parameters \ - --names "/golden-images/amazon-linux-2" "/lambda/memory-size" \ - --region YOUR_REGION - ::: -3. 次に、CloudFormation コンソールで、最後に作成したスタック (例: `cfn-workshop-lambda-memory-size-stack`) を選択します。 -4. **削除**を選択した後、**スタックの削除**をクリックして確定します。 -5. このラボで作成した他のスタックについても上記の手順を繰り返します。具体的には、`cfn-workshop-lambda-stack`、`cfn-workshop-database-stack`、`cfn-workshop-ec2-stack` スタックです。 +1. `cfn-workshop-dynamic-references-lambda` と `cfn-workshop-dynamic-references-lambda-memory` で作成した Lambda 関数に関連付けられた CloudWatch ロググループを削除します (チャレンジセクションの Lambda 関数を呼び出した場合は、関連するロググループが存在しているはずです)。 + + スタックごとに、CloudFormation コンソールの **リソース** タブに移動して Lambda 関数名を検索し、Lambda 関数の物理 ID を探して、その値を書き留めます。次に、作成した各 Lambda 関数に対して以下のコマンドを使用します (`YOUR_FUNCTION_NAME` を Lambda 関数名に置き換え、`YOUR_REGION` を必要な値に置き換えてください)。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws logs delete-log-group \ +--log-group-name /aws/lambda/YOUR_FUNCTION_NAME \ +--region YOUR_REGION +::: +1. 次のコマンドを使用して、AMI ID と `MemorySize` 設定を保存するために作成した 2 つの Parameter Store パラメータを削除します (`YOUR_REGION` は必要な値に置き換えてください)。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws ssm delete-parameters \ +--names "/golden-images/amazon-linux-2" "/lambda/memory-size" \ +--region YOUR_REGION +::: +1. 次に、CloudFormation コンソールで、最後に作成したスタック (例: `cfn-workshop-dynamic-references-lambda-memory`) を選択します。 +1. **削除** を選択した後、 **スタックの削除** をクリックして確定します。 +1. このラボで作成した他のスタックについても上記の手順を繰り返します。具体的には、`cfn-workshop-dynamic-references-lambda`、`cfn-workshop-dynamic-references-database`、`cfn-workshop-dynamic-references-ec2` スタックです。 --- ### まとめ diff --git a/content/intermediate/templates/language-extensions/index.ja.md b/content/intermediate/templates/language-extensions/index.ja.md index 349c6b944..4c356120b 100644 --- a/content/intermediate/templates/language-extensions/index.ja.md +++ b/content/intermediate/templates/language-extensions/index.ja.md @@ -1,67 +1,65 @@ --- -title: "Language extensions" +title: "言語拡張" weight: 640 --- -::alert[日本語翻訳準備中]{type="info"} - -_Lab Duration: ~30 minutes_ +_ラボ実施時間 : 30分程度_ --- -### Overview - -With the goal of extending the AWS CloudFormation language, the CloudFormation team has been having open discussions with the CloudFormation community, by using an [RFC mechanism](https://github.com/aws-cloudformation/cfn-language-discussion). These discussions have led to the launch of new language extensions for CloudFormation. A language extension is a transform, which is a macro hosted by CloudFormation. In its first release in 2022, three new language extensions were added: +### 概要 -1. JSON string conversion ([Fn::ToJsonString](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ToJsonString.html)): converts an object or array to its corresponding JSON string. -2. Length ([Fn::Length](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-length.html)): returns the number of elements within an array. -3. [Intrinsic functions and pseudo-parameter references](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/function-refs-in-policy-attributes.html): allow the user to define the `DeletionPolicy` and `UpdateReplacePolicy` [resource attributes](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-product-attribute-reference.html) whose values can be referenced by parameters, for example. +AWS CloudFormation 言語を拡張することを目指して、CloudFormation チームは [RFC](https://github.com/aws-cloudformation/cfn-language-discussion) を通じてして CloudFormation コミュニティとオープンな議論を交わしてきました。これらの議論の結果、CloudFormation のための新しい言語拡張がリリースされました。リリースされた新しい言語拡張は変換機能で CloudFormation によって実行されるマクロです。2022 年の初期リリースでは、3 つの新しい言語拡張が追加されました。 +1. JSON 文字列変換([Fn::ToJsonString](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ToJsonString.html)): オブジェクトまたは配列を対応する JSON 文字列に変化します。 +2. Length([Fn::Length](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-length.html)): 配列内の要素数を返却します。 +3. [組み込み関数と擬似パラメータのリファレンス](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/function-refs-in-policy-attributes.html): ユーザが定義した `DeletionPolicy` と `UpdateReplacePolicy` [リソース属性](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-product-attribute-reference.html) の値をパラメータなどから取得できるようにします。 -For more information, see [Introducing new language extensions in AWS CloudFormation](https://aws.amazon.com/blogs/mt/introducing-new-language-extensions-in-aws-cloudformation/). -In this lab, you'll explore and learn how you can leverage these language extensions to augment your developer experience. +詳細については、[Introducing new language extensions in AWS CloudFormation](https://aws.amazon.com/blogs/mt/introducing-new-language-extensions-in-aws-cloudformation/) をご参照ください。 +このラボでは、 これらの言語拡張を活用してどのように開発者体験を向上させるのかを探り、学習します。 -### Topics Covered -By the end of this lab, you'll be able to: +### 取り上げるトピック -* Understand how to incorporate the `AWS::LanguageExtensions` transform in your CloudFormation templates. -* Use language extensions in your CloudFormation template. +このラボを修了すると、次のことができるようになります。 -### Start Lab +* `AWS::LanguageExtensions` トランスフォームを CloudFormation テンプレートに組み込む方法の理解 +* CloudFormation テンプレートでの言語拡張の使用 -### Prerequisites +### ラボを開始 -You can use the default VPC that comes with your AWS account. +### 事前準備 +AWS アカウントに付属するデフォルト VPC を使用できる状態にあります。 -### Part 1 -In part 1 of this lab, you'll use an example CloudFormation template, `language-extensions.yaml`, to create a stack in the `us-east-1` region. To get started, follow steps shown next: +### ラボパート 1 -1. Navigate to `code/workspace/language-extensions` directory. -1. Open the `language-extensions.yaml` CloudFormation template in your own text editor. -1. Familiarize with the configuration of resources in the template. This template creates an [Amazon Elastic Compute Cloud (Amazon EC2)](https://aws.amazon.com/ec2/) instance tagged as a `DEV` environment resource. Note that, up to this point, the template does not specify a `DeletionPolicy` [attribute](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html) for the EC2 instance. +このラボのパート 1 では、サンプルの CloudFormation テンプレート `language-extentions.yaml` を使用して、`us-east-1` リージョンにスタックを作成します。開始するには、以下に示すステップに進んでください。 -By default, CloudFormation uses `Delete` as the default value for the `DeletionPolicy` attribute for resources; exceptions to this are `AWS::RDS::DBCluster` resources, and `AWS::RDS::DBInstance` resources that don't specify the `DBClusterIdentifier` property. If you use the template above for the creation of a stack, upon deletion of the stack itself the EC2 instance will be terminated. One of the common use cases is to retain the resources that are created in production, whilst having the flexibility to discard and recreate test resources, as needed, for development activities: with the `AWS::LanguageExtensions` transform in your template, you can reference the `DeletionPolicy` value you need from a parameter. The language extension you'll use adds the functionality of referencing a value for resource attributes like `DeletionPolicy` and `UpdateReplacePolicy` that natively accept a string value and not a parameter reference. +1. `code/workspace/language-extensions` のディレクトリに移動します。 +2. ご自身のエディターで `language-extensions.yaml` の CloudFormation テンプレートを開きます。 +3. テンプレート内のリソースの設定を確認します。このテンプレートは `Dev` 環境リソースとしてタグづけされた [Amazon Elastic Compute Cloud (Amazon EC2)](https://aws.amazon.com/ec2/) インスタンスを作成します。この時点のテンプレートでは EC2 インスタンスの `DeletionPolicy` [属性](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-deletionpolicy.html) が指定されていないことに注目してください。 -In this example, your intent is to specify `DeletionPolicy` as `Delete` for your instance in the `DEV` environment; follow steps shown next: +デフォルトでは、CloudFormation はリソースの `DeletionPolicy` 属性のデフォルト値として `Delete` を使用します。ただし、 `AWS::RDS::DBCluster` リソースと、`DBClusterIdentifier` プロパティを指定しない `AWS::RDS::DBInstance` リソースは例外です。上記のテンプレートを使用してスタックを作成した場合、スタック自体を削除すると EC2 インスタンスは終了します。一般的な使用例の 1 つは、本番環境で作成されたリソースを保持しながら、必要に応じてテストリソースを柔軟に破棄して開発アクティビティ用に再作成することです。テンプレートの `AWS::LanguageExtensions` トランスフォームを使用すると、必要な `DeletionPolicy` の値をパラメータから参照できます。`DeletionPolicy` や `UpdateReplacePolicy` のようなリソース属性は通常は文字列の指定が必要ですが、言語拡張を使用すると値をパラメータから参照する機能が追加されます。 +この例では、`DEV` 環境のインスタンスの `DeletionPolicy` を `Delete` として指定することを意図しています。次の手順に進んでください。 -1. Open the `language-extensions.yaml` template. Add the `AWS::LanguageExtensions` transform line by copying and pasting the content below _underneath_ the `AWSTemplateFormatVersion: "2010-09-09"` line: +1. `code/workspace/language-extensions` ディレクトリに移動します。 +1. `language-extensions.yaml` テンプレートを開きます。`AWS::LanguageExtensions` のトランスフォーマ行を追加するには、`AWSTemlateFormatVersion: "2010-09-09"` の行の下に、以下のコンテンツをコピーして貼り付けます。 :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=3} Transform: AWS::LanguageExtensions ::: -1. Add a parameter, called for example `DeletionPolicyParameter`, by copying and pasting the content below _underneath_ the existing `Parameters` section: +1. 既存の `Parameters` セクションの配下に、例えば `DeletionPolicyParameter` という名前のパラメータを次のコードのように追加します。 :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=13} DeletionPolicyParameter: Type: String AllowedValues: [Delete, Retain] Default: Delete ::: -1. Underneath the `Resources` section, modify the EC2 instance resource configuration: add `DeletionPolicy` at the same level as `Type`, and reference the `DeletionPolicyParameter` you added earlier, as shown next: +1. `Resource` セクションの配下にある EC2 インスタンスのリソース設定を変更します。`Type` プロパティと同じレベルに `DeletionPolicy` を追加し、先ほど設定した `DeletionPolicyParameter` を参照させます。 :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=18 highlightLines=20} Resources: EC2Instance: @@ -75,48 +73,48 @@ Resources: Value: DEV ::: -Save the template file, and proceed to the next steps. +テンプレートファイルを保存し、次の手順に進みます。 -You'll now create a new stack, using the template you modified, in the `us-east-1` region. +次に、変更したテンプレートを使用して `us-east-1` リージョンに新しいスタックを作成します。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -1. Let's create a stack by running the following AWS CLI command. +1. 次の AWS CLI コマンドを実行してスタックを作成します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ --stack-name cfn-workshop-language-extensions \ --template-body file://language-extensions.yaml \ --capabilities CAPABILITY_AUTO_EXPAND -1. CloudFormation returns the following output. +1. CloudFormation は次のアウトプットを返却します。 :::code{language=json showLineNumbers=false showCopyAction=false} "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-language-extensions/466df9e0-0dff-08e3-8e2f-5088487c4896" ::: -1. Wait until the `CREATE` operation is complete, by using the [wait stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) AWS CLI command. +1. [wait stack-create-complete] (https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) AWS CLI コマンドを使用して、`CREATE` 操作が完了するまでお待ちください。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation wait stack-create-complete \ --stack-name cfn-workshop-language-extensions ::: :::: -::::tab{id="local" label="Local development"} -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. From the left navigation panel, select the **Stacks** tab. From the right side of the page, choose **Create Stack**, and then choose **With new resources (standard).** -1. From **Prerequisite**-**Prepare template**, choose **Template is ready**. -1. Under **Specify template**, select **Template source**, and choose **Upload a template file**. Select **Choose file**, and supply the `language-extensions.yaml` template you updated earlier, and then choose **Next**. -1. In the **Specify Stack details** page: - 1. Specify a **Stack** name. For example, choose `cfn-workshop-language-extensions`. - 1. Under **Parameters**, choose to accept the value for `DeletionPolicyParameter` as `Delete`, which is set as the default value in the template; keep the value for `LatestAmiId` as it is. Choose **Next**. -1. On **Configure Stack options**, leave the configuration as it is. Choose **Next**. -1. On the **Review** page, review the contents of the page. At the bottom of the page, choose to acknowledge all the capabilities shown in the **Capabilities and transforms** section. Choose **Submit**. -1. Refresh the stack creation page until you see the stack to be in the `CREATE_COMPLETE` status. +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール] (https://console.aws.amazon.com/cloudformation/) に移動します。 +1. 左側のナビゲーションパネルから **スタック** を選択します。ページの右側から **スタックの作成** を選択し、**新しいリソースを使用 (標準)** を選択します。 +1. **前提条件 - テンプレートの準備** から **テンプレートの準備完了** を選択します。 +1. **テンプレートの指定** セクションで、**テンプレートソース** で **テンプレートファイルのアップロード** を選択します。**ファイルの選択** を選択し、更新した `language-extentions.yaml` テンプレートを指定して、**次へ** を選択します。 +1. **スタック詳細を指定** のページで + 1. **スタック名** を指定します。例えば `cfn-workshop-language-extensions` を入力します。 + 1. **パラメータ** で、テンプレートのデフォルト値として設定されている `DeletionPolicyParameter` の値に `Delete` を選択し、`LatestAmiId` の値をそのままにしておきます。**次へ** を選択します。 +1. **スタックオプションの設定** では、設定をそのままにしておきます。**次へ** を選択します。 +1. **レビュー** ページで、設定内容を確認します。ページの下部に **機能と変換** セクションに表示されている機能をすべて承認するように選択してください。**送信** を選択します。 +1. スタックが `CREATE_COMPLETE` ステータスになるまで、スタック作成ページを更新します。 :::: ::::: -Congratulations! You have learned how to use intrinsic function references for the `DeletionPolicy` attribute; you can also use them with the `UpdateReplacePolicy` attribute as well. In the next part, you'll learn how to use another language extension: `Fn::ToJsonString`. +おめでとうございます!これで `DeletionPolicy` 属性用の組み込み関数リファレンスを使用する方法を学びました。`UpdateReplacePolicy` 属性と一緒に使用することもできます。次のパートでは、`Fn::ToJsonString` という別の言語拡張の使い方を学びます。 -### Part 2 +### ラボパート 2 -Now that you have your EC2 instance running, you choose to monitor it by creating an [Amazon CloudWatch dashboard](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Dashboards.html) that provides customized views of the metrics and alarms for your AWS resources. You can add metrics such as `CPUUtilization`, `DiskReadOps`, etc. to a dashboard as a [widget](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/create-and-work-with-widgets.html). +EC2 インスタンスを実行できたので、AWS リソースのメトリクスとアラームをカスタマイズして表示する [Amazon CloudWatch ダッシュボード](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/CloudWatch_Dashboards.html) を作成してモニタリングすることとします。`CPUUtilization` や `DiskReadOps` などのメトリクスを [ウィジェット](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/monitoring/create-and-work-with-widgets.html) としてダッシュボードに追加できます。 -A dashboard body is a string in JSON format: for more information, see [Dashboard Body Structure and Syntax](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/CloudWatch-Dashboard-Body-Structure.html). When you describe a CloudWatch dashboard with CloudFormation, you specify a JSON string that contains keys and values, such as: +ダッシュボード本文は JSON 形式の文字列です。詳細については、[ダッシュボード本体の構造と構文](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/APIReference/CloudWatch-Dashboard-Body-Structure.html)を参照してください。CloudFormation を使用して CloudWatch ダッシュボードを記述する時は、次のようなキーとバリューを含む JSON 文字列を指定します。 :::code{language=json showLineNumbers=true showCopyAction=false} { @@ -127,17 +125,17 @@ A dashboard body is a string in JSON format: for more information, see [Dashboar ::: -To make it easier to write and consume a dashboard (for example, to avoid escaping inner quotes like `\"`), and to avoid maintaining a single-line string you can use the `Fn::ToJsonString` language extension to specify a JSON object, which is easier to compose and to maintain. With this language extension, you can specify the structure of a CloudWatch dashboard as a JSON object instead, thus simplifying the task. +ダッシュボード作成と利用をより簡単にするため (例えば、`\"` のような内部引用符のエスケープを避けるため)、また一行の文字列を保持しないようにするには、`Fn::ToJsonString` 言語拡張を使用して JSON オブジェクトを指定できます。これにより作成と管理が容易になります。この言語拡張機能を使用すると、代わりに CloudWatch ダッシュボードの構造を JSON オブジェクトとして指定できるためタスクが簡単になります。 -`Fn::ToJsonString` allows developers to convert a template block in the form of an object or array into an escaped JSON string. You can then use a newly-converted JSON string as a set of input values to string-type properties for resources that include the CloudWatch dashboard resource type. This simplifies the code in your template, and enhances its readability. +`Fn::ToJsonString` を使用すると、開発者はオブジェクトまたは配列形式のテンプレートブロックをエスケープされた JSON 文字列に変換できます。その後、新たに変換された JSON 文字列を CloudWatch ダッシュボードリソースタイプを含むリソースの文字列型プロパティへの入力値として使用できます。これにより、テンプレート内のコードが簡略化され、読みやすくなります。 -In this part 2 of the lab, you'll update the `language-extensions` stack you created earlier, and add a CloudWatch dashboard with the `CPUUtilization` metric for your EC2 instance. +ラボのこのパート 2 では、前に作成した `language-extensions` スタックを更新し、 EC2 インスタンスの `CPUUtilization` メトリクスを含む CloudWatch ダッシュボードを追加します。 -For simplicity, in this exercise you'll add the dashboard to your existing template, so you can focus on the language extension you'll use. Normally, you would create a separate template for your dashboards, for considerations on best practices that also include organizing your stacks by [lifecycle and ownership](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/best-practices.html#organizingstacks): you would want to, for example, create a separate template to decouple the lifecycle of your CloudWatch dashboard from the lifecycle of your EC2 instance. +作業をシンプルにするため、この演習ではダッシュボードを既存のテンプレートに追加して、使用する言語拡張機能に焦点を当てれるようにします。通常、[ライフサイクルと所有権](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/best-practices.html#organizingstacks)によるスタックの整理を含むベストプラクティスを考慮して、ダッシュボード用に別のテンプレートを作成します。例えば、CloudWatch ダッシュボードのライフサイクルを EC2 インスタンスのライフサイクルから切り離すために、別のテンプレートを作成したいと考えることがあると思います。 -You'll now update the `language-extensions.yaml` template to add a CloudWatch dashboard with CPU utilization data of the EC2 instance you created in part 1. To do so, follow steps shown next: +`language-extensions.yaml` テンプレートを更新して、パート 1 で作成した EC2 インスタンスの CPU 使用率データを含む CloudWatch ダッシュボードを追加します。そのためには以下のステップに沿って実施します。 -1. Open the `language-extensions.yaml` template. Underneath `Resources` section, add `Dashboard`: +1. `language-extensions.yaml` テンプレートを開きます。`Resources` セクション配下に `Dashboard` を追加します。 :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=29} Dashboard: @@ -161,128 +159,128 @@ Dashboard: title: EC2 Instance CPU ::: -In the above snippet, note that the `CPUUtilization` metric is reflected underneath the `properties` section through the `metrics` field. Note also the references to your EC2 instance with `!Ref`, that in this case will return the instance ID, and the reference to the current region with `!Ref AWS::Region`, where you'll use the `AWS::Region` CloudFormation pseudo parameter to resolve the name of the region where you are creating the stack and the EC2 instance (in this lab, `us-east-1`). +上記のスニペットでは、`CPUUtilization` メトリックが `properties` セクション配下に `metrics` フィールドを介して反映されていることを注目してください。EC2 インスタンスの参照のための `!Ref` を利用し、インスタンス ID を取得しています。また、現在のリージョンを参照するには `!Ref AWS::Region` を使用しています。`AWS::Region` CloudFormation 擬似パラメータを使用して、スタックと EC2 インスタンスを作成するリージョンの名前で取得します。(このラボでは `us-east-1`) -Save the template file, and proceed to the next steps. +テンプレートファイルを保存し、次の手順に進みます。 -You'll now update your existing stack that you created in Part 1. To do so, follow steps shown next: +パート 1 で作成した既存のスタックを更新します。そのためには、以下に示す手順を実施します。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -1. Update the stack `cfn-workshop-language-extensions` by running the following AWS CLI command. +1. 次の AWS CLI コマンドを実行して、スタック `cfn-workshop-language-extensions` を更新します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation update-stack \ --stack-name cfn-workshop-language-extensions \ --template-body file://language-extensions.yaml \ --capabilities CAPABILITY_AUTO_EXPAND -1. CloudFormation returns the following output. +1. CloudFormation は次の出力を返却します。 :::code{language=json showLineNumbers=false showCopyAction=false} "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-language-extensions/466df9e0-0dff-08e3-8e2f-5088487c4896" ::: -1. Wait until the `UPDATE` operation is complete, by using the [wait stack-update-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-update-complete.html) AWS CLI command. +1. [wait stack-update-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-update-complete.html) AWS CLI コマンドを使用して `UPDATE` 操作が完了するまで待ちます。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation wait stack-update-complete \ --stack-name cfn-workshop-language-extensions ::: :::: -::::tab{id="local" label="Local development"} -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. From the left navigation panel, select the **Stacks** tab. Select the `cfn-workshop-language-extensions` stack you created earlier. -1. From the top-right menu, choose **Update**. -1. Under **Prerequisite - Prepare template,** select **Replace current template** and choose **Upload a template file**. Select **Choose file**, and supply the `language-extensions.yaml` template you updated earlier, and then choose **Next**. -1. On **Specify Stack details** page, leave the configuration as it is. Choose **Next**. -1. On **Configure Stack options**, leave the configuration as it is. Choose **Next**. -1. On **Review** page, review the contents of the page. At the bottom of the page, choose to acknowledge all the capabilities shown in the **Capabilities and transforms** section. -1. Choose **Submit**. Refresh the stack creation page until you see the stack in the `UPDATE_COMPLETE` status. +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +1. 左側のナビゲーションパネルから、**スタック** を選択します。前に作成した `cfn-workshop-language-extensions` スタックを選択します。 +1. 右上のメニューから **更新** を選択します。 +1. **前提条件 - テンプレートの準備**で、**既存テンプレートを置き換える** を選択し、**テンプレートファイルのアップロード**を選択します。**ファイルの選択** を選択し、更新した `language-extensions.yaml` テンプレートを指定して **次へ** を選択します。 +1. **スタックの詳細を指定** ページでは、設定をそのままにしておきます。 **次へ** を選択します。 +1. **スタックオプションの設定** では、設定をデフォルトのままにしておきます。**次へ** を選択します。 +1. **レビュー** ページで、ページの内容を確認します。ページの下部で、**機能と変換** セクションに表示されている機能をすべて承認するように選択してください。 +1. **送信** を選択します。スタックのステータスが `UPDATE_COMPLETE` になるまでスタック作成ページを更新します。 :::: ::::: -* Navigate to the [CloudWatch console](https://console.aws.amazon.com/cloudwatch/). From the right navigation panel, choose **Dashboards**. -* Select the **Dashboard** that you have created, From the top-right, choose **Actions**. -* Select **View/edit source**, you should see `JSON` for the dashboard that matches `YAML` from `language-extensions.yaml` +* [CloudWatch コンソール](https://console.aws.amazon.com/cloudwatch/)に移動します。左側のナビゲーションパネルから、**ダッシュボード** を選択します。 +* 作成した **ダッシュボード** を選択し、右上から **アクション** を選択します。 +* **ソースを表示 / 編集** を選択すると、`language-extensions.yaml` の `YAML` と同等の `JSON` がダッシュボードに表示されるはずです。 -Congratulations! You have learned how to use `Fn::ToJsonString` to transform JSON objects into escaped JSON strings as inputs to resource properties. +おめでとうございます!`Fn::ToJsonString` を使用して JSON オブジェクトをリソースプロパティへの入力としてエスケープされた JSON 文字列に変換する方法を学習しました。 -### Challenge +### チャレンジ -In this exercise, you'll use the knowledge gained from earlier parts of this lab. Your task is to create an [Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) bucket with its deletion policy set to a parameterized value of `Delete`, and create a CloudWatch dashboard that reflects the number of objects in the bucket. Use the `language-extensions-challenge.yaml` template, and add content to it. +この演習では、このラボで得た知識を使用します。あなたのタスクは、削除ポリシーを `Delete` というパラメータ値に設定した [Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) バケットを作成し、バケット内のオブジェクト数を反映する CloudWatch ダッシュボードを作成することです。`language-extensions-challenge.yaml` テンプレートを使用して、コンテンツを追加してください。 -Refer to the [CloudWatch Dashboard structure](https://docs.aws.amazon.com/AmazonCloudWatch/latest/APIReference/CloudWatch-Dashboard-Body-Structure.html) mentioned in Part 2 of the lab as you describe the dashboard in your CloudFormation template. For the `metrics` field underneath `properties`, use `[[AWS/S3, NumberOfObjects, StorageType, AllStorageTypes, BucketName, !Ref S3Bucket]]` to denote the `NumberOfObjects` metrics in an S3 bucket for your CloudWatch widget. Please note that [S3 storage metrics are reported once per day](https://docs.aws.amazon.com/AmazonS3/latest/userguide/cloudwatch-monitoring.html) at no additional cost, so you may not see them when you are running the lab. +CloudFormation テンプレートでダッシュボードを記述する時には、ラボのパート 2 で記述した [CloudWatch ダッシュボード構造](https://docs.aws.amazon.com/ja_jp/AmazonCloudWatch/latest/APIReference/CloudWatch-Dashboard-Body-Structure.html)を参照してください。`properties` 配下の `metrics` フィールドには、`[[AWS/S3, NumberOfObjects, StorageType, AllStorageTypes, BucketName, !Ref S3Bucket]]` を使用してください。[S3 ストレージメトリクスは 1 日に 1 回報告されます](https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/cloudwatch-monitoring.html)。追加料金は発生しないため、ラボを実行しているときには表示されない場合があることにご注意ください。 -:::expand{header="Need a hint?"} -* Recall using the language extension in Part 1 of the lab to use a parameter for the deletion policy. -* Don’t forget to reference the deletion policy parameter in your S3 bucket resource. -* Additionally, recall how you added a CloudWatch dashboard earlier, add use the `NumberOfObjects` metrics for the relevant field. +:::expand{header="ヒントが必要ですか?"} +* ラボのパート 1 で説明した言語拡張を使用して、削除ポリシーのパラメータを使用したことを思い返してください。 +* S3 バケットリソースの削除ポリシーパラメータを参照することを忘れないでください。 +* さらに、以前 CloudWatch ダッシュボードを追加した方法を思い出してください。関連フィールドに `NumberOfObjects` メトリクスを使用することを追加してください。 ::: -::::::expand{header="Want to see the solution?"} -* Add the `Transform: AWS::LanguageExtensions` line to the template like you did in Part 1 of the lab. -* Edit the `Parameters` section to add the `DeletionPolicyParameter` like you did in Part 1 of the lab. -* Underneath the `Resources` section for the `S3Bucket` resource, add the `DeletionPolicy` attribute with a reference to the parameter. -* Underneath the `Resources` section, add the `Dashboard` resource. -* You can find the full challenge solution in the template called `language-extensions-solution.yaml`, that is in the `code/solutions/language-extensions` directory. +::::::expand{header="解決策を確認しますか?"} +* ラボのパート 1 で行ったように、テンプレートの `Transform: AWS::LanguageExtensions` の行を追加します。 +* ラボのパート 1 で行ったように、`Parameters` セクションを編集して `DeletionPolicyParameter` を追加します。 +* `S3Bucket` リソースの `Resources` セクション配下に、パラメータへの参照を含む `DeletionPolicy` 属性を追加します。 +* `Resource` セクション配下に、`Dashboard` リソースを追加します。 +* チャレンジソリューションの全文は、`code/solutions/language-extensions` ディレクトリにある `language-extensions-solutions.yaml` というテンプレートにあります。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -1. Let's create the stack by running the following AWS CLI command. +1. 次の AWS CLI コマンドを実行してスタックを作成しましょう。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ --stack-name cfn-workshop-language-extensions-solution \ --template-body file://language-extensions-challenge.yaml \ --capabilities CAPABILITY_AUTO_EXPAND -1. CloudFormation returns the following output. +1. CloudFormation は次の出力を返却します。 :::code{language=json showLineNumbers=false showCopyAction=false} "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-language-extensions-solution/466df9e0-0dff-08e3-8e2f-5088487c4896" ::: -1. Wait until the `CREATE` operation is complete, by using the [wait stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) AWS CLI command. +1. [wait stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) AWS CLI コマンドを使用して、`CREATE` 操作が完了するまで待ちます。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation wait stack-update-complete \ --stack-name cfn-workshop-language-extensions-solution ::: :::: -::::tab{id="local" label="Local development"} -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. From the left navigation panel, select the **Stacks** tab. From the right side of the page, choose **Create Stack**, and then choose **With new resources (standard).** -1. From **Prerequisite**-**Prepare template**, choose **Template is ready**. -1. Under **Specify template**, select **Template source**, and choose **Upload a template file**. Select **Choose file**, and supply the `language-extensions-challenge.yaml` template you updated earlier, and then choose **Next**. -1. In the **Specify Stack details** page: - 1. Specify a **Stack** name. For example, choose `cfn-workshop-language-extensions-solution`. - 1. Under **Parameters**, choose to accept the value for `DeletionPolicyParameter` as `Delete`, which is set as the default value in the template, Choose **Next**. -1. On **Configure Stack options**, leave the configuration as it is. Choose **Next**. -1. On the **Review** page, review the contents of the page. At the bottom of the page, choose to acknowledge all the capabilities shown in the **Capabilities and transforms** section. Choose **Submit**. -1. Refresh the stack creation page until you see the stack to be in the `CREATE_COMPLETE` status. +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +2. 左側のナビゲーションパネルから、**スタック** を選択します。ページの右側から、**スタックの作成** を選択し、**新しいリソースを使用 (標準)** を選択します。 +3. **前提条件 - テンプレートの準備** から、**テンプレートの準備完了** を選択します。 +4. **テンプレートの指定** セクションで、**テンプレートソース** で **テンプレートファイルのアップロード** を選択します。**ファイルの選択** を選択し、先ほど更新した `language-extensions-challenge.yaml` テンプレートを指定して、**次へ** を選択します。 +5. **スタックの詳細を指定**ページで + 1. **スタック**名を指定します。例えば、`cfn-workshop-language-extensions-solution` を選択します。 + 2. **パラメータ** で、テンプレートのデフォルト値として設定されている `DeletionPolicyParameter` の値が `Delete` であることを確認し、**次へ** を選択します。 +6. **スタックオプションの設定** では、設定をそのままにしておきます。**次へ** を選択します。 +7. **レビュー** ページで、ページの内容を確認します。ページの下部で、**機能と変換** セクションに表示されている機能をすべて承認するように設定してください。**送信** を選択します。 +8. スタックが `CREATE_COMPLETE` ステータスになるまで、スタック作成ページを更新します。 :::: ::::: :::::: -### Clean up +### クリーンアップ -You'll now tear down the resources you created in this lab. Use following steps: +このラボで作成したリソースを削除します。以下の手順を実行してください。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -1. Delete the stack `cfn-workshop-language-extensions` by running the following AWS CLI command. +1. 次の AWS CLI コマンドを実行して、スタック `cfn-workshop-language-extensions` を削除します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation delete-stack \ --stack-name cfn-workshop-language-extensions ::: -1. Wait until the `DELETE` operation is complete, by using the [wait stack-delete-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-delete-complete.html) AWS CLI command. +1. [wait stack-delete-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-delete-complete.html) AWS CLI コマンドを使用して、`DELETE` 操作が完了するまで待ちます。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation wait stack-delete-complete \ --stack-name cfn-workshop-language-extensions ::: -1. Repeat steps (1-2) above to delete the stack `cfn-workshop-language-extensions-solution`. +1. 上記のステップ (1-2) を繰り返して、スタック `cfn-workshop-language-extensions-solution` を削除します。 :::: -::::tab{id="LocalDevelopment" label="Local development"} -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. On the **Stacks** page in the CloudFormation console, select the stack you created in **Part 1:** `cfn-workshop-language-extensions`. -1. In the stack details pane, choose **Delete**. Select **Delete** when prompted. -1. On the **Stacks** page in the CloudFormation console, select the stack you created in **Challenge** section: `cfn-workshop-language-extensions-solution`. -1. In the stack details pane, choose **Delete**. Select **Delete** when prompted. +::::tab{id="LocalDevelopment" label="ローカル開発"} +1. [AWS CloudFormaiton コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +1. CloudForamtion コンソールの **スタック** ページで、パート 1 で作成した `cfn-workshop-language-extensions` スタックを選択します。 +1. スタックの詳細ペインで、**削除** を選択します。プロンプトが表示されたら、**削除** を選択します。 +1. CloudFormation コンソールの **スタック** ページで、チャレンジセクションで作成した `cfn-workshop-language-extensions-solution` スタックを選択します。 +1. スタックの詳細ペインで、**削除** を選択します。プロンプトが表示されたら、**削除** を選択します。 :::: ::::: --- -### Conclusion +### まとめ -Great work! You learned how to incorporate `AWS::LanguageExtensions` in your CloudFormation templates. Please feel free to provide feedback for RFCs in the [Language Discussion GitHub repository](https://github.com/aws-cloudformation/cfn-language-discussion). We welcome your contributions! +`AWS::LanguageExtensions` を CloudFormation テンプレートに組み込む方法を学びました。 RFC に関するフィードバックは [Language Discussion GitHub repository](https://github.com/aws-cloudformation/cfn-language-discussion) にお気軽にお寄せください。皆さんのコントリビューションをお待ちしています! diff --git a/content/intermediate/templates/looping-over-collections/index.ja.md b/content/intermediate/templates/looping-over-collections/index.ja.md index af9aafb94..d206dd763 100644 --- a/content/intermediate/templates/looping-over-collections/index.ja.md +++ b/content/intermediate/templates/looping-over-collections/index.ja.md @@ -1,37 +1,35 @@ --- -title: "Looping over collections with Fn::ForEach" +title: "Fn::ForEach を使用してコレクションをループオーバする" weight: 641 --- -::alert[日本語翻訳準備中]{type="info"} - -_Lab Duration: ~45 minutes_ +_ラボ実施時間 : 45分程度_ --- -### Overview +### 概要 -When you describe infrastructure with code, there are use cases where the code you write describes resources that share the same configuration, or that contains some differences that could be managed with mechanisms like variables. As the number of such resources and relevant properties grow, the code you write grows as well, thus making it not easy to maintain over time, and prone to human errors. +インフラストラクチャをコードで記述する場合、記述するコードが同じ構成を共有するリソースや、変数などのメカニズムで管理できるいくつかの相違点を含むリソースを記述するケースがあります。このようなリソースや関連するプロパティの数が増えるにつれて、記述するコードも増えるため、長期にわたる保守が容易ではなくヒューマンエラーも発生しやすくなります。 -In the [Language extensions](../language-extensions) lab, you’ve used the `AWS::LanguageExtensions` [transform](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-languageextensions.html) to leverage a number of functions that extend the [AWS CloudFormation](https://aws.amazon.com/cloudformation/) language: such functions are the result of feedback that the CloudFormation team receives from the community via open discussions driven by an [RFC mechanism](https://github.com/aws-cloudformation/cfn-language-discussion). One of these functions is the `Fn::ForEach` [intrinsic function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-foreach.html), that you’ll learn how to use in this lab. This intrinsic function allows you to describe resources, that share the same/similar configuration, with dynamic iterations that you use to map resource configurations to loop-like structures. +[言語拡張](../language-extensions) ラボでは、`AWS::LanguageExtensions` [変換](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/transform-aws-languageextensions.html) を使用して [AWS CloudFormation](https://aws.amazon.com/cloudformation/) 言語を拡張するいくつかの関数を活用しました。このような関数は、CloudFormation チームが [RFC](https://github.com/aws-cloudformation/cfn-language-discussion) によって推進されるオープンディスカッションを通じてコミュニティから受け取ったフィードバックから生まれています。これらの関数の 1 つは、`Fn::ForEach` [組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-foreach.html)であり、このラボではその使用方法を学習します。この組み込み関数を使用すると、リソース構成をループ状の構造にマッピングするために使用する動的な反復処理を使用して、同じもしくは類似した構成を共有するリソースを記述できます。 -### Topics Covered +### 取り上げるトピック -By the end of this lab, you will be able to: +このラボを修了すると、次のことができるようになります。 -* Identify example use cases where you can simplify and reduce statically-described code, for resources that share the same/similar configuration, using `Fn::ForEach`. -* Describe, with code, the desired state of resources by using `Fn::ForEach` to loop over collections. -* Discover, for applicable use cases, how you can use `Fn::ForEach` to have fewer lines of code, thus leading to code that is easier to maintain, and less prone to human errors. +* 同じもしくは類似した設定を共有するリソースについて、`Fn::ForEach` を使用して、静的に記述されたコードを簡略化および削除できるユースケースの例を特定できるようになります。 +* `Fn::ForEach` を使用してコレクションをループさせて、リソースの状態をコードで記述できるようになります。 +* 該当するユースケースについて、`Fn::ForEach` を使用してコードの行数を減らし、保守が容易でヒューマンエラーを起こしにくいコードを作成することができます。 -### Start lab +### ラボを開始 -### Lab part 1: basic looping over a collection for S3 buckets +### ラボパート 1: S3 バケットのコレクションの基本的なループ処理 -Let’s start with an example use case: you’re tasked with describing 3 [Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) buckets that will have a number of configuration properties in common, for example [bucket encryption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-bucketencryption.html) set to use [AWS Key Management Service (AWS KMS)](https://aws.amazon.com/kms/), [lifecycle configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-lifecycleconfig.html) set to transition to the `GLACIER` [storage class](https://aws.amazon.com/s3/storage-classes/) after 30 days and to expire objects after 1 year, `PublicAccessBlockConfiguration` [properties](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-publicaccessblockconfiguration.html) set to `true`, and tags set to use `aws-cloudformation-workshop` as the tag value for the `Name` tag key. +ユースケースの例から始めましょう。多くの共通の設定プロパティを持つ 3 つの[Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) バケットを定義する必要があります。例えば、[バケットの暗号化](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-bucketencryption.html)が[AWS Key Management Service (AWS KMS)](https://aws.amazon.com/kms/)、[ライフサイクル設定](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-lifecycleconfig.html)は 30 日後に `GLACIER` [ストレージクラス](https://aws.amazon.com/jp/s3/storage-classes/)に移行し、1 年後にオブジェクトの有効期限が切れるように設定し、`PublicAccessBlockConfiguration` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-publicaccessblockconfiguration.html) を `true` に設定し、タグは `Name` タグキーの値として `aws-cloudformation-workshop` を使用するように設定します。 -S3 buckets you’re tasked to describe with code share the same properties in this use case. While you certainly can describe all of them with three discrete code blocks, in this lab you choose to use `Fn::ForEach` to reduce the code size and relative complexity, so that you describe all the three buckets once with a single, iterative structure. This also has the benefit of having code that is easier to maintain, and it helps with reducing human errors as well. +コードに記述する必要がある S3 バケットは、このユースケースでは同じプロパティを共有します。これら全てを 3 つの個別のコードブロックで記述することもできますが、このラボでは、`Fn::ForEach` を使用してコードサイズと相対的な複雑さを軽減し、3 つのバケット全てを 1 つの反復構造で一度に記述できます。よって、保守が容易なコードになるという利点もあり、ヒューマンエラーを減らすのにも有効です。 -If you were to describe the three S3 buckets above *without* `Fn::ForEach`, the resulting template would be something like the following one, shown here as an example: +上記の 3 つのバケットを `Fn::ForEach` なしで記述すると、結果として下記のようなテンプレートとなります。例として次に示します。 :::code{language=yaml showLineNumbers=false showCopyAction=false} AWSTemplateFormatVersion: "2010-09-09" @@ -112,13 +110,14 @@ Resources: Value: aws-cloudformation-workshop ::: -In this lab, you choose to use `Fn::ForEach` to describe the S3 bucket configuration properties only once, by looping over a collection of buckets. This means that, in this case, the initial template you'll use will have fewer lines of code, thus making it easier to maintain. As a result, you’ll have a template, processed by the `AWS::LanguageExtensions` transform, that will describe content like the above, with three S3 bucket resources having the same properties but different [logical IDs](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/resources-section-structure.html), such as `S3Bucket1`, `S3Bucket2`, and `S3Bucket3`. +このラボでは、`Fn::ForEach` を使用してバケットのコレクションをループすることで S3 バケットの設定プロパティを一度だけ記述することになります。つまりこの場合、最初に使用するテンプレートのコード行数が少なくなるため、保守が容易になります。 +`AWS::LanguageExtensions` トランスフォームによってテンプレートが処理され、その結果には `S3Bucket1`、`S3Bucket2`、`S3Bucket3` など、プロパティは同じで [論理 ID](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/resources-section-structure.html) が異なる 3 つのバケットリソースを含む上記のようなテンプレートが作成されます。 -Let’s get started! Navigate to the `code/workspace/looping-over-collections` directory, and open the `s3-buckets.yaml` file in your favorite text editor. +それでは、始めましょう! `code/workspace/looping-over-collections` ディレクトリに移動し、お好みのテキストエディタで `s3-buckets.yaml` ファイルを開きます。 -::alert[Note the `Transform: AWS::LanguageExtensions` line, that is already present in the `s3-buckets.yaml` template you just opened (you've already used this transform in the [Language extensions](../language-extensions) lab). This line activates the language extension [transform](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/transform-aws-languageextensions.html), that is *required* in order to use the `Fn::ForEach` intrinsic function.]{type="warning"} +::alert[先ほど開いた `s3-buckets.yaml` テンプレートですでに存在する `Transform::AWS::LanguageExtensions` 行を削除しないように注意してください。このトランスフォームは [言語拡張](../language-extensions) ラボで既に使用しています。この行は言語拡張 [変換](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/transform-aws-languageextensions.html) を有効にします。`Fn::ForEach` 組み込み関数を使うために *必須* です。]{type="warning"} -With the `s3-buckets.yaml` file opened in your text editor, remove the TODO reminder line that is commented out, and append the code shown next to the `Resources` section (indentation matters - make sure the leading character of the `Fn::ForEach::S3Buckets` line starts at column number `2` in your editor): +テキストエディタで `s3-buckets.yaml` ファイルを開いた状態で、コメントアウトされている TODO リマインダー行を削除し、以下のソースコードを `Resources` セクションに追加します。インデントは重要です。`Fn::ForEach::S3Buckets` 行の先頭の文字がエディターの列番号 `2` から始まることを確認してください。 :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=8} Fn::ForEach::S3Buckets: @@ -149,23 +148,23 @@ With the `s3-buckets.yaml` file opened in your text editor, remove the TODO remi Value: aws-cloudformation-workshop ::: -Save the updated file to disk. Looking at the code you just pasted, you note that the content starting from the `Type: AWS::S3::Bucket` line is something you’ve seen in the example at the beginning of this lab: it is the same set of properties that all the three S3 buckets have in common. Let’s look into the lines that are above `Type: AWS::S3::Bucket` to understand how `Fn::ForEach` works! +更新したファイルを保存します。貼り付けたコードを見ると、このラボの最初の例で見た `Type: AWS::S3::Bucket` 行から始める内容は、3 つの S3 バケット全てに共通するプロパティのセットであることがわかります。`Fn::ForEach` の仕組みを理解するために、`Type: AWS::S3::Bucket` の上にある行を見てみましょう! -In this example, you want to iterate over a three-element collection, that is composed of the three S3 buckets. You choose to create this collection as `[S3Bucket1, S3Bucket2, S3Bucket3]`, and use each of the elements, that are denoted by the `S3BucketLogicalId` identifier described above the collection itself. In this example, you described the collection as an array, but you could also have used a reference to a template [parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html) of type `CommaDelimitedList`. +この例では、3 つの S3 バケットで構成される 3 つの要素のコレクションを繰り返し処理する必要があります。このコレクションを `[S3Buckets1, S3Bucket2, S3Bucket3]` として作成し、コレクション自体の上に記述した `S3BucketLogicalId` 識別子で示される各要素を使用することを選択します。この例では、コレクションを配列として記述しましたが、`CommaDelimitedList` 型のテンプレート[パラメータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/parameters-section-structure.html)への参照を使用することもできます。 -On the top of the code you pasted, you note the `Fn::ForEach::S3Buckets:` line, that describes the intent of using `Fn::ForEach` to iterate over a collection. The rightmost part of the line, `S3Buckets`, indicates the name you choose for the loop. When you create a loop, make sure you indicate a name that is unique within the template: do not choose a name used for another loop in the template, and that you used or plan to use for the logical ID of a resource in the same template. +貼り付けたコードの一番上にある`Fn::ForEach::S3Buckets` 行に注目してください。この行には、`Fn::ForEach` を使用してコレクションを反復処理する旨が記述されています。行の右端の `S3Buckets` は、ループに選択する名前を示しています。ループを作成するときは、必ずテンプレート内で一位の名前を指定してください。テンプレート内の別のループに使用している名前や、同じテンプレート内のリソースの論理 ID に使用した、または使用する予定の名前は選択しないでください。 -The line right above `Type: AWS::S3::Bucket`, that is `${S3BucketLogicalId}:`, denotes the `OutputKey` content that you’ll find in the template that will be transformed. In this case, the value of `OutputKey` will be the logical ID of each of the 3 S3 buckets: `S3Bucket1` in the first loop iteration, `S3Bucket2` in the second, and `S3Bucket3` in the third. +`Type: AWS::S3::Bucket` のすぐ上の行、つまり `${S3BucketLogicalId}` は、変換されるテンプレートにある `OutputKey` コンテンツを示しています。この場合、`OutputKey` の値は 3 つの S3 バケットそれぞれの論理 ID になります。最初の反復ループでは `S3Bucket1`、2 番目の反復ループでは`S3Bucket2`、3 番目の反復ループでは `S3Bucket3` になります。 -The lines starting with `Type: AWS::S3::Bucket` and below, in the example, constitute the `OutputValue` that will be replicated for each `OutputKey` in the processed template. These lines contain the common configuration that will be applied to the three S3 bucket resources with the logical IDs mentioned in the previous paragraph. +この例では、`Type: AWS::S3::Bucket` で始まる行とそれ以下の行は、処理されたテンプレート内の `OutputKey` ごとに複製される `OutputValue` を構成します。これらの行には、前の段落で記述した論理 ID を持つ 3 つの S3 バケットリソースに適用される共通の設定が含まれています。 -::alert[CloudFormation uses service quotas that are applied to the processed template. For more information on CloudFormation service quotas, see [AWS CloudFormation quotas](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html) in the CloudFormation User Guide.]{type="warning"} +::alert[CloudFormation では、処理されたテンプレートにサービスクォータを適用しす。CloudFormation サービスクォータの詳細については、CloudFormation ユーザガイドの [AWS CloudFormation のクォータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html) を参照してください。]{type="warning"} -It’s now time to create a new CloudFormation stack, to see how your three S3 buckets will be provisioned by looping over the collection you described above! You'll create a new stack in the `us-east-1` region. +これで新しい CloudFormation スタックを作成し、上で記述したコレクションをループして 3 つの S3 バケットがどのようにプロビジョニングされるかを確認します。`us-east-1` リージョンに新しいスタックを作成します。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -Run the following AWS CLI command: +次の AWS CLI コマンドを実行します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ @@ -175,7 +174,7 @@ aws cloudformation create-stack \ --capabilities CAPABILITY_AUTO_EXPAND ::: -The command above should return the ID of the stack you are creating. Wait until the stack is in the `CREATE_COMPLETE` status by using the [wait stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) AWS CLI command: +上記のコマンドは、作成しているスタック ID を返すはずです。[wait stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) AWS CLI コマンドを作成して、スタックが `CREATE_COMPLETE` ステータスになるまで待ちます。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation wait stack-create-complete \ @@ -184,44 +183,44 @@ aws cloudformation wait stack-create-complete \ ::: :::: -::::tab{id="local" label="Local development"} -Steps: - -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. Make sure you are in the **US East (N. Virginia)** region. -1. From the left navigation panel, select the **Stacks** tab. -1. From the right side of the page, choose **Create Stack**, and then choose **With new resources (standard).** -1. From **Prerequisite**-**Prepare template**, choose **Template is ready**. -1. Under **Specify template**, select **Template source**, and choose **Upload a template file**. -1. Select **Choose file**, and provide the `s3-buckets.yaml` template you updated earlier. Choose **Next**. -1. In the **Specify Stack details** page, specify a **Stack** name: `looping-over-collections-s3-buckets`. Choose **Next**. -1. On **Configure Stack options**, leave the configuration as it is. Choose **Next**. -1. On the **Review** page, review the contents of the page. At the bottom of the page, choose to acknowledge all the capabilities shown in the **Capabilities and transforms** section. Choose **Submit**. -1. Refresh the stack creation page until you see the stack to be in the `CREATE_COMPLETE` status. +::::tab{id="local" label="ローカル開発"} +手順 + +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +2. **米国東部 (バージニア北部)** リージョンにいることを確認してください。 +3. 左のナビゲーションパネルから、**スタック** を選択します。 +4. ページの右側から、**スタックの作成** を選択し、**新しいリソースを使用 (標準)** を選択します。 +5. **前提条件 - テンプレートの準備** から、**テンプレートの準備完了** を選択します。 +6. **テンプレートの指定** セクションで、**テンプレートソース** で、**テンプレートファイルのアップロード** を選択します。 +7. **ファイルの選択** を選択し、更新した `s3-buckets.yaml` テンプレートを指定します。**次へ** を選択します。 +8. **スタックの詳細を指定** ページで、**スタック名** に `looping-over-collections-s3-buckets` と入力します。**次へ** を選択します。 +9. **スタックオプションの設定** では、設定をそのままにしておきます。**次へ** を選択します。 +10. **レビュー** ページで、ページの内容を確認します。ページの下部で、**機能と変換** セクションに表示されている機能をすべて承認するように選択してください。**送信** を選択します。 +11. スタックが `CREATE_COMPLETE` ステータスになるまで、スタック作成ページを更新します。 :::: ::::: -When stack creation is complete, navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/), and locate the `looping-over-collections-s3-buckets` stack. Select the stack, and then select the **Template** pane. Note the following: +スタックの作成が完了したら、[AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動し、`looping-over-collections-s3-buckets` スタックを探します。スタックを選択し、次に **テンプレート** タブを選択します。次の点に確認してください。 -* you should see the initial template you provided, that uses the loop over the collection of buckets you described; -* choose **View processed template**: you should see the expanded template, that instead of the looping structure shows the three S3 buckets statically described, as a result of the processing. Note that you’ll see the processed configuration in JSON format; -* navigate to the **Resources** tab, and note the 3, newly-created S3 buckets whose logical IDs should be `S3Bucket1`, `S3Bucket2`, and `S3Bucket3`. +* 指定した最初のテンプレートが表示されます。記述したバケットのコレクションに対してループを使用するものです。 +* **処理されたテンプレートの表示** を選択します。展開されたテンプレートが表示され、処理の結果として、ループ構造の代わりに静的に記述された 3 つの S3 バケットが表示されます。処理された設定は JSON 形式で表示されることにご注意ください。 +* **リソース** タブに移動し、論理 ID が `S3Bucket1`、`S3Bucket2`、`S3Bucket3` であるはずの 3 つの新しく作成された S3 バケットを確認できます。 -Congratulations! You have completed the first part of this lab, and have learned the basics of `Fn::ForEach`. In the next part, you’ll go over a new example with more moving parts. +おめでとうございます!このラボの最初の部分を終了し、`Fn::ForEach` の基本を学習しました。次のパートでは可動部分を増やした新しい例を見ていきます。 -### Lab part 2: inner loops for VPC-related resources +### ラボパート 2: VPC 関連リソースの内部ループ -In this part of the lab, you’ll learn how to nest `Fn::ForEach` looping structures, when needed. Recall the usage of `Fn::ForEach` above: you pass the following parameters to the intrinsic function, right below the definition of the unique loop: +ラボのこのパートでは、`Fn::ForEach` ループ構造をネストする方法を学びます。前回の `Fn::ForEach` の使い方を思い出してください。ユニークループの定義のすぐ下にある組み込み関数に以下のパラメータを渡します。 * `Identifier` * `Collection` * `OutputKey` -In the previous example, you have used `${S3BucketLogicalId}:` as the `OutputKey` for the logical ID of each bucket you wanted to create. In this example, you’ll use another `Fn::ForEach` loop instead for the `OutputKey`, to drive an inner looping logic for a new use case: the creation of resources related to an [Amazon Virtual Private Cloud (Amazon VPC)](https://aws.amazon.com/vpc/) resource. +前の例では、作成したい各バケットの論理 ID の `OutputKey` として `${S3BucketLogicalID}:` を使用しました。今回の例では、`OutputKey` の代わりに別の `Fn::ForEach` ループを使用して、[Amazon Virtual Private Cloud (Amazon VPC)](https://aws.amazon.com/jp/vpc/) リソースに関連するリソースの作成のための内部ループロジックを駆動します。 -Let’s get started! Make sure you are in the `code/workspace/looping-over-collections` directory, and open the `vpc.yaml` file in your favorite text editor. Note the `Transform: AWS::LanguageExtensions` line in the code, that is *required* for the `Fn::ForEach` intrinsic function you’ll use next. The template already describes a VPC [resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html), an `InternetGateway` [resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html), and a `VPCGatewayAttachment` [resource](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html) without the use of `Fn::ForEach`, because you’re defining such resources only once in the template. In the template, you can also find a `Mappings` [section](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html) with a number of settings for the VPC and VPC-related resources that you’ll use next. +それでは、始めましょう!`code/workspace/looping-over-collections` ディレクトリにいることを確認し、お好みのテキストエディタで `vpc.yaml` ファイルを開きます。コード内の `Transform: AWS::LanguageExtensions` 行に注意してください。この行は次に使用する `Fn::ForEach` 組み込み関数に *必須* です。テンプレートには既に `VPC` [リソース](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc.html)、`InternetGateway` [リソース](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-internetgateway.html)、および `VpcGatewayAttachment` [リソース](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-vpc-gateway-attachment.html) が記述されていますが、`Fn::ForEach` は使用していません。なぜなら、このようなリソースはテンプレート内で一度しか定義していないからです。テンプレートには、次に使用する VPC と VPC 関連リソースの様々な設定が含まれている `Mappings` [セクション](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/mappings-section-structure.html) もあります。 -Remove the TODO reminder line in the file you just opened, and append the code shown next, to start describing public and private subnets. Make sure the level of indentation is the same as for the `VpcGatewayAttachment` resource declaration (that is, starting at column `2`): +開いたファイルの TODO リマインダー行を削除し、次のコードを追加して、パブリックサブネットとプライベートサブネットの記述を開始します。インデントのレベルが `VpcGatewayAttachment` リソース宣言と同じ(つまり、列 `2` から始まる) ことに注意してください。 :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=63} Fn::ForEach::SubnetTypes: @@ -249,19 +248,19 @@ Remove the TODO reminder line in the file you just opened, and append the code s VpcId: !Ref Vpc ::: -The code you added above shows the intent of describing two public subnets, and two private subnets for a total of 4 `AWS::EC2::Subnet` resources. +上で追加したコードは、合計 4 つの `AWS::EC2::Subnet` リソースについて、2 つのパブリックサブネットと 2 つのプライベートサブネットを記述する意図を示しています。 -With the first `Fn::ForEach::SubnetTypes` loop, you iterate over the collection of subnet types (public and private), and with the second, inner loop (that you are using here as your `OutputKey`), you iterate through each subnet (subnet 1 and subnet 2, using the strings `["1", "2"]` in the collection), of a specific type (public, private). +最初の `Fn::ForEach::SubnetTypes` ループでは、サブネットタイプ (Public と Private) のコレクションを反復処理し、2 番目の内部ループ (ここでは `OutputKey` として使用している) では、特定のタイプの各サブネット (サブネット 1 とサブネット 2、コレクション内の文字列 `["1", "2"]`) を反復処理します。 -::alert[The numbers `1` and `2`, that are elements of the `["1", "2"]` example collection, are represented here as quoted because a collection must be a list of strings.]{type="warning"} +::alert[`["1", "2"]` サンプルコレクションの要素である数値 `1` と `2` は、引用符で囲んで表現しています。コレクションは文字列のリストでなければならないからです。]{type="warning"} -In the `OutputKey` section of the inner loop, `${SubnetType}Subnet${SubnetNumber}`, you compose the name of the logical ID of each resource that, respectively, will be `PublicSubnet1`, `PublicSubnet2`, `PrivateSubnet1`, and `PrivateSubnet2` as both outer and inner loops iterate through the collections (`[Public, Private]`, and `["1", "2"]`) that you defined in the loops. +内部ループ `${SubnetType}Subnet${SubnetNumber}` の `OutputKey` セクションで、各リソースの論理 ID の名前を作成します。各リソースの論理 ID の名前は、外部ループと内部ループの両方がコレクションを反復処理するため、それぞれのループで定義したコレクション (`[Public, Private]` と `["1", "2"]`) を繰り返し、リソースの論理 ID が `PublicSubnet1`、`PublicSubnet2`、`PrivateSubnet1`、`PrivateSubnet2` になります。 -In each inner loop iteration, besides the four logical IDs above, each resource will have its properties configured to pull CIDR addressing information from the `SubnetCidrs` mapping via the `Fn::FindInMap` [intrinsic function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html), as well as the indexes to use when selecting Availability Zones for subnets with the `Fn::GetAZs` [intrinsic function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getavailabilityzones.html). The intent with the configuration used for the indexes in the `SubnetAzIndexes` mapping is to create public and private subnets with ID 1 in the same Availability Zone, and public and private subnets with ID 2 in a different Availability Zone: the reason behind this choice is to optimize Availability Zone-related traffic, so to have resources for a private subnet in the same Availability Zone as the NAT gateway, that you associate to the relevant public subnet (for example, to have `PrivateSubnet1` use the NAT gateway target that is associated to `PublicSubnet1`). For more information, see [NAT gateways](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-nat-gateway.html) in the Amazon VPC User Guide. +内部ループの各反復では、上記の 4 つの論理 ID の他に、`Fn::FindInMap` [組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-findinmap.html) を使って各リソースのプロパティが設定されます。`SubnetCIDRS` マッピングから CIDR アドレス情報を取得し、`Fn::GetAZs` [組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getavailabilityzones.html) でサブネットのアベイラビリティーゾーンを選択するためのインデックスを取得します。`SubnetAZIndexes` マッピングのインデックスに使用される目的は、同じアベイラビリティゾーンに ID 1 のパブリックサブネットとプライベートサブネットを作成し、ID 2 のパブリックサブネットとプライベートサブネットを別のアベイラビリティゾーンに作成することです。この選択の理由は、アベイラビリティーゾーン内のトラフィックを最適化し、プライベートサブネットのリソースを NAT ゲートウェイと同じアベイラビリティーゾーンに配置し、関連するパブリックサブネットに合わせます。(例えば、`PrivateSubnet1` に `PublicSubnet1` に関連付けられた NAT ゲートウェイターゲットを使用させる場合などです。) 詳細については、Amazon VPC ユーザガイドの [NAT ゲートウェイ](https://docs.aws.amazon.com/ja_jp/vpc/latest/userguide/vpc-nat-gateway.html) を参照してください。 -Other properties, for subnets, that will be replicated over inner loop iterations also include `Tags` and `VpcId`. +内部ループの繰り返しで複製されるサブネットのその他のプロパティには、`Tags` と `VpcId` があります。 -Let’s continue to describe other resources you’ll need: this time, you want to describe two public and two private route tables, and then associate such route tables to the relevant subnets you defined above. Add the following code to the existing inner loop (make sure the indentation is correct: the column where `${SubnetType}RouteTable${SubnetNumber}` starts must be the same as where `${SubnetType}Subnet${SubnetNumber}` above starts, which is column `10`): +他に必要なリソースを定義していきましょう。今回は、2 つのパブリックルートテーブルと 2 つのプライベートルートテーブルを定義し、そのルートテーブルを上記で定義したサブネットに関連付けます。既存の内部ループに次のコードを追加します。(インデントが正しいことに注意してください。`${SubnetType}routeTable${SubnetNumber}` の列は、上記の `${SubnetType}Subnet${SubnetNumber}` の列と同じく、`10` 列目とでなければなりません。) :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=86} ${SubnetType}RouteTable${SubnetNumber}: @@ -280,11 +279,11 @@ Let’s continue to describe other resources you’ll need: this time, you want Fn::Sub: ${SubnetType}Subnet${SubnetNumber} ::: -With the above, you create four route tables (two public, and two private) with the first block and, with the second block, you associate them to the relevant subnets you’re defining within the same inner loop iterations. +上記では、最初のブロックで 4 つのルートテーブル (2 つはパブリック、2 つはプライベート) を作成し、2 番目のブロックでは、同じ反復ループ内で定義しているサブネットに関連付けます。 -Now that you have the subnets you need for this lab’s example use case, and that each subnet has a route table associated to it, it’s time to add default routes to all IPv4 destinations (`0.0.0.0/0`) that are assumed to be a requirement in your example use case as well. Now, while the `0.0.0.0/0` CIDR is going to be the same for routes you’ll assign to both public and private subnets, public routes will need the `InternetGateway` you created earlier as a target, whereas private subnets will need a Network Address Translation (NAT) mechanism instead. You then choose to describe public and private routes with two separate, new loop iterations to decouple public from private routes in specialized business logic for each type. +これで、このラボのサンプルユースケースに必要なサブネットが用意され、各サブネットにルートテーブルが関連付けられました。次は、このサンプルユースケースの要件であると想定されるすべての IPv4 宛先 (`0.0.0.0/0`) へのデフォルトルートを追加します。これで、`0.0.0.0/0` CIDR はパブリックサブネットとプライベートサブネットの両方に割り当てるルートは同じですが、パブリックサブネットのルートには先に作成した `InternetGateway` がターゲットになり、プライベートサブネットのルートには代わりにネットワークアドレス変換 (NAT) の仕組みが必要になります。次に、パブリックルートとプライベートルートの 2 つの別々の新しいループイテレーションで記述し、それぞれのタイプに特化したビジネスロジックでパブリックルートとプライベートルートを分けます。 -Let’s start with creating routes for public subnets first, that we’ll add to the public route tables you described earlier; here, you create a new loop that you’ll indent 2 columns to the right (that is, column number `2`); add the content below to the `vpc.yaml` file: +まずは、パブリックサブネット用のルートを作成し、先ほど定義したパブリックルートテーブルに追加します。ここでは、右に 2 列 (つまり、列番号 `2`) をインデントする新しいループを作成し、以下の内容を `vpc.yaml` ファイルに追加します。 :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=101} Fn::ForEach::DefaultRoutesForPublicSubnets: @@ -300,11 +299,11 @@ Let’s start with creating routes for public subnets first, that we’ll add to GatewayId: !Ref InternetGateway ::: -With the new loop above, you described 2 `AWS::EC2::Route` resources for public subnets - that is, each is configured to be a default route with the `InternetGateway` (that is already described in the template you're using for this lab) as a target. +上記の新しいループでは、パブリックサブネット用の 2 つの `AWS::EC2::Route` リソースについて記述しました。つまり、それぞれが `InternetGateway` (このラボで使用しているテンプレートですでに定義されています) をターゲットとするデフォルトルートとして設定されています。  -::alert[The `AWS::EC2::Route` resources described above use the `DependsOn` attribute to add an explicit dependency on the VPC gateway attachment. The same is also true for `AWS::EC2::EIP` resources you'll define next. See [When a DependsOn attribute is required](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html#gatewayattachment) to learn more on why these resources need `DependsOn` in the current context.]{type="warning"} +::alert[上記の `AWS::EC2::Route` リソースは `dependsOn` 属性を使用して VPC ゲートウェイアタッチメントへの明示的な依存関係を追加します。次に定義する `AWS::EC2::EIP` リソースについても同じです。現在のコンテキストでこれらのリソースに `DependsOn` が必要な理由について詳しくは、[DependsOn 属性が必須の場合](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html#gatewayattachment) を参照してください]{type="warning"} -You’ll now need to set up routes for private subnets. For this, you choose to create a new loop where you describe 2 `AWS::EC2::EIP` [resources](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-eip.html), that you’ll use for 2 `AWS::EC2::NatGateway` resources you’ll define in this new loop as well later on. You’ll also describe two routes for private subnets that will have each NAT gateway as a target, respectively. Add the following code for the new loop to the template: +次に、プライベートサブネットのルートを設定する必要があります。そのためには、2 つの `AWS::EC2::EIP` [リソース](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-eip.html) を記述する新しいループを作成します。このループは、後でこの新しいループで定義する 2 つの `AWS::EC2::NATGateway` リソースに使用します。また、各 NAT ゲートウェイをそれぞれターゲットとするプライベートサブネットの 2 つのルートについても記述します。新しいループの次のコードをテンプレートに追加します。 :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=113} Fn::ForEach::NatGateways: @@ -336,15 +335,15 @@ You’ll now need to set up routes for private subnets. For this, you choose to Fn::Sub: NatGateway${SubnetNumber} ::: -In the code above, note the logical IDs for the two elastic IP resources you’re creating (`Eip${SubnetNumber}`), the logical IDs for the two NAT gateways (`NatGateway${SubnetNumber}`), and the logical IDs for the two routes for private subnets (`DefaultRouteForPrivateSubnet${SubnetNumber}`). +上記のコードでは、作成している 2 つの elastic IP リソースの論理 ID (`Eip${SubnetNumber}`)、2 つの NAT ゲートウェイの論理 ID (`NATGateway${SubnetNumber}`)、およびプライベートサブネットの 2 つのルートの論理 ID (`defaultRouteForPrivateSubnet${SubnetNumber}`) をご確認ください。 -Moreover, note the `AllocationId` [property](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html#cfn-ec2-natgateway-allocationid) of the NAT gateway resource: when you describe this property, you use the `Fn::GetAtt` [intrinsic function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html) to consume the allocation ID of the relevant elastic IP resource, by passing the logical ID of the elastic IP resource as well. In the example above, you first use the `Fn::Sub` [intrinsic function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html) to compose the logical ID of each elastic IP resource (`!Sub Eip${SubnetNumber}`), and then you use the `Ref` [intrinsic function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html) to pass the composed logical ID as a reference for the relevant resource described in the template (in this case, described as part of a looping iteration). The `RouteTableId` property for `AWS::EC2::Route` resources uses a similar logic (`Fn::Sub: PrivateRouteTable${SubnetNumber}`) when composing the logical ID of the route table. The same also holds true for the `SubnetId` property of the `AWS::EC2::NatGateway` resource. +さらに、NAT ゲートウェイリソースの `allocationId` [property](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ec2-natgateway.html#cfn-ec2-natgateway-allocationid) にも注目してください。このプロパティを記述するときは、`Fn::GetAtt` [組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html) を使用して、elastic IP リソースの論理 ID も渡すことにより、関連する elastic IP リソースの割り当て ID を使用します。上の例では、最初に `Fn::Sub` [組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html) を使用して、各 elastic IP リソース (`!Sub Eip${SubnetNumber}`) の論理 ID を作成します。次に `Ref` [組み込み関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html) を使用して、形成された論理 ID をテンプレートに記述されている関連リソースへの参照として渡します (この場合は、反復ループの一部として記述されます)。`AWS::EC2::Route` リソースの `RouteTableId` プロパティは、ルートテーブルの論理 ID を形成する際に同様のロジック (`Fn::Sub::PrivateRouteTable${SubnetNumber}`) を使用します。`AWS::EC2::NATGateway` リソースの `SubnetId` プロパティも同じです。 -It’s now time to provision the infrastructure for the VPC-related resources you described with code! Save the `vpc.yaml` file with all the changes you’ve been applying along this part of the lab, and follow the indications below to create a new stack, called `looping-over-collections-vpc`, using the `vpc.yaml` file. You'll create the new stack in the `us-east-1` region. +さて、コードで記述した VPC 関連リソースのインフラストラクチャをプロビジョニングしましょう!ラボのこの部分で行ってきたすべての変更を含む `vpc.yaml` ファイルを保存し、以下の手順に沿って `vpc.yaml` ファイルを使用して `looping-over-collections-vpc` という名前の新しいスタックを作成します。新しいスタックは `us-east-1` リージョンに作成します。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -Run the following AWS CLI command: +次の AWS CLI コマンドを実行します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ @@ -354,7 +353,7 @@ aws cloudformation create-stack \ --capabilities CAPABILITY_AUTO_EXPAND ::: -The command above should return the ID of the stack you are creating. Wait until the stack is in the `CREATE_COMPLETE` status by using the [wait stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) AWS CLI command: +上記のコマンドは、作成しているスタックの ID を返すはずです。[wait stack-create-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-create-complete.html) AWS CLI コマンドを使用して、スタックが `CREATE_COMPLETE` ステータスになるまで待ちます。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation wait stack-create-complete \ @@ -363,51 +362,51 @@ aws cloudformation wait stack-create-complete \ ::: :::: -::::tab{id="local" label="Local development"} -Steps: - -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. Make sure you are in the **US East (N. Virginia)** region. -1. From the left navigation panel, select the **Stacks** tab. -1. From the right side of the page, choose **Create Stack**, and then choose **With new resources (standard).** -1. From **Prerequisite**-**Prepare template**, choose **Template is ready**. -1. Under **Specify template**, select **Template source**, and choose **Upload a template file**. -1. Select **Choose file**, and provide the `vpc.yaml` template you updated earlier. Choose **Next**. -1. In the **Specify Stack details** page, specify a **Stack** name: `looping-over-collections-vpc`. Choose **Next**. -1. On **Configure Stack options**, leave the configuration as it is. Choose **Next**. -1. On the **Review** page, review the contents of the page. At the bottom of the page, choose to acknowledge all the capabilities shown in the **Capabilities and transforms** section. Choose **Submit**. -1. Refresh the stack creation page until you see the stack to be in the `CREATE_COMPLETE` status. +::::tab{id="local" label="ローカル開発"} +手順 + +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +2. **米国東部 (バージニア北部)** リージョンにいることを確認してください。 +3. 左側のナビゲーションパネルから、**スタック** を選択します。 +4. ページの右側から、**スタックの作成** を選択し、**新しいリソースを使用 (標準)** を選択します。 +5. **前提条件 - テンプレートの準備** から、**テンプレートの準備完了** を選択します。 +6. **テンプレートの指定** セクションで、**テンプレートソース** で **テンプレートファイルのアップロード** を選択します。 +7. **ファイルの選択** を選択し、前に更新した `vpc.yaml` テンプレートを指定します。**次へ** を選択します。 +8. **スタックの詳細を指定** ページで、**スタック名** を `looping-over-collections-vpc` と指定します。**次へ** を選択します。 +9. **スタックオプションの設定** では、設定をそのままにしておきます。**次へ** を選択します。 +10. **レビュー** ページで、ページの内容を確認します。ページの下部で、**機能と変換** セクションに表示されている機能をすべて承認するように選択してください。**送信** を選択します。 +11. スタックが `CREATE_COMPLETE` ステータスになるまで、スタック作成ページを更新します。 :::: ::::: -Once you created the new stack with the method of your choice, continue to follow directions you found in part 1 of the lab to navigate to the **Template** and **Resources** sections, this time for the `looping-over-collections-vpc` stack: compare the template you provided with the processed one, to see how the code maintainability has improved with the method of looping over collections. +上記のどちらかの方法で新しいスタックを作成したら、引き続きラボのパート 1 で説明したと同様に、`looping-over-collections-vpc` スタックの **テンプレート** タブと **リソース** タブに移動します。送信したテンプレートを処理済みのテンプレートを比較し、コレクションをループする方法によってコードの保守性がどのように向上したかを確認します。 -Congratulations! You completed the second part of the lab, and learned how to use inner loops when needed in more complex use cases. +おめでとうございます!ラボのパート 2 を終了し、より複雑なユースケースが必要な時にインナーループを使用する方法を学びました。 -### Challenge +### チャレンジ -In this challenge, you’re tasked with adding the IDs of public and private subnets to the `Outputs` [section](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html) of the `vpc.yaml` file, using `Fn::ForEach`. Requirements for outputs are: +このチャレンジでは、`Fn::ForEach` を使用して `vpc.yaml` ファイルの `Outputs` [セクション](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html) にパブリックサブネットとプライベートサブネットの ID を追加する必要があります。出力の要件は以下のとおりです。 -* add the `Outputs` section in the `vpc.yaml` template; -* add a meaningful description for each output, so that it will contain text composed such as: +* `vpc.yaml` テンプレートに `Outputs` セクションを追加してください。 +* 出力をわかりやすくするために、各出力のコメントに以下のような説明を入れてください。 * `The ID of PublicSubnet1.` * `The ID of PublicSubnet2.` * `The ID of PrivateSubnet1.` * `The ID of PrivateSubnet2.` -* Add the `Value` for each output, as a reference to the relevant subnet ID. -* Add the `Export` [name](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html) for each output, so that you can [consume](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html) it from other stacks in the future. Create the name of each export using this pattern: `YOUR_AWS_ACCOUNT_ID-SUBNET_TYPESubnetSUBNET_NUMBERId`; example for the first public subnet: `111122223333-PublicSubnet1Id`. - -:::expand{header="Need a hint?"} -* Use the same outer + inner loops logic you followed to create the two public and the two private subnets, and apply it to content you'll write underneath the `Outputs` section. -* Make sure you recall how to describe the [structure](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html) of an output when you build the looping logic for your outputs. -* When you describe the `Value` of each output, you’ll need to reference the logical ID of a subnet, but you need to compose it first using `Fn::Sub`. Look at the example pattern you used for composing the referenced value for `RouteTableId` in the inner loop you used to describe `AWS::EC2::Route` resources, or the `SubnetId` property of the `AWS::EC2::NatGateway` resource. -* Is there a [pseudo parameter](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) you can use to return the ID of the current AWS account you're using? +* 関連するサブネット ID への参照として、各出力に `Value` を追加します。 +* 出力ごとに `Export` と [Name](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-stack-exports.html) を追加して、将来的に他のスタックから [インポート](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-importvalue.html) できるようにします。`YOUR_AWS_ACCOUNT_ID-SUBNET_TYPESubnetSUBNET_NUMBERId` のように各エクスポートの名前を作成します。例えば最初のサブネットが `111122223333-PublicSubnet1ID` のようになります。 + +:::expand{header="ヒントが必要ですか?"} +* 同じ外部 + 内部ループロジックを使用して 2 つのパブリックサブネットと 2 つのプライベートサブネットを作成したように、`Outputs` セクションに記述するコンテンツに再利用します。 +* 出力のループロジックを構築するときは、出力の [構造](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/outputs-section-structure.html) の記述方法を思い出してください。 +* 各出力の `Value` を記述するときは、サブネットの論理 ID を参照する必要がありますが、まず `Fn::Sub` を使用してサブネットの論理 ID を作成する必要があります。`AWS::EC2::Route` リソースの記述に使用した内部ループで `RouteTableId` の参照値を作成するために使用したサンプルパターン、または `AWS::EC2::NatGateway` リソースの `SubnetId` プロパティをご確認ください。 +* 現在使用している AWS アカウントの ID を返すのに使用できる [擬似パラメータ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html) はありそうですか? ::: -::::::expand{header="Want to see the solution?"} -The complete solution is available in the `vpc.yaml` file, that you can find on the `code/solutions/looping-over-collections` directory. +::::::expand{header="解決策を確認しますか?"} +ソリューションの一式はこのファイルは `code/solutions/looping-over-collections` ディレクトリにある `vpc.yaml` ファイルにあります。 -Append the following content to the `vpc.yaml` file: +次の内容を `vpc.yaml` ファイルに追加します。 :::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=141} Outputs: @@ -425,11 +424,11 @@ Outputs: Fn::Sub: ${SubnetType}Subnet${SubnetNumber} ::: -Next, update the existing `looping-over-collections-vpc` stack with the updated template containing the `Outputs` information below. +次に、既存の `looping-over-collections-vpc` スタックを以下の `Outputs` 情報を含むテンプレートで更新します。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -Run the following AWS CLI command: +次の AWS CLI コマンドを実行します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation update-stack \ @@ -439,7 +438,7 @@ aws cloudformation update-stack \ --capabilities CAPABILITY_AUTO_EXPAND ::: -Wait until the stack is in the `UPDATE_COMPLETE` status by using the [wait stack-update-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-update-complete.html) AWS CLI command: +[wait stack-update-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-update-complete.html) AWS CLI コマンドを使用して、スタックが `UPDATE_COMPLETE` ステータスになるまで待ちます。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation wait stack-update-complete \ @@ -448,34 +447,34 @@ aws cloudformation wait stack-update-complete \ ::: :::: -::::tab{id="local" label="Local development"} -Steps: - -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. Make sure you are in the **US East (N. Virginia)** region. -1. From the left navigation panel, select the **Stacks** tab. -1. Choose the existing `looping-over-collections-vpc` stack from the list of stacks. -1. From the right side of the page, choose **Update Stack**. -1. From **Prerequisite**-**Prepare template**, choose **Replace current template**. -1. Under **Specify template**, select **Template source**, and choose **Upload a template file**. -1. Select **Choose file**, and provide the `vpc.yaml` template you updated earlier. Choose **Next**. -1. In the **Specify Stack details** page, choose **Next**. -1. On **Configure Stack options**, leave the configuration as it is. Choose **Next**. -1. On the **Review** page, review the contents of the page. At the bottom of the page, choose to acknowledge all the capabilities shown in the **Capabilities and transforms** section. Choose **Submit**. -1. Refresh the stack creation page until you see the stack to be in the `CREATE_COMPLETE` status. +::::tab{id="local" label="ローカル開発"} +手順 + +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/) に移動します。 +2. **米国東部 (バージニア北部)** リージョンにいることを確認してください。 +3. 左側のナビゲーションパネルから、**スタック** を選択します。 +4. スタックのリストから既存の `looping-over-collections-vpc` スタックを選択します。 +5. ページの右側から、**更新** を選択します。 +6. **前提条件 - テンプレートの準備** から、**既存テンプレートを置き換える** を選択します。 +7. **テンプレートの指定** セクションで、**テンプレートソース** で、**テンプレートファイルのアップロード** を選択します。 +8. **ファイルの選択** を選択し、更新した `vpc.yaml` テンプレートを指定します。**次へ** を選択します。 +9. **スタックの詳細を指定** ページで、**次へ** を選択します。 +10. **スタックオプションの設定** では、設定をそのままにしておきます。**次へ** を選択します。 +11. **レビュー** ページで、ページの内容を確認します。ページの下部で、**機能と変換** セクションに表示されている機能をすべて承認するように選択してください。**送信** を選択します。 +12. スタックが `UPDATE_COMPLETE` ステータスになるまで、スタック作成ページを更新します。 :::: ::::: -When the stack update is complete, you should be able to see the outputs in the `Outputs` pane for the stack in the CloudFormation console. +スタックの更新が完了すると、CloudFormation コンソールのスタックの `出力` タブに出力が表示されるはずです。 :::::: -### Clean up +### クリーンアップ -You'll now delete the resources you created as part of this lab. Use the following steps: +次に、このラボで作成したリソースを削除します。以下の手順を実行してください。 :::::tabs{variant="container"} ::::tab{id="cloud9" label="Cloud9"} -Delete the `looping-over-collections-s3-buckets` stack, by running the following AWS CLI command: +次の AWS CLI コマンドを実行して、`looping-over-collections-s3-buckets` スタックを削除します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation delete-stack \ @@ -483,7 +482,7 @@ aws cloudformation delete-stack \ --stack-name looping-over-collections-s3-buckets ::: -Wait until the `DELETE` operation is complete, by using the [wait stack-delete-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-delete-complete.html) AWS CLI command: +[wait stack-delete-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-delete-complete.html) AWS CLI コマンドを使用して、`DELETE` 操作が完了するまでお待ちください。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation wait stack-delete-complete \ @@ -491,7 +490,7 @@ aws cloudformation wait stack-delete-complete \ --stack-name looping-over-collections-s3-buckets ::: -When done, repeat the steps above to delete the `looping-over-collections-vpc` stack: +完了したら、上記の手順を繰り返して `looping-over-collections-vpc` スタックを削除します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation delete-stack \ @@ -499,7 +498,7 @@ aws cloudformation delete-stack \ --stack-name looping-over-collections-vpc ::: -Wait until the `DELETE` operation is complete, by using the [wait stack-delete-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-delete-complete.html) AWS CLI command: +[wait stack-delete-complete](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/wait/stack-delete-complete.html) AWS CLI コマンドを使用して、`DELETE` 操作が完了するまでお待ちください。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation wait stack-delete-complete \ @@ -508,18 +507,18 @@ aws cloudformation wait stack-delete-complete \ ::: :::: -::::tab{id="local" label="Local development"} -Steps: - -1. Navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/). -1. Make sure you are in the **US East (N. Virginia)** region. -1. From the **Stacks** page, select the `looping-over-collections-s3-buckets` stack. -1. In the stack details pane, choose **Delete**. Select **Delete** when prompted. -1. From the **Stacks** page, select the `looping-over-collections-vpc` stack. -1. In the stack details pane, choose **Delete**. Select **Delete** when prompted. +::::tab{id="local" label="ローカル"} +手順 + +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +2. **米国東部 (バージニア北部)** リージョンにいることを確認してください。 +3. **スタック** ページから、`looping-over-collections-s3-buckets` スタックを選択します。 +4. スタックの詳細ペインで、**削除** を選択します。プロンプトが表示されたら、**削除** を選択します。 +5. **スタック** ページから `looping-over-collections-vpc` スタックを選択します。 +6. スタックの詳細ペインで、**削除** を選択します。プロンプトが表示されたら、**削除** を選択します :::: ::::: -### Conclusion +### まとめ -Great work! You learned how to loop over collections using the `Fn::ForEach` intrinsic function and the `AWS::LanguageExtensions` transform. For more information, see [Fn::ForEach](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-foreach.html) in the AWS CloudFormation User Guide, and the [Exploring Fn::ForEach and Fn::FindInMap enhancements in AWS CloudFormation](https://aws.amazon.com/blogs/devops/exploring-fnforeach-and-fnfindinmap-enhancements-in-aws-cloudformation/) blog post. We welcome your contributions to RFCs and your feedback in our [cfn-language-discussion](https://github.com/aws-cloudformation/cfn-language-discussion) GitHub repository! +`Fn::ForEach` 組み込み関数と `AWS::LanguageExtensions` トランスフォームを使ってコレクションをループさせる方法を学びました。詳細については、AWS CloudFormation ユーザガイドの [Fn::ForEach](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-foreach.html) と、[Exploring Fn::ForEach and Fn::FindInMap enhancements in AWS CloudFormation](https://aws.amazon.com/jp/blogs/devops/exploring-fnforeach-and-fnfindinmap-enhancements-in-aws-cloudformation/) を参照してください。[cfn-language-discussion](https://github.com/aws-cloudformation/cfn-language-discussion) GitHub リポジトリで RFC への貢献やフィードバックを歓迎します! diff --git a/content/intermediate/templates/nested-stacks/index.ja.md b/content/intermediate/templates/nested-stacks/index.ja.md index f7a714758..31503d9f4 100644 --- a/content/intermediate/templates/nested-stacks/index.ja.md +++ b/content/intermediate/templates/nested-stacks/index.ja.md @@ -3,13 +3,17 @@ title: "ネストされたスタック" weight: 400 --- +_ラボ実施時間 : 30分程度_ + +--- + ### 概要 CloudFormation テンプレートは、このワークショップを進めることでボリュームが多くなりました。 インフラが拡大するにつれ、それぞれのテンプレートで同じコンポーネントを宣言するパターンが出てくることがあります。 同じコンポーネントを宣言するケースにおいては、共通コンポーネントを分離して、専用のテンプレートを作成することが可能です。 -具体的には、[**ネストされたスタック**](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html)を用いて、様々なテンプレートを組み合わせ、1つの統合されたスタックを作成することができます。 +具体的には、[**ネストされたスタック**](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html)を用いて、様々なテンプレートを組み合わせ、1 つの統合されたスタックを作成することができます。 例えば、Systems Manager Session Manager によるすべての EC2 インスタンスへのアクセスを有効にしたい場合があります。 @@ -21,12 +25,12 @@ CloudFormation テンプレートは、このワークショップを進める このラボでは、以下を作成します。 -1. **_root_ スタック**: (第1レベルにある親スタックでもあります)。root スタックには、他のすべてのスタックが含まれます。 -2. **VPC スタック**: EC2 インスタンスを配置するシンプルな VPC テンプレートが含まれています。 -3. **IAM インスタンスロールスタック**: EC2 テンプレートから切り離された IAM インスタンスロールテンプレートが含まれています。 -4. **EC2 スタック**: 以前の CloudFormation テンプレートで定義した EC2 インスタンスが含まれます。 +1. **_root_ スタック** : (第 1 レベルにある親スタックでもあります)。root スタックには、他のすべてのスタックが含まれます。 +1. **VPC スタック** : EC2 インスタンスを配置するシンプルな VPC テンプレートが含まれています。 +1. **IAM インスタンスロールスタック** : EC2 テンプレートから切り離された IAM インスタンスロールテンプレートが含まれています。 +1. **EC2 スタック** : 以前の CloudFormation テンプレートで定義した EC2 インスタンスが含まれます。 -> ネストされたスタックの最上位レベルと第1レベルの階層 +> ネストされたスタックの最上位レベルと第 1 レベルの階層 ![nested-stack-hierarchy](/static/intermediate/templates/nested-stacks/nested-stack-hierarchy.ja.png) @@ -37,7 +41,7 @@ CloudFormation テンプレートは、このワークショップを進める ### ラボを開始 1. `code/workspace/nested-stacks` ディレクトリに移動します。 -2. 以下のトピックを読みながら、コードをコピーします。 +1. 以下のトピックを読みながら、コードをコピーします。 #### 1. ネストされたスタックのリソース @@ -81,7 +85,7 @@ VPC テンプレートは既に作成されており、タイトルは `vpc.yaml 以下のコードを `main.yaml` テンプレートの **Parameters** セクションにコピーします。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} AvailabilityZones: Type: List Description: The list of Availability Zones to use for the subnets in the VPC. Select 2 AZs. @@ -111,7 +115,7 @@ PublicSubnet2Cidr: AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/([0-9]|[1-2][0-9]|3[0-2]))$ ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16-28 Default: 10.0.1.0/24 -``` +::: ##### 2. メインテンプレートに VPC リソースを作成 以下のコードでは、単一のスタンドアロンテンプレートを使用する場合と同じように、リソースにパラメータ値を渡すことができます。 @@ -119,7 +123,7 @@ PublicSubnet2Cidr: このコードをメインテンプレート (`main.yaml`) の **Resources** セクションに追加します -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} VpcStack: Type: AWS::CloudFormation::Stack Properties: @@ -134,34 +138,74 @@ VpcStack: VPCName: !Ref VPCName PublicSubnet1Cidr: !Ref PublicSubnet1Cidr PublicSubnet2Cidr: !Ref PublicSubnet2Cidr -``` +::: ##### 3. VPC スタックを S3 にアップロード +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/nested-stacks` ディレクトリに移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/nested-stacks + ::: +1. 以下のコマンドを実行して `vpc.yaml` を S3 バケットにコピーします。`bucket-name` を前のステップのバケット名に置き換えてください。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws s3 cp vpc.yaml s3://{bucket-name} + ::: +:::: +::::tab{id="local" label="ローカル開発"} 1. [S3 コンソール](https://console.aws.amazon.com/s3/home?region=eu-west-1) に移動し、バケットを選択します。 -2. **アップロード**ボタンをクリックし、**ファイルを追加**をクリックします。 -3. `vpc.yaml` ファイルを選択します。 -4. **アップロード**ボタンをクリックし、ファイルをアップロードします。 +1. **アップロード** ボタンをクリックし、 **ファイルを追加** をクリックします。 +1. `vpc.yaml` ファイルを選択します。 +1. **アップロード** ボタンをクリックし、ファイルをアップロードします。 +:::: +::::: ##### 4. ネストされた VPC スタックをデプロイ :::alert{type="info"} -**YAML** はインデントを区別するマークダウン言語であることに注意してください。`cfn-lint`、または、 CloudFormation コンソールが`Template format error: [/Resources/VpcStack] resource definition is malformed` というエラーを報告した場合、**Parameters** と **Resources** セクションが正しくフォーマットされていることを再確認してください。 +**YAML** はインデントに敏感なマークダウン言語であることに注意してください。`cfn-lint` または CloudFormation コンソールが`Template format error: [/Resources/VpcStack] resource definition is malformed` というエラーを報告した場合、 **Parameters** と **Resources** セクションが正しくフォーマットされていることを再確認してください。インストール方法や詳細なガイダンスについては、以前の [静的解析とテスト](/basics/templates/linting-and-testing)のラボを参照してください。 ::: -1. コンソールで CloudFormation に移動し、**新しいリソースを使用 (標準)** をクリックします。 -2. **テンプレートの準備**セクションで、**テンプレート準備完了**を選択します。 -3. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -4. `main.yaml` ファイルを選択します。 -5. **スタック名**を入力します。例えば、`cfn-workshop-nested-stack` と入力します。 -6. **AvaliabilityZone** パラメータには、2 つの AZ を選択します。 -7. **S3BucketName** には、[S3 バケットを準備](#2-prepare-s3-bucket) セクションに書き留めたバケット名を入力します。 -8. 残りのパラメータはデフォルトのままとします。 -9. **スタックオプションの設定**はデフォルトのままにして、**次へ**をクリックします。 -10. **レビュー ** ページで一番下までスクロールし、両方の **IAM Capabilities** チェックボックスにチェックを入れます。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/nested-stacks` ディレクトリに移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/nested-stacks + ::: +1. AWS EC2 Api を使用して VPC からアベイラビリティーゾーンのリストを取得し、出力から任意の 2 つの AZ をコピーして次のステップで使用します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws ec2 describe-availability-zones --output json --query "AvailabilityZones[*].ZoneName" + ::: +1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。`ParameterValue` の **bucketName** を [S3 バケットの準備](#2.-s3)セクションでメモした値に置き換えてください。`ParameterValue` の **AZ1** と **AZ2** を前のステップでコピーした値に置き換えてください。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation create-stack --stack-name cfn-workshop-nested-stacks \ + --template-body file://main.yaml \ + --parameters ParameterKey="S3BucketName",ParameterValue="bucketName" ParameterKey="AvailabilityZones",ParameterValue=AZ1\\,AZ2 \ + --capabilities CAPABILITY_NAMED_IAM + ::: +1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 + :::code{language=json showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-nested-stacks/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。最新のスタックステータスを確認するには、定期的に更新を選択する必要があります。 +:::: +::::tab{id="local" label="ローカル開発"} +1. コンソールで CloudFormation に移動し、 **新しいリソースを使用 (標準)** をクリックします。 +1. **テンプレートの準備** セクションで、 **テンプレート準備完了** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. `main.yaml` ファイルを選択します。 +1. **スタック名** を入力します。例えば、`cfn-workshop-nested-stack` と入力します。 +1. **AvaliabilityZone** パラメータには、2 つの AZ を選択します。 +1. **S3BucketName** には、[S3 バケットを準備](#2.-s3) セクションに書き留めたバケット名を入力します。 +1. 残りのパラメータはデフォルトのままとします。 +1. **スタックオプションの設定** はデフォルトのままにして、 **次へ** をクリックします。 +1. **レビュー ** ページで一番下までスクロールし、両方の **IAM Capabilities** チェックボックスにチェックを入れます。 ![iam-capabilities.png](/static/intermediate/templates/nested-stacks/iam-capabilities.ja.png) -11. **スタックの作成**をクリックします。CloudFormation コンソールで作成中のネストスタックの進行状況を確認できます。 -12. 数分後にスタックが作成されます。`CREATE_COMPLETE` のステータスが表示されるまで、更新ボタンを数回クリックします。 +1. **スタックの作成** をクリックします。CloudFormation コンソールで作成中のネストスタックの進行状況を確認できます。 +1. 数分後にスタックが作成されます。`CREATE_COMPLETE` のステータスが表示されるまで、更新ボタンを数回クリックします。 +:::: +::::: #### 4. ネストされた IAM スタックの作成 @@ -172,9 +216,9 @@ VpcStack: 1. `iam.yaml` ファイルを開きます。 -2. 以下のコードをテンプレートの **Resources** セクションにコピーします。 +1. 以下のコードをテンプレートの **Resources** セクションにコピーします。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} SSMIAMRole: Type: AWS::IAM::Role Properties: @@ -195,41 +239,79 @@ WebServerInstanceProfile: Path: / Roles: - !Ref SSMIAMRole -``` +::: ##### 2. メインテンプレートに IAM リソースを作成 以下のコードを `main.yaml` テンプレートの **Resources** セクションにコピーします。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} IamStack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://${S3BucketName}.s3.amazonaws.com/iam.yaml TimeoutInMinutes: 10 -``` +::: ##### 3. IAM スタックを S3 にアップロード -[VPC スタック](#3-upload-the-vpc-stack-to-s3) と同様に、IAM テンプレートを S3 にアップロードします。 - +[VPC スタック](#3.-vpc-s3) と同様に、IAM テンプレートを S3 にアップロードします。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/nested-stacks` ディレクトリに移動します。 + :::code{language=shell showLineNumbers=true showCopyAction=true} + cd cfn101-workshop/code/workspace/nested-stacks + ::: +1. 以下のコマンドを実行して `iam.yaml` を S3 バケットにコピーします。`bucket-name` を前のステップのバケット名に置き換えてください。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws s3 cp iam.yaml s3://{bucket-name} + ::: +:::: +::::tab{id="local" label="ローカル開発"} 1. コンソールで S3 バケットに移動して選択します。 -2. **アップロード**ボタン -> **ファイルを追加**をクリックします。 -3. `iam.yaml` ファイルを選択します。 -4. **アップロード**ボタンをクリックしてファイルをアップロードします。 +1. **アップロード** ボタン -> **ファイルを追加** をクリックします。 +1. `iam.yaml` ファイルを選択します。 +1. **アップロード** ボタンをクリックしてファイルをアップロードします。 +:::: +::::: ##### 4. ネストされた IAM スタックをデプロイ 以前に作成したネストスタックを新しいテンプレートで更新します。 - +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/nested-stacks` ディレクトリに移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/nested-stacks + ::: +1. AWS EC2 Api を使用して VPC からアベイラビリティーゾーンのリストを取得し、出力から任意の 2 つの AZ をコピーして次のステップで使用します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws ec2 describe-availability-zones --output json --query "AvailabilityZones[*].ZoneName" + ::: +1. AWS CLI を使用してスタックを更新します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。`ParameterValue` の **bucketName** を [S3 バケットの準備](#2.-s3)セクションでメモした値に置き換えてください。`ParameterValue` の **AZ1** と **AZ2** を前のステップでコピーした値に置き換えてください。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation update-stack --stack-name cfn-workshop-nested-stacks \ + --template-body file://main.yaml \ + --parameters ParameterKey="S3BucketName",ParameterValue="bucketName" ParameterKey="AvailabilityZones",ParameterValue=AZ1\\,AZ2 \ + --capabilities CAPABILITY_NAMED_IAM + ::: +1. `update-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 + :::code{language=shell showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-nested-stacks/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **UPDATE_COMPLETE** になっているかどうかを確認します。最新のスタックステータスを確認するには、定期的に更新を選択する必要があります。 +:::: +::::tab{id="local" label="ローカル開発"} 1. AWS コンソールの Cloudformation サービスに移動します。 -2. **root** スタック (**ネストされた**タグが関連付けられていないスタック) を選択します。 -3. 右上の**更新**をクリックします。 -4. **テンプレートの準備**セクションで、**既存のテンプレートを置き換える**を選択します。 -5. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -6. **ファイルを選択**ボタンをクリックし、ワークショップディレクトリに移動します。 -7. `main.yaml` テンプレートファイルを選択し、**次へ**をクリックします。 -8. ウィザードに従い、IAM Capabilities を確認し、**送信**をクリックします。 +1. **root** スタック ( **ネストされた** タグが関連付けられていないスタック) を選択します。 +1. 右上の **更新** をクリックします。 +1. **テンプレートの準備** セクションで、 **既存のテンプレートを置き換える** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. **ファイルを選択** ボタンをクリックし、ワークショップディレクトリに移動します。 +1. `main.yaml` テンプレートファイルを選択し、 **次へ** をクリックします。 +1. ウィザードに従い、IAM Capabilities を確認し、 **送信** をクリックします。 +:::: +::::: #### 5. ネストされた EC2 スタックの作成 @@ -243,7 +325,7 @@ VPC テンプレートと同様に、`ec2.yaml` テンプレートの **Paramete `main.yaml` テンプレートの **Paramaters** セクションに以下のコードを追加します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} EnvironmentType: Description: 'Specify the Environment type of the stack.' Type: String @@ -253,26 +335,26 @@ EnvironmentType: - Test - Prod ConstraintDescription: 'Specify either Dev, Test or Prod.' -``` +::: ##### 2. メインテンプレートに EC2 リソースを作成 以下のコードを `main.yaml` テンプレートの **Resources** セクションにコピーします。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} EC2Stack: Type: AWS::CloudFormation::Stack Properties: TemplateURL: !Sub https://${S3BucketName}.s3.amazonaws.com/ec2.yaml TimeoutInMinutes: 20 -``` +::: ##### 3. EnvironmentType を EC2 スタックに追加します テンプレートに `EnvironmentType` パラメータを追加したので、これを `EC2Stack` リソースで参照する必要があります。 -`main.yaml` テンプレートのEC2 スタック [6-7] 行目に、`Parameters` セクションと `EnvironmentType` を追加します。 -```yaml {hl_lines=[6,7]} +`main.yaml` テンプレートの EC2 スタック [6-7] 行目に、`Parameters` セクションと `EnvironmentType` を追加します。 +:::code{language=yaml showLineNumbers=true showCopyAction=true highlightLines=6-7} EC2Stack: Type: AWS::CloudFormation::Stack Properties: @@ -280,13 +362,13 @@ EC2Stack: TimeoutInMinutes: 20 Parameters: EnvironmentType: !Ref EnvironmentType -``` +::: #### 6. 別のネストされたスタックから変数を渡す CloudFormation のネストスタックを更新する前に、やるべきことが他にもいくつかあります。 -+ EC2 セキュリティグループを作成する VPC を指定する必要があります。VPC パラメータを指定しないと、セキュリティグループは**デフォルト VPC** に作成されます。 ++ EC2 セキュリティグループを作成する VPC を指定する必要があります。VPC パラメータを指定しないと、セキュリティグループは **デフォルト VPC** に作成されます。 + EC2 インスタンスを作成するサブネットを指定する必要があります。 @@ -294,39 +376,40 @@ CloudFormation のネストスタックを更新する前に、やるべきこ 1. `ec2.yaml` ファイルを開き、テンプレートの **Parameters** セクションに `VpcId` と `SubnetId` の 2 つのパラメータを作成します。 - ```yaml - VpcId: - Type: AWS::EC2::VPC::Id - Description: 'The VPC ID' - - SubnetId: - Type: AWS::EC2::Subnet::Id - Description: 'The Subnet ID' - ``` - -2. 次に、`WebServerSecurityGroup` リソースを探します。 -3. `WebServerSecurityGroup` リソース [18] 行目に `VpcId` プロパティを追加し、 `VpcId` パラメータを参照します。セキュリティグループリソースは以下のコードのようになっているはずです。 - - ```yaml {hl_lines=[18]} - WebServerSecurityGroup: - Type: AWS::EC2::SecurityGroup - Properties: - GroupDescription: Enable HTTP and HTTPS access - - IpProtocol: tcp - FromPort: 80 - ToPort: 80 - CidrIp: 0.0.0.0/0 - SecurityGroupEgress: - - IpProtocol: tcp - FromPort: 80 - ToPort: 80 - CidrIp: 0.0.0.0/0 - - IpProtocol: tcp - FromPort: 443 - ToPort: 443 - CidrIp: 0.0.0.0/0 - VpcId: !Ref VpcId - ``` + :::code{language=yaml showLineNumbers=true showCopyAction=true} + VpcId: + Type: AWS::EC2::VPC::Id + Description: 'The VPC ID' + + SubnetId: + Type: AWS::EC2::Subnet::Id + Description: 'The Subnet ID' + ::: + +1. 次に、`WebServerSecurityGroup` リソースを探します。 +1. `WebServerSecurityGroup` リソース [18] 行目に `VpcId` プロパティを追加し、 `VpcId` パラメータを参照します。セキュリティグループリソースは以下のコードのようになっているはずです。 + + :::code{language=yaml showLineNumbers=true showCopyAction=true highlightLines=18} + WebServerSecurityGroup: + Type: AWS::EC2::SecurityGroup + Properties: + GroupDescription: Enable HTTP and HTTPS access + SecurityGroupIngress: + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + SecurityGroupEgress: + - IpProtocol: tcp + FromPort: 80 + ToPort: 80 + CidrIp: 0.0.0.0/0 + - IpProtocol: tcp + FromPort: 443 + ToPort: 443 + CidrIp: 0.0.0.0/0 + VpcId: !Ref VpcId + ::: ##### 2. VPC テンプレートの準備 @@ -336,7 +419,7 @@ CloudFormation のネストスタックを更新する前に、やるべきこ 以下のコードを `vpc.yaml` テンプレートに追加します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} Outputs: VpcId: Value: !Ref VPC @@ -346,14 +429,14 @@ Outputs: PublicSubnet2: Value: !Ref VPCPublicSubnet2 -``` +::: ##### 3. VpcId と SubnetId を **EC2Stack** スタックに追加する これで、VPC スタックから値を取得して EC2 スタックに渡すことができます。 `VpcId` と `SubnetId` パラメータを `main.yaml` テンプレートの EC2 スタックに追加します。 -```yaml {hl_lines=[8,9]} +:::code{language=yaml showLineNumbers=true showCopyAction=true highlightLines=8-9} EC2Stack: Type: AWS::CloudFormation::Stack Properties: @@ -363,33 +446,33 @@ EC2Stack: EnvironmentType: !Ref EnvironmentType VpcId: !GetAtt VpcStack.Outputs.VpcId SubnetId: !GetAtt VpcStack.Outputs.PublicSubnet1 -``` +::: ##### 4. IAM テンプレートの準備 `iam.yaml` を開いて、以下のコードを追加します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} Outputs: WebServerInstanceProfile: Value: !Ref WebServerInstanceProfile -``` +::: ##### 5. EC2 テンプレートの準備 1. `ec2.yaml` を開きます。 -2. テンプレートの **Parameters** セクションに `WebServerInstanceProfile` パラメータを作成します。 +1. テンプレートの **Parameters** セクションに `WebServerInstanceProfile` パラメータを作成します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} WebServerInstanceProfile: Type: String Description: 'Instance profile resource ID' -``` +::: ##### 6. WebServerInstanceProfile を **EC2Stack** スタックに追加 `webServerInstanceProfile` パラメータを `main.yaml` テンプレートの EC2 スタック [10] 行目に追加します。 -```yaml {hl_lines=[10]} +:::code{language=yaml showLineNumbers=true showCopyAction=true highlightLines=10} EC2Stack: Type: AWS::CloudFormation::Stack Properties: @@ -400,40 +483,82 @@ EC2Stack: VpcId: !GetAtt VpcStack.Outputs.VpcId SubnetId: !GetAtt VpcStack.Outputs.PublicSubnet1 WebServerInstanceProfile: !GetAtt IamStack.Outputs.WebServerInstanceProfile -``` +::: ##### 7. メインテンプレートの `WebsiteURL` を出力する `WebsiteURL` を `main.yaml` テンプレートの `Outputs` セクションに追加します。 -```yaml +:::code{language=yaml showLineNumbers=true showCopyAction=true} Outputs: WebsiteURL: Value: !GetAtt EC2Stack.Outputs.WebsiteURL -``` +::: ##### 8. EC2 スタックを S3 にアップロード 更新されたネストスタックをデプロイする前に、親テンプレート `main.yaml` が参照する S3 バケットのテンプレートを更新する必要があります。 -前のステップの [VPC スタックのアップロード](#3-upload-the-vpc-stack-to-s3) と同様に、`vpc.yaml`、`ec2.yaml`、 `iam.yaml` テンプレートを S3 バケットにアップロードします。 - +前のステップの [VPC スタックのアップロード](#3.-vpc-s3) と同様に、`vpc.yaml`、`ec2.yaml`、 `iam.yaml` テンプレートを S3 バケットにアップロードします。 + +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/nested-stacks` ディレクトリに移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/nested-stacks + ::: +1. 以下のコマンドを実行して、`iam.yaml`、`vpc.yaml`、`ec2.yaml` を S3 バケットにコピーします。`bucket-name` を前のステップのバケット名に置き換えてください。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws s3 cp iam.yaml s3://{bucket-name} +aws s3 cp vpc.yaml s3://{bucket-name} +aws s3 cp ec2.yaml s3://{bucket-name} + ::: +:::: +::::tab{id="local" label="ローカル開発"} 1. コンソールで S3 バケットに移動して選択します。 -2. **アップロード**ボタン -> **ファイルの追加**をクリックします。 -3. `vpc.yaml`、`iam.yaml`、`ec2.yaml` ファイルを選択します。 -4. **アップロード**ボタンをクリックしてファイルをアップロードします。 +1. **アップロード** ボタン -> **ファイルの追加** をクリックします。 +1. `vpc.yaml`、`iam.yaml`、`ec2.yaml` ファイルを選択します。 +1. **アップロード** ボタンをクリックしてファイルをアップロードします。 +:::: +::::: ##### 9. ネストされた EC2 スタックをデプロイ 以前に作成したネストスタックを新しいテンプレートで更新します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/nested-stacks` ディレクトリに移動します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + cd cfn101-workshop/code/workspace/nested-stacks + ::: +1. AWS EC2 Api を使用して VPC からアベイラビリティーゾーンのリストを取得し、出力から任意の 2 つの AZ をコピーして次のステップで使用します。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws ec2 describe-availability-zones --output json --query "AvailabilityZones[*].ZoneName" + ::: +1. AWS CLI を使用してスタックを更新します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。`ParameterValue` の **bucketName** を [S3 バケットの準備](#2.-s3)セクションでメモした値に置き換えてください。`ParameterValue` の **AZ1** と **AZ2** を前のステップでコピーした値に置き換えてください。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation update-stack --stack-name cfn-workshop-nested-stacks \ + --template-body file://main.yaml \ + --parameters ParameterKey="S3BucketName",ParameterValue="bucketName" ParameterKey="AvailabilityZones",ParameterValue=AZ1\\,AZ2 \ + --capabilities CAPABILITY_NAMED_IAM + ::: +1. `update-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 + :::code{language=json showLineNumbers=false showCopyAction=false} + "StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-nested-stacks/739fafa0-e4d7-11ed-a000-12d9009553ff" + ::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **UPDATE_COMPLETE** になっているかどうかを確認します。最新のスタックステータスを確認するには、定期的に更新を選択する必要があります。 +:::: +::::tab{id="local" label="ローカル開発"} 1. AWS コンソールの Cloudformation サービスに移動します。 -2. **root** スタック (**ネストされた** タグが関連付けられていないスタック) を選択します。 -3. 右上の**更新**をクリックします。 -4. **テンプレートの準備**セクションで、**既存のテンプレートを置き換える**を選択します。 -5. **テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。 -6. **ファイルを選択**ボタンをクリックし、ワークショップディレクトリに移動します。 -7. `main.yaml` テンプレートファイルを選択し、**次へ**をクリックします。 -8. ウィザードに従い、IAM Capabilities を確認し、**送信**をクリックします。 +1. **root** スタック ( **ネストされた** タグが関連付けられていないスタック) を選択します。 +1. 右上の **更新** をクリックします。 +1. **テンプレートの準備** セクションで、 **既存のテンプレートを置き換える** を選択します。 +1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 +1. **ファイルを選択** ボタンをクリックし、ワークショップディレクトリに移動します。 +1. `main.yaml` テンプレートファイルを選択し、 **次へ** をクリックします。 +1. ウィザードに従い、IAM Capabilities を確認し、 **送信** をクリックします。 +:::: +::::: #### 7.デプロイメントのテスト @@ -441,7 +566,7 @@ Outputs: プライベートモードで新しいブラウザウィンドウを開き、`WebsiteURL` を入力します。 -`WebsiteURL` は、CloudFormation コンソールのメインスタックの**出力**タブから取得できます。 +`WebsiteURL` は、CloudFormation コンソールのメインスタックの **出力** タブから取得できます。 ![website-url-output.png](/static/intermediate/templates/nested-stacks/website-url-output.ja.png) @@ -451,19 +576,16 @@ Outputs: ##### 2. SSM セッションマネージャーを使用してインスタンスにログイン -SessionManager 経由でインスタンスにログインできることを確認します。 - -方法が不明な場合は、[Session Manager](/basics/operations/session-manager#challenge) ラボの指示に従ってください。 - +**[セッションマネージャ](https://console.aws.amazon.com/systems-manager)** 経由でインスタンスにログインできることを確認します。インスタンスがデプロイされているのと同じリージョン、たとえば`米国東部(バージニア北部) us-east-1` を選択します。 ### クリーンアップ 作成したリソースをクリーンアップするには、次の手順に従います。 -1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** で、このラボで作成した **root** スタックを選択します。具体的には、`cfn-workshop-nested-stack` を選択します。 -2. **root** スタックは、すべての **子** スタックの削除を自動的に処理します。 -3. 右上の**削除**をクリックします。 -4. ポップアップウィンドウで、**スタックの削除**をクリックします。 -5. **DELETE_COMPLETE** のステータスが表示されるまで、**更新**ボタンを数回クリックします。 +1. **[CloudFormation コンソール](https://console.aws.amazon.com/cloudformation)** で、このラボで作成した **root** スタックを選択します。具体的には、`cfn-workshop-nested-stacks` を選択します。 +1. **root** スタックは、すべての **子** スタックの削除を自動的に処理します。 +1. 右上の **削除** をクリックします。 +1. ポップアップウィンドウで、 **削除** をクリックします。 +1. **DELETE_COMPLETE** のステータスが表示されるまで、 **更新** ボタンを数回クリックします。 --- ### まとめ diff --git a/content/intermediate/templates/package-and-deploy/index.ja.md b/content/intermediate/templates/package-and-deploy/index.ja.md index c930b2d23..bf3f8bca5 100644 --- a/content/intermediate/templates/package-and-deploy/index.ja.md +++ b/content/intermediate/templates/package-and-deploy/index.ja.md @@ -3,6 +3,10 @@ title: "パッケージ化とデプロイ" weight: 600 --- +_ラボ実施時間 : 15分程度_ + +--- + ### 概要 このワークショップの [基本](/basics)で、CloudFormation コンソールを介して単一の YAML テンプレートをデプロイしました。 @@ -43,16 +47,15 @@ cfn101-workshop/code/workspace/package-and-deploy └── requirements.txt ::: - #### CloudFormation テンプレート内のローカルファイルを参照 -従来は、すべての Lambda ソースを圧縮して S3 にアップロードし、次にテンプレートでS3 ロケーションを参照する必要がありました。この作業はかなり面倒です。 +従来は、すべての Lambda ソースを圧縮して S3 にアップロードし、次にテンプレートで S3 ロケーションを参照する必要がありました。この作業はかなり面倒です。 -ただし、[aws cloudformation package](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html) を使えば、ローカルファイルを直接参照できます。直接参照の方が、S3を参照する従来の方法と比較し利用が簡単です。 +ただし、[aws cloudformation package](https://docs.aws.amazon.com/cli/latest/reference/cloudformation/package.html) を使えば、ローカルファイルを直接参照できます。直接参照の方が、S3 を参照する従来の方法と比較し利用が簡単です。 `infrastructure.template` スニペットを見ると、`Code` プロパティのローカルディレクトリの [9] 行目への参照が分かります。 -:::code{language=yaml showLineNumbers=true showCopyAction=false} +:::code{language=yaml showLineNumbers=true showCopyAction=false lineNumberStart=19} PythonFunction: Type: AWS::Lambda::Function Properties: @@ -61,7 +64,7 @@ PythonFunction: Runtime: python3.8 Role: !GetAtt LambdaBasicExecutionRole.Arn Handler: lambda_function.handler - Code: lambda/ # <<< This is a local directory + Code: lambda/ # <<< This is a local directory ::: #### アーティファクトをパッケージ化してアップロード @@ -69,8 +72,8 @@ PythonFunction: `aws cloudformation package` は以下のアクションを実行します。 1. ローカルファイルを ZIP で圧縮します。 -2. 指定された S3 バケットにアップロードします。 -3. ローカルパスが S3 URI に置き換えられた新しいテンプレートを生成します。 +1. 指定された S3 バケットにアップロードします。 +1. ローカルパスが S3 URI に置き換えられた新しいテンプレートを生成します。 ##### 1. S3 バケットの作成 @@ -79,7 +82,7 @@ PythonFunction: ::alert[`s3://` の後のバケット名は必ず一意の名前に置き換えてください!]{type="info"} :::code{language=shell showLineNumbers=false showCopyAction=true} -aws s3 mb s3://example-bucket-name --region eu-west-1 +aws s3 mb s3://example-bucket-name --region us-east-1 ::: ##### 2. インストール機能の依存関係 @@ -93,6 +96,8 @@ aws s3 mb s3://example-bucket-name --region eu-west-1 pip install pytz --target lambda ::: +`python 3` がお使いの場合は、上記のコマンドで `pip` の代わりに `pip3` を使う必要があるかもしれません。 + `lambda/` フォルダの中に `pytz` パッケージがあるはずです。 ##### 3. `package` コマンドの実行 @@ -101,10 +106,10 @@ pip install pytz --target lambda :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation package \ - --template-file infrastructure.template \ - --s3-bucket example-bucket-name \ - --s3-prefix cfn-workshop-package-deploy \ - --output-template-file infrastructure-packaged.template +--template-file infrastructure.template \ +--s3-bucket example-bucket-name \ +--s3-prefix cfn-workshop-package-deploy \ +--output-template-file infrastructure-packaged.template ::: 上記のコマンドで使った個々の `package` オプションを詳しく見てみましょう。 @@ -120,7 +125,7 @@ aws cloudformation package \ `Code` プロパティが [12-14] 行目の `S3Bucket` と `S3Key` の 2 つの新しい属性で更新されていることが分かります。 -```yaml {hl_lines=[12,13,14]} +:::code{language=yaml showLineNumbers=true showCopyAction=true lineNumberStart=16 highlightLines=12-14} PythonFunction: Type: AWS::Lambda::Function Properties: @@ -135,9 +140,7 @@ PythonFunction: Code: S3Bucket: example-bucket-name S3Key: cfn-workshop-package-deploy/1234567890 - TracingConfig: - Mode: Active -``` +::: アップロードされたファイルの内容も見てみましょう。上記のリストから、ダウンロードするバケットとオブジェクト名が判明しています。 @@ -145,9 +148,10 @@ PythonFunction: aws s3 cp s3://example-bucket-name/cfn-workshop-package-deploy/1234567890 . ::: -`package` はファイルを圧縮することがわかっているので、`.zip` 拡張子がなくても `unzip` できます。 +`package` はファイルを ZIP 形式で圧縮することがわかっているので `.zip` 拡張子がなくても `unzip` できます。 -##### Unix/Linux +:::::tabs{variant="container"} +::::tab{id="shell" label="Cloud9/Unix/Linux"} :::code{language=shell showLineNumbers=false showCopyAction=false} unzip -l ce6c47b6c84d94bd207cea18e7d93458 @@ -158,7 +162,8 @@ Archive: ce6c47b6c84d94bd207cea18e7d93458 455 02-12-2020 17:18 lambda_function.py 4745 02-13-2020 14:36 pytz/tzfile.py ::: -##### Powershell +:::: +::::tab{id="powershell" label="Powershell"} :::code{language=powershell showLineNumbers=false showCopyAction=false} rename-item ce6c47b6c84d94bd207cea18e7d93458 packagedLambda.zip @@ -174,6 +179,8 @@ d----- 10/29/2021 4:25 PM pytz-2021.3.dist-info -a---- 10/29/2021 11:19 AM 475 lambda_function.py -a---- 10/29/2021 11:19 AM 14 requirements.txt ::: +:::: +::::: ### テンプレートの検証 @@ -190,10 +197,10 @@ aws cloudformation validate-template \ 成功すると、CloudFormation はパラメータ、テンプレートの説明、機能のリストを含むレスポンスを送信します。 -:::code{language=json showLineNumbers=false showCopyAction=true} +:::code{language=json showLineNumbers=false showCopyAction=false} { "Parameters": [], - "Description": "CFN 201 Workshop - Lab 12 Helper Scripts. ()", + "Description": "AWS CloudFormation workshop - Package and deploy.", "Capabilities": [ "CAPABILITY_IAM" ], @@ -211,10 +218,10 @@ aws cloudformation validate-template \ :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation deploy \ - --template-file infrastructure-packaged.template \ - --stack-name cfn-workshop-lambda \ - --region eu-west-1 \ - --capabilities CAPABILITY_IAM +--template-file infrastructure-packaged.template \ +--stack-name cfn-workshop-package-deploy-lambda \ +--region eu-west-1 \ +--capabilities CAPABILITY_IAM ::: ::alert[S3 のアーティファクトを参照するパッケージテンプレート `infrastructure-packaged.template` を利用した点に注意してください。ローカルパスを持つオリジナルのものではありません!]{type="info"} @@ -240,27 +247,24 @@ Lambda 関数は、現在の UTC の日付と時刻を取得します。次に ターミナルから以下を実行します。 :::::tabs{variant="container"} - -::::tab{id="sh" label="Unix/Linux"} +::::tab{id="sh" label="Cloud9/Unix/Linux"} :::code{language=shell showLineNumbers=false showCopyAction=true} aws lambda invoke \ - --function-name cfn-workshop-python-function \ - --payload "{\"time_zone\": \"Asia/Tokyo\"}" \ - --cli-binary-format raw-in-base64-out \ - response.json +--function-name cfn-workshop-python-function \ +--payload "{\"time_zone\": \"Asia/Tokyo\"}" \ +--cli-binary-format raw-in-base64-out \ +response.json ::: :::: - ::::tab{id="cmd" label="CMD"} :::code{language=shell showLineNumbers=false showCopyAction=true} aws lambda invoke ^ - --function-name cfn-workshop-python-function ^ - --payload "{\"time_zone\": \"Asia/Tokyo\"}" ^ - --cli-binary-format raw-in-base64-out ^ - response.json +--function-name cfn-workshop-python-function ^ +--payload "{\"time_zone\": \"Asia/Tokyo\"}" ^ +--cli-binary-format raw-in-base64-out ^ +response.json ::: :::: - ::::tab{id="powershell" label="Powershell"} :::code{language=powershell showLineNumbers=false showCopyAction=true} aws lambda invoke ` @@ -278,7 +282,7 @@ Lambda がトリガーされ、Lambda からのレスポンスが `response.json :::::tabs{variant="container"} -::::tab{id="sh" label="Unix/Linux"} +::::tab{id="sh" label="Cloud9/Unix/Linux"} :::code{language=shell showLineNumbers=false showCopyAction=true} cat response.json ::: @@ -292,6 +296,42 @@ more response.json ::::: --- + +### クリーンアップ + +次の手順に従ってこのラボで作成したリソースをクリーンアップしてください。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. 次の AWS CLI コマンドを使用して S3 バケットを削除します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws s3 rb s3://example-bucket-name --force +::: +1. 次の AWS CLI コマンドを使用してスタックを削除します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ + --stack-name cfn-workshop-package-deploy-lambda +::: +1. 次の AWS CLI コマンドを使用して、スタックの削除が完了するのを待ちます。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-delete-complete \ +--stack-name cfn-workshop-package-deploy-lambda +::: +:::: +::::tab{id="LocalDevelopment" label="ローカル開発"} +1. [AWS S3 コンソール](https://s3.console.aws.amazon.com/s3/)に移動します。 +1. このラボで作成した S3 バケットを選択し、 **空にする** を選択します。 +1. コンソールの指示に従って、バケット内のオブジェクトの削除を確認します。 +1. 次に S3 コンソールに戻り、このラボで作成した S3 バケットを選択し、 **削除** を選択します +1. コンソールの指示に従って、S3 バケットの削除を確認します。 +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +1. `cfn-workshop-package-deploy-lambda` という名前のスタックを選択し、 **削除** を選択します。 +1. ポップアップウィンドウで、 **削除** を選択します。 +1. **DELETE_COMPLETE** というステータスが表示されるまで、画面を更新します。 +:::: +::::: + +--- + ### まとめ おめでとうございます。コマンドラインを使用して CloudFormation テンプレートを正常にパッケージ化およびデプロイしました。 diff --git a/content/intermediate/templates/policy-as-code-with-guard/index.ja.md b/content/intermediate/templates/policy-as-code-with-guard/index.ja.md index 339f0f061..fbbcdb7f1 100644 --- a/content/intermediate/templates/policy-as-code-with-guard/index.ja.md +++ b/content/intermediate/templates/policy-as-code-with-guard/index.ja.md @@ -13,9 +13,9 @@ weight: 700 * 開発者のワークステーションで検出 * デリバリーパイプラインの継続的インテグレーション (CI) フェーズで検出 -policy-as-code を採用すると、SDLC プロセスの早い段階で発見したポリシー・コンプライアンスの問題に対処する機会が得られるため、**SDLC のフィードバック・ループをスピードアップ**できます。 +policy-as-code を採用すると、SDLC プロセスの早い段階で発見したポリシー・コンプライアンスの問題に対処する機会が得られるため、 **SDLC のフィードバック・ループをスピードアップ** できます。 -Policy-as-Codeをプログラムで活用するには、ポリシー要件を、Policy-as-Code ツールが理解できる言語で記述されたルールに変換する必要があります。このラボでは、[AWS CloudFormation Guard](https://github.com/aws-cloudformation/cloudformation-guard) (Guard) などのツールを使用して、作成したルールに対するポリシーコンプライアンスの検証方法を学びます。 +Policy-as-Code をプログラムで活用するには、ポリシー要件を、Policy-as-Code ツールが理解できる言語で記述されたルールに変換する必要があります。このラボでは、[AWS CloudFormation Guard](https://github.com/aws-cloudformation/cloudformation-guard) (Guard) などのツールを使用して、作成したルールに対するポリシーコンプライアンスの検証方法を学びます。 ### 取り上げるトピック @@ -56,8 +56,8 @@ cfn-guard help さあ、始めましょう! 次に示す手順に従って進めます。 1. `code/workspace/policy-as-code-with-guard` ディレクトリに移動します。 -2. お好みのテキストエディタで `example_bucket.yaml` CloudFormation テンプレートを開きます。 -3. テンプレートには `AWS::S3::Bucket` リソースタイプが記述されています。AES256 アルゴリズムを使用して [サーバー側の暗号化](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-bucketencryption.html)と[バージョニング](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-versioningconfig.html)有効化設定を含む `Properties` セクションを追加してテンプレートを更新します。次に表示される内容をコピーし、`example_bucket.yaml` ファイルにペーストします。 +1. お好みのテキストエディタで `example_bucket.yaml` CloudFormation テンプレートを開きます。 +1. テンプレートには `AWS::S3::Bucket` リソースタイプが記述されています。AES256 アルゴリズムを使用して [サーバー側の暗号化](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-bucketencryption.html)と[バージョニング](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-versioningconfig.html)有効化設定を含む `Properties` セクションを追加してテンプレートを更新します。次に表示される内容をコピーし、`example_bucket.yaml` ファイルにペーストします。 ```yaml Properties: @@ -69,7 +69,7 @@ Properties: Status: Enabled ``` -4. ガードルール節の例を作成して、両方のプロパティが期待どおりに記述されていることを確認します。前述と同じディレクトリにある `example_bucket.guard` ファイルを開き、**type ブロック**を作成して、テンプレートに記述した `AWS::S3::Bucket` タイプのリソースの設定を検証します。次に表示されるコンテンツをコピーし、`example_bucket.guard` ファイルにペーストします。 +1. ガードルール節の例を作成して、両方のプロパティが期待どおりに記述されていることを確認します。前述と同じディレクトリにある `example_bucket.guard` ファイルを開き、 **type ブロック** を作成して、テンプレートに記述した `AWS::S3::Bucket` タイプのリソースの設定を検証します。次に表示されるコンテンツをコピーし、`example_bucket.guard` ファイルにペーストします。 ```json AWS::S3::Bucket { @@ -86,12 +86,12 @@ AWS::S3::Bucket { ::alert[ガードルールを書くときは、リソースタイプを選択するデフォルトモードとして **filters** を使用します。新しい概念について少しずつ学んでいくので、このセクションでは引き続き type ブロック (特定の型をマッチさせる場合に使うフィルターのためのブロック) を使います。フィルターについては次のセクションで学びます。]{type="info"} -5. 前述のルール節のサンプルセットを確認してください。次の点に注意してください。 +1. 前述のルール節のサンプルセットを確認してください。次の点に注意してください。 * 外側のブロックには `AWS::S3::Bucket` タイプが含まれています。このブロック内のルール条項は、入力データとして提供しているテンプレートで宣言した `AWS::S3::Bucket` タイプのすべてのリソースに適用されます。 * ルール節は、ドット (`.`) 文字を使ってデータ階層を下ります (例えば、`VersioningConfiguration.Status` は `VersioningConfiguration` の下の `Status` プロパティを参照します)。 * ワイルドカード (`*`) 文字は、特定のレベルのすべての配列インデックスを辿るために使われます (例えば、`ServerSideEncryptionConfiguration[*]`)。 * ルール節には、`<<` と `>>` ブロックで区切られたオプションのセクションが含まれており、[カスタムメッセージ](https://docs.aws.amazon.com/ja_jp/cfn-guard/latest/ug/writing-rules.html#clauses-custom-messages) を指定できます。 - * 例で宣言されているルール節は検証に合格することが期待されます。Guardでは、[連言標準形](https://ja.wikipedia.org/wiki/%E9%80%A3%E8%A8%80%E6%A8%99%E6%BA%96%E5%BD%A2) (CNF) を使用し、複数の論理的な `AND` 節を、`OR` 節を交えて記述します。前述の例では、ルール節は `AND` 節として解釈されます (つまり、サーバー側の暗号化 *と* バージョン管理を検証し、データがルールに照らして検証に合格するには、*両方* が満たされる必要があります。)。例えば、ClauseA *または* ClauseB が満たされているかを検証したいユースケースがある場合は、ClauseA の行に `OR` を追加してこの動作を記述します。次の例において、ルールを合格するためには、`ExampleClause1` と `ExampleClause2` の両方の要件が満たされている必要があります。`ExampleClauseA` か `ExampleClauseB` のどちらかが満たされなければなりません: + * 例で宣言されているルール節は検証に合格することが期待されます。Guard では、[連言標準形](https://ja.wikipedia.org/wiki/%E9%80%A3%E8%A8%80%E6%A8%99%E6%BA%96%E5%BD%A2) (CNF) を使用し、複数の論理的な `AND` 節を、`OR` 節を交えて記述します。前述の例では、ルール節は `AND` 節として解釈されます (つまり、サーバー側の暗号化 *と* バージョン管理を検証し、データがルールに照らして検証に合格するには、*両方* が満たされる必要があります。)。例えば、ClauseA *または* ClauseB が満たされているかを検証したいユースケースがある場合は、ClauseA の行に `OR` を追加してこの動作を記述します。次の例において、ルールを合格するためには、`ExampleClause1` と `ExampleClause2` の両方の要件が満たされている必要があります。`ExampleClauseA` か `ExampleClauseB` のどちらかが満たされなければなりません: :::code{language=shell showLineNumbers=false showCopyAction=false} [...] @@ -102,13 +102,13 @@ ExampleClauseB [...] ::: -6. ルール節の例を詳しく見てきたので、次に示すように、`-d` (または `—data`) フラグでテンプレートを指定し、`-r` (または `—rules`) でルールを指定して、`validate` Guard サブコマンドを実行します。 +1. ルール節の例を詳しく見てきたので、次に示すように、`-d` (または `—data`) フラグでテンプレートを指定し、`-r` (または `—rules`) でルールを指定して、`validate` Guard サブコマンドを実行します。 :::code{language=shell showLineNumbers=false showCopyAction=true} -cfn-guard validate -d example_bucket.yaml -r example_bucket.guard +cfn-guard validate -d example_bucket.yaml -r example_bucket.guard --show-summary pass ::: -7. テンプレートがルール節に対する検証に合格したことを示す次のような出力が得られるはずです。 +1. テンプレートがルール節に対する検証に合格したことを示す次のような出力が得られるはずです。 :::code{language=shell showLineNumbers=false showCopyAction=false} example_bucket.yaml Status = PASS @@ -121,7 +121,7 @@ Rule [example_bucket.guard/default] is compliant for template [example_bucket.ya -- ::: -::alert[前述の `example_bucket.guard/default` 出力部分に示されている `default` サフィックスは、ルール節が `default` という名前のルールに属していることを示しています。このラボの後半で、特定の名前 (**名前付きルール**) でルールを作成し、デフォルトルールの代わりに使用します。この作業を実施することで、モジュール化された再利用可能なルールを作成できます。]{type="info"} +::alert[前述の `example_bucket.guard/default` 出力部分に示されている `default` サフィックスは、ルール節が `default` という名前のルールに属していることを示しています。このラボの後半で、特定の名前 ( **名前付きルール** ) でルールを作成し、デフォルトルールの代わりに使用します。この作業を実施することで、モジュール化された再利用可能なルールを作成できます。]{type="info"} おめでとうございます! 最初のガードルールを作成し、それを使用して S3 バケット設定例を記述したサンプルテンプレートを検証しました。 @@ -167,7 +167,7 @@ cfn-guard validate -d example_bucket.yaml -r example_bucket.guard #### モジュール性と再利用性を考慮してルールを書き直す -このセクションでは、ルール節を別々のルールに分解して、モジュール化して再利用できるようにします。**シンプルでモジュール化されたガードルールを作成すると、再利用の機会が得られるだけでなく、データを検証したときに失敗したルールを特定したり、必要に応じてルールをトラブルシューティングしたりするのが簡単になります。** +このセクションでは、ルール節を別々のルールに分解して、モジュール化して再利用できるようにします。 **シンプルでモジュール化されたガードルールを作成すると、再利用の機会が得られるだけでなく、データを検証したときに失敗したルールを特定したり、必要に応じてルールをトラブルシューティングしたりするのが簡単になります。** 前に示したルール節の例を思い出してください。1 つの節では、バケットに設定したサーバー側の暗号化設定を検証し、もう 1 つの節ではバケットのバージョニング有効化設定を検証しました。このロジックを 2 つの [名前付きルール](https://docs.aws.amazon.com/ja_jp/cfn-guard/latest/ug/named-rule-block-composition.html) に書き換えてみましょう。これらは名前を割り当てたルールです。 @@ -321,10 +321,10 @@ Test Case #2 タスクは以下のとおりです。 1. `example_bucket_tests.yaml` ユニットテストファイルの内容に、`true` に設定されたすべての `publicAccessBlockConfiguration` プロパティを含むテスト入力データを提供するときに、これから作成する `validate_bucket_public_access_block_example` という新しいルールを検証するための新しい `input` セクションを追加します。 -2. `example_bucket.guard` ファイルに `validate_bucket_public_access_block_example` ルールを実装します。ルールに記述する各節の後に、`PublicAccessBlockConfiguration` プロパティごとにカスタムメッセージを追加します。 -3. テストを実行するには、`test` サブコマンドで Guard を実行します。ユニットテストの出力に Test Case #3 セクションがあり、新しいルールのユニットテストが成功したことを示す `validate_bucket_public_access_block_example: Expected = PASS, Evaluated = PASS` のような行があるはずです。 -3. `example_bucket.yaml` テンプレートを更新し、関連する `PublicAccessBlockConfiguration` 設定を追加します。 -4. `validate` サブコマンドを使用して Guard を実行し、`example_bucket.yaml` ファイルの内容を、`example_bucket.guard` ファイルに記述したルールと照らし合わせて検証します。結果の出力には、新しいルールに対する検証が成功したことを示す `example_bucket.guard/validate_bucket_public_access_block_example PASS` のような文字列が表示されるはずです。 +1. `example_bucket.guard` ファイルに `validate_bucket_public_access_block_example` ルールを実装します。ルールに記述する各節の後に、`PublicAccessBlockConfiguration` プロパティごとにカスタムメッセージを追加します。 +1. テストを実行するには、`test` サブコマンドで Guard を実行します。ユニットテストの出力に Test Case #3 セクションがあり、新しいルールのユニットテストが成功したことを示す `validate_bucket_public_access_block_example: Expected = PASS, Evaluated = PASS` のような行があるはずです。 +1. `example_bucket.yaml` テンプレートを更新し、関連する `PublicAccessBlockConfiguration` 設定を追加します。 +1. `validate` サブコマンドを使用して Guard を実行し、`example_bucket.yaml` ファイルの内容を、`example_bucket.guard` ファイルに記述したルールと照らし合わせて検証します。結果の出力には、新しいルールに対する検証が成功したことを示す `example_bucket.guard/validate_bucket_public_access_block_example PASS` のような文字列が表示されるはずです。 :::expand{header= "ヒントが必要ですか?"} diff --git a/content/intermediate/templates/resource-dependencies/index.ja.md b/content/intermediate/templates/resource-dependencies/index.ja.md index a5bcdf7ef..c194283e0 100644 --- a/content/intermediate/templates/resource-dependencies/index.ja.md +++ b/content/intermediate/templates/resource-dependencies/index.ja.md @@ -3,6 +3,10 @@ title: "リソース依存関係" weight: 200 --- +_ラボ実施時間 : 15分程度_ + +--- + ### 概要 [AWS CloudFormation](https://aws.amazon.com/jp/cloudformation/) を使用して、テンプレートに記述したリソースをプログラム的にプロビジョニングする際、あるリソースが 1 つ以上のリソースに依存する場合があります。例えば、[Amazon Elastic Compute Cloud](https://aws.amazon.com/jp/ec2/) (Amazon EC2) インスタンスは、Amazon EC2 インスタンスに使用するセキュリティグループに依存します。CloudFormation スタックにおいて、EC2 がセキュリティグループを参照するように記述することで、最初にセキュリティグループが作成され、次に Amazon EC2 インスタンスが作成されます。 @@ -34,9 +38,9 @@ weight: 200 リソース間に依存関係がない場合に、CloudFormation がリソースの作成順序をどのように処理するかを見てみましょう。 -次に示すテンプレートの抜粋にある 2 つのリソースに注目してください。1 つは [Amazon Simple Storage Service](https://aws.amazon.com/jp/s3/) (Amazon S3) [Buket](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html)、もう1つは [Amazon Simple Notification Service](https://aws.amazon.com/jp/sns/) (Amazon SNS) [Topic](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sns-topic.html) です。両方のリソースには、相互に依存関係が定義されていません。 +次に示すテンプレートの抜粋にある 2 つのリソースに注目してください。1 つは [Amazon Simple Storage Service](https://aws.amazon.com/jp/s3/) (Amazon S3) [Buket](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html)、もう 1 つは [Amazon Simple Notification Service](https://aws.amazon.com/jp/sns/) (Amazon SNS) [Topic](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sns-topic.html) です。両方のリソースには、相互に依存関係が定義されていません。 -::alert[次の例には、Amazon S3バケットのための `BucketName` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html#aws-properties-s3-bucket-properties)とAmazon SNSトピックのための `TopicName` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sns-topic.html#aws-resource-sns-topic-properties)は含まれていません。どちらの場合も、CloudFormation は指定されたリソースに一意の名前を生成します。]{type="info"} +::alert[次の例には、Amazon S3 バケットのための `BucketName` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket.html#aws-properties-s3-bucket-properties)と Amazon SNS トピックのための `TopicName` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sns-topic.html#aws-resource-sns-topic-properties)は含まれていません。どちらの場合も、CloudFormation は指定されたリソースに一意の名前を生成します。]{type="info"} `resource-dependencies-without-dependson.yaml` ファイルに、以下のコンテンツをコピーし追加します。次に、スタックを作成し、スタックイベントを確認してリソースが作成される順序を確認します。 @@ -59,20 +63,40 @@ Resources: AWS CloudFormation コンソールにて、`resource-dependencies-without-dependson.yaml` を使用し、[スタックを作成](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cfn-console-create-stack.html)します。 +:::::tabs{variant="container"} -1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 -2. **スタックの作成**、**新しいリソースを使用 (標準)** を選択します。 -3. **テンプレート準備完了**オプションを選択します。**テンプレートの指定**セクションで、**テンプレートファイルのアップロード**を選択します。`resource-dependencies-without-dependson.yaml` テンプレートをアップロードし、**次へ**をクリックします。 -4. スタック名を入力します。例えば、`resource-dependencies-lab` と入力します。準備ができたら、**次へ**をクリックします。 -5. **スタックオプションの設定**ページはデフォルト値のまま、ページの一番下までスクロールして**次へ**をクリックします。 -6. **レビュー**ページを一番下までスクロールして**送信**をクリックします。 +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/resource-dependencies` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/resource-dependencies +::: +1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-resource-dependencies \ +--template-body file://resource-dependencies-without-dependson.yaml +::: +1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resource-dependencies/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: + 1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +1. **スタックの作成** 、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレート準備完了** オプションを選択します。 **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。`resource-dependencies-without-dependson.yaml` テンプレートをアップロードし、 **次へ** をクリックします。 +1. スタック名を入力します。例えば、`resource-dependencies-lab` と入力します。準備ができたら、 **次へ** をクリックします。 +1. **スタックオプションの設定** ページはデフォルト値のまま、ページの一番下までスクロールして **次へ** をクリックします。 +1. **レビュー** ページを一番下までスクロールして **送信** をクリックします。 +:::: +::::: スタックの `CREATE_COMPLETE` ステータスが表示されるまでページを更新します。それでは、スタックイベントを確認しましょう。次に示す画像のようになるはずです。 ![resource-dependencies-lab.png](/static/intermediate/templates/resource-dependencies/resource-dependencies-lab.ja.png) -スタックイベントを見ると、`SNSTopic` リソースと `S3Bucket` リソースの作成が同時に開始されたことがわかります。2つのリソース間には依存関係がないため、CloudFormation は両方のリソースの作成を並行して開始しました。 +スタックイベントを見ると、`SNSTopic` リソースと `S3Bucket` リソースの作成が同時に開始されたことがわかります。2 つのリソース間には依存関係がないため、CloudFormation は両方のリソースの作成を並行して開始しました。 ここで、最初に Amazon S3 バケットを作成し、バケットが正常に作成されて初めて Amazon SNS トピックの作成を開始するシナリオを考えてみましょう。シナリオを実現するために、`DependsOn` 属性の使用が役立ちます。`DependsOn` を使用して `SNStopic` リソースの依存関係を明示的に定義し、`DependsOn` 属性の値として Amazon S3 バケットリソースの論理 ID (例では、`S3Bucket` を指定) を使用します。`DependsOn` を利用すると、CloudFormation は S3 バケットの作成が完了するのを待ってから、トピックの作成を開始します。それでは、見てみましょう! @@ -101,7 +125,7 @@ Resources: ``` -上記と同じ手順に従って、`resource-dependencies-with-dependson.yaml` テンプレートファイルを使用して新しいスタックを作成します。その際、別のスタック名 (例: `resource-dependencies-lab-dependson`) を指定し、スタックを作成します。 +上記と同じ手順に従って、`resource-dependencies-with-dependson.yaml` テンプレートファイルを使用して新しいスタックを作成します。その際、別のスタック名 (例: `cfn-workshop-resource-dependencies-dependson`) を指定し、スタックを作成します。 前回とは、スタックイベントが違って見えるはずです。 @@ -175,21 +199,43 @@ Resources: スタックを作成して、上記の動作を確認してみましょう。AWS CloudFormation コンソールにて、`resource-dependency-with-intrinsic-functions.yaml` を使用し、[スタックを作成](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-console-create-stack.html)します。 +:::::tabs{variant="container"} -1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 -2. **スタックの作成**、**新しいリソースを使用 (標準)**を選択します。 -3. **テンプレート準備完了**オプションを選択します。**テンプレートを指定**セクションで、**テンプレートファイルのアップロード**を選択します。`resource-dependencies-with-intrinsic-functions.yaml` テンプレートをアップロードし、**次へ**をクリックします。 -4. スタック名を入力します。例えば、`resource-dependencies-lab-ref-getatt` と入力します。準備ができたら、**次へ**をクリックします。 -5. **パラメータ**セクションで、Amazon SNS トピックサブスクリプションのメールアドレスを入力します。準備ができたら、**次へ**をクリックします。 -6. **スタックオプションの設定**ページはデフォルト値のまま、ページの一番下までスクロールして**次へ**をクリックします。 -7. **レビュー**ページを一番下までスクロールして**送信**をクリックします。 +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/resource-dependencies` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/resource-dependencies +::: +1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack --stack-name cfn-workshop-resource-dependencies-ref-getatt \ +--template-body file://resource-dependencies-with-intrinsic-functions.yaml \ +--parameters ParameterKey="EmailAddress",ParameterValue="your-email-address-here" +::: +1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resource-dependencies-ref-getatt/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。 +:::: + +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +1. **スタックの作成** 、 **新しいリソースを使用 (標準)** を選択します。 +1. **テンプレート準備完了** オプションを選択します。 **テンプレートを指定** セクションで、 **テンプレートファイルのアップロード** を選択します。`resource-dependencies-with-intrinsic-functions.yaml` テンプレートをアップロードし、 **次へ** をクリックします。 +1. スタック名を入力します。例えば、`cfn-workshop-resource-dependencies-ref-getatt` と入力します。準備ができたら、 **次へ** をクリックします。 +1. **パラメータ** セクションで、Amazon SNS トピックサブスクリプションのメールアドレスを入力します。準備ができたら、 **次へ** をクリックします。 +1. **スタックオプションの設定** ページはデフォルト値のまま、ページの一番下までスクロールして **次へ** をクリックします。 +1. **レビュー** ページを一番下までスクロールして **送信** をクリックします。 +:::: +::::: スタックが作成されると、スタックのイベントは次のようになります。 ![resource-dependencies-lab-ref-getatt.png](/static/intermediate/templates/resource-dependencies/resource-dependencies-lab-ref-getatt.ja.png) -`resource-dependencies-lab-ref-getatt` スタックのスタックイベントを確認しましょう。`SNSTopic` リソースと `SecurityGroup` リソースの作成は、両方のリソースには相互に依存関係がないことから、並行して開始されます。また、`SecurityGroupIngress` リソースの作成は `SecurityGroup` リソースが `CREATE_COMPLETE` ステータスになった後にのみ開始され、`SNSTopicSubscription` の作成は、`SNSTopic` リソースが正常に作成された後に開始されます。 +`cfn-workshop-resource-dependencies-ref-getatt` スタックのスタックイベントを確認しましょう。`SNSTopic` リソースと `SecurityGroup` リソースの作成は、両方のリソースには相互に依存関係がないことから、並行して開始されます。また、`SecurityGroupIngress` リソースの作成は `SecurityGroup` リソースが `CREATE_COMPLETE` ステータスになった後にのみ開始され、`SNSTopicSubscription` の作成は、`SNSTopic` リソースが正常に作成された後に開始されます。 スタックを削除すると、CloudFormation は作成順序が逆になります。この場合、`SNSTopicSubscription` と `SecurityGroupIngress` リソースが最初に削除され、続いて `SecurityGroup` と `SNSTopic` が削除されます。 @@ -206,7 +252,7 @@ Resources: * セキュリティグループが `CREATE_COMPLETE` としてマークされると、Amazon EC2 インスタンスリソースの作成が開始されます。 * Amazon EC2 インスタンスが正常に作成されると、CloudFormation は Amazon S3 バケットの作成を開始します。 -はじめに、`code/workspace/resource-dependencies` ディレクトリにある `resource-dependencies-challenge.yaml` テンプレートを、お好みのコードエディターで開きます。上記の要件例に従い、必要に応じてリソースの依存関係を確立します。準備ができたら、`resource-dependencies-challenge` という名前の新しいスタックを作成し、スタックイベントが、学んできた一連の流れと一致することを確認します。 +はじめに、`code/workspace/resource-dependencies` ディレクトリにある `resource-dependencies-challenge.yaml` テンプレートを、お好みのコードエディターで開きます。上記の要件例に従い、必要に応じてリソースの依存関係を確立します。準備ができたら、`cfn-workshop-resource-dependencies-challenge` という名前の新しいスタックを作成し、スタックイベントが、学んできた一連の流れと一致することを確認します。 :::expand{header="ヒントが必要ですか?"} * Amazon EC2 インスタンスの `SecurityGroups` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-properties-ec2-security-group.html#aws-properties-ec2-security-group-properties)で、セキュリティグループを[参照](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference.html)する方法を確認してください。 @@ -214,7 +260,7 @@ Resources: * リソースの作成は別のリソースに従うべきだと[指定](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html)するにはどうすればよいでしょうか。 ::: -:::expand{header="解決策を確認しますか?"} +::::::expand{header="解決策を確認しますか?"} * `Ref` 組み込み関数を使用して、セキュリティグループの論理 ID を `SecurityGroups` EC2 インスタンスリソースプロパティのリスト項目として参照します。その後、CloudFormation は最初にセキュリティグループが作成されるのを待ってから、Amazon EC2 インスタンスの作成を開始する必要があります。 * Amazon EC2 インスタンスリソース定義を次に示すように変更します。 @@ -231,7 +277,7 @@ Ec2Instance: Value: Resource-dependencies-workshop ``` -* Amazon EC2 インスタンスとAmazon S3 バケットリソースの間には依存関係がないため、Amazon S3 バケットリソースの `DependsOn` 属性を使用し、Amazon EC2 インスタンスの論理 ID を `DependsOn` 属性の値として指定します。 +* Amazon EC2 インスタンスと Amazon S3 バケットリソースの間には依存関係がないため、Amazon S3 バケットリソースの `DependsOn` 属性を使用し、Amazon EC2 インスタンスの論理 ID を `DependsOn` 属性の値として指定します。 * 次に示すように、Amazon S3 バケットリソースの `DependsOn` 属性を追加します。 ```yaml @@ -243,9 +289,34 @@ S3Bucket: - Key: Name Value: Resource-dependencies-workshop ``` -::: -更新した`resource-dependencies-challenge.yaml` テンプレートを使用して、`resource-dependencies-challenge` という名前の新しいスタックを作成し、スタックイベントが前述の順序で表示されることを確認します。 +:::::tabs{variant="container"} +::::tab{id="cloud9" label="Cloud9"} +1. **Cloud9 ターミナル** で `code/workspace/resource-dependencies` ディレクトリに移動します。 +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd cfn101-workshop/code/workspace/resource-dependencies +::: +1. AWS CLI を使用してスタックを作成します。必須パラメータ `--template-body` はあらかじめ入力されています。 + :::code{language=shell showLineNumbers=false showCopyAction=true} + aws cloudformation create-stack --stack-name cfn-workshop-resource-dependencies-challenge \ + --template-body file://resource-dependencies-challenge.yaml +::: +1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 +:::code{language=shell showLineNumbers=false showCopyAction=false} +"StackId": "arn:aws:cloudformation:us-east-1:123456789012:stack/cfn-workshop-resource-dependencies-ref-getatt/739fafa0-e4d7-11ed-a000-12d9009553ff" +::: +1. **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** コンソールを新しいタブで開き、スタックのステータスが **CREATE_COMPLETE** になっているかどうかを確認します。 +:::: +::::tab{id="local" label="ローカル開発"} +1. [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/) に移動します。 +1. **スタックの作成** から、 **新規リソースを使用(標準)** を選択します。 +1. **テンプレートの準備完了** オプションを選択します。 **テンプレートを指定** から、 **テンプレートファイルをアップロード** を選択します。`resource-dependencies-challenge.yaml` テンプレートをアップロードし、 **次へ** を選択します。 +1. スタック名を入力します。たとえば、 `cfn-workshop-resource-dependencies-challenge` と入力し、 **次へ** を選択します。 +1. **スタックオプションの設定** ページでデフォルト値をそのまま使用することを選択し、ページの一番下までスクロールして、 **次へ** を選択します。 +1. レビューページの一番下までスクロールし、 **送信** を選択します。 +:::: +::::: +:::::: この課題の解決策は、`code/solutions/resource-dependencies/resource-dependencies-challenge.yaml` テンプレートの中にあります。 @@ -254,9 +325,9 @@ S3Bucket: 以下の手順に従って、このラボで作成した[スタックを削除](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/cfn-console-delete-stack.html)します。 1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 -2. CloudFormation コンソールのスタックページで、`resource-dependencies-lab` スタックを選択します。 -3. スタックの詳細ペインで、**削除**を選択した後、**スタックの削除**を押して確定します。 -4. 上記の手順を繰り返して、作成した他のスタック `resource-dependencies-lab-dependson`、`resource-dependencies-lab-ref-getatt`、`resource-dependencies-challenge` を削除します。 +1. CloudFormation コンソールのスタックページで、`cfn-workshop-resource-dependencies` スタックを選択します。 +1. スタックの詳細ペインで、 **削除** を選択した後、 **スタックの削除** を押して確定します。 +1. 上記の手順を繰り返して、作成した他のスタック `cfn-workshop-resource-dependencies-dependson`、`cfn-workshop-resource-dependencies-ref-getatt`、`cfn-workshop-resource-dependencies-challenge` を削除します。 --- ### まとめ diff --git a/static/basics/operations/helper-scripts/az-update-1.ja.png b/static/basics/operations/helper-scripts/az-update-1.ja.png deleted file mode 100644 index 715312372ac9ee47a54c3e1b6c636c4f7d2335ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 101798 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 z%0D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 diff --git a/static/intermediate/operations/stacksets/createstacksetcompletion.ja.png b/static/intermediate/operations/stacksets/createstacksetcompletion.ja.png new file mode 100644 index 0000000000000000000000000000000000000000..dd5aff1b73cd88c16d74ce5fb0e9cc22d0b6e648 GIT binary patch literal 56188 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 t-{l`ClH^p1lHQx~r$RejVG* literal 0 HcmV?d00001 diff --git a/static/intermediate/operations/stacksets/exportssecuritygroup.ja.png b/static/intermediate/operations/stacksets/exportssecuritygroup.ja.png new file mode 100644 index 0000000000000000000000000000000000000000..6b2ba250f127c4048647ecdd38dbb36387789fe9 GIT binary patch literal 84373 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�QTd=+?( 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
J8oxj$HhO znTit3hohNd+xe}JUIUY2#fxuBf=2>_)p0(jW^!v>U)`Tbg5_=A^;+`v1J}b7=9|673M1Re3&mrB)4@9GX16PgJ4UEsnatoHrd~t?t+*YW))e( z$yj8DQyNtlW&f@R`HM5!BAS_)%rMhZCO#h=ZH^)Bn9!Im97)7;6THU8!Q*1 z>AvqcS9eop%4{d=qxS+f!VqxdG+RBJu29^@-1_?upr4@pTdbV}1MlZIhGYJqGq2%@ zc#epr_!_QKZ-MeyjKs^7^uZbz)`Nnd%qd`lXqj8~)0iT;K)kLn)$;u&Y36cJ6O_%5 zh5pJsSDMOV%@ipYo=np8{g3B~-VUCAmrhD;MjilPX)2XLhY!_%!US)d?qQ1wHrPYdwJ403!|X*DZX6hc?}&STiX=pHCzSaZlow>>X*9DjRZe7 zPvq)azt^YxjMNR+A8IYciI7~c(S-z2=J9Z#T%LLWVdp7{E54xK{4j$lDM@sreWWb1 ztJ(a>In`PC{B0JCcXgMPU!{u0Kjyk4j0yj8UQm!yf;tJyslpG%t$}A1TM+|PAQl;s zL1pv#bx##KsPT@I7HU6;RAjHVk1j_y69KJN4cfZ~90>2B=0mcfEgn(m&7slGqmpx+KT; zAX*)2l2mKIHX!p8RVc#i$6HXOzQ93b0cY^tG4~enu@}uEG81Js-^`p}_w{u|yGCb= z{8GTd`^CxCKUpFpBRdw5;eUA~*KFOOOF8qm4_&LWhD|;L+6QkUOju978qbIMCTp3?E_;>%X_4Z{@w(=lANl(xmYj~4c zBN3}UK!#OWT0MThGps&Av3dLZL2$H(z5KAV;RB!TF*|jPJAU1w^2W}`2o$bM2pJlw zqNCdVXysYFTx(t7*IW{m=T(bPrQSUOC8wnb+jFj)9lxdD?*aa4zPsqQ^20Dv^{ldY zd##$4?JyL^%Hbh79d4`XS-9d6`%OZj-}%S~%~fdy-H}-S8e}~-Qv{J*bkD7vNwr^kWV5wk>^Iy#c{mXZB=LGgFf|gH zq3X2wAJ9xuk0@v0(Q0zXTvn8PbZ^>4C?91RigFKg#fmYUu@ZB`&!{#|EEJpNdG$c5c96Wjb%V_C^sdg9eW9}0UR}~emU6L z*HOWKVh8(RIGL@E-_>w&Wl>&^jpfar*v`+!GhP$t`iA7c{JN2s4V;@mN^V~{B=d(8 zXl75Kt5}VVotN+ARISY#ObsbLXn&-C2D1B|(rtg+i|_bDzQyXf?AgMd%gd5kvcxyU z6Ee`uy;CKO6Iwi;o_MaybS=$;+jyr7Fx+sv{z%S_^Vw??47b>VwLpCvkc?}wt@kEF z;%{qgSNqqnilmDKEKhtCY*b_8)PhOJMK!T1)ilN0ncP}OA&f(da^PKFT3r;Szeu6jUaW@Rf|7&>wlVQ3C)FfYch0+?{qa(hk+q7CI=qKEow}G z&V@Wj-Uc(aR20Pum~RvRL=7&M#0jd>VfHXL-8~*ba(=$rgzYq}Brg6Fhl=wRTopP^uZIPa`#_F- zF7t1zoG7Eu&8@}bGx?G2W+pJywG*JNEGXhYVUfz88&v~v3{|5bhjJ8-uuzr00^A0x zs2oqYyNTaLJBb?SYuWjmCZabJ%0afAUi(o)jV_0I6BZx29LE7)RD+JuGeS;4$`>== z=b9N&drx}~^LPqmiM#R&*eD=;&r*^=ZB$s4!a=~mjHxc2MJifY9Nj;4mKTOQH+3vU zmCy7i9bNG*tZEs3Vjrzucha9*iaGviknZiI^`wviExZCrk z80NbSEMC~CaP0P|p7E}#++Sp~T(LZ#UVJ&FEOx z+L&5<0kk)}%C@6DyRreggu7>Rbx5B4R0MmQDR#^A0<#EcVfE0)5EN@QS^f>*3p)qQ zkSXZM=`ga$(`-UYJ%AmA#&20`u?Y3La>Sg63LnpP>!a z;>)Kt$QkVn`Q;2qM$Jc&F`bbQ4kIKxhmu<45XTy1j8|u6#A%K&LoRcz%$3z8SjWGP zNf1@O(Td;g>KTrco8kMtFIMVwO}BRxp$_=6OT)vqwYy&nu7gVm;7<7N@wd*3)fOg; zXUIhhkFshSq{fXqzv!h29)%|C%P$}6QjuOPMV)iEew(()6v{pOp+0`fabqg}BXjV> ztkm9oHME&EqbY#Y5OemJ;J`#7(=)ysP3_*!B8wuxU#f?hqV(V`!x5&h>>=6y;|c$`;^ zMXI;hR>)L3Rj?-YkiSmTFh8AX0$EFU+8?q7hCy&w7%Rn1$s8}qTz=K*&9GWFi&4I7 z<7&Ir_C?B`COz$7UN2BOc`E;4NhT`G2HW)g*3Z20d!EfOC$#iWh$B|(8*uHPkq_2+3k(?Sdtppm=tbP zufNuTDa>qJ5fn7A*Q~i{*D~2Un1^+(S5)dB#gAgfbAnGA-HWIj^6bZF#-DYd^=aLd0unht)(27-4?VHk{06@J*vPulkG6;vW5;F#Rb9 z6#qSd(xgs4geALlkXSY8B=G%&T27S(kSr9I%h%%%KZcMnUU|qy&s+B(4NtRc05>OvQe5-)A%ii^cGxZWby>H>K11gT3LVCxcsggg97;g z6QSDjFfy5V@aajjbY*jpUA#_$U~z$SPY>PXR@IXxrac z5-99xaBwh|Ydx>vYD7^G5b{#0`H4M=U3hZ1HDrt`T#oin_#sH0C;kdtCPa~ui2h?# zG@PL?TJDjOFo+sLA2u4!DHAS{&+F7BuU{RuYByd-LivjOoh~<$ z;D`ifZ0m;)JomNjw-!(=1%umRiQu6xwcA6ATdBuSDg=*kkWDhU^#LClX%c^ADUWjQ zI`=&ckMf&wVYMWB%_5B>S;=;rb=v8Ma{wVh1r6IOTfo6M?kP@-K(3Q$zVmeiHX%*2 zOor-m#xvsA|BJo1j*4q*_5g8r32s3`fZ!HrT!Tx3y99^E8wl>8<+O=y})&5mgvXH5tK-qdcn+DzRAWb&5 zWyn4uzIC;GuZOk6EK#u!D4&@Y54Okz9QN^bgP?co5(gc3ze zQw>cr==eOtP+()W)x4w(0Q961c2Ot4vk!e1675u;AaL$o!gY=Xb2?j0b+P+9m3~D5 zUVqWv(%OR}z%^pwD(R^r8wn9Dv`}?rhcD5_*$#6jm?*U}o{h`Z~ z(2;lt5ualBb49tcEnjjQ0CpnwIzNT-5>!FyJNJAGrJDuQqCc8&?+mD}RPHxPvzdy8 z!m3eXc)ei1bx>{)P9bIVNAhhCClHHMF0g;N4mAtCNw!I*c^y9({^dE|PfTXIBN{9g zebh%_-^ir-HjUa{pqWN53yR#Ic|poDxXH3NqADeF?yrOe~O=efH_SA246Tje0gQ%a73Yuj!E`*)?IlDk?0kb zSj$zCoPu2ow*={r_oAQK1|Ci;X*VV`q{W2-rsN{hImHTxPxXCh_J z&G_b(!mazhSSziTKGF0Yxyppj8o%NI*kX|iOzgdNpdWC@!_fU5bSnfGI%EJh-DE2U zb*P#Dl^;6U_@+4hM>*4BLRAL&+`pXp{vD_J?@w6R5Ev%4Xb%5B14{o@cq{}R($cu= zo$7yw#Q*y#e}}34zw=CAPHHX3pEp7tX3%CIPJ2$pK2st|7x?5-(pvaP2ggjlrd+0y zc72ERfDcVeOCuqJ1rJYykBlsmDAFp4xzvQ^6w6R-K?EbMzMN5^ik(v zM-3sNl3_vj4eG}HyZirnBV3P_HBQW|(V&b&3H=Y3Z-KavsMUMEMS$8rw1E867f28;*iOY+@csQI_I^nv?|1C3Imyk~u` z@ta1Sfso#S9fRS&A%Hk744zibOxu;`xgyq@|Sul@(K2*@Ee83f^%8C1eix__oACA2rPlKEvK-fsuy^NXl0KI_*1%$(3T;6$iEwg0aU2}Cts ztIEP6%bNNf`AAcI#v;fz_X8GjuoPD1ql z?TnQ}sE5wYUi!}q60+QUe>EERZ~GhX{Kv|poQJR*0tu1&Kgx(-5}^H8qwNm;->hvK zENjSQ`GYK z68X~;Y_Q4HwoT05)dG!FEXT4C>%w+DkjYhMQCWgx~ zZ>@CnLOH3u#pC+tVElI+>W^q{dsG2wmd5hSboplP-#5 z3A%r(hy7y?eAjSqEVhV4Ed~L3lrLRRR^s2k){C33Fdi6wi<&!uShLm89s099yNlg* z#mKE}sVU~QvHP6D3$Hpkm#5prYHJmJ9J)_x3Yl-eZxNX#BbcTw*4fFPnY?RBaMmFS z>&A_|BO?w~7H=qiY_=>};_#lxal2aVjA1BC1Q$!|jrM+?rOrYnW4yb8M9 zd|mR6WKxmj8nX3YT)#EsJ8buF+w*`TYxl-=Bfl$NN03j6Ps=G@ykuZ8Y}E&VN>dT{ zrWA$9e%8(vFVeR?wtna#HlynIqm>ey)VlsZ(d<4wKGZohIecxLX*vX-foKpR-saiNF-?R|ntdJ0if zay>F5Ym82RfPH-_t1VYQlP-54N_pUo2n&<}LyJTf{b)M^<_Y=M_>-FQ zCC)mDKeiRDAUHbtbRu)BEt$kPYfU}uX4gC~0VzmkbcS;R=9yIqR080)7N^@vCap7n z06u@M@bEkOu|cWjyMYqzIvtBNTzXZJ>cGH@^sAAFp33#P5$Mix$Ia_}yVX`|yXJ&N zGqSF(B9T#)V}8!uJ^~ZEde%-PxpX%5vV(eifw?NXrFts*RD6c0G1}@US4as^(leos z>*T5(lap3hhr0{STj!}4Eo~8*fY+O^Jl{}EmrxOL=T>UXGqE7AVht0i6__Ng%am|vrKs``b#DO4u{FQ17 zsLHZi$~red4dGGPH;}?-HAckK3%I=zpnlZFJgID$AgdD7duG0HnGRj*dBMwRRrY#s zOm%n-f}k^4bjw*K5fN$ z3}drO<&xiW&pb?NGfu~|{@k+z!l2wonyu0plqf``$eIaa0ErqZZE-3jUSlND@aUZd zxWY6eMro|aNjo-gnuV2vxe=dJ`n4+G;xai zYQ)oCtjwFnN0`UyC*d2%4`nJHpiW8E4#c4~;pt*~fjx^sJ}fpHYQBWG=$Ahgr6T9< zS{w!QINHuCovar-S;iE!%j{Q!@>lEU>{c7zu(X1knI&Om@{b>BTu0Tz+u!QGyNoiX@62g2bp(0zP4T96$8p)=KSMX$f}$s_D?k z*ob3&(fW8yZgzaPv*BALXRe*d1Jpybz~rQlTPDsYrP@uFS+o3yb~pL@(%(O#Ke$i8 zEf9H&^T9-~KY-MC`G|Rmt%#W6l$e(n&n`|3g8e1i`r^ znenesEBNEWy9ahC@mQ=jBr4>rOyqu$vRJIF_`VU0vi9U3T+OWVRfFo*>ck5jA2uHw zspNL0pAk|hhFi}~iZcyn1R?c0`r>nybeg>vDG=D54jqTJ$6m6J-vV5M5+zd2y z9D3s%TNE(@15Rr(rR7TJrd+m5&kI1Orw@V=QUU!U6&3>Y z4$dD&#fphg~^_x*tIjB*m`rw4;=7pN}A7YqVxcf3lL_T^L1&jvdE1J8FtF6ws z)M~a-#hUCEb_a4q9OjrRO>DfVjcp_qO!e1v#IH`DOZM<%x-YaOZqi{9BX?~_i4|RS zV1e!()l*d1$gLRyiU;N?^QXSIq;rJ zl=>v~gsqKF-UbGWf2R!4TcV`z)?BoND=hIojLLXK7=qNqI64$wHIVWEAc+Uvcj>E) z4*InnfMkLRI?pn_C(5A<>JM)Z>{O*=g-gt^CdT1O-mHx>dtg<$Uy*HG28IP+<+41v zwkgvZoESRmyYamkMb(F?&G&a?p)c2FN!|YdLtL0P#OAs2v+ZoFyO58>@Ksu%NI>7b@XGPA%*)YoO8@ZgAMn4 z@gYAgO`}_8Ry4*50p5oF8xI^!SeyQ?$j06&l9CZnDWtH0C?ivW1{%dupP1$7%Rj78 zumt65s@ql}Z-wsZ9#$|8+g|Ncg|1QG=QrLbLRq>@6Q10Kg+lF%=q)IeCX~h48GF0Y z{>Skl(8pzgKhuL8FaiG7V%c?`BIXiX_?>FzZ*n0Eh*aPFeDJa>5^BGm-Xm+6JT6-= zjNBfn#kX+}V`_`s^bJz^qq|GOSX)v-TLn6=R@P`3yBDNrz*f8*%R$}*`oia8pq@Le zDnj90ea&nK)$rHRm9cKmKqNl94%f*7FB@IV@ZEy^&BYXS3j^;((_;Y@9ul_s&&ATH zb_z&E!12zO>4KhM$trqqR6mLc(TfBO`bH5<3i|V}$NHThxK3Ow3^=06eDpYn_)~{; z!|vAs{Pw*$WUMAXAIW>zV7~QXPA5XN@?(dqN@VaS+0<>?H?PFz_l+B~yx&@CP`1)j zOyVe$y_M>omFQIr%SFHpQTHEz69BpiVP^ptC6~(aL%tD zY83UjF>x6`ZabjHEbe#NN>X`CfsL-GXY_ft*Eho~3VUH81;QYrzO*Ql~xdac^J=8ipYdegfmN}ts+*(AWU zo<4Jw!_9uZ*t3tUQ@^I2f zQl!59An*FAa&nhlVl#BzT`XCyhz7k0E_!+~U$}}mWhgO2vxGfKpILTL)mK)3HLdH? z@m)zMu`flc=APUlF!(J_P^fk3U)uvZGcJW)nK8cH4>kxWNTEUFEwE+54A)LK?!cY4 zV{H=5!2tBUHJg;L$ar%D2SE0lDN%T<2MpYt;f|ioQs84v6C?XJ)yfc*5+q%J&ukH> zgc+Sa1+hRpe?bF*fOLEJkJN2L^8Q4{X>OSTy-GJy^H9x>;HS=0`>6VHtgS|fH$gcb zij-9eq2dx1*nWdX`}u{MGCm9nLto3C)7EY3s@6eGdCVAvLaBU zQS)YqU@>bJm%lGG>6A*YEapO5$I9qH=`5IXXh|92JbT4??=*_<{L-JN5I+o-1^;N7 zzusGs%zDpr>T;DFak9e=%2X-t9aT{9^ctLM^|&?+`gY{~^1N7MNkKJvDMhzj_sjqLw8e8cL|UiqeZ14_yDg zNMe4GGT93(>!nJ6lhHV35{W#8nu>)`I zQjjNJ%nH0sa|4^*`Lb^)?z1ZR*E^aQws&Ep0Q@w>%yrG0-(u_k#NRAM1A=%D`GMmf zqI=juFOHt9$_A9%yU?PS08&+yT^|d*o?6$XfeQX->t_xc0_|Dp-mi;k#pP!UnA`B4_EQyK@oZ z0$QnOx8tb^R?~R@TC-jHo~VcZ+q#~;5UO&6Q+9M*e*$2adkx^D(aOWg#j;N#8-Vf- zle}=Q=Po?88tBJ-1Ih%U$SQa0q=FN4E!_2{i?x)?)VnFW%##Tp;DVU56}pgSur#Um zxw)2y(}F~?64tdOJLs#gKAq*3%0E~ceQxmh+4#c2?@wh<8fF)Jy(l-i2mx;9ovN96 zOHZk}z#*6fhE5zBEh>-?x*PLBTg(*anKgv#DM{#rGej5^EbbWgVA}#-+qx*g|24oRd5`XMgb@QH{4`rx)`Gyn8L$RLQh)(Ib(h$k9HRZ#>qDI6WJn{J@B;#$i zPIAoXjLwvr`6W%K=5sO z6{ZAlm}20h@5xzE%D*9$KACi-4X7nfMy=PJ|E&Re2HL+X8ei)?RgZ+F37tC_3w=rs zb`v$ogA^AB?lM8>`f%m|ajMPkR*ZyBk4=CJQpt>}fhU%P>M=d0$0QUP`EzfCkpzn6 z4Trhcn*|r{F<-`_=N}f=xS>GYf+_7Tckp}HQL%n##Rzqmbg5IaY*9v|fezr;)A3Pj zBQ9a{#~%fI^|z-!qG-s~Me{Hy;)($J_vT#ZHjFaNj*}%bJR7JC6H1j6M({Vd;rXv% z7^%qvSgPQu-gicXdt+gZ!jBPw;Hv}%O!VGU`x-yi z6_xN?bVGjNa*hG4{gBq-e1((v;C$~8ejuSfY2XOfO?GtaX@Mx~}=uNqQ5_hP$?Wb^x8694aJe8ks> z0I%3ToboqP2DPE^p{}7d>?e4Mvm+#h*ZW2Kvlhmz`y`MetQvu|92MJZHm>^@L`Umt zv(u*ItZ0~ONK(6xP|^6X&FxlW35!R9X{%4IQ%c;9#2e&V*)@$so6zL)$1hUYwaizt zM?c+oKn~h@$=)J0KhCDoUFa%UOh1T`b&%SVC`Sa-Dx@hXWB|4pPO`KeI_l2%)*OJJ zLSim$rjf9*SevHikDsa|um=bAy+ju;YvoSAHHil7|8LweG$_tQc+bMK5!8Oy> zI+L9tQEgrc>;i5H2GJ1l1+0{^lO%lAuouRE{M&?tmt0j zwX{`__BDXgj^0j`_rY_>MZg7=FRFonc(|zUIY46{__DiIY5UO9y-}1jUC=6HFZ}~{ z)eNQk0`pHK#pE78SLvmhyKD!{)f=BW_h9evoLE5qId$Bm$f=wl{lHoEDzlmS zZWl3#YPcS%H}vpqPW&o1`5w(aA=}%qt-zZqh~xM+?JdkjOH*&`q6JXJ7dCzh_}nz+ zIQJ%PkD|vZ0HuV!pdHJuTB3=$bTe@1t&yWJaKLz@6yoprj8RZe4~5=IJGlK zs7F4#=BAyyrhS!vu!xe!tB0gcXu6!Z9>}%=_f%71#5R~#72h#+hlM=;2BpMsCftn4 z4@Jy8oQPVK1yNBmeDeI|)FU)BvL5d7M=_oGQht}WOV>@VmR8f6)`#MNfnrh1^bqnmbT2vb&WK-`N0ei=~JpwSvYi)7b&YB^{pm4HV0xLeG<$ z1+O%f2L}6Ju9o%Ukl}l*hLSyp}R;>k& zJoYfewEF_nM!!v1%#E=&Byd8P^yE`WF<3^lS%?szgnhF@90z*Xgb~lCqwkXKt*xfg zZCRMn&BjVQSpODC0@cZ3i!%fd&(O@fq|ZF+EFiz>7f4`5#K9}eF4zyC`W)pJefk9S zYj@_Ia?0-AZD57_iiz39VU&t|hM_2N-&~&K<-SOvB< za7VZ|-qw9=>0vE{xCi-!-!KGlmwwX0WyH?-_@rgN3XwS?AlP|++Rt}Qi%Q>6A!>Ma zA3;%=!xoUr$DMxk`{k3QE@5`k8hmgi*M9zP4|10$wvr+N2k0{Mqtp4NmQ)ZJ)*k;Q zpb;QuBEj>KvC?4qP*Z<`O>x0>-;|gKChavbNidaF2(875X26_(_6n=pzML**TQ*NS zHHovsPxK(qMiTexR#SJDx7R0fuoYajg^Sc-P)1T-(M@jkPvc(2-XZYQ^tQ zi57k6#w&Ckk17t9KAPuuJeNUsOn`iVi4WB?M0m|-pea}$M_5Xmi6Mft5YJ1K$#o$o zA}l0wX)ED$&9E76tN>W-DlVqMOu|)!XV$m_izjR!seM{U@9AQ-cLF^}S_M^`fOxO` zBy26*@4G^soPq{mHjh>yix{duEK;+Ky|+>NT==WHCN3`H$7xO~0pO^ZgI(v8=T2tR z$fK*27>E)Lvr{<>8vbMEt1pR9YYSYxCKaMq)>E7OIrgp9LD!rC`a6J&C9sqCqBD6< z-A>95^?ViCPej|>QS6kylov0%1t^SnXlFGdSEf% zNMey@w^Il@4A!%;p zz|3av3XrA5WWY8oJYM&Z@GkUyRwwE}Y#$>zuX(g1F*6g0*vLfKb^(bcO5vqw z#lgm+c3393xh(B|$7vqBy$T0jM;ocD3e$*zp_3IL1d)qh!wn#1$0jti&G)3B=ZI0x ztK=A)ZEkxScVFyBW`q6F=`-U44{rymY%J@cP6 zd+1{9AVz8A{PWN|3cEbpcziJ{!s1gG(g?&sKT#UD+uLaJ1Lacgu|OAfz_$4otk4Oi z3EuTze}okyZPabLPV$w8aThvVuG8P4062+zZ0%v5V=uT82VlkxVV&bGiY}vMV{}gW zonxRMod)jM0~aAXi0yIk2@kM~pJW4J|0k9u4xL=q+=^e%>OqiIl15(!;Jf`QWh+Ck z`RyWz`Rg&ptC#a6Wi6H)Z&u#3O@9_XnJX?jeQC1{D-Z}|QDB3$v01qb{vH;2Ku%uE zij-MDX8@cmP^lpNf?f0-F`^jb>y-ZD)Oz+nK^5ih_`@rF}M>}Z=ADStr>cj_gagBYL@ z5(knppfm{BsK%f}szMg)Cz-zNOD3NhPhMK31%K?heQQXpVF0lpuvezsMRG7c6n?T$ zC&O5D!UzgnJw||@aSN-Dw130D^8*3%+L>bO1PNEmX6pr;UfNZj8&Jf&#~)8mW)~-_ z3xsS)e&{=%vQm?x3JSF|;?H777eRVv)uE|J0xG+)hcv30^!Qgv#NL&bqGU`OlPj#~ z=M7<@>D7|SAL8D#HaXr$%+Jy=xnjQZahnDER2xArHE8qL(F32aP4*^RbF1t>fkK;4 zwV3hK54{9RHq%_Mz0`y5!$G4GX%QxH5PfD{+`kuoiG@|iHROk%2OZN`}@&^P>jlm7 zFhA`V{L)GlDQEN{kQ(Pgp@kCClLN z(?xpkta+h_g+6sJq2`HxCd^g?NZ6&dh2_)02|sK$`o`jktHfCeQn2;&svb@RSxzTY z9WLDQ4+-fgy^X^Z9 zUkGNt*IWiKJ5ki@XA`}&c>n=hLJU3C};Eor_b z;Bpv%jOHb#@=f}5ylZ*j6apeT>j`+RG7mE7U>t8CGvnhAKPF-UWG2d3f_y1t7lZv}(SU)El^V&j7mJuD9OJhApIy z1i*^yMrIxBnys*gdz^HKs+PX6+Bs`DCnyZQPkKgY3#@Cmk;`s?NcFXgF1XHvr}lPK zvte1TKq4JhdjH@Fh|>*`Z>JuS^{Zu3-0Sx=o&{&5(+DH%0Yt*SP^aNbh;3)J3;-+j z;)fozG$nZtVUTR!?VoD-6E0GuD;mIsnA55(ULhbr^XZ&LORB)5tq!V@o|+RKA=8P z`;Hll+r-ZP5Z;$;;_*j;eUH8xp@h=NTP$dt;dG}&DE@>k&F5m8uAJw2tz#B1$lY{(4lL8UR1Kxwe`Fd2Z&k_3aawWkco*n9B z3k}SJ_K%2>tedgjNYhob$#l6>Sia+g(FZfuB9>58%dL(A-Nq6j#nyDyqQIfbark1& zou%yo)qJNzq5z5xN(lviy9jicdLhwLM*#&PIZD8>d=tUN*RFY7kaxD!tK+gydB?|` z7o=pifPr9)L(}Fi;~}U`U)>fN_^BMHOk|M?5wX;_h{K%*Q&_eWAuw-Hs8|6#b~X1% zqb;G=duq50ti6v)UtLJ9?jt7l$Cdnp5`#t-53IXCVGL5fq%Onli$G)0j2fy<)~nnb z7EVCI$HDP<88{o|v&Kh*r2?~ln}uePQBRI6{sJcY@<~{NjW_VDzccpsPnaP{m=dtU z1`;wDPYIA@6+H>{Ij)(|JwfArM<|7_dt9i^>CUE84;%;(k}X1?++Cm;d3fugCmh#e z16WTxCnx>zGjoHV^DLA4CoA9>Q&B2H68}v8zj6TpVV={4%3#m}c=NM)BGZGJTfu4` zcYC}J2itGve3V8nT!_C~4JWbbT&Jgx+2Me2kOFpELU%Ysh1VVfMCQ`;x)fYSJ*EVw zPQzU@$U;Vw1=;1g{O?~=qvaSvRR7aeu8fx5Eo>Fkl5yhs62{zyHTQqP3&DigS^al} z=}aI0z~z!tK{r#R88$C@%(kaO3aK(X5%jikDH<^`R7BUjv^po7=2^`anFw_s+UVn% zYrefUf$UZ6pd`a#_@w-MQG%ss;ECt9POk+-XE}ibe+rr_WN}3^_2b6s-{ zs0%SiMasgNXjpst4P07!jg3w?`;tx2ZJ6(WLoEJ@(-i(m3Bh?gq(Qui|BQtE|DP1~ z|0tcXjyAr@Ui%FWj%e5YY+uib;jr4yim@m9=V^jM2GqjU9xc4tQ^}8k?23WAgu4^O zFRgV#|9RFRQ3jA;fIA=f{NF-q#eYH1kx114JRttx5y8HQkVb+A9k2gTr2jA=|7Sxa zYzR1)s z&uPE$e*%Zcaz-NMb6|RpI5ZBO-PsrayA>!LAj((<^ShToqJ@wn8?JxmcaQObJmnu~ z{^u#lj%}&|=pX$E>cb_EarbY2ro8K*skU@g*;5q1~$`2d6sa z{scOLsDURd0(-M9bw62@#3#*$8OnAT>GdO0cVz^Px2-K!v#TIM;gSsM-)a33FmZ>i zrb_*pG#lj@)C#FI^+%}XQ)(RCL~ZXptD1G|1FRRXf^E$fE{IgVzSmq9yz+h2ZE^qL zrCFuM@V=PN`*FBwMcGW6{!)$a=YxDI&y@l+uez=zN*1f5a zW#jgnMVZAbGTj4GAumy_THCTdl_DqjWImf9t7ONG3SKwz3bG1 z&LuF4ia!bZ5WDU)B8=gA$}1qHlWXpmyrNq?o@XyDX9~-{RHVC8aL#T*T~l>QA~nA@ z1m|@NCY0T1x?dgVFGY|G(CIc_PJ2S)Hgk_Lho!>F84q|K7@YUH$89{v%L@+|y@l)i zv7ij%85IQuxRFAH9-CznsWOe*NLe6o=?Twu($38*a5QzLZI`6Hf23?8^Fc#rg&{wZ zH}LL)XwKm$vKyhmw(Q8Ov*{c&{Y0sP^JdCS-csYfC;O7f&E6VQ^f}~71OEQ|3<2*S z669?i1v-HY?w@!eHRqr5_Wbx9cUt}X~b!l`LI48d=daD2FtpnAHlb(o8Od6TzHl#`I}M)jHFU?@uKT9A&*xKxz%BQMhxcuO#Fy;t@MEF zAOuPOigRz)X3=y^-$VDiZj*~{lzvES`8$1ie56d|Oiwjpo?^S%)uQvGzN#@gR>;{A z&AXVLiyO!7VJh`fo#+kPq5evW1ja9MuT=*_qBGyEdigtXrC}bzZoEFbhMXYNsvT-n zTFu!m6Le3?oWw&Q%FwXE(mjJSwDud~XI|-Al^6FEab(<1$4lN0k9X*hq==19PX+#I z&nL|nhcoKe*w=gcw0cYReBtLYn=^+vZ?rglguW{xC3XM%__wtMVFVnY41F+|3|y z2x^w^%QjM;yCwr+vat~Cv1_gFKjP!CwRD0Av?{7(wmwT148DfIvbtXG&E@BNZNidQ z4<$ZZH#4fs+&Y*#r4j;)Ouyuv9h9a1Og7sn%%>HfQ)f4wc0%8uoy#xS96WoR;@cLgbi15_IJ7baWkw>>CqqxoWg z;=|6zv4jteE+?h|)99t1t+%}gm1~PX7^XA$oV6-{qtaCQWEK_?Q%0$eT>h(DO9bWibN#2lYV(zVY}mB& zxAK3B_{09Cal!fS*#2wrE3DmJ9_)M88}~84OJFLrg#_ND`f{5~sO`vsth8if>1xur z^y12QCvs2$x+NX5xGNb}v&9@M>F=h+a90voyWxAFRCd|h3^&X6H5+%EXwMey+N|b2 zIoSo*y{U}^WPN`N5KQH^$n_(xg^pCVx(^dZ@;D!vJ7S7l1($c%p6_^1)c|5czoGc& ze`E1CV*uzgzNbH6w8+}RVl{L-`{^(;mU)7HDJkH7n3T)ahwN{buWHf*V5Bo%Am;!m zm(a?lyjMtxf}W*RV7a#sbh&N=uKSI)I&)Bp`^s+~-DhDl8QL{x%*E5#tt|1i*sVe* zj^ABO*}pgGf$=!furo=OnnUnQ0yPPH;VZ1VHx*Rd%`NC4p2(j4957jKL_Z7Po3(or zdI}EgV;oiXyFt#idxlap0FiV7pQgUafA4J0HSrFAXZwhq(L1eC65sh=aE~ArT^HqW7bIY9>n`Z}Xo$rOOTX`U%sC*u z6Zc1h-SCugn|CWXRq}6)NrUC}%RZsdwoU$1l_EuAVy*ZvG2^wjal3DdO!eBiQ9Uft zX#NmQw*i~K+ANZJvPgnsnI3_)G9xKje<0V0GJp$|B#IY67}`-nneq}1x|5`RoUHB3 zo?he;r}?xT{9D&-t`9|VDK1~IZCBkHGZj4U%Kg&Au|IQymEgZ{7Q!~mu$@ePLu8XU zU0i^~S$s#bZrWeGZEe+;iI<5zT)NF4`aZM0-h;<-qqTgp6>@^2-F9WR6$D26P&DIW z-^UKV`uJKkcU(fd&K4K6)LHvjq1&dKho+Gy^zcv)b29UNMZ!8Dg;2mUH^>H5cj&=> zbdb#MaD#Q}?y@=}%kpiq9BsMD#X*;X8y(@u&yC+je=d5&YJZxgp;Knw=KN13^WQO^ zYZKUO1{#qOT-V}%3TFhk;ZBg;Gagu;?7HSK2JzimhF%sT| z3A0^&>QYEKUUrq)bItUEHGT4vfa$>ZXYXL;o$>V#{uz11|32;ehpNWYue!83l9BPN z+>gws6{dSaO0 zVu{f1Hy)xKqKOun&Np{Q;@+INRlUo zG){k3+87Lq+W4|OxkS>2m8c4Rg>k}^Su3oAcm`!1btyfAkjqewl=8acJ|zi)vq(hD zSQz*(?~dorz9U@?ly{^coa%e?JhOr%j3}8vliXGll50e7A$EqYT9qW%TaT+^PTK_) z?`zfyK}ZH023Q1)3E#Mc$8w#!>mypiHDtAX7j*m=LkVR}&ijT@d5HFA6`#OaPb#@U zk;~$e_ceLsWga?{gcGpM_R-`C-15XDtE0M2xehg2lZCRb15s4|VGkxD%yk*9chn)6 zsm$)2V-k^CHASzxUiPd+!vubA61Ny4^JCfQ_LE3&q$t>7HagJy755}ZDx@}N1u=%2 z^~<7r1=86qnpfFm(s#D-skIV0cZfRK&#F!K*aw`wfn0~@S=jB1)dyKSwMr8z#8Ndj zsXpf>=RY4x^-793A%QsUj&+~`_QsJ@TskXh->e9Mf&+TlZS~w3B5U-QKnS#s0)=F4 zNhtq6%F7eHCCQ~7shS-n)+C`2i>%swVr^d z*ad>)^=73-w5wUO2LGy;SW-`xQXM*C02gvChHHI%+BP9q;i~9vG$8Cs_BR@Mo_6hc4GaU2d`H@-C4tzPnYZRunw@ zB72-z$4E}`?}GTh?1W$c26sauYsT-g#+Gq|gAo4|Gk^X4FZYo_kU(pxu4E6Yf19oU z;|Amh30n8`Q)I^cT`r7?U*0TpUPqSy82?{CD*g%(R|F4iW&b9U9zYCUhJzx;xL2slE%HG6>7 zFvown34Ih{f-%SvqMu1<`yw;J$yZlLi<7yUjLDpCmRZ$2b}Mln*T?WF1PQ-92qkV0 zmv!=jJRY09=$RIsj2$U82f3<=$CE8m6mQ)xG(bmm?-$WWZ(WYfw+|c6Mw)L&HPfy{ z4IsLXdyBi~@DB)?mD7BLUNU0crZRs8t~5F`_Ui^;d4@T_50X*UjHK4>SIs9YUSB%_ zS8V#nYOLl&Q_`_YcJ>I%v&Soul|RhN(Okb!U!+j=uxBp|B<)bA#Ogc9{sHP)bedOeaHRo!#mr;Hh@cb*?rYSG`Ox{)&uG_AX3w z>sxj5g}dG2iZ@GEdH<_XiFnHz)4Ed?QTSbm);r21nX#|)5M zre3jZv0S-q4!DZ#`fC+v;3jc+HiPalzr*?~-Fmf1-j!l}w_%1jJNBn-C||3#F@2L! zk78*}!;;2If4Y?O#N6~uV^nMvK8cWTvzs-gPvm=UBjuTh7l_kEL?eCKaK4==r|GbJ z?+LNcOShgBtRF6UJYVFn5pM4Z9E~+W;(5PJ7L5dJjlPQ&tTOTBie%D1t!n#$^nvf% z7>SWPdk{~Z&X@IN`#7{ATukbpD-PrY*P6nvdx!a;QE4*DbdO0IHK^e&;{zsy+UYd6qv7+#({j(+B(jyC(!xxKZd;N+uYQ;$~ z9g`N343Ur%&}fRpvZzrCPx@qb(>U*E0a`4)$C~o~ox%9F-Q(62PK68)=8CqakBvaO z^8fZiF{WL2kNiTU`nbYmbi%*?K6R6g-^r)bjx=Qqf6`}`5qdq|D#{Lf@`Mnc@-DU) z{b!TJIh=sJ`!yM*IryR6lf*aJJUFsZrYbKy_jwT>jy(5`b{)^Xx8%y}52AXYC$}nF zvANQ=3^rNHudU$D^HMhr2nNW*RQP%2>|#oB=oR(TD||-v#F5ll*-o=e=WnRT;?gTq zSQe|_HRN3{PusoDHc(mmLt|gj8g@qQP}kqOgBiA+(ja&Jut%fjb`Lnc+;1{?iS8dYPXr&gcH+M~rK9A*L~+S}{AFLd zXzJJ85!_x+zoxztc!e%h@Jc=vP%xe)da-AgGjqVMnwR)Z{ve?deW&ku`Tt<;t)rsq z-+p01IwX|t7HR1Y>6GqnDe0lRQ&5^gB$e)N1nKV1p&1xD&-T85&v~Bnu6Lck&Y#1A zy@r`<@9%Ye>hj6g9}`L9^<>>&EvvDc2zY)hS}k>0s{IOJkb|R!aNU{_SWACMDmr%M zBTz{riiBPf&ubSd+WGTob(MvY=601F5t_J++C+gmJK33c-`xD4;X*9?M-AVb-&yRuO33m!7DR0% z;QBVNSu*zrijy;#)8eTRjzN^~+;gW^;38#6;I(pbkN@*yduc4Ou-18+tKNEmpPgd(0K)g<`4k%?o@2B^x0YEk^u4R+>;2As1>r=2 z`;gTxIUx;2CM<^z#uRLqXLWp+L^s3~d}*@Aa%*SXqhAAX(S9kn$8h6IfZqkFE>xar&-p5Xd>l80BcQyigSa4y zt_-eElt0x9zRsQRPC%9h0-k4Xw}yS#0-ks;7vhP2N8|I{KPida`^KV`F{&4izkijY z`{go*Bc}-*H!r%nzcZ9F;fXM5*z6|PgD*aeDQ^>I67x}Z?=gvEYbc4*-?y~a<*5#^W3aGu+A?UxB;FYTn&C{RIogQAGGzjoXo5buK~33atSRk z3>|NJ4Qd}0xE~u7jtD-FybU;As_;5lt*g-}zW^)#i+SS4JPgvbDo{$ZK0YDaE;Wat z)dJWL9!e-Q;$<)K9H^R+8B54hK~Cz`8%UKqW{b7Bu< z#}c#}W$4w)=QlNj(zge!>`A~j{M)Ha=Iq9GM$-=~Wv*G1mQZR4SPg0i>dplmA7~T$ z;n^6By}I1t&xpE@nJO%jfJ4wD8+lH7nckN}l2^mcG>(9+d_AMtF3o+9a9j*~4kYor zg>8K+ON>-%hvY#kqmrPq2+C2;fQD)KRk5+9Xs7emVj z(m5l%lbdmymBi*twL7X(Fh9){7h-nW&6Rl;NNg1rU31}nU#_!-;kzq0I;>KGb}Krb z!AMM8gTLeP^o2tLZk(HV-Zb+ZSyC6nw#tNd4+$j(`xNl`GZCn>I%!}waZnmdq<>q> z9~eP1qR%!$r$409x8jD8oBJbeu)&jsax@*~#>WQ|4Toc*1+p6wf05{*YOJxA9DgIa ziZsXbS#&Ja-QkQ~dF@(RDlcJUaoslWvgu+YDMVIggPKoaz#xNO?#5I2P6%VE9zD|T zZX}C{HFug`a=1>&%Vl6ldOf5o*|P7VB44TH)w`42LrNhN)vloas0N{{!>K7pHS=@{ z*{6NTw}TNg^V%lJ#48c!>run4fx9ng=C0N%bI}AmvqhesG+b+{D(aD5dtj6VDYvtb zEM?!SET#t1;#7|TFDA9|Qv#-wZv)`%SUN;}$VBU!|*e%IR znS*`^oW6!mos_a<3|4eFPF^}MV;efFY?pS~oriuo|8!*!A6^-aH>5DJc}hHX zlurB$9!9x3%5@DdRA<7I0<9OVFS#)QM)BK+8l3X2S;>dLQ)v)3?z|mXlS%v0%-iZB z73-j*LO)2S@hD;^cvTVV8yXqqX~MK+DcaZiItzc=mD6ysRy>7nGGDGtICs1x-{i{+ z=Q_WZ*>X?4rs~tdWv6!TjhD^EFJeE6>;;8bGoOcfZlrTs7wBKFX3(M3gG8}7PpuEj zqFvz4I=9HI*IWhb9bCw}KTI(xjv-wTi#O#1AV)LlDN>97$5Y#j$aL#L;mX;v47<{6 zZt46mYgX@y&OB~~tL5fpe@gq{mOzKpTLIBkAdO@+L;%TNl-Az9{YDA?OB^sT{_&7b zqxc6S4f^;xumPXN1zSwYybNb(e24TKp&j=xP0fT?u_kNPQm+|pC6Ey;2?J3j7URiU zfJm+UjEmW_KygYB0H6er9uip#cgK?QGX(Jhi-k!ktO9Ymm){z{^hEG!qwe80dVKSq zp$yl%#}XXK4T;FtpHmK+BAqKYYv5>EJxt_WgHA2v_;rf2o*2CoACsZepfB-=P8}nd{?N1dMR^3cs zhZ<4XX;-k1fg=hqjK@a458~?A+b5q0``8tehoUD^ikHHqak!gY- zv-!$@+=6|k1R2X@v5}N|(1~RXWM}yxLjE0v9Z;@P4L@6@gu4V?+rhLPEC=(?T=viD zhy?5{C^g!A+^53d4-Y2`7TM`?p@OcPtw8CKmaEyb;~($t?7R@WSvK245G8oy?%W#N z6DB@JV~b}Cc&2_6WtjpKfsFNgS`HViU+<|nLHhM|k>mU-zsFP2+Ls2FkwB19C8^=D zPFiKZGFts_EMa|sGO%lKJdVWZhw=yJKdDCYbkL8z#a-WGi#Fybas-ka3sp@A?xo?% z-iX-?dY*_HT9L|5Q|_5!qZxY~&Xz?abt=5k>eB!(vxo=Z9H@pgelHl(eAByjG})9F z-FISp)?&J~s|P1($!s-D7|a^M?~2fCa><)ed;@xqqGh~GRAAHztq+pHXhkj4twJY{ zypfp;P(j+j+N`d#kV`%gqqreUd1-jO)M5N27|?Yh-NyFCSVM8b0mtjD!JfkaSU3|$ zRB&K4yG7&XL#YuVhzhB6>SIvYM-=fT3RlrJ^xcsp6{XgxGwDjOur>HEr+{c=yo4ra z1dbw5;q`gyfCb<9EARdkLP-Umzo>d+HOA7ePpmSNYCO8m*fh#yR0^2zGviENoX$8K z$IilH=b(r6GWf#C78Umm<=wn6?1U0 z5AiS!QQAVfcvCBGOpBB|jW$1)>7wrTdUc@hM?g!b ze(?M`b^u$tpSQQ?f)NXN6zhBo*ctH88UD6|s;kpomU8)TNTX-(@;}H90PaXSz|T(g z$ib19UmncPc6|}ycu5{dc$@Bac>YBpu@3x2$2#a|TBm~RU(y5arxD@45eGRfoWA6+ zmK%4k39iTb&pu)l>zrw5?4(rLdYT=M>pccA7vc*CqcP5t{ zZnm^#g?2(YIO$NxT0~X1w`1z)+*mPeTwB`{;w`Q;mccQzW!9VZyQw?S92>4CJ1)wnC$i(hLI@>4{*BCb6 zOvrP_Hv4r6mQ+E1_z?N957E@~s5<29zyaKnf=Z_(gsW1sE^F6nD@`z!ILN0DP4hc9 z_5HD1=d%TC>8ndzW_fuNEc&yh8MJw}wIOpX-AsTfRtI9(>L%B*)$295)q?J9XbKd~ zt`F1UjX-!}b(e@OEjAHQFmbWgVP5~L-B9p?{)$~l)y2s9&1{P6d%k^8SqBL3+Cz?a zjG84gvp8NQ+9lM4Z%`4PKtFzvkTHj!!H4BS6HZoc67V=v6y9{3sAHG2%QsKGOY;+J z4Ut7X!+&{A+ql+-xj$a!H#%&qR%&5OhK(M~B6MwUUq?(Ys@!AKM@R^u>BG&e%}X>Q z1^_ZMorh?<0!w2xBwp#A$m_2?ubYSr21Gl@XqxLR3D{>Q97+VTpbM=sBN<_f(qbWt zc@(+FNd@{*2k9yI^Vry1v#i1j)x2MQ$Ds_+1{i_7(bk#XFo@GEbfe>Wm7(sF)|}hP z?Zxyr5^_F5H-st(HVl(S$b7u`XrX2hVB!uvx)1U+1~%1BLjt3D-o-+R!$Hx0<}cXo z_*gYe1l{*pQ3NZGA}D4)G}=J|by|3`i=0#-Bw)oo_$W{pq3l6?luwM~{Zm?pS5R71 zkUsVp{tv-4y;F*St1U2+p@y?z-u*iXOfkwZ2%8y+`DYHMNVC9_d}+Sl+%K>yU3TQ{ zmd!%t#a_ZUM@zUNj-^Y#2{YAilxF`vUp!$xlV^L8#^$aI44xN)#aLM_KaJxELT$x7 zRSa4hcMX)lfrjXv^Fw!K8sul#9>P9fT3+hb?#amNv%*e2^Bn{=W+AAxyM9dZlwp0G!{XV z&k`8KO`ria@d|R14`inl^U!BMt3g4II+CaS0l2s%kfRUhA=Ofzw&-o8A(P)&fUtQ= z!*me^tu?>zTVf z)0#bV#{gntz@ks|f3sBwm~o`=oBxxo+DSvTezFnHm!6BmM=n>G_ea^=i` z<-BATtJ@=3$T9;>O$TKHwiSeh1iJgadVesWoomKTR%v=tx(|?j68IS11j7O`0M_P> zJiIO+`Fy*QbXw=*_T1i9i~gOSiz0F&s?nBC{@b_3!jd%!&d90Qbk|ym)Kh<6(M){u z8qSgT8i^)*j+k%_4u>f`QBi(Gd)rR2FR2 z84dzvWku{B~&|c{Ik>AMX+-FZRF_SyCLhK@l#Wgr_IGqyD8st1OA_XN!50{>4=Wzn$OZQLq=eq(Jyan~z6L zjKqcEN-qaei1QZ1z9>(yyyKIv)4`Q|Dy!w@@hESeQ^T~K+f*O-!M9K-I$>h|$F4w~ z4s5VEhJ&=#O|gtVWgAYu#UrGJy2v-%f}va ztvjh}^+ZmoEQqx^zVH|vz+95v0KQ;^1?F;+{iWUD|6=C8>qL$nA3ZYJ9b@}g9Agyuu4B~QUCN;DdZ;s#f&E8YjLmjKZ`AVape@9314 zc8DD)NR9%kr)l4hrbulx`S6e?dd6b@l|d@&4SZ%_x@j8)zW) z9nz>&`XeCM1m+@~r#J13jfmvGWANPD#)QhuA#I-|*G^L(-(u&R{>4~<$!c<6(JD}~ z*IJ5(n>g7N^kfcYb=p0A05KhYSHzv>2>lw@;OioSD#;aO(C&iS~VV3Mx&!Sgu4EwIgKt9|k8B2d;NdBK3IQs*qW!WzPAdgJaOJH7Tu2l~v!ya#Tj-Prq2&A7Tq_Mt!#)qCT{&#FlbD!W-^rc;eb@#%yeP~R($)sSTV z&&>eAIW)z`cj!GdG_E53tMlpf>;v)K34lumndKl^Q-CKIAI(hOK^{$}HZx*8Md?ek z39^9D6d`lT&1rg#AYQh@b^B8}xuwtEO1dop1?0+k4=md&rFgXJ=gfEa6#>s*Pd!<_ zq8|3|ox<q*5t(`qhbqL1;2ZYxGkFAC?o8otpTjlvqV3(d z%<|8o9_gZM;=;Us-{_76c{K;WVzsGMIfb%E+9K#)FheZ}hE2Zi1qEBzb1DXMvaCw+ z@dzg7yQVkT4$*p5TVQ=lZv{%=+1mT(_lIpp(YL9j{NB^tm8pgd#ZH+7|8)QTqntS=$ z@XloK;CO@*Z3{?j8>B&~_%2zozCCe5K)$rfx4^YGYqQnA0Hi9biyXhdcGBpDQs`oQ zlPH>VvVq~fVK830Vqg60M-F6;7?Uz@j zlW-m|O7Ts8OMX!a`Oav@Kc;lPMgz%rt%qCGxfMbSgDvFOnSQxyx+uTR0{Nm?jAY4q z96t?Nhqr~HLu;v5^`F|ugvzODExEjlz+jC3zi&IteUb&`804Cg$ z9?`DKDvp)4o>tKc+}t;MSY9Zond{rxwsPyLe|hJ(Z(S*9p`o~94S$j1z2aqYGV11u zD~g+{K0(Qbk*UHG>VLRv>ZBLV({mO2{dq;7BzI%({U1=it3{>-*D{2>Fsokt3PV?S{b-EZ3Gp4-UW;L{oZ7&A@8%VtTk8iNcBq~1?T=@?0w4a*GQI92T)4<027(~u#BN64kTk@(`_D(9entvc>n2#M@|-xU$`%) zQ_vAGe{R*e+pI|=-$Lv2c9{HA#-!sWx^&-L{Gp8OPdy!(OK-Wx&)TwcBf0!bzA=^dn zpLP^kJl@3xr-ip%AAO0>Zr)#KCggV+19xmkNAW{O*f%Z6IByibbR!n{XmeKfl=4sJ znp^93cog)ZEmI5FG?WMRZDr&6z7 z-#Tvwvc9#QEX0p3Pwz#kT^-gYAago&7C{X~gtLwvubd}u5dTO10Nuu&H)&-ujT}G| z^xvR}i?|6slMEBL@Ov(ahKH*=oh*Ofd}pDAo;y=sf_fStrWpE}&#Q;P<$jdKR(0=# z9O;}-`an~;D=`%k<$QZ8jfn{v&|S$Rg{co>J$YzJ5hDPRdz)+PyorYhubZr*6VgO~@AA zOrts2utP@gfk&DAZS2MSkr=>RPk9LeM#+`rssbrB9bu4uJo|d!EN(QnuP^;ApY^UJ_vXb_QpV!FBGR zW)cDJpowAYA0X#nVHJoOrI$Tqf{d?5<(CRG)AcaL=GPzh4;Oc9@=4Z7x9%8`Kbu=e zq;*@(+kNX@B8Q*N;~%_jvPUQdDx~ck3We3AgQm(9! zMZ0nHJ4tvBwK>Od7Ga&kPIb>)nqB{7mw`(kkb%;L5T5|ok;q{-pirGJVD*gLwwfmfw z`_3A$F_y7WJ<$RwzV!yuuPCSiEx{{!w_B;!`9t2P&!uf1!o|$}Xruqz6_nVi zph&4&O6$@GO7IW34YiO>)ZOL2G59q0>#cRgV`-T(Dbr78o7!%a7$^QKcrVlW+2q_M zAtBu%>tECk_`F}sMD4#)lxIzgS65;prMlFwIT}y=mffJ<=aM`6uG&=w`Q>Ufd@tW{ zixX0(v3PyFNuzGOUrr)+^ZUCYf6_K;%GXi1=W8vM%3-UGekSp}S%&!RY3`{1sGUVn zK$CF3_I=ydfC~MP6Mo1{Zrv6IK}3Te2p~VMA`HbyV|T1|JDikTWztvOWznI{lfg{A z9%{Y+!xQzIA?Y-pjQ32pMdW?=)eky_orX34)H*w@;%i2PIog4#G?0b(Z^`I4a?PH{ z%nteuU;C6sImB_0Lho{#e&@LaQ1u7eLs9cUL z6JJe-5hD@kRvG_6@2PKRRxD=MV+F88pOM>--wo^rZH#M6%wg^f?c=xG&T0o-4y_l& z=uzY8-=So~i+ADYRb<(y@DseSpSi&qQY;PevU}w}qwXe||_b zAGh_lSiOp*j!=veqZ0Ms1gxjObpjW-EHDn!b8Za}mdUtLNW^Q)~-#{8=Onzjh ze7vC$HK&J)nkvpqxv*Dwizu~-BVu}j`90OUYEILwrqX$93R~kr1XsUZAi>2%LS|GbvUVZsau0Y_qCmjwVVukD^|{? z@M+#xXgTT4i8putt^+684)GnVcv>|Wv^t9`KVIc2F7X?k2sbkLt&)@qk*4!~_>X+= zSsZvWK8GO3DfwTbhGLRvnOD3bFK(I!s4Jd{VpOl{k>J9uNMs9T@mv^Rn(L1TM^BEmYh&L4CT7LV0O28 zS^i7c@pb*5YHc(W38aPlHs%ei*_JndRMiR%==LX@LVRtW9;(LaSBd_IBGQNlUibBG zq8>kS@jTiFZ0eV~roB7F7L^0X%VZvDsd-T}=$TO5r6k3As+w+)E?eQkB{G_ZDIwJ( zhg*FDx0?=wL%Uxyhg@;q!LT^FH};Lbv?KA`koE)181-Cy^!CYPq~lbcni_$!)RL$R z9_k`)r~OFnB^OoU5wr=SB@fmKeTnpd(eTI0d$T!;6QT>DsGZ!y`~3qHQ<~yGOKlf2 zNi@!mncvj^V{W(^!$on2&9cxGf$Hz!;Lc$Sup~|e`myu}*@bq$7K)~{9jVuE4H}^_ zj_`+`)GsP#L}TZp(n?Qy2LLgy-1eU@bXKv1%KBblDWO^P4uh`^uY2c?vs@)=<7`^Z z@}%Q7TlFARjjL_0+PK0|2iO0V1(0@Zz(Tnmgk$;q1-cR9Y3e%CZ;1=SM|gU=ce;h- zh`kQryYc)G+KXZ>f}~NVHeg=I2hlD!qCtK|ItjP?Y3>&eGuu-KrCVRX3N~rL+LP1e zR$PT2D*N>VyJ>f0+v?5Ym2P34Ay1#1?5ykalV8OgYpC=D`AhQAmjR2Hv=E%lPco6% zRP*IvepfB6QUez5U)t_IEcNN0N6U0}?K*a&&z~o&rPSrVzO|us%6y_OBuqSWow^$8 zFiQEP$)o@lYO;XsmH`_LkfQKeez~zzpqT^mDT9owsh>HP>)&&OyU1WWepf%@D_nOV&r7++b_^R?gY#<^V3bun4vAfv7|&f&#!9VafQ3v*B1wBS2$e+_j(LVHWIFfsg39q$L zG|=ucz~Q1e!|%l>q*{1VGrd#57HwanW;*}C<;`FjEhDLw-(@$O4P+IeG@Sr1#MgiP zLBp+u$gKmivdMZw2DxuM$+U_|YJY_{1gsC6Hr?G}3Kk3Jc=48=oPb(QGr_^vr=9PjNr8W}%gW{0yR%Vu)h zs|xYFb?}ESp3gObaL1KS^Zr|fERHT9qp$=vXz=MwO9#zVxv)=NTRfhll|O)gz0>&R zsMAh!nm_QCOwe;G=sc^&d&vpn3*PO*yGO_!q6mrPvOVWw)NL-UFEI)!Jl|P#k5@XJ zbviP!*ENrJ?aItu7I{RHy;EGEQ=Qb%dzv_nM_k%Y$mG2w%va17AA7m&E`o1^e1Kdr zY5DHYHsjRqXrs4(a$s+D!mtQFB41HCS5GgtGpaw65j`y5!n{cXnm`jPh0P}y>6~hH z-emk<=RPnv=8xr1SDE_K#V;Y1Y#$UIt?Nf&9Y*b?nfC&at{-YM8Rxgrnz&SE2yjbI zfE=_LGvg1PYx|}Yv?AgqkH|6qu3bRl(}MMo#mZgW--R~;)uO88#t_2zk+iDU7ld0n z1k7q`P~4LW!**Y(&xT%t&hn2v52qc-hCLs{D-QEIE?ZA-DYLp2@Q}po25TpiOg~aT z_O#;Ze(6vB6a5}r9WTVr3s?6GgH^sx(*AL2FkHiORM8)EmQSHJ^lpJ((rz@>)Cm=C z`mc&;p{*#C7wIs+-ciA|L-Gcer{$uoq2*S~%zD#X2vfGUPxiHkQ$2~dkB4g;@7Bwc zn)klTk8Z;tzxdyeh+}Wj2?BQO1(r*o_F)iaVu1YlgZudzRmkGdqr8`hl7Dnexw7!KG(?w zLn5i=6dp;n(veMoVz-lKWbud}h6wKf=*YP9`vBO_AxW9dppi1Q!r+TYn>XKVe>~X` z$EjW62r^k5O0BqBq2kY-5A0`i(9YQ7v&x)F-;ZZ=>s9d)N6fnKhhlA$r(^shQHfjt z$#y!oc{Ki(U5DSy^P!sO6^K)~(bopG5yTed*$)Xfy9)#&V_sGCWGf2+j(JK_l< z9yjO+wh@8Fk!x_rWe%V}1pU8l{UeWAhl4%qU&W$Ae^uiOB0C%2_f&1qXZ zQa`IV4QZb2FlOWTf5^W$7X8?rk)W$Yj2I=%nkiJ>=zciY?07Z&^SqCwN|V`XwN$Rs zcdo)%`^zQ87UszikWa`^Wripk;7m%Xxb+foc#i+M<1}ELotGkk@ZD*fzI;R1En+6G zbzu+5qwN?6%XmN5Qv$P2t>incx7P92iWE&bLJM>JJRT3Ua3O%fPVN`bIybwMXi~0K zI>z-0U2DOBHBtp?--r*+gsd+5?}FSqzvrsec=+iy0P2r?(c{Yr{l^M@z31x)yX6^8 znUoB|UxGUimo?FUn`Qwho>_G>IsvrVdGjeLP!wUaKZarSn$}0Oix5ZU6Ht%#3pZl( zt(GKy^&cw41BP>aYAURG=X`2JFGXz0V+Wk~pg6YI;&xN&v?CUbxoCB95NU18UZ&dYHY-H|%6YbPqH0pcR%KhH+Da4%tN3tB4IbDp|)tYeH@uW2j9!pIp?vtjby*LWC z&e(~e#lyUchGcl^($@S9YVywTehqQJ!ivXK;n-Io_-TN9t1U)VPV`_-zik;pct*$! z_<4%J$Mg8dwhPVKzSc-1LupiPH;Yc5mkaJF6XU;>d|q2O=X>KWUZ!=oI71URsvYiM zp*B)bTCOs&_<4J3Q*10F5r#$wH2CjBE?JV9v_pE2&v#ZmS><1m3zZHj z5zk=NuX@4#cprLkVkoEp%uHO2`m@7H^nO~L>+967J)4tOLVx4ftH0a8lne z1fM)Ys~I&a11}C1l++4k%h@bP*{leCaVUsC%@!Z*DQz5Q8Q;%%r}LPn%toBtK_9{% z-44Dgmxx@5fX$!S?gjc=AJ>AgR~y#EZm*U?T!3vka@hjk+)n0=q5;F_<$TVu@u|i{ zgVxBw!P!!YXMpR8Um1nWDrgH6uhuy(P}tV5eY6T|v3A-#+FQhCO8&6BDjdS!3V{q~ z(67c1thTM~$)tVD3842WrhGZNUEe&FZkUtzPWMRry6@Kd zjPWjplvqTW?Sf%(Bjr;uy9?%(URQz0??vioIdba`=3uM(Z*|}d0Q3Mm{MEYLzg8n? z4mEU2MVwkG{Nfoc8w8TsLywf2U3YI-b5jjxzv~n-=@I;VebSae%C@R6pagi^Ex0B0 zqqhgP$8#xjSpj$4Vw~sBFYe&Rw9#;El2x-XBhJ;}J)}4X90u6KE&6EYP(tBxF(80& z{HrBT=dg>nUu>QEf_#=n^-iRG!xXd!O|a~~QK9q3xF*jA%0WG$o6A;hD60v*7tImM zCrOBVlv#(dAF_!J_MRVEoAX~fHYfs7?T!D8@s6*zKeIsz!)ICgH6PcQz0R=$O4TFB zUd2Y+2)W9hX~CCxi@_#$Vt+op@BK>S?P(Lb!G+C)n`i===*C-kHXOdEE1eKJgfZww z_ul2gFSu&L3VKDGC=!PFT_vYc##+<> z9`X{ycoQ?<{}i`1%s60W>iLi`|1A7=eWK`8CZ1<8osQoA#Q|fYXhpcE7-5WBfxIlh z0gfOi<$K3#f2g)xyiR@p#dU3^`$P8z6gLTmYz|KeolxX4${nx;fM+- zt6Fb-{A!n6{@J^mpwPM0wzPCPG#g@_qfFs3hqd(WT}nfVpHV6qQQL51iwc!s_iIu< z&_`(ul7~ODtL4{E%b9J$EndyMDjDyU#!29={d@_9KzoT>O~XsVm>Zzhl@jakN15(Yb})X`-|GABq5g1uq1;6=F0g1Ptt)}_P-w)U!}-GyhqDYf`c;c9Y&QPLqoZB0 zFN@!<+#L3a`v56}6%=n-S=A4x4(nc*bp`YL-No*5k_U~Jtc;R$8N&R94yMF7Kk9ss zdRcO>QKI~EB*C@62}rm@dgJ=F!RBnz#4GmCv20E2qi{lHE{<4TD-gWHKiD<=YsPrb zdkT|%9K?7a#HYsze&0Om7BsEtK?G?LL(o;2UMl+A>@&<2!ZHqnf4;6NJNtxn0lC{N ze^vgEzbyde#`V;Lwg2+Y{qn%cyRG_KOQ>Ru9g57mDa)<9Q@y}^qgTvZHmy(m0a+;i-AL=d_zhcD z;IS3fsgU(OY^+0(VDWq77aa=LqmBkX(3|b|#xUOWuJCc;!sTqiJcjoaAu;CEcb~z9$1`4U0^Kd1d&DPzSAwaf9EM{BxYlZz_%- z$!Dc8G#lL!>MBAlZ4Ezh5G~WE)-jzGF_hiTfQ^}{C!Pt86y8e)=Ddp-UM>(^8ZNYE zei;r^`0=*21!iH^(rNzkbko0oc}l3WB2ahq?s8Gsce~h} zXr=V8LMo1AHWe_B37YkF`{3oiUiF44jl`V5YEo&!{%V+pHpCLLFVrojS>9h|olvfK-FAOXdi*<9xSvKU_ARec8e$r3 zJrc;`m~fXy@Xya|rRRH0LpBfMWp1T#NOjG`csiVOnsnXfeeLoR!@wZ~RriHTLD$PW zM1^zrQRJbAH|Xt8rRu12%Vj@YHN&4s`wTq-E=TH`CeO zT}*7;ecko|C{-zcP+T{q$>>#)Eqd#D8SrR)yt_)GAJH3(F!cH40ov%P#Paya>~mrh zd|Ndqqw;Lbu}Ak0(Bz8)bwBO9S}ix`Fz-vm8%iyP&^Fi7i13<4Emrb_%ZHu}T9#Le zu;-e+O0c-LF(nA8LIX>@npY$IZbf%JM=LofozR&L=+-~={?ONiqx4{cye-*0xqgR<`s))h1sY~3@Hj9HY= zBN;rnkvb7dq;qCc=q*dk^8(gY@ZFAW&2Ug*M@M1&lTFDCniE2^K$V?-}V;oN-{T6q6;(2^3ZKoq%hUdn( z1Nj&lN1@o(J@`6ReeY50tA^l1r63+uL~L+uxdCDa5 zxy7cjjg~g(p_;v_b-6FzX}o2+MaNJ6Ib}W2PZQ3k7etWqbIR)1A7Wm|kG$@*)K z?HFfrIC?KB;IlCEa6WW~zsRH%_dRak%W{MO?Q-c+G#-lB0w zwGC=&@icF%I3y@ny*=NR)_N3+!~%k@?6q=dmfRO|>{46qr~g6}y6D#~LNW7p4+m`R z)7Ei)^yMu@hi#(QRx4lnAH*XW?XGT-DH6{JMnd_{Jyc+Qe^R1+jOR|;wmXA91cO#l zun>Cu`Y(DXeVXF-+pjYp-`xc(IlTTf6pk9XVQ!+TPw*ECKLIqE?qgwg|7Hmosli7Q zA#xgib{{7hHWy<`i_jWj()ppej??Ko zrm^z9L!p$%_VW}+G8PO8daZ9wzE{yG8~vKM0u!~O&E`A5%wD8G$<@NBJ3M;BrlM78 z+~A*A9u7jRc`4JG+3U@bSuUP|&tZnJ(D58-vQBFUO&JAqm-Ib{5rUa@)s)WN$i*u? zh2!TbwOO~E+q`1@xhl;a|c`QP*DKep%V6I;8weBVyZBZF%%ATbYyE zeS$j70^nhqV}nHLRnqa9u{LKn!!XHZOk+`wN3zDeoNmb(M&_Q$P>w5C1RM4`KSpNi z*Ljaqe$q*R8>Dm$5b&nOpV7*|dc)U0Tdr$rwr#1|#VvQvwfk(I$eYseT+)8<0TDdP zk>$zvim%?|GmdXsr%dvqRVPlGXg>l3Md-IFuv>V-mdBOcs1>9N5jLa{ehiq2yZMJ0 z5J6cFAst?6BRPC*@~5I0zBMOIX){dqGi(uBDU!(4*#O~JjR_Ychhrt&uL)2}MZdYY zv%jLf-u+H2^t?E~W3tfTnIQAtyQLpwZh_t%;dz0Q!EG*INzM$11^*TCe8F1UXROm@ zAnCVzqDsDb;Kal3Z7k3iLM{G=ZW8f2{<}pR8jP|YL}a*zj73(C6}lH5?zjS#aL2EN zjtg7N%QC7pCNkgJ|Mai=tEcVPqM<-YH1fM6ft2qZwAuXrd9gp~wLD5MW^+PDf7uj$3Ka_K-%c7!87f_X<$vCQw-PI*P!fb3I0t${lEE^Uar3P%GsIgC zlM2M#rA3B|9Fd4d-IR;EJ^U-h;=*`H{c$<@7_P*pwoXX7INjtxb`bAN6@C%~K@fW; zUo-KlDX<-WbU+~C8TsZJQN_X<<~}M2@yoc?DI}pAo_Z!bEOTANFp5Z|a)ls@UY9~f z|0Z?i!h?I+F@l4!Ud5y`&saVPIRFDXM<_nw*_ll`k6+<7&)oY5iolsNL-nHec+~o^ z{)eSqIx<5`jz8!ktLucfK7P~D|5jvzoS2U&sL}I7G0fw!TlShT5p7J8u+(`Z)oy2c ztca{lqZO!6?x`uiU)I;G!J>9IP%xz`+HIvea@*XUHxKN3)qd#O8cq5elV;+Wc4-pn z?g!(uO{q(f*j3b<_1$CeZp=jW4%5XGd<5Jw7H@`6C^u;i*;23w>ykV4hD^}^hq2eAX7%;EIM+b)s4S5l!B}&PG{!dm#=a7`i;I?zH>KXur zmtuyzZSdWvzO<@g8L=SW9_d65j*!(!md4E2`!*L4iqZSpt{PwOglI|N`+*$xr$GqMTcqnMc??pLW==H$8j|UsTq1|a$AU4J9*7BFuzK(=4yT4d?&04OL~k{kuaEK| zeLkltDXiIoHm||kLfzp|(x85u2J$w`jURM+_z2o9PPre#X5HnIX*u!`8zyeQ!(6ME z`0O$^HpVXYYuw6>vMH&?_%V&fC_Ij-7F>7cU}pNZColJ=Jw+`smJG#plsoH`yH zi|nv=zyyr135>6;Ak{~0BezdGStmjXI#)M;qV5CR2*gOk#t)9kw_}o0f8p)qUDaHIne2iSI&e+1U z8miO&YtE*Udtn$bam-^XF=kk_Q5IN!|AcX5vE*^KNk`U*wp#ck#J+UQ4k#&rpq`)F z%OqBv@3dQ7A@R#?_eFgxZc0A0LxjE?rvXp+o>dK$@?GZadbP#mEx$x#u5yifDWo2_ zJ;`gKdcOm4_IL=@!Ue{%gqffiQRnPNWp)dE@z|t!GBM@w`E~+GV|+d*S+w$L<2VFU z++)dEGFJ~l4L^!pXJbq4k$ju?>kZ2tpw>k0)FRBIp7%fY#yofu95{uP^^d@P_cwMc5mO%c&Yg8t>E2X)hPfANl)FGRA44jxq*jAU^)g z3iDvs^`j=(fdhi`TK280pIZaj9N?5r3}k~}Jy~flHx5XH%fSv=p7I+78Y=A;FxSf5 z#wHT$YopAh?7BNmG|b*S_a+t@XWY?eBa4?mv4B2V+jg6ds+&z*TVzM<=lR$X8A3M{}q*F@?Vm;{^ zT+f{n?iO2Mb0$-BzR*J^tZJL+$W*Q8OJ$+W(yhm*WZ3 zdZ&v1qa$1ERTz3#?V>yr_0j=eGM>C(-NAbD=21v_L2y)NG$@4#Sw63eO62f z9cHt<|EtS@Y)Tc(j=WVe`fk~@2K z5R%@7DhqR_KY!!zdXqbue=acrBKCTQ^eLze+Jla-D=Z>1>>mB&via0}LLrEgy3rNS z{`+A2q5FVXj34I$H>AGsXUa@H&}R~@N)8#q*+FzHi@~e6J_-}-zTq%Ftj0Z0!%qiT zQ{1`bI4ox=71PDu>D;QHaNb>rysn+8vQ9V?{h}<85{=-6fU`9e?y$od>zFb23ka{g zszeb9H6q!C$K$o9BRL{Gk{~d&FP2NIqgDjrOahR!A0;PX)2U1v1U?~7-C?}F%4-kB zYquGW%!C;@#3fQM_ICYjK$0dFMtcy=m@{*_J0}ka9@@2@Q<5WDvJ4>DY509Zg~I{o zb%ynA=SZ;-WNV=)2E;xqU7e9U*KhOxN*#vpJo9F>()w02yUbMXE9ZPr!HMyLm;CX1 zcfrYI=+rCsRT|LS#z(?oOf2k;X3vX5JKpqv1q5DO2nnY(VG^;xJEflJqO@!O_g=TB zAUpS`I1Dk|4^Wh{4FVAoSf;Hq!C=rxothKmd?i9)YiuS$fRN7$jcNQUEM5vwLmyo~ z(x3fF%I0;nrlyqbC@apBG|Kg_RJFrIq}h50x}li`o5{jQ`#kpTyuE*24vQUF%)%Oa z$4(=U95<&rhGW0xO~5tc2}mw7;V^Me=$rh?UV$ky>cvt|8@u)aUacq50sa74we9Gz z%|7xni4|9fxmYy`zSbj5^OUW~uJ*)TP*5-xW5a%Y)&+UCa;?>07iRbjT=+txYWdoG z+M=l#7O-{pJ9x3I@zoeY z@tM>MNUU}z(yP{wIxylqFV_t8z;x@cDc>W|nX#Wq;Ou9Ozx2iXtTyVUbXOvSd!Hj3fiYL;C{v`{#MrM{9u4hW4iNq%+F?1F zD_Jq{qq{U&@C4TE*bJ%D@ChvXs8JY$_QunR1UU=hB#-MoxDSYF++TN@JRqJ%h+cc)qM3x za+jA}cI)|tuq4hN0i4OnhntWl{d8B^Y1ENyc^dHuPn`T~cRA%IjF0TS-$Vi(;`!WE zPaW9}s?sgB0_wJw+Qh-Z8-;d`=8Hk98oO1swL$7Ut4=(7hE~kL`;{xytFDlUY-xvu3euC4 z0iG8QXI&|GrwSdHaCP=uks#7q2pzdXuf_fS<`4#-9AcaIMe{_c0__U5Oypr!7&cvW z3<$cjh-3;!L{&JRE5(l{^QbLX0;O!*a-}r^gXWtSz}dq&V33spjla_7qs-s;!oRD9 z`d2XEcrH(s{n>S=q4eIL)vC0fd=(#*iFCbx=qYZ#*#ok)waka>gI9ZjwIqQd(ZegqC3`aqz85fm0JOQhHSEXzusnCs{`Jlm4Ac^Off|eGz!6^Z=oEugF#l zw3-x$80MYdgOKZkULg3Hoj#nC*24#WbDm!^>}c3C`?A;v(7taxoXp~{e8 zZU$qYb1+w?Rs67)wAPoR&-qdBk0p_eKDSJwHOtv@4N~|vpfplLxSc)?Bu(dCKuVoi zAPWU9z7%XiY%`Pr-C$3>Ry*dH#6eoU3{M81Wpxz1CIzWyl-cnHrC% z;JM4qg2U<~IDePIrEG)uqcr6F!sO039gY!1+_WqMD&Q8l{$yMm* z=$ubM<|lx0r7zFQVwKqe>3!|+b9ybYfXm5hXHv>a#bWafnkdL{Mfnhtu-1>3QuA1b$74 zx&yg71h;7LWMmxiYnEHX8xGc|4`jq!(5}GU z{W^NUyZQz^xb64Gy=HxCD4yfrC6RwNIR#S6B}#Dig4~OIotiP{?{{y{OmjjBPjg&L zh3WmznWj06HW5o;jeKxW%qKnT3s3Z>L2d{V+dV%KtBy&3vZ?6iV@&Qh3JBj|E>Fz) zH%N2|y{@*tm<$?*6a0rM6NurY`8V@l_L4&&U{l^hOEeQ z*qhg^WH6o$?p*2#m{jgsy&r`ul1;$y84@L&IBt<)n5o*V-N1?ZZhjrIu#~@ zU@V^-rF2adA2X}v$hR@4c%#(aVFa9CP(@8q3?9K3gH-uxr=Wav{ZV}VQjJkD+Bd}f z$4RNu^>lQ*B=E~0obt5rt5roQO?${H9w z3bHw^La;SiQs3-rmsB7I#mAMcM_bJ}A^NGRU!!SC+l_jbqh51+bXu~MXgLV%@o)4e zbYYOE8D68kG4pq_;vQWiISa^X8z;v0HQV{{wMMuJ=Z=ZG+dw^Wy?tAJOAWlFPs_0*J`7K%g5(@yqP};aj*|I8h)? zgVkFeweuDdP;7441yZ*2C6+#L%Nj37l5^12i<1er$|yJ`iG|_{WnTp2v1Z)~4b1@; z->=>I*Q1eC(z(jcOVMn?oG38t^ip4bboN#hYpH_VHRcl2Dzja+_DX-Nd)L6nc|jC2 zRrjQjDz}YiD_;pESDHY!K$nHP)?D*eSEpRZT^%dy^SDB>phu=69-!*P2&$Ei@hCLl zo1l{WqENOs-=KDmjLeZJ_~p4G+>w*M$piLooA7TuC+#f5ZKY_$yu0tToYvkE{i}%X z6$cBwUMHC;^56TD2@X90lVf|d1hW&-fu&DSjn%Y&++nTf>o9Igrd0Hh@wIZMt5vX- zXgxIaKNl!xqT&hsCcAKWKsuW`#g@sJX_vW8^)L;q!=tvxB~qX>4EW_3g`SkQ!_Uh{ zBP+J)`#q9ROBG9aF%&7nb^)bRMVnSFmo%kForH(7N?6xKL*_ve!0;U;bWdnx*plt3E&$92AN=8mjt7vS)U z+Yc>*exQr3G+?tekD9O45DpM7)SNtXrSGMNdTd4b7H0($C!mWXN76O)VxXDGhyR;$!_S@#6 zF1YYTFouLpab+9ZN4{P3Q{V2A>KxtHF6QepjfWPOM!cH!%;$1zC?ylstruz-{2xCX zI==kN%>UO@8-PiFmG)c+6#>DrBU_Tp)r81XJ`n;8(J&^-liYO>eG zpMQ`gXtei35wx7~KQWbV6YI~^_Roz+Fj&dQQ)c_(U1)m(8zE1aXU*r@+xl9X4FOIK zMH?Q_OltEvlPkg6H?J31%!hNTh8`|>-TQt_cLc;phwY4`@Rm~h;+&jOqU3(Pkf~DD z^1whk__9*iJTi~g>ftBy5H`IZsS&GAE4MRg;|SBlH+r@&6WxkyOdc?yL_b<*Zolvk z+73zQOJUiJkDRbF|_>ui>b0r`5TkZ1}gkqHTt z(v}AizaCE_j60@c~Q=f!D0PhBC!u?F`PBOv0pq#FT%vz|1FUJwUhp?NPoZJ zr2*Pe3YMAbzs~8uZ}i~B;Wl7RU2PLd{8?})9t7!U< zg(dheI_xl}0}$t2h{2|Jc57GIe-kI6Sh>Ofij{Mgf}S{-q?};*;(rw!|M=$P0$zlF zZ0$ccNn-H@wBVNVo=yC7fcAg=@bmIx!vFhsfRsYeEB|)-;^BL{|FS9I9PY9E*RTKQ z+vG?P3z!Y}qyN9{89>S#{BM6T=Kn`K#wX@WGZ;-Y24gFOQ25b1{!`rYmUiXbR?@qD|Z$pwn^DCZ^>k3kAf#0lvcHn5hTyVh@tK@4B%ED{Nv7Z*orume(L|t zwBz@;<%LO^nH5~mwrPM&`}Jwgh;(7SzfsQ^UU=FwMon^P2?Oe6iLcug#y^Tbe{k62 zwvT3-ER2#;v5*48G?^~Fl~3e<+%6D*`tVw+2S^mFe(eJ4`^)yPa~Km^Rm|s0n>pq0kugDyd@Fo{CF! z30%A8_|shGJ#5fPlnH-B#E6-)je%}3y~K{@361~ndVC%59{p}{dwhX#%M5FpS%3Md z70vV*m>&4x;mt*YQ;v1*u++*FzE`sFsw#hpSBUtFZ{_`g*TPJO-e?z}&7$NiNZaKT zn~KnBxbD^Uy3I6RRwqSu_%I9{H>+SxtSN92O2nx+<5!IJFJ^+zhBT<3PuBXUf1l6b zT5cB(vdfhEs&LS-+8rsia0g3N!p(H^UeSLXzhb+aibAh599z2By4$o@#nOYu_;HR> zP1@0?8{uaRS29|5fQ*NY16pg@y#jakQXr<2zQNUgw4T+Z|1*$5bF(+*ZO*zU3TD_B z&c!~>-km=2Su`<>E7Up3tfX?kI2=iR$6DifTl;H&98zlBOY3!mF@{ajI+NURU5ox*UsP`zKKD#_yqV9UD-CdD>19wlt^`x9=5AAGZeP+mwKA zTWWnPX8f61U-;7Km-?kyGy2@KE?5Ua-q+Xj&J>k?$Ru*%Bmy}OLi7dNCH1aJPe9Kd zD%S%-UL;t9^-dQ}(D6LA2ZjU+>iH;WHaZw2UF$q07y))_P4QKU&y-TDKe!`SBDs{s zkg#dL2&T?AxD{b|_%8pbd^;*oZKn*iL2FC_Pu{leLW-gj z6kfkuKAYx7|4YQ;o0G3fAa2x{-(%g9?_R;AYTv_XrITT#!NT;#iHXsA^(GLkrj9-g)P*JHQ&42vF2BeEAm5Hfz zU7cE}A^8d8w!fY_N=JAj(SAd{;$z-1kgGzA_l`CsL*_G~;&Sv#5YJD$ z*4t2IY;gFUqd@Bi=fZBxcg6JYP|zG(jwQV;qrLB3Mvu~L4!n^?ZKQG2&s;ZG8cWM=)3m0tb1 z#_<#R=7uhGLP|*yM(urf9&Sj>?(=WKzFKG z-=0XcrN#G3I&^c`0Z#y&lJ#>*4p7kv=%xwp zeWg>QGK`j`OznEsB>!UHWTgd=Bw9BdXMH^dk;?F4H&CI?&lB&%;Kg~ z*PBho>pQpiH|&*=bcSF)giD&H2=B+b! zUEz?=2PYq6_gwYh(-Xl^ z(}UrV@KaznRJ9p9!C{nmS(d`=?8qIGuWs65)HmZ1aGnXZi+Dr4^U z{$d3ULS!rOT-2w3#oYDE{?lO`kJ=OQXhN>its8lP+g)@`iq{{%lha}D))+Q?wjv;U z~=N+ukBB_ zRoYf_3yU-w;-OLR=*iz?ch;41jgTM*`w03N`>~&JCblOE@pfNLpCX1qR@~+2);9Kpqj3KM?MC&^*w{EQAT~Dih$0Z}^VR8Fi}>3TeHiW6 zQVG`CUi_iMTZv4TQ^mA;AA*_cPMHaXz%+}yF>17RZ#YQaH1t5ha(!?XgCvWt1Yack zCvGl+MBv-&w)80ykytqOaz&;=?Uoc4dAfPR|aEIja=&R)ky)Pno(=U3#B3<m z&ak+(D-_YxJ?69JnUCKW3R|R!BC#I`QOvFnrl@Vq-Kw_?bRxbccK-h1^$4YqPNurk z&O{T->k>=Uxk)mZnZhf_hN2woi*O>IrNe-7D~Ur#cin{Rr0|PEs9o|or=RI}&4zGa zo{{F6sBb&GyF&m*7@>s=AN+wz2KP%Avge(;&-p%NkeowURtA?-vyG!(tun1ot5`xT z0>5xRuWhZzkPxMvgoL37&&iJtO0>U5P>G*zpki^<;01 zac1y0*X317aiT*udbPsPk0pqx570)nx$M6GfuxI}-J0_3$FX>{C(3!zbbmR67$o!! znYq@Zj6*H)uPlHrISBg#a9d57LvbMh%L?dp`WSk+iQ5~armH`O58l)lK=J~P(&nh4 z?Ie%urmw_&*KZq-*A^yUwDY!~x8Ff$00Sa$Gk5mTwp$k=ZGEox?+)fq7Szi*B6iAU z;!@90aoOHD?$0vVtuqe!#6SK6PAAf1sR8QjuOwbKlAvD1%{K#V%3_xG3IFrrGUJ!9 zdQ_l4fKc1YGE@96D)c2eW&4`&A9%XU>I{iw8BUE-`#9I{;Y0$GB7#%zn{m6Aaaf0@ zA)|aGAG|2Dhn{kzBwe}9lfpCAyVA%eXKl3A*lidC`mrl7#_|JL_a*m>+j9$pHd;Rx zoyk{f#YG7mHlJY;p1csz;{1;sk3ZJ_gMnaawb2$=@%xYgi$JRw8#JZa^%E$l)cj?h zTDiprI<8D_TPNAskxr2hY-LI}#S6t6NCMxTgWk734ZB{@f20C2dfd;W=dymaRmYkk zqm=Nol=9Nwx8de)3iE@^ix&#ttBrc&==Bd(q8)WkbBdI=i1M9~lol4*z{Nh7$ij8sz=Nm)OURk=9Cou<) zo3XV}T_(}>K>BsaQ>DRaFfFxpSKCR2ipBkd0OwM_JCb_*47e8mpm%@T1O`8xlI?}n;!qF4y_dr+>$M+a1cs!#|QIqfeLBErif$kUS|2*pnxCSPuyt zaJ59np({9Yo~c6SmP_tA->45pC;I?st%}4qw^hk#TqjSzKqoXQ9G(8XN`Y~ua zC_O+gRI-(9bD~c0=M`B^c-R{hwb5 zt~~Te@Sy-o+34Q}@4s}oe|+Xp6Dsd%5f z3rImgJMfwO*bH!Sx_P%Acutkzyk;^io1*@=LW9Tx^UDmC(L}Ne&<8M_$o^}&}(tfVK_fnh-q$a*4q(&|8Rq8`l7$_ zmOrEc2r7fTgS2hoNp%?(=Q<-`E}F~huC*+8J*USbab-_?_)i&TAn(yJ-Lc&izZZQ!B7px=^|0_=A0k_*( z;>^c$FSq7B*Ftv}Btd2#kM%xf&O;F9@zS#W`Q_U3>l9;;2E&+q&0BwH3;D$QXDvi3 znvpIzGAr^+4(sOS83=#~e=nRHhDHo$MsN=GkX4@a&DA+&8g5uelB>8%Cel}|(kZ-| zcKWq|{G4(+*iaD~4PsvZfc5yRE6Z1)3GqotI)4nI%C7Qqp3=5-KldLbH1|YSG9#)^qSX!X&{t#cVH#=wrn4 z`%(cb#P%{7JXQ%1Y_K|#scXFYefa(UtcylHb2TTq=2HP3UM`32?2XA+6Timb;L(V_ z8OtQRT*~P^uJZ2a%wv&D7$#i|#E*BH66JO~6GauZKUuST2yEKVs@|@i025+H$xHcU7u1K7-BdNMLzff&1Z9bo0;$GrfbH=uH zK1|wzFepbfgTyP!$7G+aH$&ZjL;(dH@6a z3~VjW{4l*M-j2>MoyIUP&5)@wA-leZf!YHb1*Ylc|w<2|Axb#LgDr zRF=J`jm7a!Zn(<9p~^bM^f5IBLSOq&5jc<}C?(N8b!vQs^qqr%7dXZZz|r9#JY1P z?Q&5*pHJCRr_(RN_>OpuW9O;!!E6n5h&AF`uVwyR0 zhZf1v5q2|boHAaxt!0Q^?JuXwoKhBK%;)rJ@~6nNJ(1^Oz^1x$uV|`M*}RrgGtHiG1|8~24q+7v}OAB6K=%E=l1(OgNYo7YKJ7?o-G z?ntGB^xoR>&RVZ#*PE5Nc(A&@1fz>DKt(wpQfAam4+QWrdtMt3O9i$2L!W2lJFCHl zneH{`>_n$4$;kpX#4We=fF(52ida@1&Lco)W)eg4#orWm*5X}*)BdBCE&eca&->f> z`GgjXL4|=qIWWO6aoy4Ss4Ua9g7zw35$H{GPBGiQ3|HLz$;l4&du^k|NE5FZK@g%a zP$H$@lTM-hehku3cq6<)L;+3vPaxdOj12v4KIxHB=KH)))DKv&(0;1^*qUgF084<^ z(D*=*QDUXTW^M5mWbut`5!lp|0YFCd>Wj!6(qAB(EAveb=185X6G&9af#%@&3mSFy zDgqPZ8%u^iJ$)Dh`(|8c2+M}!_ztVbMKPHUdFzf9a%x2ydCK*A%^#mKW+*#X3eMVv z`vkx_S+!r0cyVW1?T@D?d@TD@-X!lX;%KeQ0F(Nqz$QF$=Q{!QXq@#4=VU! z*WJDtc6(SqEPAryT2H3OX*MfU7#4)oRz!^$1M`)Vq&%!L9L4PY8LRgL0b&hY2#W zH{3|vaFzQ50~j+-8%O*C1<+Hps`f~amK!qDeC+U{QkISYOfn$L-L9x3pL|0jd1ou% z87SwzTXL@S#djmvgh6xX1Qt%w^u%$ly^G3b5Yzwh`ed5z!9BP?j~Qa?=YadS)MU1N zid=ZSEyJ1X$FE%d4LB}IsOO%u@}_br^dOqTiPHZuw$!=#((<6uO?&rMVrjEqp^rMU zjgmaPewk34$(5x-oryzt5?%K0Y{ksyxls>%yu;aw`(~lNhiA>RBDVbtw}8J*&P!hB z;xPKHg4RbaXGk`OW>J^d-CdXSiKC*vb@vR$AnJTV*J1!NDHyH))^_yH6kCR;D?BA*ZOIsiL~>{iWCFrQvWU2P zb@Xvk`X$nR4one9=przpBV1%&#Z1@$(e)P@z@%q{*JkH^OUk z{nFt|rfK?kuQBO~<6-HXCI5pKtmy=oJREY4i@p>dWxfJdBZ=(!0`wG~a+|y~mR5;Z z_W}%{Ek}!J+%#&J_oyzxgs}PJcDm}cE0g>{m!xtW|8Y5%i_C;vh$jQCvGGt zc2QeDz0vfX8NqV{@#BO=-Q4_)2R@%cbixMl6oQqOdHy-kA6Pm5{4@kn;0I@$y8~Fc zJa4N}cOnw`L4cKO*n{oy!sMugBt|v^U||hn0n?0J8Q<@!u?YTQ`+7W|X=Ay~q*z1k zu10)Vr>?br&Xu>(-rm>Te4aOc zK&YXQ{jser=COhV)ADw1dOTvaMH*gbSuEl)vD^bDRyRj$r(+FNN7R^>m1R6IkB!)Ib;DN<{8=J{Ei@Ei0;kyWB~>GjcTE0 zdNO^TqvdDBrM4a9`JztgD$ppb?KU43tKXbsBW6Z_4na-tWMXCFomh^I&9efjPgbTd2 zUy=SDwSqL2Oi=B)l#aQ(J)UrY7)4C|r)K##yAg9QUI!)lIMO-698r@OQuDoqLP zHDOmz=cw(7AB(jXQqdq`4f3Y+!}dyOcr^ctU>dv-ns4%DskgVccMz1hEsmyGn2_|h2m#?{4QL zT6Ru-R``D?rHg0}uis&|W;UE*vo}y;(nw{HfVqU7oaIGR=@^T5Zebhz`^Xo~Z)Q+F zZSU1??PwSb)L&|%iAvz|S5JWW4FN|XvoKtiw8fRkTLph&HpGJu*SYN4;-DX15HjT% zczIZ>-)4fXIb3D{+~r1hiK*&E7eoF-Jh<+5D_Q-nR*sEospz~|vyIqKHIYsQ3WT0l zz&P@r%s!p=n-zWzquv5@nJHG03v+Z1fP*VE`PuSY2}+nZ?W+$NtBs-fx&fSIt8akd$5`AU08j^>vQNZ%HHY^E*U4%cSGX>W-HZVuBO-Kv;)2CUjckn1h4e(e{+nx&$k z7#KBZqpMA55n$v!ORgX(Kgj=vI*WSf^KvvB?YLDm|7Z2PWxcPiTW6qu3A!S$s<4?_Tjg5tgZ#kJ>c%5kUN$P-Qu4ic=SM@^lF< zaW8hu1GcTm(K|7D_oZO4&N6W&CJe-v{zDJ3{Fi`;IlW9d!KjF8J zgBR0VTsUm{^i;n_zKEDx;ZuJix$*lwr5TX&7;HxTN!;sY>)z%Ghd?%vXmpfvRf^Kn zk0!qBs4zdrB(7fy{%CDq%-o6mG$7E+{-9I0x_F5&4IMt=gKfoBJw2C}|Kqhcf1&9_ zy`~yaFNX?l%U+*kIOn|NCVd8{<-GrM>Mgsh8%V3cGt^79Hy_=u+_a9kuR@Gfyee4{bh5#;**mF2@i_UF%LqnpvoZnMa!YFfavpKR_}eiRG(0+5G?L3;;3J+w zDgM%9pL8QjEti~oX)%$XMS{DCbOYjYBio$opK;EI;_6>?k$6Q;SG+ajpLDF<=|M#! zMB)B0WfycA(9*r=6VGDk8hk#Xr70(I`-M?O7@zI2>u@JBMSTESa+)>D0~6G1e;oBt z-mqd=(9BRkTOywOV6ZpszMr)p&RIwRz;r&j%%8>0Ni$?0N8tNkwgMeJN96cN?uX>wDLRcK2`KIzAYh0FL$Pd6U$Hurp`ONX^1djrEy zy6F2ENb`;ZhGB2kI5|F(ojQAr!zL8Sa|z$KThs} zbhY6pkPB5+A`MzMxq~k!lY`rg)E~c!9#hkiV!u?2%15%R|5(@WLGEKJMQRw}B~tZD z&F|C83w3Dp@rn=0xIO#eTVCeD*bTpH+Km0F%3-cL05WfBze|4Z*if~Tb=$nUr2#{d zH8k_kSL7L^b~DQR)AYW0Ry8*{A*0t9Zwc`46w}O5O4UnLiGR;;x?Dc93i~q>6rA4{ zA?A#ZyZg=7o;o$)tUytBXW#qi;duD(k{v$miHQDmu8QcT1aN^vTYijNwarqZ-(~1| z;sZZQ=Vz^?mer^_9-EpWui{h}y_+#9u4F-$x5>bQ8VnAT_L~UV_ATMbgP(TmIi&t# zg1-p4FD4$yhvAPY%Qs3DsZ2g3;8$nUtvmd=g1UrklJq(kkEx--#Fnc4{^lm6sNC&W z^PLC4-kGp@p{HZL8yJ`u4%?# z@}Jl{t*mm!6?tQdnVOu=?!%z4|96VGjK94yF^C#R9{`!Rz!cBnM=^SKSIH zrREVYMDIRR%sU<<#3M~S(|XqRP?!q^B7A+euOCIuR-nI(>)TSkRrV`T>M&BPT0y9w z$o;aEdVU|1^~#ZsPn^?QJzYl{gSsUMjvh@+wLPsVZSCgga=QWz;)f!d1@)*I z3v^YuwI}bAL4H+K^YY~=pPDnn(od_-a!LHE^4GnU@gLooUCEmb*<&BoS}(_|Z+Bo0 zl%=1Si7w3Z^^1SU&5G&g87UCAX()_#tI48vGbBb`guxc1q&wbXlg? z)wNLeBv}#$dOlxR&`d@(gUK(972^G^(f#qX9Wt`g^JcQ{7*_huShe@n&%ksjQK5U^ zuLF$dI`tP#Rqw31dN2hEsptY;Yaq@ZNsxKlAwwz+<61uG)uX+Byv~#R^gIq(%6b_WQ#jGE+S!E$X4M%8rGjqw{>j-bd4cLB&X8s#%`} zMS&f-ROMxcG)0Mw{I?)nK1~YYFk?^`SW|eDu76u!P~I9{h+fz6aTaR}2pduSwDj%t z{m&8ZtFk?%<$+!o%%JBFA75Zl;nb`_DR_^=qna$>{nTs}k#wScP#`gFJ3hgT9?bTq zXQt@>M<=F@(}*o}pEez6tjcFz%P4szS`yn^lpn3^a`T*y%O$Myb%fx0-eb2(f1BAk zx1PZcQZBA-8;us+kS@Nu%|w{7PCe<@P1--@m``%mD z=BLsc`c02%9=(mnl*~z5sKDR^U-sRXDt+7F8jgh55d47x zYL6bYuWB+L)^yA_Tv0^<_H?6z8V!4!HZNCqbV_$Fp42$+eV`1B(av2fWZ08(9Ov~J zx%QlY-8g?2ryP@%qn27y&NwgmAu}dH{mpm3x+8)G@$hJfzl;cp6M1O+J|UgW3uuBs-FKFMp%YSA=xOF3xBs93n)p z%cSjH^r70u|J-vw&pma=q}ViA?|fFz*M{6kI<@-1tf=X_qR69UXFotPO*Gh&y-M~- z`vdVSCxe#hf7+QI? zt}D5T*E{(iv-WFQB2Kdzlk8Q!YEMPB>N6^M6Lz_BBJ-jtU3QVU94<2`o!Kl`_w=^J z2S_HkXPP#-oOSluF6{|gM#$2rKPIT-W4|TqVj_$RLzw72T!UR3Eg(#LQw)~YD9jC_N=t~(A=eq_WSNae^dxqVq` z^-2+3NKV#Iyt`&FL54QLN#8?x&DxFmNpR$%40sm6jQ$4d=DaMmR3u8Al_FPl+zBQ*fat$-VqN;b9UW0{7VX{!$6Dc;<>YgOSX5PCSAOhS&q+281qdXU8Ty_q_lB z+s!Wc=v1yUd-Utqn(~O%mR2N>tf$6BXLi+Bv}kK&K@=;+{3J-d6+S&5WEo|oSkEqd zcA76QT}MPOVV8K$s3bP2=_!pGc7aRzKAOL5yCkp3FY8h4eYDL#@u-G`GQV zd$;l$jmS04hjg;3*Yem5XG?#lp{rM#6F#n?Gv(cud?rxS9<(knF=xS**IR6S zYrL@4AXeW<)m&TE;qs^H!xD1}2?d1HlqLY0l?cFv_S}$za@{7hpT}R@G{`!4dS1`b7WBGy*N)!yGu{5OW8h5HwMl7Nzx}%6`aj;2AQYIu0pg*z zEQjN9blCu%r%G@3D|q%|!$#al)@C{Q%*!}73Wv2aztH~HrRiv6#9asycRng}+Yp^z z`^#g^D%h|U$#3#3X+B*8!?ii)k#vHLHFGyu}HBp%h& z_(beKGqv;JOAK)-@T2KpR|Sk?KM zbq-6}ht6p6L?!!_l!Ze>7jm6aTXrlKm6)nI(v;gu(ar)wYH3dhy}(M1=ng=!MUB*a#ee>-!MpkRg&0+dWFqqoM_SwY8#7s-G+SleLjMi&Eb~dw%N_di<(p=spScGEC>1Qb}!yVRA#*M$EtQd ziX6+i519FeqC#h zYnaX|4<6}t3ya3pXQ>$#TlN2zFCbFo;#}Go-|(?qb4)??u0;FpRfz~fw=fIGb}cqC>07D$DPj$ilZUJN3MoT5}oHo{%J4H5lxm^n2b{$1WQd%l zXQyd)vdHcgmU|Q&5GQqH4XwO07*WZx<$fJOFQF!#xB4TYCI&rfJN%5C<@Js3w^4$} zOd>@+nibAk1lN}ZpJ8Z*BEPj(6Gjh`vD>P5jF>aoCEgikvwN(ne*>xSp!E83lb zbgw!J)jc9WQy8xk_w{9<25`C7|JKBD1j+>uRt6*!?RH`%$(?|w3=^w-X3sD*Ka@c# zMe~@din?sQ>16pmE@seO){)R?rpOwn57JK-&|N?i64@P$>Fa3M{cPv*jMw2}Vg>&1 zV^`U}Z5)mpv#+P96G0h`f?~e3e?2kO1R$)&3Y>kNlVq1ee^;<)IaY5|7S#9+5c)&< zcM>N;$1yhCl)UmjXkdT*X*@J_oKC{)>(jEPNxTEgNe8>!?kzfp6lSo@Noycz$%;2Z=*xBb>u(ig4c_v^i>% zxSZgsuIHdW$Xu7%5R@XUfLdi9+Abw-UH|k*e8lIda-483pHY}d3A5CQfG?piVl&_w z|4tD~%_7{keG1T1M}0}xiegBTqGpX|Ua)JGoEpAH@_)an(Er#} zudK{$@+oCZak}=q)Y4N7T{uDK7dpj(!%*StuhhO)_9yF;nf{-1YtJ!pE_Kqio!{1K z8TZ99)L#~>!ct{!g|c$0c_Im8Gww6=ky^PdzA|pFgfzaN)!gK%9n}_ybs&{TI{)xt zin%Fp!T(!d%52?(j!6E(;a`&?tx9OgI|_*zdbzA}uL3@GAc+%yJu34MyJ7QMe3{>u zu_POz&0jY>go`g(BP2S(Vwv-e&gT`8UO`BqP_y`$#hDnYG!es(AQiSZC~hM|N||EJ z1YYTrh+9JMO^xlS`rhanij}~J!z`fWP<|kEUEw&W z$x74Pl`Wr12gpf?bFhh0GZ^xuOfpMigZ!ukn$yQH956=wsqBAf>wniFmYtOQ_456_e%aN?TVltZM%5p9B`+~%Hmo83~; z1dCZ*Z;%#Z;TID2LubMc?s!XC*)ClxwqK2Qc@sb zQr>rOTQ8k8#8HjRS#tK~bKwQndR6?*tH&O!69LZKEu(o?qCyv!ueMAEzB%DB3}daI z?&n%9f*jqi)$nH8PsETxwIT+grykZlfjt;=F#K7gaYtcm?*Q z)J4fuKK`L)c2aum7vllL76XZjkHj1FYac*F^{cxI18IBosJ^g^qTLa#Mslk`5q=kE z<8U_i>dP}r>Ob7_Jbt_7Ngx8ZJR0pHJCCD3-14jt9c{O;?O69~ORKeAc(!UU@=H)2 zK#S1-v4^${QMb)>S-9DD%j9Ac2C;@9Ll|JMyFEEP84Rq*4W}yBlYGNE-%ur?l;=;0 zNCn9Jp7sw_ML#*zqhIdq;ySsUKIYRA!fe7}t#F({_`>BvE*){L`b4wL%lvBV#F_`g z3AdTocJ$E~0V`c%084u$OwRobojeMIka_Lkq^Edk4(?YN6bQfBEpsO2+&_fuD{ceF zv#2VgkCnq~N#THd*a_sPUp)(JJV%{u?N(Y*37}&qntKy3Xl0k-;~KZ zaYCo_@w_j`*{{9aG|I0f8QdDZPL`TOqjZ9Nh@q|d-zYr=7Jeb{N?ML?3iu*K!LRb=DDR(VRY&$3ln<(BK6SFZiV+&8tp zaj1`Mm!2#}kfKPNPnUTwtJlp7s1L`AS-1Rf_oCkCpci)I|8&Gm zz+NZ5!<&2lhPG+U2iDZwpsjgvyc3->ve5yIL6BE4eGJNjLDNM@>C| zmEDFDY2e#k_%XHe5`4Y3kK{eB$Js#2BjFaMxI8`(N>-=3@{!o|x` zeL%cdIZ?%bqpJMOnSQT#q4v?{MChgGc1h#51bnhO-f&7BPAnjrjB4H2$}#695$LA$ z$psmOr|rrQ5VowX(06T*YnM9z?9IJKLWZ+b! z5_aDx%W?fM_Few^#&WY9e`D9=V-6AR1m4h>@k&-GjN2S!T9?rAj#v(Vuzgl_!NYWN z@ktPHlr`#0STA{PP?)#-lJAMavpmKvpglJj3mEvaRM{N@V~4y4n@E=3;YTWYS+g{E zLgaz*!|RIJ!3hYH$5jt|XAE1~=6JOnWkn^H7gtN&D6_g0&?<4R^$9x)sCr##i(PJW z829p@u?>M1>Q5dAywsLFEn|LQXAaOYhLdGvUN>@VL6U|GFLbG+By|gYbuep+U6=|q zhzW9*r&Wg_5T$SvSb?xXR}@e;?^3DJkMR*FU42Z6re_vyNnH)&U6GHsRw#*5^L(yIBrWSHMrtg^(I%smGMVw)y9DRN6`6;zZ z>3*VM3S^M>WhRm~6@6}@HNsmG62~OuOPmHG?Cp(N7Yu?m$z9NEbNU3=m8&TeAOO!2 z3^v?`%`WeG^wD~jJxDV1D7r9Dae13!AxUeIjy_N}J~cT}W@55U_o=%bCU@9;%&|Pq ztPO{dD~51WAAw28P6Hc(lIy;|FO^ z(;$~%3tg&!u9?UAYTU4lrQXP9Xy!6|k{(7nh?6A(naLqbw3+t4pk1Yf&Mr@ zTaiJSM3xgR@?3eE2c!ZoG&XaRPHmUFl|`Wd6GTEty0+VIHBg-2mh9&*Y`)Sf{Qd31 zvX?Ej{rd1=iHouAlvOY%dDgU=XQ=S52r)=a5hqxuI}~~}whX$vbckfDq}D9INK_0) z)w_0eGK5dX%F210v~fIS`*Crym45cJRz<9D%Lb30Ps}XTGSLvghn^NUB8^$>?rsj` z7IIolNjaa~!&40pan_kTt3NbtRpulL=i5#vKYR0d1Rt%uW3x{h%@9L(yWGC$xcy3a1>!umd zYHl57Q=Mi%3dxokC%e7izARFkZx3bIUA&83epX$eVzmdZ|K?5Oxy7PCG zZB5$a{HolMjV?B9>h+we{O~gAQUY1eErN%nil^BL$amg7$#52()B8&QF;oPQKOz)! zVXLzhOI?v8E@(bIB7MrIZ!8MEl`s?8O%lc~&U5+@8+zTlZ_vY?VEN<4$5ZXZw zD(*gaHE263H44rluf0YTj6ingM(ZmT?sp@Ar`K&um<)X%fJ?5{+JaR66OF8}${p-} zYa7W>vIrqJ)OC&?-#|iI`3&Q9{R;O&+= zJm!~%5yRP<;+90RyIvaQmfkYQF-^HAgXvw%66q=J&O5%sjyvHRFYHiV9z_FgS;uE9 zWz(`mKeCn&n1{y9>Z3)_AeSJV_dR}`S&C^@oA6rooRO?tcr*8v?1V+vPxGs<3pY zytwoaOUl7x&eQZJ9iM+GnyywJT{l&dvxcb3TmYtVPg)?f4pMmpDZ;00D=&P*D%F1G zt1{L48K2;pkBv@7*Pol zBVU=7-yUyIGi(Kke0KAa%)=V-{19`}eusiYD_=vVbriJI42zP_l?FcJLC2#T?pfws zz?`iRCgAC|#oKcrtgBbi^2q;!D(6UA+t;ack-EhRU%lZ#Wa!0pedGCN%i{FLry!xU zr#*zq`@)P#Cmt1%(fzu6#(s(TfEw#!C?RxoHWsVdKW%!s#^10jPBHTosgXvjru|Sq zqU6gTIW3&~h&?i_Xj82HxyUDj#2K(Kkgs;GD^^^92d;#wa%6OvEhiao0U|f9E0j@w znQje;<Gz>6ekdP5%A<7@eto58M>lb^71b3X46THgJ|nb;QQ3 zeO?fU-4DH9o2X1n;GmduIaw<-as1W6kG{x3VVXZj<1)0&JVMpTTt_X~&ymL52RaW$ ztZ#eddISCtOMgVZ7DuMkqRudw9JR_Jd>V%$SHF+1J)}gPVKefyFgx>3-DuhdR|}0@ zr?7|o>BmeY_t7^DDBYffRL`@|4veHzsp+^J@b^=$SrR8EH_3;9E7aPD(x-(28d+EZQji7u%NZ+~Eidij12k$JG~ky#6g`av`Q(X1WJ zyU}C9el>40TeT!kV6Dt)GMEH?_nvCqrN9xjFArALL$GsM{A4w6&^+~x0-`)oYLUJ{ zwJExIF^<+Wn#)zQHF~d`qDEof)$&b!h}>Ie(3c-V6ji9hM$Bd&u#gWJv3y7HZ2*0* z+x(U|ldqA^8apQJftWj8=H}$vA4n)~h9k{DtV`BTGj>C#jw0{c(Xi*k!>7d}E++O< zYe!`s-O>-ASJy`gx~Dgp%$%4fCIHC?90rUt%MsITMVd`0ik^=CMZT(G%`f?MyEr6P zvINrAkeM!MZkpieEVJ(oUg>25EBtn)K$>iGcdaqVzAj?E)Nbc9mypZzuDBC#R6t4^ zWPEk{BaO4>Qvv3F`;2|7!_^Kjx~m!gmR-60Ji<4yNpGLZz+cc~ud&?%Xr?*DHn-R? zr=5Q1BP|i3FFc|CE9oz=n&+h!h%p3}`>SdD5AfF;OUotu>eT3ja2BowntZGq-4MOs zuxN4ijXz4#-zRhyRVvil*y~<4*adCbX`do8*KHA-gjF$)U(fH1r%ZJjdcm8gPRObS zPaeVyv`?s8qFU=Fce$uCwuW9y(H?$iklb^!HR2tiWv9TxH75I^mHaYUXeua-qEByC z`U{7oLq2vNN(J^@^9M6LQBvkHnMroJxkK@E4B=zkgpBWArft?I0O^y&1z+@{F;u^RzS!xJc%2IJ4 zu^Ol(@Y>jY79I!+Fzl)8aJ#v}4(TV!ny!OV5inp<5x5d-84S3Q|B%V-i%HkT07`!v zlc5YYcxUTjE5Q$;J?|p_0}L;lXW{sh#YrWnH;6kFEnRNLo5-Fk29YpE6P|&90MOd)GVrhVd!n0kW8NbvDdM7A*_2yD)ieA5s%>ieY1 z#w(l^`@Qxbx53f&M4dz}tWe{u%dT}Qg~GJzc$H?xwen%7>B0=L2_)s_9kvGMENZIm z*2#?Nd!+bw7-zrz-3zaNRJ3*-RI?KJoK%Uog4%YOyM_l&6q47)E^drzE7E-q^w)&n=+DkigXF z0jqk82!qZqrjb-sux9&2wX#d~tpN_GNK9B@(<&G4W^Bt$i72%2YNA8n)O+PMB!W7L z8^zLhYqDHBS(GKF2ooKTo>ME|cyYs!5fdgK5+TxYgwwMT8cq+twCy+>4l?E9^ zD4K6;;L2K}J%=j8F8!7J5<4GYw%#M!MS-$gypXoBZMYlM@cHcyuI)oatSWO=@n~&K zlEYSG3bPJRv9@YNJ#syfI^B8MZ-FsfHIxk`qu7BApPX7yy>)4At(v`AnT)z)dLL46 zar7As8@24uc&TlhV(C zWsY7v(`5H+U*~WyDoj>k``1Kw(Y!e_WU6Goj=nAs4vjCmdz{`|;8(%x^ve#v0pMed zlymQF8%5F|MZ}F(ti_*uA$YO_K-Prp#!@)7#633~I~Ol%?x)>#n`>Sha(OC0?A8{u z)mdW-3=-|jCka^@6&R#lFV4K~Q8q02A5fVLG9X{vVZ#z*oS)O3Wx*Wtjpk11LX+{d zrGprqR_kx_4B-W#)O>UzgRlC!SZX!n2t40?%)QWKMTPM&w8yx2zFuF8c7 zyluy0)P77pU~>sXXLJ&u7tci-uWs(HIco&@6aPVroI>tTC-d9*<`(tD1R}Th2odAZ z)z>Z{dX);P`QV`pMYW`Vrp}I_f@Am*t(d#pDv8yHI+U7qg!!geGHyN_ z_AA~4$NK>*#%M`zM&pK^{=T+C-hE&}*NB63oCmaYwh881J5Or#<^&f)*w90x9kv8a zRJ=h#2l~)+)!f%O{!Tc7)+3_B&gDXt?3{(OSQ;1Z;EU?!fX-3UUH_wv(hAKo`|&lF z61is=UM8@~Y{%-YGovB4yR1YnxE&}cG}n&WolzI297vIcE@ySGwj6VjL7_$8#43q2 zz|BltMx*Y7YT(57stVd67^22-mq5F+JyI;-l(^hy1qrXelJynbAVbEssS(lBDI4aI z*qz|Y-EdlXJJ#;SgVeGs&ZC4DK59E8$!3f%MBb32l)ahP{JO}Neas!I;9!ezb2FQ0 zhNyV@lKY3h)vEK(!WyG(%Esp&>^?J}2aT_|QIK0CALNPiD2!n*^Xk9BkE!jQ)5r5c zFNftD%~IU{iFZZsP<+sl=s7?ZLUB<~Sz+9%sZgri!n1X2vqeFv?gm_~dj)Ik2HYo< z=+22vwGS!KsK%<23;QwX`Z=Tl2p&<0^!eh%4xB;zKsp)if(Sjz&Dp-58AC{|X*B;z zws0<>RvQ2dY6(&G3>cf*ZCnGA1Z{IT#-0v}S^Dsvs9tFJuRJ4)dKJyGbQ1fPV-FjQ z!U`a`!Qy#p^xH1>lohAry^m4=r+iO}z^B)QoKW-B+>*&>am+P{#YCRE7sq577j7{p zrkey1uGeRI>vJe?(WWm3BFR{h>PhEH4L;3J1iLl)Joz$><}N1~ z2}h$+H$3kipAdvd9#gcZJwLG9<4?)gR2Lm%ijl$;QHq~w_mXXTjSSg@htPiVJ5QCPIE z^9$OO0i>Td$+!0(7Vt4t;r%=4(ydi*5*GbO5llR&nux`+s?aaemsB=ssB^m zb-6p16N0FBznKQt9BR#DI2`7 zs$evnAB9nLLeD3DZe-b5-kPp?myH+Qf1f=0tctV7dya0S3?zMut{VI?H%SX9c8#=6 z#G>;wt7WSXoAuGtc>A~}{fa&T=-Bnox7FQxVSssf0%|IReb|PF9kHz0A@~$F- zs-R-hOE4mZ2c;XtFGXhcF6wiMs5F>u0Wol=9uB$ecXUUwhjK$M=ty*WMM`5rcqfnM z0swewR)H)C7e&9N1ZnQ;N|6!lyY*8MYyaOAfZ6JGgxqD;8)R)_2 zbkN1V!Em?5y*Ew})`{wHJXV=Gi%^R=7MYNcU|j#w zJlrPx+BKBIE*tdXnG58g8T)bRa9 zzQ)_W=P?tV%EVjI12(2D#|K%Yn7bY=7WDUXCCN1+xUJ?6YU6QlE8=pF!*loRa->zxJmcI+$_uqkLQwZDW(n$7Y?E8|ZF zQ^OVQ9XaF{)6zZc=}B(vJHRy+=x}uT=YSI z?`3g_RJDb>5cPedSWH&n8Ma|hVXZjn-s^N;px?C)G z#W>;uW@-5w1N#>od>aD+TDvoGovUpHyBI{X^!Xd8YBrStNKaCQTc$++DK4Z$*s+YI z75hv6^_TMIr;8@l#-H;XxElZS;h6=*e`X2-^HbXY>A!!!z|%z*=#K;?f8D!P0sk+L zZzP~_^>!=3*5kh%w9N+&I(hVj@pnM;A3hMmg8mV&lDTD6yq}KfPi8!U0n{?SEfXeo70aSg9w2Ni-aqZVaRBhVp%R(XhC7} zvWMGw%6fB3_(TX<0JW)WYJ9aP)^?@O#eAsts@y;HLow=PT}1fb6q~W6hhuEgF}nof>N~ZwK3D!Ji5$lFWBJ^Q z6L`AB;p9}n$Rz^Muhui7+|MgH%?8xe%FU^2ogIekJ+3P!xy30T8+i!D-xf?l$OY+X zUId4Gqhfb{yK9>Wxi<2$xcSD%!W*jB9>T2O9yDyL2mI@v9=cyGz57HiSfv0>Pq@V! z^LXk*%v;`f?rRv``UVwXINYB?x81o4AY+W;G@BUHKLVhe$WGz5WFck0D}!_fc}S>S$wW2Um0S_c{khS*l2G8Yc_|i~cT^R6e>ev=^S@hMDSn3CinW+jJ!F?zzF|i_ zDvPk;I_BAK8r^Nz&26c!M$q6R9MkxLDarkhyqBy`hY?TxM%fGJlSJ8%` z+`Hd`C(Vf+Q}%vb$^F7D9-`l}3y3!_huVU_I~IbRVJs-uBI0pbi2@;R{N46@=9E4t zdJoMn+Jmey_AWqLfRv4^-V$5P9q_uA{Ovc6AX%XPTi_pUrnnH902IlwJdPPH0l3Ff z_?wT=+8&8HCf6Y?tt9hw{;lBn>yE{b6)_^LaOsH5HS>HmT`#Ait;r96soVZSE>5`s zYd-6p*y0y|%y6Dkw7VTNp;Dzeg=RIw=n)wmOI^`RwRd-NqiG@R`J$(!{N~?ZC+vpM zLLr`-Td(KP$9_7!S{qGITkMK&R}Ce$le3zriFAHh2Qu=I^VPI{(9G++xL10|6JOW^ zh3!6duCTYH;rIu9!$RB(kg}lzfT!?+X&3aWl4g3jM3&tmu)i(;Yz0C>2On;2duo)Y zK9lT*T3@sTt3auL@Kv%q(uf)UStA-e2C!`36~e8en3d%;95p?8Qv;pXq8YPxA|m$GTnWD0l@+bUh)juqt?8aWe(A{fy`+0!o;Vr z9quFRyDxXERyrTWId3{_O}*_+6lAEqI4q9`l}iDK`NiyabsDNpPu-klFv{FQ?^XQI z+Xpx`B+VQAX}Nsj-SE-9Hn^co4duSGy2seEl{zvpM15m;D+3X4#O?Zf-c)Ny^^EJa#8L%70>wxi7eg^_w33(NMtW8o*7};`1Vg+bshVv=n@ksJ@zf0)Y^+#;tIkw0>!& z^GGE$I9e~gg~0Qf*Vy4IQGvZjA|&SQawt^6^?sX4=U|@#Q6j%njY5IKK-zt6jP?); zM~JG0^Cj}0J;A&oh|=up3^&TZdiQ`*={@#Nv}GLbX>Nc$>VeJWbN8-`1bJBqH_OXC zIoZRbkAHKAjaIYjXYu@Gq}s{ZL3xvi$ZUC&OPyD%K}!+UQwRQFv}brhe8?NOH5D$} zmtWuLuWnD)&)~{iQ1@b?4Z-J-&H4YG!g~_^afP(&YMQ(JFW*C4>W_`_KvUfD1)H#Q zMcb7Q_zHycsFz3Zm1LM{^ss2Um|_kC2hp=U4`2!Gg%CYjpq1(s=a?~5ZlT=R^Epq- z5hIr9p;=d%9f{@MK%<(x55|5h3|8;lk(nvC zs=sGJ_?l@fJgx1QAs&CD+Vlih@QNAB0-2LyopuSBF)ZR~UqvZIh>I0$JT$?*iLbW>haAms6u9{VVFp)iQtJGW;q z8p}dog8IM{fQ7^%9Yw&@jUrnn<;r6~qbjnPydNv1AH``prSWG$MD&9QM%yD_+>0ZS z%wGgsOp*_GeT9e+(YVGUQeQR6ko3c>I2Y}>2h`U({p ziM}V9L;fBiOICgK>!1-edyVA1j@@jO;#-$CdWOX9BT;wgjdLY3QbL5&5HUELt;de0= zc>~>LKq{Nrbqi)B8Oh19uJyQSOi3`0xl>LV{FyST>P(017;93TNh81q4FN$sPoBu< zHKP&1Q-yx?AN_Tjq`;K0BLZLTts@|OavF$4%WjoIu95Y@q@R`cd{3{~?4l4D%X{t_ zwTWmfJymd+@P_QVwqoz8M$o$fN}ts)IZ}`N(fuR=d}5Lfw)jYXRG2S7S~)nTnk-(y zh~M_0Z+!=rqs$C(Gx_Jr{Krglg9V_eH>B;J`M)DrGzJ7{eA6s~3A5vN0{_Lu&SbiX zXU$WgBwm|$wTR(5wU6iM(5Ud|X)(KsfP8B8;q9t6IF_{<6-*TKqg!eRK3Zyv+PI^o zz8>#ou@yIx$UR{(^-LF0C;MIcSE1Uf$&ub+m$1jQOhAP^eZnfNJ`XL==n5MTNYHIf za-&acGx9~foe=Do?s60nF*yglmnFTlc?le>m#2T41U`K7PHJTjRjU}(xrSBCIQWW< zheR73h~`Lt=;{jRX&1^fO`ZZywFQn3-$zZ5%*_mq^=#20a?Mo>=70J@Hl7_$lOQt4 zkkk*kCb|nCn%o{Z-x}^eJMPR(UR$54Y=Wp;kPDRV>E~OU!!F`c^sZOae#kryP*t;= zp4d5jq+N21%CV|MCK*$9q=&=QQdR10JN`f5{+BMdZE-G}m4?5UO*EX21ipwUlA~T; z8kDxM_8t-C5~IEmdwk%Xo4{9`o0(R<{?y3swB^%-&ckdx`=dC;uIWy8hpFepzt=kF4Ib=!4d1;C2)xF_6ML_Zek<ZjIf+e<~Ll5s8y~DT!Q7mh<@DogJ;KS@b6G8I1LdJ}rg^Zt2WE z@ga?2xA*g-`dDu0Kx3y>xvyN2TdsL?gy2Et40}5;suq(o) z(+#lwTyPB9B>E{vMIRn9{1i*@2^cSMQ^`{c2zy4#e`iwMb(DLH{}*h==TqNZjKyeN z9@NRfZiMSG{ed60JSIR6xcppQ>#@?X@e?1S1`+iDB%rW1i$k3xJ?VYSa1$nawe)kZ z$l`iAAEDscDPag3%9mpAH{))_cjuNSa|{nY1~rwqwG{h8O|iTjPb|yzuBf$G=8M4> z%y#36Mf3*(4(94Du~nh@n#4g)0KUFNisw;gkR4qr6}+zd!voi{aUzJg#J)@`G0q{f zFS~H-qPrvV-{y}Kp9Y$Yz}b8TM+!wPZ1nIyn;_i2f587Ug#hk_-bCTTJrN7@K9}hS zKKDhYx@o1Gszzou&aX!NpCRDj&+TvwOLyTeWfBq{7`*lQ2;T~M*f zz98@6WjSUzIzyvybErhUPOB1i&ZtO$%1lN4E-iafTiqr=wSM>&@N2F6jyyL#;7eSO z-o1^Psg}oA8XCpdQ%O0Nw_I<|RwyFe-&7wroAFY689iG@3;%dph&%4+@wx&qBL1E* zpnT>TtX}rg&(5Tqh=L8t_%PyS>IgPb!EfWQ|G3)^;78t8dLK++|Hek{zoZsGcQWYo z41QFQ7x}Mm`7dvO?=~gid!O6!za8}dPxSxv8nvKVm9~dcU|T6I|JPL2V+qPBF*C4+ zr9C9t{(C0vA3@IVCnCdC*1N0Id~xh{BEx*j75^TR{{2=9e-6@Lw4R2gfB)gXJ%8&j zQX!5CrQrjXIgj{0JTK6wq~@`l+LirX2>CtT{p0I%K14RXmaqz&1(3AKrhWVE`CH4I z%I4d1;zXi9mwGQ~yBxGRQOfw#cA@T{t%m>j9U3fZ>Om- z)7#Y{;IStfdOne0_+PRAznpJ2`OZw@Rf+Ds+ZhcKgiKBQQ*XGXJC@^>7cx36@Kna8 zA>79MTgLRSYc$1%P(!nzNxahyb^J3`{+tXES4kR=?j`N%z`sm5f4}>|bIKgNfG|lj z1^>3I|7s%1<7w^kQ>z9#pc!)TFCY4k=D~3& zg;mpk9nAh-B0pCLXe9;>zAztfATo1)JMI8^1aTz%`&d|!fH|`d11+2%7OWcC|IkeQ zZ@&~d3L=iOep>*G4Y`|wUTYAs?hmf4{_|%I^Fsd^lKD@5%#_h%qli1;pR|PR^8zs)um1xd Ce4bbU literal 0 HcmV?d00001 diff --git a/static/intermediate/operations/stacksets/stacksetsdeploymentoptions.ja.png b/static/intermediate/operations/stacksets/stacksetsdeploymentoptions.ja.png new file mode 100644 index 0000000000000000000000000000000000000000..3726146456e2bcbfdfd7b3bd458619886aea4a2a GIT binary patch literal 120482 zcmd42byS;6*FFpsiWDofP@JO0Del_h?(V_eU0W#b?he6(Rx3jvN?lfr?oE^%b1eJ)`lLW+EnfzR*yjXH?`!Lp_Lb+J|!Rlsv!4$hja- z_GHHhmIJG7+2v5k)01Z6jwAa#oJcRqpbOi)6-utetZI`;8WJ23J=~^d3}?&{`CFY> zk?5y8a~`LdfZX+K-bbEHT)YiTxD0f-oG}wrTzGN@3MU;d{+H$AC6u-k;FD_<+P8;U zDJc`8EqKPys3ZeV4$Ldti%Z9P;u~E~AD|714H(x9)m@X!_+3~E+CBl6+9R&sOoxk

R{JEnd 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%0AB0vhX8>wp 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


@e_8F)#N1S`XA9Ub5-Uo~|tRR~l<$k}{!T)Qx2K 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
    G0NYH8QA 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 Odm=9TDEonq$NvKfpMhQg literal 81022 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 Date: Wed, 15 May 2024 12:38:39 +0200 Subject: [PATCH 7/9] Bug Fixes (#263) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix intermediate conditions page. * Remove ``` from the code in the challenge section * Fix intermediate dynamic references page. * Fix code snippets indentations. * Fix intermediate dynamic references page. * Update the prompt phrase for a user to enter parameter details. * Bump version: 3.4.2 → 3.4.3 --------- Co-authored-by: sirbmatt Co-authored-by: Franco Rezabek <43790446+rezabekf@users.noreply.github.com> --- .bumpversion.cfg | 2 +- .../templates/conditions/index.ja.md | 2 +- .../templates/conditions/index.md | 2 +- .../templates/dynamic-references/index.ja.md | 34 +++++++++--------- .../templates/dynamic-references/index.md | 36 +++++++++---------- 5 files changed, 38 insertions(+), 38 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 636632a50..296c80fd5 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,4 +1,4 @@ [bumpversion] -current_version = 3.4.2 +current_version = 3.4.3 commit = True tag = False diff --git a/content/intermediate/templates/conditions/index.ja.md b/content/intermediate/templates/conditions/index.ja.md index a52d5fbfc..9aa2d7d2d 100644 --- a/content/intermediate/templates/conditions/index.ja.md +++ b/content/intermediate/templates/conditions/index.ja.md @@ -308,7 +308,7 @@ Outputs: :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation update-stack --stack-name cfn-workshop-condition-prod \ --template-body file://condition-resource.yaml \ ---parameters ParameterKey="EnvType",ParameterValue="prod"``` +--parameters ParameterKey="EnvType",ParameterValue="prod" ::: 1. `update-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 :::code{language=shell showLineNumbers=false showCopyAction=false} diff --git a/content/intermediate/templates/conditions/index.md b/content/intermediate/templates/conditions/index.md index b06c8d441..eaa2f11a5 100644 --- a/content/intermediate/templates/conditions/index.md +++ b/content/intermediate/templates/conditions/index.md @@ -307,7 +307,7 @@ Next, navigate to the AWS CloudFormation [console](https://console.aws.amazon.co :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation update-stack --stack-name cfn-workshop-condition-prod \ --template-body file://condition-resource.yaml \ ---parameters ParameterKey="EnvType",ParameterValue="prod"``` +--parameters ParameterKey="EnvType",ParameterValue="prod" ::: 1. If the `update-stack` command was successfully sent, CloudFormation will return `StackId`. :::code{language=shell showLineNumbers=false showCopyAction=false} diff --git a/content/intermediate/templates/dynamic-references/index.ja.md b/content/intermediate/templates/dynamic-references/index.ja.md index 9e86cc26e..24f88f1a5 100644 --- a/content/intermediate/templates/dynamic-references/index.ja.md +++ b/content/intermediate/templates/dynamic-references/index.ja.md @@ -84,8 +84,8 @@ aws ssm put-parameter \ 2. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ ---stack-name cfn-workshop-dynamic-references-ec2 \ ---template-body file://ec2-instance.yaml + --stack-name cfn-workshop-dynamic-references-ec2 \ + --template-body file://ec2-instance.yaml ::: 1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 :::code{language=shell showLineNumbers=false showCopyAction=false} @@ -140,11 +140,11 @@ aws ec2 describe-instances \ 1. `AWS::SecretsManager::Secret` タイプのリソース。データベース接続パラメータを JSON キーと値のペアとして、`DatabaseConnParams` という名前のシークレットに保存します。 :::code{language=json showLineNumbers=true showCopyAction=false lineNumberStart=47} { - "RDS_HOSTNAME": "${Database.Endpoint.Address}", - "RDS_PORT": "${Database.Endpoint.Port}", - "RDS_USERNAME": "${DBUsername}", - "RDS_PASSWORD": "${DBPassword}" -} + "RDS_HOSTNAME": "${Database.Endpoint.Address}", + "RDS_PORT": "${Database.Endpoint.Port}", + "RDS_USERNAME": "${DBUsername}", + "RDS_PASSWORD": "${DBPassword}" + } ::: 2. データベーススタックをデプロイするには、以下の手順に従います。 :::::tabs{variant="container"} @@ -156,10 +156,10 @@ aws ec2 describe-instances \ 1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` はあらかじめ入力されています。`DBUsername` パラメータと `DBPassword` パラメータの値を入力します。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ ---stack-name cfn-workshop-dynamic-references-database \ ---template-body file://database.yaml \ ---parameters ParameterKey=DBUsername,ParameterValue='admin' \ -ParameterKey=DBPassword,ParameterValue='wjznf74irj831o9' + --stack-name cfn-workshop-dynamic-references-database \ + --template-body file://database.yaml \ + --parameters ParameterKey=DBUsername,ParameterValue='admin' \ + ParameterKey=DBPassword,ParameterValue='wjznf74irj831o9' ::: 1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 :::code{language=shell showLineNumbers=false showCopyAction=false} @@ -190,9 +190,9 @@ ParameterKey=DBPassword,ParameterValue='wjznf74irj831o9' 1. テンプレートには `AWS::Lambda::Function` リソースタイプが記述されています。`Properties` セクションに `Environment` プロパティを追加し、先ほど作成した AWS Secret Manager シークレットへの動的参照を使用する変数を追加してテンプレートを更新します。 :::code{language=yaml showLineNumbers=false showCopyAction=true} Environment: - Variables: - RDS_HOSTNAME: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_HOSTNAME}}' - RDS_PORT: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_PORT}}' + Variables: + RDS_HOSTNAME: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_HOSTNAME}}' + RDS_PORT: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_PORT}}' ::: 1. Lambda スタックをデプロイするには、以下の手順に従います。 :::::tabs{variant="container"} @@ -204,9 +204,9 @@ ParameterKey=DBPassword,ParameterValue='wjznf74irj831o9' 1. AWS CLI を使用してスタックを作成します。必須パラメータ `--stack-name` と `--template-body` と `--capabilities` はあらかじめ入力されています。 :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ ---stack-name cfn-workshop-dynamic-references-lambda \ ---template-body file://lambda-function.yaml \ ---capabilities CAPABILITY_IAM + --stack-name cfn-workshop-dynamic-references-lambda \ + --template-body file://lambda-function.yaml \ + --capabilities CAPABILITY_IAM ::: 1. `create-stack` コマンドが成功すると、CloudFormation は `StackId` を返却します。 :::code{language=shell showLineNumbers=false showCopyAction=false} diff --git a/content/intermediate/templates/dynamic-references/index.md b/content/intermediate/templates/dynamic-references/index.md index 1d51954a2..a159f283f 100644 --- a/content/intermediate/templates/dynamic-references/index.md +++ b/content/intermediate/templates/dynamic-references/index.md @@ -83,8 +83,8 @@ With the dynamic reference above, you describe the intent of resolving the `LATE 1. Use the AWS CLI to create the stack. The required parameters `--stack-name` and `--template-body` have been pre-filled for you. :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ ---stack-name cfn-workshop-dynamic-references-ec2 \ ---template-body file://ec2-instance.yaml + --stack-name cfn-workshop-dynamic-references-ec2 \ + --template-body file://ec2-instance.yaml ::: 1. If the `create-stack` command was successfully sent, CloudFormation will return `StackId`. :::code{language=shell showLineNumbers=false showCopyAction=false} @@ -137,11 +137,11 @@ Let’s get started! Choose to follow steps shown next: 1. The resource of type `AWS::SecretsManager::Secret`, where you will store database connection parameters, as JSON key-value pairs, in a secret named `DatabaseConnParams`: :::code{language=json showLineNumbers=true showCopyAction=false lineNumberStart=47} { - "RDS_HOSTNAME": "${Database.Endpoint.Address}", - "RDS_PORT": "${Database.Endpoint.Port}", - "RDS_USERNAME": "${DBUsername}", - "RDS_PASSWORD": "${DBPassword}" -} + "RDS_HOSTNAME": "${Database.Endpoint.Address}", + "RDS_PORT": "${Database.Endpoint.Port}", + "RDS_USERNAME": "${DBUsername}", + "RDS_PASSWORD": "${DBPassword}" + } ::: 2. To deploy the Database stack, follow the steps below: :::::tabs{variant="container"} @@ -150,13 +150,13 @@ Let’s get started! Choose to follow steps shown next: :::code{language=shell showLineNumbers=false showCopyAction=true} cd cfn101-workshop/code/workspace/dynamic-references ::: - 1. Use the AWS CLI to create the stack. The required parameters `--stack-name` and `--template-body` have been pre-filled for you. Enter your values for the `DBUsername` and `DBPassword` parameters. + 1. Use the AWS CLI to create the stack. The required parameters `--stack-name` and `--template-body` have been pre-filled for you. Enter the `DBUsername` and `DBPassword` from the CloudFormation template file into the command parameters. :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ ---stack-name cfn-workshop-dynamic-references-database \ ---template-body file://database.yaml \ ---parameters ParameterKey=DBUsername,ParameterValue='admin' \ -ParameterKey=DBPassword,ParameterValue='wjznf74irj831o9' + --stack-name cfn-workshop-dynamic-references-database \ + --template-body file://database.yaml \ + --parameters ParameterKey=DBUsername,ParameterValue='admin' \ + ParameterKey=DBPassword,ParameterValue='wjznf74irj831o9' ::: 1. If the `create-stack` command was successfully sent, CloudFormation will return `StackId`. :::code{language=shell showLineNumbers=false showCopyAction=false} @@ -187,9 +187,9 @@ ParameterKey=DBPassword,ParameterValue='wjznf74irj831o9' 3. The template describes an `AWS::Lambda::Function` resource type; update the template by appending the `Properties` section with the `Environment` property, with variables using dynamic references to the AWS Secret Manager secret you created earlier: :::code{language=yaml showLineNumbers=false showCopyAction=true} Environment: - Variables: - RDS_HOSTNAME: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_HOSTNAME}}' - RDS_PORT: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_PORT}}' + Variables: + RDS_HOSTNAME: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_HOSTNAME}}' + RDS_PORT: '{{resolve:secretsmanager:DatabaseConnParams:SecretString:RDS_PORT}}' ::: 4. To Deploy the Lambda stack, follow the steps below: :::::tabs{variant="container"} @@ -201,9 +201,9 @@ ParameterKey=DBPassword,ParameterValue='wjznf74irj831o9' 1. Use the AWS CLI to create the stack. The required parameters `--stack-name`, `--template-body` and `--capabilities` have been pre-filled for you. :::code{language=shell showLineNumbers=false showCopyAction=true} aws cloudformation create-stack \ ---stack-name cfn-workshop-dynamic-references-lambda \ ---template-body file://lambda-function.yaml \ ---capabilities CAPABILITY_IAM + --stack-name cfn-workshop-dynamic-references-lambda \ + --template-body file://lambda-function.yaml \ + --capabilities CAPABILITY_IAM ::: 1. If the `create-stack` command was successfully sent, CloudFormation will return `StackId`. :::code{language=shell showLineNumbers=false showCopyAction=false} From a47e4a3d0d774c2374791f6c8810504f2498b641 Mon Sep 17 00:00:00 2001 From: mackey0225 Date: Fri, 24 May 2024 18:00:57 +0900 Subject: [PATCH 8/9] Fix typos and syntax errors (#264) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Fix typo (CloudFormation) * Fix typo (parameter) * Fix typo (AvailabilityZone) * Fix missing closing parenthesis * Bump version: 3.4.3 → 3.4.4 --------- Co-authored-by: Franco Rezabek <43790446+rezabekf@users.noreply.github.com> --- .bumpversion.cfg | 2 +- content/advanced/modules/index.ja.md | 4 ++-- content/basics/templates/outputs/index.md | 2 +- content/basics/templates/template-and-stack/index.md | 2 +- content/intermediate/templates/conditions/index.ja.md | 2 +- content/intermediate/templates/cross-stacks/index.ja.md | 4 ++-- .../intermediate/templates/dynamic-references/index.ja.md | 6 +++--- .../intermediate/templates/language-extensions/index.ja.md | 4 ++-- content/intermediate/templates/nested-stacks/index.ja.md | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 296c80fd5..90a805e55 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,4 +1,4 @@ [bumpversion] -current_version = 3.4.3 +current_version = 3.4.4 commit = True tag = False diff --git a/content/advanced/modules/index.ja.md b/content/advanced/modules/index.ja.md index 14df5ebcb..641a55f37 100644 --- a/content/advanced/modules/index.ja.md +++ b/content/advanced/modules/index.ja.md @@ -5,7 +5,7 @@ weight: 300 ### はじめに -この章では、開発したモジュールを使用して [AWS CloudFormtaion](https://aws.amazon.com/jp/cloudformation/) の作成、プロビジョニング、管理に関する機能を拡張する方法に焦点を当てます。 +この章では、開発したモジュールを使用して [AWS CloudFormation](https://aws.amazon.com/jp/cloudformation/) の作成、プロビジョニング、管理に関する機能を拡張する方法に焦点を当てます。 これまでは、CloudFormation を使用して AWS が公開しているリソースタイプを使用してアプリケーションを構築する方法を見てきました。このラボでは、[AWS CloudFormation モジュール](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/modules.html)を活用し、同じ AWS アカウントとリージョンを利用するユーザーが何度も使用できる再利用可能なテンプレートスニペットを作成します。 @@ -15,7 +15,7 @@ CloudFormation モジュールの一般的な使用例は、企業内での利 1. モジュールの開発とテストの利用に必要なツールをインストールします。 2. モジュールの開発を開始します。 -3. 準備ができたら、モジュールを [AWS CloudFormtaion レジストリ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/registry.html) に送信します。 +3. 準備ができたら、モジュールを [AWS CloudFormation レジストリ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/registry.html) に送信します。 4. CloudFormation を使用してモジュールを管理します。他の AWS リソースタイプと同様に、CloudFormation テンプレートにモジュールとそのプロパティを記述します。 ::alert[モジュールを CloudFormation レジストリにプライベート拡張として登録するか、パブリック拡張として登録するかを選択できます。このラボでは、プライベート拡張の例を取り上げます。]{type="info"} diff --git a/content/basics/templates/outputs/index.md b/content/basics/templates/outputs/index.md index 62d20b221..5b85b54ad 100644 --- a/content/basics/templates/outputs/index.md +++ b/content/basics/templates/outputs/index.md @@ -73,7 +73,7 @@ aws cloudformation create-stack --stack-name cfn-workshop-outputs --template-bod :::: ::::tab{id="local" label="Local development"} 1. Open the **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** link in a new tab and log in to your AWS account. -1. Choose **Create stack** (_With new resources (Standard)_ from the top-right side of the page. +1. Choose **Create stack** (_With new resources (Standard)_) from the top-right side of the page. 1. In **Prepare template**, choose **Template is ready**. 1. In **Specify template**, choose **Upload a template file**. 1. Select the **Choose file** button and navigate to your workshop directory. diff --git a/content/basics/templates/template-and-stack/index.md b/content/basics/templates/template-and-stack/index.md index 8d9faee6c..7a1f9e1b9 100644 --- a/content/basics/templates/template-and-stack/index.md +++ b/content/basics/templates/template-and-stack/index.md @@ -52,7 +52,7 @@ By the end of this lab, you will be able to: :::: ::::tab{id="local" label="Local development"} 1. Open the **[AWS CloudFormation](https://console.aws.amazon.com/cloudformation)** link in a new tab and log in to your AWS account. - 1. Choose **Create stack** (_With new resources (Standard)_ from the top-right side of the page. + 1. Choose **Create stack** (_With new resources (Standard)_) from the top-right side of the page. 1. In **Prepare template**, choose **Template is ready**. 1. In **Template source**, choose **Upload a template file**. 1. Choose the **Choose file** button and navigate to your workshop directory. diff --git a/content/intermediate/templates/conditions/index.ja.md b/content/intermediate/templates/conditions/index.ja.md index 9aa2d7d2d..d83a51264 100644 --- a/content/intermediate/templates/conditions/index.ja.md +++ b/content/intermediate/templates/conditions/index.ja.md @@ -45,7 +45,7 @@ CloudFormation は、スタックの作成時またはスタックの更新時 それでは、始めましょう! -まず、テンプレートを再利用可能にすることに集中しましょう。テンプレートに、ライフサイクル環境の入力パラメータを含む `Parameters` セクションを追加します。`EnvType` パラメータを呼び出し、使用可能な入力値として `test` と `prod` という 2 つの環境名の例を記述します。使用する [Amazon Machine Image](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIs.html) (AMI) の入力パラメータを定義します。この例では、[AWS Systems Manager](https://aws.amazon.com/jp/systems-manager/) [Paramater Store](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html) を使用して、使用可能な最新の Amazon Linux AMI を参照し、`LatestAmiId` というパラメータを呼び出しています。 +まず、テンプレートを再利用可能にすることに集中しましょう。テンプレートに、ライフサイクル環境の入力パラメータを含む `Parameters` セクションを追加します。`EnvType` パラメータを呼び出し、使用可能な入力値として `test` と `prod` という 2 つの環境名の例を記述します。使用する [Amazon Machine Image](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIs.html) (AMI) の入力パラメータを定義します。この例では、[AWS Systems Manager](https://aws.amazon.com/jp/systems-manager/) [Parameter Store](https://docs.aws.amazon.com/ja_jp/systems-manager/latest/userguide/systems-manager-parameter-store.html) を使用して、使用可能な最新の Amazon Linux AMI を参照し、`LatestAmiId` というパラメータを呼び出しています。 ::alert[詳細については、[AWS Systems Manager Parameter Store を使用して最新の Amazon Linux AMI ID を取得する](https://aws.amazon.com/jp/blogs/news/query-for-the-latest-amazon-linux-ami-ids-using-aws-systems-manager-parameter-store/)をご参照ください。]{type="info"} diff --git a/content/intermediate/templates/cross-stacks/index.ja.md b/content/intermediate/templates/cross-stacks/index.ja.md index 1aad5e8a4..6fc6b7213 100644 --- a/content/intermediate/templates/cross-stacks/index.ja.md +++ b/content/intermediate/templates/cross-stacks/index.ja.md @@ -91,7 +91,7 @@ aws cloudformation wait stack-create-complete \ 1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 1. `vpc.yaml` ファイルを選択します。 1. **スタック名** を入力します。例えば、`cfn-workshop-cross-stacks-vpc` と入力します。 -1. **AvaliabilityZone** パラメータには、 **2 つの AZ** を選択します。 +1. **AvailabilityZone** パラメータには、 **2 つの AZ** を選択します。 1. 残りのパラメータは **デフォルト** のままとします。 1. すべてデフォルトのままウィザード内を移動します。 1. レビューページで一番下までスクロールし、 **送信** をクリックします。 @@ -142,7 +142,7 @@ aws cloudformation wait stack-create-complete \ #### EC2 クロススタックの作成 ##### 1. EC2 テンプレートの準備 -**クロススタック** のコンセプトは、 **Paramaters** を使用する代わりに、組み込み関数を使用して、以前にエクスポートされた値をインポートすることです。 +**クロススタック** のコンセプトは、 **Parameters** を使用する代わりに、組み込み関数を使用して、以前にエクスポートされた値をインポートすることです。 従って、`ec2.yaml` に最初に加えるべき変更は、今後使用されなくなる `SubnetId`、`VpcID`、`WebServerInstanceProfile` のパラメータを削除することです。 diff --git a/content/intermediate/templates/dynamic-references/index.ja.md b/content/intermediate/templates/dynamic-references/index.ja.md index 24f88f1a5..99703f453 100644 --- a/content/intermediate/templates/dynamic-references/index.ja.md +++ b/content/intermediate/templates/dynamic-references/index.ja.md @@ -26,7 +26,7 @@ _ラボ実施時間 : 30分程度_ ### ラボを開始 -#### Paramater Store の動的リファレンス +#### Parameter Store の動的リファレンス 開発チームにライフサイクル環境を提供する必要があるシナリオを考えてみましょう。このプラクティスには、多くの場合、最新のオペレーティングシステムアップデート、セキュリティの強化要件、必要なサードパーティのソフトウェアエージェントを含むカスタム [Amazon Machine Images](https://docs.aws.amazon.com/ja_jp/AWSEC2/latest/UserGuide/AMIs.html) (AMI) の構築と配布が含まれます。 あなた (または組織のチーム) がカスタム AMI を作成したら、Parameter Store を使用して AMI の識別子を保存することができます。これにより、EC2 インスタンスを起動するときに使用する AMI をプログラムで指定しやすくなり、設定ミスの可能性が低くなります。 @@ -53,7 +53,7 @@ aws ssm put-parameter \ --region YOUR_REGION ::: -::alert[CloudFormation を使用して、`String` または `StringList` タイプの Paramater Store パラメータを作成可能です。詳細については、[AWS::SSM::Parameter](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html) のドキュメントをご覧ください。]{type="info"} +::alert[CloudFormation を使用して、`String` または `StringList` タイプの Parameter Store パラメータを作成可能です。詳細については、[AWS::SSM::Parameter](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-ssm-parameter.html) のドキュメントをご覧ください。]{type="info"} 3. `put-parameter` コマンドが成功すると、SSM は `Version` と `Tier` を返します。 :::code{language=json showLineNumbers=false showCopyAction=false} @@ -253,7 +253,7 @@ output.json の内容が出力されます。 ### チャレンジ この演習では、*動的参照*についての理解を深めます。 -AWS Lambda では、`MemorySize` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-memorysize)で、[関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)のメモリ構成をサポートします。ここでのタスクは、AWS CLI で Paramater Store パラメータを作成することです。ここで、`Lambda_memory_size.yaml` テンプレートに記述する Lambda 関数に使用するメモリサイズを設定します。次に、作成したパラメーターのバージョン `1` への動的参照を作成し、テンプレートを使用してスタックを作成してビルドした内容が機能することを確認します。`cfn-workshop-dynamic-references-lambda-memory` スタックを呼び出します。Parameter Store パラメータは、スタックの作成時に選択したものと同じ AWS リージョンに作成します。 +AWS Lambda では、`MemorySize` [プロパティ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-memorysize)で、[関数](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html)のメモリ構成をサポートします。ここでのタスクは、AWS CLI で Parameter Store パラメータを作成することです。ここで、`Lambda_memory_size.yaml` テンプレートに記述する Lambda 関数に使用するメモリサイズを設定します。次に、作成したパラメーターのバージョン `1` への動的参照を作成し、テンプレートを使用してスタックを作成してビルドした内容が機能することを確認します。`cfn-workshop-dynamic-references-lambda-memory` スタックを呼び出します。Parameter Store パラメータは、スタックの作成時に選択したものと同じ AWS リージョンに作成します。 :::expand{header= "ヒントが必要ですか?"} 1. CloudFormation [ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-function.html#cfn-lambda-function-memorysize) を参照し、Lambda 関数の `MemorySize` 設定を指定する方法を理解してください。 diff --git a/content/intermediate/templates/language-extensions/index.ja.md b/content/intermediate/templates/language-extensions/index.ja.md index 4c356120b..26cbab06c 100644 --- a/content/intermediate/templates/language-extensions/index.ja.md +++ b/content/intermediate/templates/language-extensions/index.ja.md @@ -271,8 +271,8 @@ aws cloudformation wait stack-delete-complete \ 1. 上記のステップ (1-2) を繰り返して、スタック `cfn-workshop-language-extensions-solution` を削除します。 :::: ::::tab{id="LocalDevelopment" label="ローカル開発"} -1. [AWS CloudFormaiton コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 -1. CloudForamtion コンソールの **スタック** ページで、パート 1 で作成した `cfn-workshop-language-extensions` スタックを選択します。 +1. [AWS CloudFormation コンソール](https://console.aws.amazon.com/cloudformation/)に移動します。 +1. CloudFormation コンソールの **スタック** ページで、パート 1 で作成した `cfn-workshop-language-extensions` スタックを選択します。 1. スタックの詳細ペインで、**削除** を選択します。プロンプトが表示されたら、**削除** を選択します。 1. CloudFormation コンソールの **スタック** ページで、チャレンジセクションで作成した `cfn-workshop-language-extensions-solution` スタックを選択します。 1. スタックの詳細ペインで、**削除** を選択します。プロンプトが表示されたら、**削除** を選択します。 diff --git a/content/intermediate/templates/nested-stacks/index.ja.md b/content/intermediate/templates/nested-stacks/index.ja.md index 31503d9f4..7c261c08d 100644 --- a/content/intermediate/templates/nested-stacks/index.ja.md +++ b/content/intermediate/templates/nested-stacks/index.ja.md @@ -196,7 +196,7 @@ VpcStack: 1. **テンプレートの指定** セクションで、 **テンプレートファイルのアップロード** を選択します。 1. `main.yaml` ファイルを選択します。 1. **スタック名** を入力します。例えば、`cfn-workshop-nested-stack` と入力します。 -1. **AvaliabilityZone** パラメータには、2 つの AZ を選択します。 +1. **AvailabilityZone** パラメータには、2 つの AZ を選択します。 1. **S3BucketName** には、[S3 バケットを準備](#2.-s3) セクションに書き留めたバケット名を入力します。 1. 残りのパラメータはデフォルトのままとします。 1. **スタックオプションの設定** はデフォルトのままにして、 **次へ** をクリックします。 @@ -323,7 +323,7 @@ VPC テンプレートと同様に、`ec2.yaml` テンプレートの **Paramete * `EnvironmentType` - このプロパティにはデフォルト値があり、頻繁に変更される可能性があるので、Parameters に追加します。 * `AmiId` - このプロパティにはデフォルト値があるため、メインテンプレートから除外してもかまいません。 -`main.yaml` テンプレートの **Paramaters** セクションに以下のコードを追加します。 +`main.yaml` テンプレートの **Parameters** セクションに以下のコードを追加します。 :::code{language=yaml showLineNumbers=true showCopyAction=true} EnvironmentType: From c6489dcaecd5a1b4aec629d2e0183b5696603f9f Mon Sep 17 00:00:00 2001 From: Zach Baker <141531139+zachbakerdev@users.noreply.github.com> Date: Wed, 12 Jun 2024 05:25:44 -0400 Subject: [PATCH 9/9] Bump database instance type from t2 to t3 (#266) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Bump database instance type from t2 to t3 * Bump version: 3.4.4 → 3.4.5 --------- Co-authored-by: Franco Rezabek <43790446+rezabekf@users.noreply.github.com> --- .bumpversion.cfg | 2 +- code/solutions/dynamic-references/database.yaml | 2 +- code/workspace/dynamic-references/database.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 90a805e55..a2154a614 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,4 +1,4 @@ [bumpversion] -current_version = 3.4.4 +current_version = 3.4.5 commit = True tag = False diff --git a/code/solutions/dynamic-references/database.yaml b/code/solutions/dynamic-references/database.yaml index 1c6253f54..206990b9d 100644 --- a/code/solutions/dynamic-references/database.yaml +++ b/code/solutions/dynamic-references/database.yaml @@ -31,7 +31,7 @@ Resources: - id: F80 - id: F27 Properties: - DBInstanceClass: db.t2.micro + DBInstanceClass: db.t3.micro AllocatedStorage: "20" Engine: mysql MasterUsername: !Ref DBUsername diff --git a/code/workspace/dynamic-references/database.yaml b/code/workspace/dynamic-references/database.yaml index 1c6253f54..206990b9d 100644 --- a/code/workspace/dynamic-references/database.yaml +++ b/code/workspace/dynamic-references/database.yaml @@ -31,7 +31,7 @@ Resources: - id: F80 - id: F27 Properties: - DBInstanceClass: db.t2.micro + DBInstanceClass: db.t3.micro AllocatedStorage: "20" Engine: mysql MasterUsername: !Ref DBUsername

cdCjwEzgfE1ny(1Y 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 literal 0 HcmV?d00001 From 51f77e0bb802729ef3d4bc8de54294c619b1299d Mon Sep 17 00:00:00 2001 From: John Losito Date: Tue, 5 Dec 2023 07:51:44 -0500 Subject: [PATCH 2/9] Fix broken links (#257) --- content/basics/templates/linting-and-testing/index.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/basics/templates/linting-and-testing/index.md b/content/basics/templates/linting-and-testing/index.md index d2fe7ae44..4c9e1b2df 100644 --- a/content/basics/templates/linting-and-testing/index.md +++ b/content/basics/templates/linting-and-testing/index.md @@ -122,8 +122,8 @@ cfn-lint vpc-and-security-group.yaml #### Template testing You will now use `taskcat` to test your template by creating stacks off of it, in AWS regions you choose. You can describe test configuration values you wish to use with `taskcat` by using [config files](https://aws-ia.github.io/taskcat/docs/usage/GENERAL_USAGE.html#config-files), whose configuration properties you have the choice to specify: -* **[general](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema.html#general) scope:** a global scope for all of your projects. For this use case, you create a `~/.taskcat.yml` file in your home directory; -* **[project](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema.html#project)-specific scope:** you create a `.taskcat.yml` configuration file in your project's root directory. You can also use [tests](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema.html#tests) configuration directives at the project-level scope. +* **[general](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/) scope:** a global scope for all of your projects. For this use case, you create a `~/.taskcat.yml` file in your home directory; +* **[project](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/)-specific scope:** you create a `.taskcat.yml` configuration file in your project's root directory. You can also use [tests](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/) configuration directives at the project-level scope. Start with configuring _project_ and _tests_ scopes in the `.taskcat.yml` file located in the `code/workspace/linting-and-testing` directory. Open this file with your favorite test editor, and specify name(s) of AWS [regions](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema.html#project_regions) where you want to test your `vpc-and-security-group.yaml` template, as shown in the file excerpt below: From 9c2e213388e4a0976703dce032a1c0e9f6f84515 Mon Sep 17 00:00:00 2001 From: Mickael Charneau <94433131+cmick-aws@users.noreply.github.com> Date: Fri, 15 Dec 2023 19:25:00 +0900 Subject: [PATCH 3/9] #256 Fixed broken/outdated links in Linting and testing lab. (#259) --- .../templates/linting-and-testing/index.ja.md | 10 ++++---- .../templates/linting-and-testing/index.md | 24 +++++++++---------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/content/basics/templates/linting-and-testing/index.ja.md b/content/basics/templates/linting-and-testing/index.ja.md index ff69c5579..5ea372349 100644 --- a/content/basics/templates/linting-and-testing/index.ja.md +++ b/content/basics/templates/linting-and-testing/index.ja.md @@ -38,13 +38,13 @@ cfn-lint --version #### テストの前提条件 -`pip` で `taskcat` を [インストール](https://aws-ia.github.io/taskcat/docs/INSTALLATION.html)します。 +`pip` で `taskcat` を [インストール](https://aws-ia.github.io/taskcat/docs/INSTALLATION/)します。 :::code{language=shell showLineNumbers=false showCopyAction=true} pip install taskcat ::: -::alert[この [note](https://aws-ia.github.io/taskcat/docs/INSTALLATION.html#windows) によると、`taskcat` は Windows ではサポートされていません。Windows 10 を使用している場合は、この [ページ](https://aws-ia.github.io/taskcat/docs/INSTALLATION.html#windows) の指示に従って、[Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about) (WSL) 環境内に `taskcat` をインストールしてください。]{type="info"} +::alert[この [note](https://aws-ia.github.io/taskcat/docs/INSTALLATION/#windows) によると、`taskcat` は Windows ではサポートされていません。Windows 10 を使用している場合は、この [ページ](https://aws-ia.github.io/taskcat/docs/INSTALLATION/#windows) の指示に従って、[Windows Subsystem for Linux](https://learn.microsoft.com/ja-jp/windows/wsl/about) (WSL) 環境内に `taskcat` をインストールしてください。]{type="info"} インストールが完了したら、`taskcat` を実行できることを確認します。 :::code{language=shell showLineNumbers=false showCopyAction=true} @@ -124,8 +124,8 @@ cfn-lint vpc-and-security-group.yaml `taskcat` を使用して、指定する AWS リージョンでテンプレートからスタックを作成し、テンプレートをテストします。`taskcat` で使いたいテスト設定値は [config files](https://aws-ia.github.io/taskcat/docs/usage/GENERAL_USAGE/#config-files) を使って記述できます。その設定プロパティは以下の通りに指定できます。 -* **[general](https://aws-ia.github.io/taskcat/docs/usage/GENERAL_USAGE/#global-config) スコープ:** すべてのプロジェクトを対象としたグローバルスコープ。このユースケースでは、ホームディレクトリに `~/.taskcat.yml` ファイルを作成します。 -* **[project](https://aws-ia.github.io/taskcat/docs/usage/GENERAL_USAGE/#project-config) スコープ:** プロジェクトのルートディレクトリに `.taskcat.yml` 設定ファイルを作成します。プロジェクトレベルのスコープで [tests](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#tests) 設定ディレクティブを使用することもできます。 +* **[general](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#general) スコープ:** すべてのプロジェクトを対象としたグローバルスコープ。このユースケースでは、ホームディレクトリに `~/.taskcat.yml` ファイルを作成します。 +* **[project](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#project) スコープ:** プロジェクトのルートディレクトリに `.taskcat.yml` 設定ファイルを作成します。プロジェクトレベルのスコープで [tests](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#tests) 設定ディレクティブを使用することもできます。 まず、`code/workspace/linting-and-testing` ディレクトリにある `.taskcat.yml` ファイルで _project_ と _tests_ のスコープを設定します。このファイルをお好みのテキストエディターで開き、以下のファイルの抜粋のように、`vpc-and-security-group.yaml` テンプレートをテストしたい AWS [regions](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#project_regions) の名前を指定します。 @@ -206,7 +206,7 @@ rm ~/.taskcat.yml ### チャレンジ -`AWS::SQS::Queue` [リソースタイプ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html#aws-resource-sqs-queue-properties) を記述したサンプルテンプレートのエラーを発見し修正してください。 +`AWS::SQS::Queue` [リソースタイプ](https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html) を記述したサンプルテンプレートのエラーを発見し修正してください。 * 次のパスのテンプレートファイルを特定してください: `code/workspace/linting-and-testing/sqs-queue.yaml` * `cfn-lint` を使ってテンプレートのエラーを発見してください。 diff --git a/content/basics/templates/linting-and-testing/index.md b/content/basics/templates/linting-and-testing/index.md index 4c9e1b2df..ae642b456 100644 --- a/content/basics/templates/linting-and-testing/index.md +++ b/content/basics/templates/linting-and-testing/index.md @@ -37,13 +37,13 @@ cfn-lint --version #### Prerequisites for testing -[Install](https://aws-ia.github.io/taskcat/docs/INSTALLATION.html) `taskcat` with `pip`: +[Install](https://aws-ia.github.io/taskcat/docs/INSTALLATION/) `taskcat` with `pip`: :::code{language=shell showLineNumbers=false showCopyAction=true} pip install taskcat ::: -::alert[As per this [note](https://aws-ia.github.io/taskcat/docs/INSTALLATION.html#windows), `taskcat` is not supported on Windows. If you are using Windows 10, follow instructions on this [page](https://aws-ia.github.io/taskcat/docs/INSTALLATION.html#windows) to install `taskcat` inside a [Windows Subsystem for Linux](https://docs.microsoft.com/en-us/windows/wsl/about) (WSL) environment.]{type="info"} +::alert[As per this [note](https://aws-ia.github.io/taskcat/docs/INSTALLATION/#windows), `taskcat` is not supported on Windows. If you are using Windows 10, follow instructions on this [page](https://aws-ia.github.io/taskcat/docs/INSTALLATION/#windows) to install `taskcat` inside a [Windows Subsystem for Linux](https://learn.microsoft.com/en-us/windows/wsl/about) (WSL) environment.]{type="info"} After you have completed the installation, verify you can run `taskcat`: :::code{language=shell showLineNumbers=false showCopyAction=true} @@ -120,12 +120,12 @@ cfn-lint vpc-and-security-group.yaml > Congratulations! You have run the `cfn-lint` tool against your template, and you found and fixed an error detected by the tool! #### Template testing -You will now use `taskcat` to test your template by creating stacks off of it, in AWS regions you choose. You can describe test configuration values you wish to use with `taskcat` by using [config files](https://aws-ia.github.io/taskcat/docs/usage/GENERAL_USAGE.html#config-files), whose configuration properties you have the choice to specify: +You will now use `taskcat` to test your template by creating stacks off of it, in AWS regions you choose. You can describe test configuration values you wish to use with `taskcat` by using [config files](https://aws-ia.github.io/taskcat/docs/usage/GENERAL_USAGE/#config-files), whose configuration properties you have the choice to specify: -* **[general](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/) scope:** a global scope for all of your projects. For this use case, you create a `~/.taskcat.yml` file in your home directory; -* **[project](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/)-specific scope:** you create a `.taskcat.yml` configuration file in your project's root directory. You can also use [tests](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/) configuration directives at the project-level scope. +* **[general](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#general) scope:** a global scope for all of your projects. For this use case, you create a `~/.taskcat.yml` file in your home directory; +* **[project](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#project)-specific scope:** you create a `.taskcat.yml` configuration file in your project's root directory. You can also use [tests](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#tests) configuration directives at the project-level scope. -Start with configuring _project_ and _tests_ scopes in the `.taskcat.yml` file located in the `code/workspace/linting-and-testing` directory. Open this file with your favorite test editor, and specify name(s) of AWS [regions](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema.html#project_regions) where you want to test your `vpc-and-security-group.yaml` template, as shown in the file excerpt below: +Start with configuring _project_ and _tests_ scopes in the `.taskcat.yml` file located in the `code/workspace/linting-and-testing` directory. Open this file with your favorite test editor, and specify name(s) of AWS [regions](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#project_regions) where you want to test your `vpc-and-security-group.yaml` template, as shown in the file excerpt below: :::code{language=shell showLineNumbers=false showCopyAction=false} [...] @@ -137,13 +137,13 @@ Start with configuring _project_ and _tests_ scopes in the `.taskcat.yml` file l When done, save the file with your changes. -::alert[As part of [requirements](https://aws-ia.github.io/taskcat/docs/INSTALLATION.html#requirements) for `taskcat`, you will need Docker if you are building AWS Lambda functions with a `Dockerfile`. You will not need this functionality for this lab, and this functionality has been disabled with the `package_lambda` configuration [setting](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema.html#project_package_lambda) set to `false` in the `.taskcat.yml` file.]{type="info"} +::alert[As part of [requirements](https://aws-ia.github.io/taskcat/docs/INSTALLATION/#requirements) for `taskcat`, you will need Docker if you are building AWS Lambda functions with a `Dockerfile`. You will not need this functionality for this lab, and this functionality has been disabled with the `package_lambda` configuration [setting](https://aws-ia.github.io/taskcat/docs/schema/taskcat_schema/#project_package_lambda) set to `false` in the `.taskcat.yml` file.]{type="info"} Next, you will create a `~/.taskcat.yml` configuration file __in your home directory, that is outside your projects' version control path__. In this file you will store, for all of your projects, configuration settings that you do not want to add to version control. This also includes any sensitive values you might have: __do not store sensitive values in version control__. ::alert[For information on how to reference sensitive values from your CloudFormation templates, see [SSM secure string parameters](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-ssm-secure-strings) and [Secrets Manager secrets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/dynamic-references.html#dynamic-references-secretsmanager).]{type="info"} -::alert[Values you pass to a given configuration setting you describe at a more specific scope (for example, in `tests`) will take [precedence](https://aws-ia.github.io/taskcat/docs/usage/GENERAL_USAGE.html#precedence) over less specific scopes (such as `project` and `general`), __with the exception to the `parameters` setting that works the opposite way__ (that is, a `parameters` setting you describe in the `general` scope will have precedence over more specific scopes). You will see how `parameters` is described in a `general` section next.]{type="info"} +::alert[Values you pass to a given configuration setting you describe at a more specific scope (for example, in `tests`) will take [precedence](https://aws-ia.github.io/taskcat/docs/usage/GENERAL_USAGE/#precedence) over less specific scopes (such as `project` and `general`), __with the exception to the `parameters` setting that works the opposite way__ (that is, a `parameters` setting you describe in the `general` scope will have precedence over more specific scopes). You will see how `parameters` is described in a `general` section next.]{type="info"} **Create a new** `~/.taskcat.yml` file in your home directory. In this file, you will specify the name of your S3 bucket into which `taskcat` will upload your template to be tested, and an example value of `172.16.0.0/16` for the `VpcIpv4Cidr` example template parameter. :::code{language=shell showLineNumbers=false showCopyAction=true} @@ -204,7 +204,7 @@ rm ~/.taskcat.yml ### Challenge -Find and fix errors in an example template that describes an `AWS::SQS::Queue` [resource type](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html): +Find and fix errors in an example template that describes an `AWS::SQS::Queue` [resource type](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html): * locate the template file available at this path: `code/workspace/linting-and-testing/sqs-queue.yaml`; * use `cfn-lint` to find errors in the template; @@ -212,9 +212,9 @@ Find and fix errors in an example template that describes an `AWS::SQS::Queue` [ :::expand{header="Need a hint?"} * From the `code/workspace/linting-and-testing` directory, run `cfn-lint sqs-queue.yaml` to find errors in the example template; -* refer to the `cfn-lint` command output, and to the SQS resource’s documentation [page](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html#aws-sqs-queue-delayseconds) for values you can specify for the `DelaySeconds` property; -* see names for available SQS queue [properties](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html#aws-properties-sqs-queues-properties); -* see names of available _attributes_ for SQS queue [return values](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-sqs-queues.html#aws-properties-sqs-queues-return-values). +* refer to the `cfn-lint` command output, and to the SQS resource’s documentation [page](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html#cfn-sqs-queue-delayseconds) for values you can specify for the `DelaySeconds` property; +* see names for available SQS queue [properties](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html#aws-resource-sqs-queue-properties); +* see names of available _attributes_ for SQS queue [return values](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-sqs-queue.html#aws-resource-sqs-queue-return-values). ::: :::expand{header="Want to see the solution?"} From 86ee01c33be76280bdd1b33aa739d44b7c9a1e1e Mon Sep 17 00:00:00 2001 From: Matteo Rinaudo <52245107+mrinaudo-aws@users.noreply.github.com> Date: Tue, 9 Jan 2024 12:44:49 -0500 Subject: [PATCH 4/9] Add cloudformation hooks lab (#260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add lab for AWS CloudFormation Hooks. * Bump version: 3.3.0 → 3.4.0 --------- Co-authored-by: Franco Rezabek <43790446+rezabekf@users.noreply.github.com> --- .bumpversion.cfg | 2 +- code/workspace/hooks/.gitignore | 1 + .../workspace/hooks/sample-s3-bucket.template | 5 + .../example-in-python/challenge/index.md | 58 +++ .../hooks/example-in-python/cleanup/index.md | 147 ++++++++ .../example-in-python/conclusion/index.md | 12 + .../end-to-end-test/index.md | 279 ++++++++++++++ .../advanced/hooks/example-in-python/index.md | 54 +++ .../model-your-hook/index.md | 62 ++++ .../register-your-hook/index.md | 68 ++++ .../example-in-python/write-code/index.md | 327 +++++++++++++++++ .../write-contract-tests/index.md | 162 +++++++++ .../write-unit-tests/index.md | 342 ++++++++++++++++++ content/advanced/hooks/index.md | 46 +++ content/advanced/hooks/prerequisites/index.md | 30 ++ 15 files changed, 1594 insertions(+), 1 deletion(-) create mode 100644 code/workspace/hooks/.gitignore create mode 100644 code/workspace/hooks/sample-s3-bucket.template create mode 100644 content/advanced/hooks/example-in-python/challenge/index.md create mode 100644 content/advanced/hooks/example-in-python/cleanup/index.md create mode 100644 content/advanced/hooks/example-in-python/conclusion/index.md create mode 100644 content/advanced/hooks/example-in-python/end-to-end-test/index.md create mode 100644 content/advanced/hooks/example-in-python/index.md create mode 100644 content/advanced/hooks/example-in-python/model-your-hook/index.md create mode 100644 content/advanced/hooks/example-in-python/register-your-hook/index.md create mode 100644 content/advanced/hooks/example-in-python/write-code/index.md create mode 100644 content/advanced/hooks/example-in-python/write-contract-tests/index.md create mode 100644 content/advanced/hooks/example-in-python/write-unit-tests/index.md create mode 100644 content/advanced/hooks/index.md create mode 100644 content/advanced/hooks/prerequisites/index.md diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 8b68d7308..388a190ed 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,4 +1,4 @@ [bumpversion] -current_version = 3.3.0 +current_version = 3.4.0 commit = True tag = False diff --git a/code/workspace/hooks/.gitignore b/code/workspace/hooks/.gitignore new file mode 100644 index 000000000..767f9efdf --- /dev/null +++ b/code/workspace/hooks/.gitignore @@ -0,0 +1 @@ +example-hook*/ diff --git a/code/workspace/hooks/sample-s3-bucket.template b/code/workspace/hooks/sample-s3-bucket.template new file mode 100644 index 000000000..c97bcac14 --- /dev/null +++ b/code/workspace/hooks/sample-s3-bucket.template @@ -0,0 +1,5 @@ +AWSTemplateFormatVersion: "2010-09-09" + +Description: Sample template describing an Amazon S3 bucket. (uksb-1q9p31idr) (tag:hooks). + +# Add your code here. diff --git a/content/advanced/hooks/example-in-python/challenge/index.md b/content/advanced/hooks/example-in-python/challenge/index.md new file mode 100644 index 000000000..4971483d3 --- /dev/null +++ b/content/advanced/hooks/example-in-python/challenge/index.md @@ -0,0 +1,58 @@ +--- +title: "Challenge" +weight: 490 +--- + +Previously on this lab, you've written unit tests to validate the core logic of your hook. One of the requirements you were given was to allow for a mechanism to ignore S3 buckets whose names are specified by the hook administrator in the hook's configuration. You've used contract tests and end-to-end tests to validate aspects for this use case: in this challenge, you are tasked to write unit test code for this use case. + +First, make sure you're in the `example-hook/` directory, as you'll need to run unit tests from there. + +Next, open the existing `src/examplecompany_s3_versioningenabled/tests/test_handlers.py` file. Your task is to append, at the end of the file, a new unit test method you'll write, called `test_when_s3_bucket_is_ignored_then_validation_always_succeeds()`, to assert that when you specify the `my-ignored-bucket,my-other-ignored-bucket` comma-delimited list as an input to the type configuration, the hook validation succeeds regardless of the versioning configuration for the bucket. When you write the unit test method, do not specify the versioning configuration in the resource properties input. + +Once you've written the new unit test method, run unit tests from the `example-hook/` directory, and make sure your new test passes as well. + +:::expand{header="Need a hint?"} +- Look at the existing `test_when_s3_bucket_versioning_status_is_enabled_then_succeed()` test method; make a copy of it, and replace the method name in the method copy with `test_when_s3_bucket_is_ignored_then_validation_always_succeeds()`; +- in the test method you just copied (see the hint above), is there something you'll need to add and to remove for the `resourceProperties` input? +- Is there anything you need to add to `IgnoreS3BucketNames` further below? +- Look at the assertion for the response's message: does it need to be updated? +::: + +::::expand{header="Want to see the solution?"} +Append the following content to the `src/examplecompany_s3_versioningenabled/tests/test_handlers.py` empty file you just created (add two empty lines before pasting the code below): + +:::code{language=python showLineNumbers=false showCopyAction=true} +def test_when_s3_bucket_is_ignored_then_validation_always_succeeds() -> ( # noqa: D103 E501 + None +): + MOCK_BASE_HOOK_HANDLER_REQUEST.hookContext.targetModel = { + "resourceProperties": { + "BucketName": "my-other-ignored-bucket", + }, + } + + response = handlers._run_pre_create_pre_update_common_checks( + session=None, + request=MOCK_BASE_HOOK_HANDLER_REQUEST, + callback_context=MOCK_CALLBACK_CONTEXT, + type_configuration=TypeConfigurationModel( + IgnoreS3BucketNames="my-ignored-bucket,my-other-ignored-bucket", + ), + ) + + assert response.message == "Ignoring versioning configuration." + assert response.status == OperationStatus.SUCCESS + assert response.errorCode is None + assert response.callbackContext is None + assert response.callbackDelaySeconds == 0 +::: + +Next, run the unit tests from the `example-hook/` directory to verify: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +pytest --cov +::: + +:::: + +Choose **Next** to continue! diff --git a/content/advanced/hooks/example-in-python/cleanup/index.md b/content/advanced/hooks/example-in-python/cleanup/index.md new file mode 100644 index 000000000..14009ea6c --- /dev/null +++ b/content/advanced/hooks/example-in-python/cleanup/index.md @@ -0,0 +1,147 @@ +--- +title: "Cleanup" +weight: 495 +--- + +You'll start with deregistering your hook: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation deregister-type \ + --type-name ExampleCompany::S3::VersioningEnabled \ + --type HOOK \ + --region us-east-1 +::: + +Next, you'll delete the stack, created or updated for you by the CloudFormation CLI that you've used to submit the hook to the private registry, by first removing its termination protection: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-termination-protection \ + --no-enable-termination-protection \ + --stack-name examplecompany-s3-versioningenabled-role-stack \ + --region us-east-1 +::: + +Delete the stack mentioned above: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ + --stack-name examplecompany-s3-versioningenabled-role-stack \ + --region us-east-1 + +aws cloudformation wait stack-delete-complete \ + --stack-name examplecompany-s3-versioningenabled-role-stack \ + --region us-east-1 +::: + +Next, before deleting objects from the artifacts bucket created by the `CloudFormationManagedUploadInfrastructure` stack (you've learned about it earlier on this lab), and the stack itself (if you'll choose to do so), you'll need to delete artifacts that you've generated as part of submitting the hook to the registry: this includes the ZIP archive for the hook's code. Start with identifying name of the S3 bucket that the managed upload infrastructure stack created for you: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-resources \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --query "StackResources[?LogicalResourceId=='ArtifactBucket'].PhysicalResourceId" \ + --region us-east-1 \ + --output text +::: + +Make a note of the bucket name returned by the command; for example, `cloudformationmanageduploadinfrast-artifactbucket-[...omitted...]`. Next, list the bucket's content: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws s3 ls s3://cloudformationmanageduploadinfrast-artifactbucket-[...omitted...] +::: + +Make a note of the ZIP file for your hook, that should look like this: `examplecompany-s3-versioningenabled-YYYY-MM-DDTHH-MM-SS.zip`. The bucket where this object is stored has versioning enabled, and you'll need to get the object's version ID with this command (make sure to replace the name of the bucket and of the object): + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws s3api list-object-versions \ + --bucket cloudformationmanageduploadinfrast-artifactbucket-[...omitted...] \ + --prefix examplecompany-s3-versioningenabled-YYYY-MM-DDTHH-MM-SS.zip \ + --query "Versions[*].VersionId" --output text +::: + +Make a note of the version ID, that should look like this: `abcdEXAMPLEabcdEXAMPLEabcdEXAMPLE`; next, delete the object version by making sure to replace the bucket name, the object name, and the version ID: + +:::code{language=shell showLineNumbers=false showCopyAction=false} +aws s3api delete-object \ + --bucket cloudformationmanageduploadinfrast-artifactbucket-[...omitted...] \ + --key examplecompany-s3-versioningenabled-YYYY-MM-DDTHH-MM-SS.zip \ + --version-id abcdEXAMPLEabcdEXAMPLEabcdEXAMPLE +::: + +If you have performed more than one registry submission for your hook as part of this lab, you might find in the bucket more object(s), whose name start(s) with `examplecompany-s3-versioningenabled-`, and that you would want to remove as well in the same way as shown above. + +::alert[If you're currently using your AWS account to create CloudFormation extensions, you might find other objects in the S3 buckets managed by the `CloudFormationManagedUploadInfrastructure` stack (the artifact bucket, and the access log bucket as well), that you might choose to retain. If you wish to proceed with deleting this data and managed upload infrastructure, follow steps shown next; otherwise, skip the remaining part of this cleanup.]{type="warning"} + +Next, retrieve the name of the access log bucket: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-resources \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --query "StackResources[?LogicalResourceId=='AccessLogsBucket'].PhysicalResourceId" \ + --region us-east-1 \ + --output text +::: + +Make a note of the bucket name (example: `cloudformationmanageduploadinfra-accesslogsbucket--[...omitted...]`. List its content (replace the bucket name): + +:::code{language=shell showLineNumbers=false showCopyAction=false} +aws s3 ls s3://cloudformationmanageduploadinfra-accesslogsbucket--[...omitted...] +::: + +As described on this [page](https://docs.aws.amazon.com/AmazonS3/latest/userguide/ServerLogs.html#how-logs-delivered), Amazon S3 periodically collects and consolidates access logs when you enable server access logging for your bucket (that is, in this case, the bucket for artifacts using the logs bucket), and then uploads the logs to the target logging bucket. If you do not see objects in the logs bucket above at this time, there might be a chance, depending on your case, that logs might be delivered whilst you are attempting to delete the logs bucket later on, if you choose to do so. You cannot delete a bucket with objects in it; if this is the case, you'll get an error when deleting the stack that created the logs bucket: if you choose to delete logs in your logs bucket, use the same process you chose to use above for objects in the artifacts bucket, before (re)attempting to delete the bucket (or the stack that creates it; see steps below for more information). + +Next, update the `CloudFormationManagedUploadInfrastructure` stack's settings to disable the `DeletionPolicy: Retain` and `UpdateReplacePolicy: Retain` for both `AccessLogsBucket` and `EncryptionKey` resources. First, get the template for the stack, and save it to the `CloudFormationManagedUploadInfrastructure.template` file on your machine: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation get-template \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --query TemplateBody \ + --region us-east-1 \ + --output text > CloudFormationManagedUploadInfrastructure.template +::: + +Open the `CloudFormationManagedUploadInfrastructure.template` file with your text editor, and: +- replace all occurrences of `DeletionPolicy: Retain` with `DeletionPolicy: Delete`; +- replace all occurrences of `UpdateReplacePolicy: Retain` with `UpdateReplacePolicy: Delete`. + +Save the updated template, and use it to update the stack next: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-stack \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --template-body file://CloudFormationManagedUploadInfrastructure.template \ + --capabilities CAPABILITY_IAM \ + --region us-east-1 + +aws cloudformation wait stack-update-complete \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --region us-east-1 +::: + +Delete the updated template copy on your machine: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +rm CloudFormationManagedUploadInfrastructure.template +::: + +Remove the termination protection from the stack: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation update-termination-protection \ + --no-enable-termination-protection \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --region us-east-1 +::: + +Delete the stack: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --region us-east-1 + +aws cloudformation wait stack-delete-complete \ + --stack-name CloudFormationManagedUploadInfrastructure \ + --region us-east-1 +::: + +Almost done! Choose **Next** to continue! diff --git a/content/advanced/hooks/example-in-python/conclusion/index.md b/content/advanced/hooks/example-in-python/conclusion/index.md new file mode 100644 index 000000000..102ba51d8 --- /dev/null +++ b/content/advanced/hooks/example-in-python/conclusion/index.md @@ -0,0 +1,12 @@ +--- +title: "Conclusion" +weight: 499 +--- + +Congratulations! You have built and tested a sample hook in Python! You've learned key concepts, expectations and objectives for you to keep in mind when writing your proactive validation controls with Hooks. + +You can see a list of hooks in the public CloudFormation registry when you navigate to the [AWS CloudFormation Console](https://console.aws.amazon.com/cloudformation/), choose **Registry** and then **Public extensions** from the left navigation bar, and then use the filters to list the available hooks. + +Also, you can find some existing hooks in the following repositories: +- https://github.com/aws-cloudformation/community-registry-extensions +- https://github.com/aws-cloudformation/aws-cloudformation-samples diff --git a/content/advanced/hooks/example-in-python/end-to-end-test/index.md b/content/advanced/hooks/example-in-python/end-to-end-test/index.md new file mode 100644 index 000000000..5ab990e8e --- /dev/null +++ b/content/advanced/hooks/example-in-python/end-to-end-test/index.md @@ -0,0 +1,279 @@ +--- +title: "End-to-end test" +weight: 480 +--- + +Are you ready to test the hook you've worked on? For this, you'll prepare a sample CloudFormation template that describes an S3 bucket, and use it for your end-to-end tests. + +To get started, change directory to the `cfn101-workshop/code/workspace/hooks` directory; as you were in the `example-hook/` directory earlier, it's easier to just run this command to go to the parent directory, that is the one you need: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd .. +::: + +Next, locate the `sample-s3-bucket.template` file; open it, and append the following content at the end of the file: + +:::code{language=yaml showLineNumbers=false showCopyAction=true} +Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: Enabled +::: + +Next, from the directory where the file above is, use the AWS CLI to create a stack, in the `us-east-1` region, with that template: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ + --stack-name example-hook-test \ + --template-body file://sample-s3-bucket.template \ + --region us-east-1 +::: + +Next, wait for the stack creation to complete: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-create-complete \ + --stack-name example-hook-test \ + --region us-east-1 +::: + +When done, describe the stack events with this command: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-events \ + --stack-name example-hook-test \ + --region us-east-1 +::: + +You should see a series of events, in JSON format, for your stack. The first block on the top of the output should have an element such as: `"ResourceStatus": "CREATE_COMPLETE"` for `"StackName": "example-hook-test"`, indicating that stack creation was successful. Scroll through the output using the down arrow key on your keyboard; you should see an event like the following excerpt: + +:::code{language=json showLineNumbers=false showCopyAction=false} + { + "StackId": "[OMITTED]", + "EventId": "[OMITTED]", + "StackName": "example-hook-test", + "LogicalResourceId": "S3Bucket", + "PhysicalResourceId": "", + "ResourceType": "AWS::S3::Bucket", + "Timestamp": "[OMITTED]", + "ResourceStatus": "CREATE_IN_PROGRESS", + "HookType": "ExampleCompany::S3::VersioningEnabled", + "HookStatus": "HOOK_COMPLETE_SUCCEEDED", + "HookStatusReason": "Hook succeeded with message: Bucket versioning is enabled.", + "HookInvocationPoint": "PRE_PROVISION", + "HookFailureMode": "FAIL" + } +::: + +As you can see, the hook has been invoked, and it verified the configuration of your bucket successfully! As you look through the events above this one, moving towards the top of the output, you can see that the bucket creation only started after the hook completed the validation of your bucket successfully. To exit the stack events view, press `q` key on your keyboard. + +Delete the stack you just created, and wait for its deletion to complete: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ + --stack-name example-hook-test \ + --region us-east-1 + +aws cloudformation wait stack-delete-complete \ + --stack-name example-hook-test \ + --region us-east-1 +::: + +Let's now test that the hook blocks the provisioning (as you configured it to run in `FAIL` mode, per your requirements) when the S3 bucket is not configured to use versioning and the bucket name is not an ignored one. Update the `sample-s3-bucket.template` file, and change the value for `Status` from `Enabled` to `Suspended`: + +:::code{language=yaml showLineNumbers=false showCopyAction=true} + Status: Suspended +::: + +Next, use the AWS CLI to create the stack again, with the updated template: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ + --stack-name example-hook-test \ + --template-body file://sample-s3-bucket.template \ + --region us-east-1 +::: + +Next, wait for the operation to complete: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-create-complete \ + --stack-name example-hook-test \ + --region us-east-1 +::: + +In this case, the behavior you're looking for is that the stack will fail to create, because the hook will return an error. When the previous `wait` command returns back to the shell with a `StackCreateComplete failed` error, describe the stack events with this command: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-events \ + --stack-name example-hook-test \ + --region us-east-1 +::: + +At the top of the output, you should first find an event where the stack is in the `ROLLBACK_COMPLETE` status. This means that the hook failed, as expected, because the S3 bucket was found not to be compliant, and the stack rolled back. To further validate that the hook behavior is the one you expect, scroll through the output, and you should see an event like the following excerpt: + +:::code{language=json showLineNumbers=false showCopyAction=false} + { + "StackId": "[OMITTED]", + "EventId": "[OMITTED]", + "StackName": "example-hook-test", + "LogicalResourceId": "S3Bucket", + "PhysicalResourceId": "", + "ResourceType": "AWS::S3::Bucket", + "Timestamp": "[OMITTED]", + "ResourceStatus": "CREATE_IN_PROGRESS", + "HookType": "ExampleCompany::S3::VersioningEnabled", + "HookStatus": "HOOK_COMPLETE_FAILED", + "HookStatusReason": "Hook failed with message: Bucket versioning is not enabled.", + "HookInvocationPoint": "PRE_PROVISION", + "HookFailureMode": "FAIL" + } +::: + +Congratulations! You have validated that the hook blocked the creation of a non-compliant bucket. + +Delete the stack you just created, and wait for its deletion to complete: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ + --stack-name example-hook-test \ + --region us-east-1 + +aws cloudformation wait stack-delete-complete \ + --stack-name example-hook-test \ + --region us-east-1 +::: + +Let's go ahead and test the use case of an excluded bucket. First, let's establish a pattern for an S3 bucket name you'll use for testing, to reduce the possibility that a bucket name is already taken. The pattern you choose for the bucket name is: `example-hook-test-bucket-ACCOUNT_ID-REGION`, where `ACCOUNT_ID` is your AWS account number, and `REGION` is the region you'll choose for creating both the stack and the bucket. For more information on how to view your AWS account ID, see [View your AWS account ID +](https://docs.aws.amazon.com/IAM/latest/UserGuide/console_account-alias.html#ViewYourAWSId); in this lab, you'll use the AWS CLI to get your account ID, by running the following command: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws sts get-caller-identity \ + --query 'Account' \ + --output text +::: + +You should get an output that looks like this example: `111122223333`. + +Let's compose the name of the bucket that you'll add to the comma-delimited string of ignored bucket names in the hook's configuration! For the AWS region, you'll continue to use `us-east-1`; with the example account ID above, your bucket to exclude would have the following name: `example-hook-test-bucket-111122223333-us-east-1`. Next, you'll update the configuration of the hook; do you recall the `typeConfiguration.json` file you created inside the `example-hook/` directory earlier in this lab? Change directory to `example-hook/`: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd example-hook +::: + +Open the `typeConfiguration.json` file, and replace its content with the following shown below (you'll add a new bucket to ignore: do not forget to replace `ACCOUNT_ID` for it, with the output you saw when you ran `aws sts get-caller-identity` above): + +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "CloudFormationConfiguration": { + "HookConfiguration": { + "TargetStacks": "ALL", + "FailureMode": "FAIL", + "Properties": { + "IgnoreS3BucketNames": "example-ignored-bucket,example-ignored-bucket1,example-hook-test-bucket-ACCOUNT_ID-us-east-1" + } + } + } +} +::: + +Next, you'll update the type configuration for your hook (you already used this method to set the configuration for the hook earlier on in this lab). First, get the ARN for your hook like you did before: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation list-types \ + --type HOOK \ + --filters TypeNamePrefix=ExampleCompany::S3::VersioningEnabled \ + --query 'TypeSummaries[?TypeName==`ExampleCompany::S3::VersioningEnabled`].TypeArn' \ + --output text +::: + +Take note of the resulting ARN for of your hook, and use it to update the type configuration as follows (do not forget to replace the `THE_ARN_OF_YOUR_HOOK` with the ARN for your hook, and to run the command below from the `example-hook/` directory): + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation set-type-configuration \ + --configuration file://typeConfiguration.json \ + --type-arn 'THE_ARN_OF_YOUR_HOOK' +::: + +Now that you've updated the configuration for your hook, you'll test it by first updating the template for your test S3 bucket, and by creating a new stack next. Change directory to the `cfn101-workshop/code/workspace/hooks` directory; as you are in the `example-hook/` directory, use the `cd ..` command to go to the parent directory: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +cd .. +::: + +Locate the `sample-s3-bucket.template` file you used earlier. Open this file: add the whole `BucketName` line underneath the `Properties` node, and leave the `Status` as `Suspended` (as you left it as such in the previous test), as follows: + +:::code{language=yaml showLineNumbers=false showCopyAction=true} +Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + BucketName: !Sub 'example-hook-test-bucket-${AWS::AccountId}-${AWS::Region}' + VersioningConfiguration: + Status: Suspended +::: + +Note that, in your template snippet above, for the account ID and for the region you chose to use the relevant CloudFormation [pseudo parameters](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/pseudo-parameter-reference.html), and you used the `Fn::Sub` [intrinsic function](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html) (shown above in its YAML short form) to compose the resulting string for the bucket name. + +Next, use the AWS CLI to create a stack, in the `us-east-1` region, with this template: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation create-stack \ + --stack-name example-hook-test \ + --template-body file://sample-s3-bucket.template \ + --region us-east-1 +::: + +Next, wait for the stack creation to complete: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation wait stack-create-complete \ + --stack-name example-hook-test \ + --region us-east-1 +::: + +When done, describe the stack events with this command: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation describe-stack-events \ + --stack-name example-hook-test \ + --region us-east-1 +::: + +In this case, the behavior you're looking for is that the stack creation will succeed, because the hook will ignore the non-compliant bucket when it looks at the bucket's name. Scroll through the output; you should see an event like the following excerpt: + +:::code{language=json showLineNumbers=false showCopyAction=false} + { + "StackId": "[OMITTED]", + "EventId": "[OMITTED]", + "StackName": "example-hook-test", + "LogicalResourceId": "S3Bucket", + "PhysicalResourceId": "", + "ResourceType": "AWS::S3::Bucket", + "Timestamp": "[OMITTED]", + "ResourceStatus": "CREATE_IN_PROGRESS", + "HookType": "ExampleCompany::S3::VersioningEnabled", + "HookStatus": "HOOK_COMPLETE_SUCCEEDED", + "HookStatusReason": "Hook succeeded with message: Ignoring versioning configuration.", + "HookInvocationPoint": "PRE_PROVISION", + "HookFailureMode": "FAIL" + } +::: + +As the bucket name is in the list of ignored buckets, the validation passed regardless of its versioning configuration. You've validated this aspect as well! + +Delete the stack you just created, and wait for its deletion to complete: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation delete-stack \ + --stack-name example-hook-test \ + --region us-east-1 + +aws cloudformation wait stack-delete-complete \ + --stack-name example-hook-test \ + --region us-east-1 +::: + +Are you ready for a challenge? Choose **Next** to continue! diff --git a/content/advanced/hooks/example-in-python/index.md b/content/advanced/hooks/example-in-python/index.md new file mode 100644 index 000000000..57b2a8489 --- /dev/null +++ b/content/advanced/hooks/example-in-python/index.md @@ -0,0 +1,54 @@ +--- +title: "Example in Python" +weight: 420 +--- + +### Overview + +In this lab, you'll follow steps to build and submit a sample hook, that you'll write in Python, to the AWS CloudFormation registry in your AWS account for a given AWS region as a private extension. You'll also navigate through the example source code implementation logic for the hook, to understand key concepts and best practices. + + +### Topics Covered + +By the end of this lab, you will be able to: + +* understand key concepts to develop a hook; +* use the [CloudFormation Command Line Interface (CLI)](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html) to create a new project for a hook, run tests, and submit the hook as a private extension to the CloudFormation registry in your AWS account and for a given region; +* understand how to use the [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html) to test your hook locally. + + +### Start Lab + +Let's get started! Make believe you are a member of the security team for an example organization. You're tasked with creating a hook to validate that [Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) bucket resources that your AWS account users create with CloudFormation, are set up with [versioning configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3-bucket.html#cfn-s3-bucket-versioningconfiguration) enabled. For this task, you choose to use CloudFormation Hooks as a proactive validation control: you'll create a hook to enforce versioning being enabled on S3 buckets that your users describe with CloudFormation templates, and that manage with relevant CloudFormation stacks. + +Your first step is to use the [CloudFormation Command Line Interface (CLI)](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html) -that you've installed in the prerequisites section- to create a project for your hook. Change directory to the `cfn101-workshop/code/workspace/hooks` directory: use the following commands to create a new directory for your project, and move into it next: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +mkdir example-hook +cd example-hook +::: + +Next, use the CloudFormation CLI to create a new project for your hook; you'll be asked a number of questions - for that, you'll follow through next on this lab: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +cfn init +::: + +When prompted: + +- specify `h`, followed by enter, to indicate your choice of developing a new hook; +- for the name of your hook, choose to specify: `ExampleCompany::S3::VersioningEnabled`, followed by pressing the _enter_ (or _return_ key) on your keyboard; +- follow the directions to choose `python39`, and use the _enter_ (or _return_ key) to continue; +- when asked to use Docker for platform-independent packaging, choose `Y` followed by the _enter_ (or _return_ key). + +At this point, you should see a message indicating your project has been initialized. The CloudFormation CLI has created for you a number of files and directories that include, in particular: + +- `.rpdk-config`: this is the project's configuration file, that contains a number of information including information on the language name (`"language": "python39",`) and the runtime (`"runtime": "python3.9",`) choices you've made. In the future, as new runtimes are made available, you might want to update both information, and then test and resubmit the hook to the registry. +- `README.md`: this in an automatically-generated file, that you'd want to update as needed for other members of the team to learn about this hook. +- `docs/`: a directory with automatically-generated documentation content. As you develop your hook, you'll want to use the `cfn generate` command to refresh content for this directory, as well as for other parts of the hook you're building. +- `examplecompany-s3-versioningenabled.json`: this is the schema model file, named after your hook: you'll start with updating this file as your next step. +- `hook-role.yaml`: this file is automatically created or regenerated when you run the `cfn generate` command. The CloudFormation CLI creates this file for you based on permissions you specify in the schema; when you use the CloudFormation CLI to submit your hook to the registry, it creates or updates a CloudFormation stack with this template that describes an IAM execution role for your hook. +- `src/`: a directory with files that you'll use to implement the business logic of your hook. +- `template.yml`: an auto-generated file for the [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-reference.html#serverless-sam-cli), that you'll use to test your hook locally. Note that this file also contains runtime information (`Runtime: python3.9` for both `TypeFunction` and `TestEntrypoint`), that in the future you might want to update as well as needed (see considerations made above for the `.rpdk-config` file). + +Are you ready to get the functional requirements for the hook you'll build? Choose **Next** to continue! diff --git a/content/advanced/hooks/example-in-python/model-your-hook/index.md b/content/advanced/hooks/example-in-python/model-your-hook/index.md new file mode 100644 index 000000000..fff29fd72 --- /dev/null +++ b/content/advanced/hooks/example-in-python/model-your-hook/index.md @@ -0,0 +1,62 @@ +--- +title: "Model your hook" +weight: 430 +--- + +So far, you've used the CloudFormation CLI to start the structure of a new project for your hook. The security team of an example company now gives you the functional requirements for the example control you'll build: + +- your hook will need to be invoked when users, in the current AWS account and AWS region, create or update S3 buckets using CloudFormation. That is, when users in the account describe resources of the `AWS::S3::Bucket` [type](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3-bucket.html) in CloudFormation templates they author, and use such templates to create or update CloudFormation stacks to, in turn, create or update S3 buckets; +- if a non-compliant S3 bucket resource is found, treat this as an error, and signal to CloudFormation that the bucket cannot be created or updated; +- the hook should also have a configuration for the account administrator to use, to ignore buckets with a given name should edge cases require an S3 bucket not to be using the versioning feature. + +Next, you'll use the requirements above to model your hook using the schema file in JSON that you've read about in the previous page on this lab. To get started, open the `examplecompany-s3-versioningenabled.json` file, and replace its content with the following: + +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "typeName": "ExampleCompany::S3::VersioningEnabled", + "description": "Example hook to validate that versioning is enabled for Amazon S3 buckets.", + "sourceUrl": "https://catalog.workshops.aws/cfn101/en-US/advanced/hooks", + "documentationUrl": "https://catalog.workshops.aws/cfn101/en-US/advanced/hooks", + "typeConfiguration": { + "properties": { + "IgnoreS3BucketNames": { + "description": "Comma-delimited string of Amazon S3 bucket names to exclude from versioning validation setting checks. Don't add space characters. Leave the value for this property empty (\"\") if you plan on not using it. Otherwise, make sure you specify value(s) conforming to S3 bucket naming rules (https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html). If you plan to use this property, specify values as in following examples: \"mybucket\", or \"my-bucket-1,my-bucket-2\". Do not add a trailing comma(s).", + "default": "", + "pattern": "^([a-z0-9][a-z0-9//.//-]*[a-z0-9]){0,1}$|^([a-z0-9][a-z0-9//.//-]*[a-z0-9]){1}(,[a-z0-9][a-z0-9//.//-]*[a-z0-9])*$", + "type": "string" + } + }, + "additionalProperties": false + }, + "required": [], + "handlers": { + "preCreate": { + "targetNames": [ + "AWS::S3::Bucket" + ], + "permissions": [] + }, + "preUpdate": { + "targetNames": [ + "AWS::S3::Bucket" + ], + "permissions": [] + } + }, + "additionalProperties": false +} +::: + +Save the updated file. As you can see, you're modeling the `IgnoreS3BucketNames` input configuration property to allow for edge-case exceptions as per the requirements, and you're targeting `AWS::S3::Bucket` resources to be examined by your hook before you create (`preCreate` handler), or update (`preUpdate` handler) a CloudFormation stack. In the schema above, you could also have added a configuration for a `preDelete` handler (which is another available invocation point for Hooks): in this case, you choose not to use this additional control as per requirements above, that are only relevant to when resources are being created or mutated, but not deleted. + +::alert[With this example hook, you only plan to inspect S3 buckets' configuration values coming from the CloudFormation template when your hook is invoked. This information will be exposed to the hook automatically, and you don't need to make any API calls to AWS service(s) from your hook to retrieve bucket configuration values: this is why you are passing empty lists to the `permissions` properties in the schema above. If you would have needed to make API calls to AWS services from your hook's handler(s), you would have also needed to indicate which IAM permission(s) (for example: `s3:ListBuckets`) you required.]{type="info"} + +For more information on the schema of a hook, and on modeling options, see [Modeling AWS CloudFormation Hooks](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/hooks-model.html). + +Now that you've updated the schema that models your hook, it's time to refresh the documentation for your hook in the `docs/` directory and, as applicable, the content of the `hook-role.yaml` template file. Run the following command: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +cfn generate +::: + +It's now time to write code for your hook! Choose **Next** to continue! diff --git a/content/advanced/hooks/example-in-python/register-your-hook/index.md b/content/advanced/hooks/example-in-python/register-your-hook/index.md new file mode 100644 index 000000000..38fc517a6 --- /dev/null +++ b/content/advanced/hooks/example-in-python/register-your-hook/index.md @@ -0,0 +1,68 @@ +--- +title: "Register your hook" +weight: 470 +--- + +For you to use your hook with CloudFormation, you first need to submit it to the registry as a private extension. You can, subsequently, also choose to make your hook public, but we'll not cover this in this lab. + +When you submit a hook to the registry, you register the hook in a given AWS account and region: if you need to make the hook available in another account or region, you'll need to make a separate submission to the registry for that. Alternatively, you can use [AWS CloudFormation StackSets](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/what-is-cfnstacksets.html) to submit the hook across regions and accounts by using a CloudFormation template where you describe, with code, the intent of submitting the hook to the registry using [CloudFormation resource types](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/AWS_CloudFormation.html) such as `AWS::CloudFormation::HookVersion`, `AWS::CloudFormation::HookDefaultVersion`, and `AWS::CloudFormation::HookTypeConfig`. In this lab, you'll use the CloudFormation CLI to submit your hook to the registry for a given region. + +To submit your hook to the `us-east-1` region with the CloudFormation CLI, use the following command from the `example-hook/` directory: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +cfn submit --set-default --region us-east-1 +::: + +At the end of the process, you should get a message indicating that version `00000001` of your hook has been registered, and set as the default version. + +When you use the CloudFormation CLI with the `cfn submit` command above to submit extensions to the CloudFormation registry (hooks, resource types, and modules), it'll create or update a CloudFormation stack in your account and for the region you're using, so to manage on your behalf a number of resources needed to submit an extension to the registry. This stack is called `CloudFormationManagedUploadInfrastructure`. Moreover, when you work with hooks or with resource types, the CloudFormation CLI also creates or updates another stack, whose name prefix is derived from the extension's name (in your case, the name of the stack will be `examplecompany-s3-versioningenabled-role-stack`), to create or update the execution role for the extension by using the CloudFormation template generated by the CloudFormation CLI (in your case, `hook-role.yaml`) that you've learned about earlier on this lab. + +As this is the first time that you're submitting the hook to the registry, as the hook administrator persona you'll need to configure the hook after you submitted it to the registry. You can also configure the hook any time you need, should its configuration settings require an update to reflect your needs in the future. + +Let's configure the hook! Create, inside the `example-hook/` directory, a file called `typeConfiguration.json` (like the one you created in your `.cfn-cli/` directory earlier): + +:::code{language=shell showLineNumbers=false showCopyAction=true} +touch typeConfiguration.json +::: + +Next, open the `typeConfiguration.json` file you just created inside the `example-hook/` directory, and add the following content to it: + +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "CloudFormationConfiguration": { + "HookConfiguration": { + "TargetStacks": "ALL", + "FailureMode": "FAIL", + "Properties": { + "IgnoreS3BucketNames": "example-ignored-bucket,example-ignored-bucket1" + } + } + } +} +::: + +::alert[In the example above, you've used `FAIL` for `FailureMode`. This is because as part of your requirements -and as part of how you'd want a hook to typically work- you want to treat compliance failures as errors that will prevent a given operation (such as, create, update, or delete) to run. If you wish to just simply emit a warning that will non prevent the provisioning of a non-compliant resource, use `WARN` instead of `FAIL`; you might only want to use `WARN` for limited use cases, such as -for example- to avoid preventing the provisioning of valid workloads in your sandbox account as you develop and test your hook with CloudFormation stacks, or if you want to give your account users a compliance deadline before you'll turn the setting to `FAIL`.]{type="warning"} + +Next, you'll use the [AWS Command Line Interface](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/index.html) (and not the CloudFormation CLI in this case) to set the type configuration for your hook. First, you'll get the [Amazon Resource Name (ARN)](https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html) for your hook: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation list-types \ + --type HOOK \ + --filters TypeNamePrefix=ExampleCompany::S3::VersioningEnabled \ + --query 'TypeSummaries[?TypeName==`ExampleCompany::S3::VersioningEnabled`].TypeArn' \ + --output text +::: + +The command above should have returned the ARN of your hook, that uses the following format: `arn:aws:cloudformation:us-east-1:YOUR_ACCOUNT_ID:type/hook/ExampleCompany-S3-VersioningEnabled`; use this ARN to set up the type configuration as follows, by replacing `THE_ARN_OF_YOUR_HOOK` with the ARN you just retrieved: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +aws cloudformation set-type-configuration \ + --configuration file://typeConfiguration.json \ + --type-arn 'THE_ARN_OF_YOUR_HOOK' +::: + +At the end of the process, you should get `ConfigurationArn` as the output, indicating information for the type configuration you've just set. + +Congratulations! You just submitted to the registry, and configured your hook as the hook administrator persona! This concludes the first of the two workflows you learned about at the beginning of this lab. Are you ready to test the hook with CloudFormation, and see what you users would see in a variety of scenarios you'll test? + +Choose **Next** to continue! diff --git a/content/advanced/hooks/example-in-python/write-code/index.md b/content/advanced/hooks/example-in-python/write-code/index.md new file mode 100644 index 000000000..ad0c1cfed --- /dev/null +++ b/content/advanced/hooks/example-in-python/write-code/index.md @@ -0,0 +1,327 @@ +--- +title: "Write code" +weight: 440 +--- + +When you used the CloudFormation CLI to generate the project for your hook, it also created some files and directories in the `src/` directory. You'll next focus on inspecting and editing the content of the `handlers.py` file in the `src/examplecompany_s3_versioningenabled/` directory, to add the business logic for the proactive control you're implementing with your hook. + +::alert[When you inspect the content of the `src/examplecompany_s3_versioningenabled/` directory, you'll see a number of files that are managed by the CloudFormation CLI when you run the `cfn generate` command (that you've already used earlier): for example, the `models.py` file and files in the `target_models` directory. Do not manually change these files or content, as they'll be overwritten by the CloudFormation CLI when you'll run `cfn generate`.]{type="warning"} + +Open the `handlers.py` file mentioned above: the content of this file has been automatically generated for you when you used the CloudFormation CLI to create the project for your hook. Familiarize with the structure of the file: you'll see 3 methods, `pre_create_handler()`, `pre_update_handler()`, and `pre_delete_handler()` that are decorated, respectively, with the following wrappers: + +- `@hook.handler(HookInvocationPoint.CREATE_PRE_PROVISION)` +- `@hook.handler(HookInvocationPoint.UPDATE_PRE_PROVISION)` +- `@hook.handler(HookInvocationPoint.DELETE_PRE_PROVISION)` + +The intent is to have each of these methods above being called for a relevant event: for example, `pre_create_handler()` to be called when the hook is invoked for a given S3 bucket on stack creation. Each of these methods will need to have the business logic -written by you, in this case- to analyze the properties for a given resource (S3 bucket, in your case), that are described by users in a CloudFormation template. + +Each of the methods above must return a properly-configured `ProgressEvent` object on events such as a successful verification of resource properties (`OperationStatus.SUCCESS`: your resource is compliant), or a failure (`OperationStatus.FAILED`: your resource is not compliant), so that CloudFormation understands what to do next. + +Per requirements you received, you'll only want to invoke your hook on pre-create and pre-update events. This means that: + +- you can remove the pre-delete method and logic, that you won't need for your use case, and +- you can conveniently use one single, shared method for both pre-create and pre-update operations in your use case: this way, you can efficiently maintain the business logic code in one place. + +How can you consume, from the business logic of a given handler method, the resource properties coming from a CloudFormation template? When you look at the input parameters for methods above, you'll see the `request` parameter: first, you get the target model of the resource (S3 bucket in your case) from `request.hookContext.targetModel`, and then you can consume `resourceProperties` from the target model. + +The boilerplate code also passes in, as an input parameter, `callback_context`. Typically, you'd use this parameter if the operations you run in your handler code take more than 30 seconds, _as hooks time out after 30 seconds_. You set up the callback context to persist values you need to read the current state in a subsequent reinvocation of the current handler. To signal the intent of calling back the current handler, you set `status` to `OperationStatus.IN_PROGRESS`, `callbackContext` to the value(s) you need, and optionally `callbackDelaySeconds` in the `ProgressEvent` object that you return from the handler's code. You won't use this functionality in the hook you're building. + +As you continue to look at the boilerplate code, you also note the `type_configuration` input parameter for each of the methods mentioned above: you'll use this parameter from the business logic of your code to consume the optional hook configuration value(s) (in your case, `IgnoreS3BucketNames`), that you've already modeled in the schema earlier. + +Before implementing the logic you need, note that the boilerplate code also has the following example snippet: + +:::code{language=python showLineNumbers=false showCopyAction=false} + if isinstance(session, SessionProxy): + client = session.client("s3") +::: + +The example above shows you how to properly create, for a hook, an SDK client (in your example, an S3 client), by using a pre-vended session proxy. You use an SDK client from a hook's code only if you need to make AWS API calls to a given AWS service (should this be the case, you'll also want to add the necessary IAM permissions to the schema for your hook). You won't need this functionality for the hook you'll build, but it's worth mentioning this important aspect anyway, as you might need it in your hooks for use cases that require verification checks that go beyond static code analysis. + +Let's implement the create and update handler logic! You'll use one shared entrypoint method, with both the pre-create and pre-update decorations. Replace the entire content of the `handlers.py` file with the following: + +:::code{language=python showLineNumbers=false showCopyAction=true} +"""Example hook to validate versioning is enabled for an Amazon S3 bucket.""" + +import logging +from typing import ( + Any, + List, + Mapping, + MutableMapping, + Optional, +) + +from cloudformation_cli_python_lib import ( # type: ignore + HandlerErrorCode, + Hook, + HookInvocationPoint, + OperationStatus, + ProgressEvent, + SessionProxy, +) + +from .models import ( + HookHandlerRequest, + TypeConfigurationModel, +) + + +# Use this logger to forward log messages to CloudWatch Logs. +LOG = logging.getLogger(__name__) +TYPE_NAME = "ExampleCompany::S3::VersioningEnabled" + +hook = Hook(TYPE_NAME, TypeConfigurationModel) +test_entrypoint = hook.test_entrypoint + + +@hook.handler(HookInvocationPoint.CREATE_PRE_PROVISION) +@hook.handler(HookInvocationPoint.UPDATE_PRE_PROVISION) +def pre_create_pre_update_common_handler( + session: Optional[SessionProxy], + request: HookHandlerRequest, + callback_context: MutableMapping[str, Any], + type_configuration: TypeConfigurationModel, +) -> ProgressEvent: + """Use a common method for pre-create and pre-update validations.""" + return _run_pre_create_pre_update_common_checks( + session=session, + request=request, + callback_context=callback_context, + type_configuration=type_configuration, + ) + + +def _run_pre_create_pre_update_common_checks( + session: Optional[SessionProxy], + request: HookHandlerRequest, + callback_context: MutableMapping[str, Any], + type_configuration: TypeConfigurationModel, +) -> ProgressEvent: + """Run common checks for pre-create and pre-update validations.""" + try: + progress = ProgressEvent(status=OperationStatus.IN_PROGRESS) + + # Read the target properties of the S3 bucket. + resource_properties = None + target_model = _get_target_model( + request=request, + ) + if target_model: + resource_properties = _get_resource_properties( + target_model=target_model, + ) + + # Return a failure immediately if there are no S3 bucket + # properties defined in the template. + if resource_properties is None: + message = "The S3 bucket has no properties set." + LOG.error(message) + progress.status = OperationStatus.FAILED + progress.message = message + progress.errorCode = HandlerErrorCode.NonCompliant + return progress + + # Consume the IgnoreS3BucketNames type configuration + # directive, and return success if the user specifies a bucket + # name that is ignored in the directive. + if ( + hasattr( + type_configuration, + "IgnoreS3BucketNames", + ) + and type_configuration.IgnoreS3BucketNames != "" + ): + bucket_name = _get_bucket_name( + resource_properties=resource_properties, + ) + if bucket_name: + ignore_s3_bucket_names_list = _get_ignore_s3_bucket_names_list( + type_configuration + ) + if bucket_name in ignore_s3_bucket_names_list: + message = "Ignoring versioning configuration." + LOG.info(message) + # Set status to success to signal that the + # validation is successful, and return progress. + progress.status = OperationStatus.SUCCESS + progress.message = message + return progress + + # If the bucket is not in the list of buckets to ignore, + # proceed with the validation: start with checking if the + # VersioningConfiguration property is set. + versioning_configuration = _get_versioning_configuration( + resource_properties=resource_properties, + ) + if versioning_configuration is None: + message = "The VersioningConfiguration property value is missing." + LOG.error(message) + progress.status = OperationStatus.FAILED + progress.message = message + progress.errorCode = HandlerErrorCode.NonCompliant + return progress + else: + # Check if the Status property for VersioningConfiguration + # is set to Enabled. + versioning_configuration_status = ( + _get_versioning_configuration_status( + versioning_configuration=versioning_configuration, + ) + ) + if ( + versioning_configuration_status + and versioning_configuration_status == "Enabled" + ): + message = "Bucket versioning is enabled." + LOG.info(message) + progress.status = OperationStatus.SUCCESS + progress.message = message + return progress + + # Fail the validation by default if the code execution did not + # succeed above. + message = "Bucket versioning is not enabled." + LOG.error(message) + progress.status = OperationStatus.FAILED + progress.message = message + progress.errorCode = HandlerErrorCode.NonCompliant + return progress + except Exception as exception: + LOG.error(exception) + progress.status = OperationStatus.FAILED + progress.message = str(exception) + progress.errorCode = HandlerErrorCode.InternalFailure + return progress + + +def _get_target_model( + request: HookHandlerRequest, +) -> Optional[Mapping[str, Any]]: + """Return the target model of the resource from the request.""" + return request.hookContext.targetModel + + +def _get_resource_properties( + target_model: Optional[Mapping[str, Any]], +) -> Any: + """Return the resource properties from the target model.""" + return ( + target_model.get("resourceProperties") + if target_model and target_model.get("resourceProperties") + else None + ) + + +def _get_ignore_s3_bucket_names_list( + type_configuration: TypeConfigurationModel, +) -> List[str]: + """Return a list of items from type_configuration.IgnoreS3BucketNames.""" + # Remove spaces on assignment for ignore_s3_bucket_names. + ignore_s3_bucket_names = ( + type_configuration.IgnoreS3BucketNames.replace(" ", "") + if type_configuration.IgnoreS3BucketNames + else "" + ) + + # Remove any list item that is an empty string when creating a + # list of bucket names to ignore from IgnoreS3BucketNames in the + # type configuration. + return list( + filter( + None, + ignore_s3_bucket_names.split(","), + ) + ) + + +def _get_bucket_name( + resource_properties: Any, +) -> Any: + """Return the bucket name from the resource properties.""" + # Remove spaces, if any, as well. + return ( + resource_properties.get("BucketName").replace(" ", "") + if resource_properties and resource_properties.get("BucketName") + else None + ) + + +def _get_versioning_configuration( + resource_properties: Any, +) -> Any: + """Return the versioning configuration from the resource properties.""" + return ( + resource_properties.get("VersioningConfiguration") + if resource_properties + and resource_properties.get("VersioningConfiguration") + else None + ) + + +def _get_versioning_configuration_status( + versioning_configuration: Any, +) -> Any: + """Return the status from the versioning configuration.""" + return ( + versioning_configuration.get("Status") + if versioning_configuration and versioning_configuration.get("Status") + else None + ) +::: + +Save the file, and take a look at the code: can you recognize some of the implementation aspects that relate to the requirements you were given, for example: the code that checks if a bucket is ignored from the validation logic, if its name is in an input list maintained by the hook's administrator? + +Also, note how the outer structure of the input data is validated. When you describe an S3 bucket with a CloudFormation template, for it to pass the validation above it needs to look like the following snippet: + +:::code{language=yaml showLineNumbers=false showCopyAction=false} +AWSTemplateFormatVersion: 2010-09-09 +Description: Example S3 bucket. +Resources: + S3Bucket: + Type: AWS::S3::Bucket + Properties: + VersioningConfiguration: + Status: Enabled +::: + +As you traverse the `Properties` tree above, you write the logic to validate that `Status`, for `VersioningConfiguration`, is set to `Enabled`. What if the `Properties` node above is missing though, or what if the `VersioningConfiguration` node underneath it is missing instead? The hook's business logic above also checks for these specific cases, and returns targeted error messages to the end user for them to easily pinpoint the relevant error. + +As part of the prerequisites for running this lab, you've installed tools such as [mypy](https://github.com/python/mypy), a static type checker for Python, and [flake8](https://flake8.pycqa.org/en/latest/) for linting Python code. You'll use both tools in this lab as examples to check the code for the hook you're building. + +::alert[You're not required to use `mypy` and `flake8` for your hook code to work. This lab shows an example usage of such tools in the context of the sample Python code for the hook you're building; you can choose to use tools and configurations you need or prefer in your projects.]{type="info"} + +First, let's configure your hook's project settings for `mypy`. Create a `mypy.ini` configuration file for your hook project as follows (make sure you are in the `example-hook/` directory): + +:::code{language=shell showLineNumbers=false showCopyAction=true} +touch mypy.ini +::: + +When done, add this content to the `mypy.ini` file you just created: + +:::code{language=text showLineNumbers=false showCopyAction=true} +[mypy] +follow_imports = silent + +strict = True +::: + +Next, run `mypy` against your `handlers.py` file (make sure you are in the `example-hook/` directory): + +:::code{language=shell showLineNumbers=false showCopyAction=true} +mypy src/examplecompany_s3_versioningenabled/handlers.py +::: + +You should see an output indicating no errors. Next, run `flake8` against the same file: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +flake8 \ + --docstring-convention pep257 \ + --ignore=W503,W504 \ + --max-complexity=10 \ + --max-line-length=79 \ + src/examplecompany_s3_versioningenabled/handlers.py +::: + +You should see no output messages, indicating no errors have occurred. As part of the example set of command options for `flake8` above, note the `max-complexity=10` directive, that uses the `mccabe` [plugin](https://flake8.pycqa.org/en/latest/user/options.html#cmdoption-flake8-max-complexity) for McCabe's [cyclomatic complexity](https://en.wikipedia.org/wiki/Cyclomatic_complexity) metric to check if the code, at the method level for example, exceeds an example cyclomatic complexity value of `10` when it takes a number of paths: you use this check to measure how complex the structure of your code is, and you can choose to use this indicator as an opportunity to improve the code you write so that it is easier to maintain over time. A practical example would be to break down methods into smaller, specialized functions you can easily maintain -and reuse, as needed- in your code that, overall, will be more readable. + +Next, you'll write some tests for your hook's logic, so that you'll have the opportunity to run these tests locally to speed up the development loop. Choose **Next** to continue! diff --git a/content/advanced/hooks/example-in-python/write-contract-tests/index.md b/content/advanced/hooks/example-in-python/write-contract-tests/index.md new file mode 100644 index 000000000..ae65e91a0 --- /dev/null +++ b/content/advanced/hooks/example-in-python/write-contract-tests/index.md @@ -0,0 +1,162 @@ +--- +title: "Write contract tests" +weight: 460 +--- + +Contract tests help you test your hook locally, thus speeding up the development lifecycle. Moreover, if you plan to make your hook available as a public extension, it is required for it to pass contract tests. + +While you're not required to pass contract tests for a privately-registered hook -like the one you're working on- it is recommended to strive to write and pass contract tests anyway: not only this helps you with development velocity, but also it helps maintaining a higher quality bar. + +To get started, first create the following files in an `inputs/` directory you'll also create at the root level of your hook's project; make sure you run the following commands from the `example-hook/` directory: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +mkdir inputs/ +touch inputs/inputs_1_pre_create.json +touch inputs/inputs_1_pre_update.json +touch inputs/inputs_1_invalid.json +touch inputs/inputs_2_pre_create.json +touch inputs/inputs_2_pre_update.json +touch inputs/inputs_2_invalid.json +::: + +As you can see above, for this hook you chose to use two series of contract tests, denoted by `inputs_1_` and `inputs_2_` file prefixes. Each series will have different permutations of inputs that you'll pass to your hook, to validate that it will work as you expect across different scenarios. + +You'll cover 2 test cases (recall the requirements you were given, as you read through): a bucket with a generic name (or with no specified name) being tested, and a bucket with a specific name that will cause it to be ignored from being validated. In the first case, the bucket is expected to pass validation on pre-create and pre-update if versioning is enabled for it in its configuration; in the second case, the bucket is expected to pass validation if its name is one of the ignored buckets in the hook's configuration (regardless of its versioning configuration). In both test cases, the hook is supposed to fail when an invalid configuration is provided as the input. + +Now that you've learned the testing logic you'll use in contract tests for this hook, open each of the JSON files above, and add content shown next for each one of them: + +- `inputs/inputs_1_pre_create.json`: +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "AWS::S3::Bucket": { + "resourceProperties": { + "VersioningConfiguration": { + "Status": "Enabled" + } + } + } +} +::: + +- `inputs/inputs_1_pre_update.json`: +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "AWS::S3::Bucket": { + "resourceProperties": { + "VersioningConfiguration": { + "Status": "Enabled" + } + } + } +} +::: + +- `inputs/inputs_1_invalid.json`: +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "AWS::S3::Bucket": { + "resourceProperties": { + "VersioningConfiguration": { + "Status": "Suspended" + } + } + } +} +::: + +- `inputs/inputs_2_pre_create.json`: +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "AWS::S3::Bucket": { + "resourceProperties": { + "BucketName": "example-ignored-bucket", + "VersioningConfiguration": { + "Status": "Suspended" + } + } + } +} +::: + +- `inputs/inputs_2_pre_update.json`: +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "AWS::S3::Bucket": { + "resourceProperties": { + "BucketName": "example-ignored-bucket", + "VersioningConfiguration": { + "Status": "Suspended" + } + } + } +} +::: + +- `inputs/inputs_2_invalid.json`: +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "AWS::S3::Bucket": { + "resourceProperties": { + "BucketName": "example-non-ignored-bucket" + } + } +} +::: + +::alert[In the examples above, you're specifying input configuration for the `AWS::S3::Bucket` resource type for each input file: this is because you're expected to test each target resource type that you declare in the hook's schema. If you are targeting additional resource type(s) in your hook's schema, you're required to add configuration(s) for such resource type(s) as well in each contract test input file; otherwise, contract tests will fail.]{type="warning"} + +Now that you have written contract test inputs, you'll need to work on 2 additional steps: + +- simulate locally the hook's type configuration; that is, how to pass the list of ignored buckets to the hook when you'll run it, and +- learn how to run contract test, so that your hook can consume the inputs above locally. + +Let's start with setting up the type configuration locally: you'll need to create a `.cfn-cli/` directory in your home directory, and then add a file in it, called `typeConfiguration.json`: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +mkdir ~/.cfn-cli/ +touch ~/.cfn-cli/typeConfiguration.json +::: + +Next, open the `~/.cfn-cli/typeConfiguration.json` file, and add the following content to it: + +:::code{language=json showLineNumbers=false showCopyAction=true} +{ + "CloudFormationConfiguration": { + "HookConfiguration": { + "TargetStacks": "ALL", + "FailureMode": "FAIL", + "Properties": { + "IgnoreS3BucketNames": "example-ignored-bucket,example-ignored-bucket1" + } + } + } +} +::: + +Save the file; as you can see, you're adding configuration directives that include the `IgnoreS3BucketNames` property with a comma-delimited string of buckets to ignore. For more information on developing hooks, including type configuration properties, see [AWS CloudFormation Hooks development overview](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/hooks-development-overview.html). + +Now that you have set up contract test inputs and the type configuration for the hook, you'll run contract tests to pass this information to the hook and consume it from your hook's business logic. You'll need 2 terminal consoles: in the first one, you'll package up the hook and run the contract tests via the `cfn test` command; in the second one, you'll use the SAM CLI (that you've installed as part of prerequisites) to simulate a local endpoint running your hook. Let's get started: + +- in a terminal window, make sure you're inside the `example-hook/` directory, and run the following command to package up the hook: + + :::code{language=shell showLineNumbers=false showCopyAction=true} + cfn submit --dry-run + ::: + +- open a new terminal window, and make sure you're inside the `example-hook/` directory (you might need to change to the `cfn101-workshop/code/workspace/hooks/example-hook/` directory first, as you opened a new terminal). Next, run the following command from the `example-hook/` directory to run a local endpoint for your hook - note that after you run the command, it will not return back to the shell (this is the expected behavior): + + :::code{language=shell showLineNumbers=false showCopyAction=true} + sam local start-lambda + ::: + +- go back to the terminal window where you packaged up the hook, make sure you're inside the `example-hook/` directory, and run the following command to run the contract tests: + + :::code{language=shell showLineNumbers=false showCopyAction=true} + cfn test --enforce-timeout 120 + ::: + +You should see 2 test cases running; at the end, both should succeed. + +For more information on command options available for contract tests, see [test](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/resource-type-cli-test.html) in the CloudFormation Command Line Interface (CLI) User Guide. + +Congratulations! You ran contract tests for your hook! In the next page, you'll submit your hook to the private registry in one AWS region; choose **Next** to continue! diff --git a/content/advanced/hooks/example-in-python/write-unit-tests/index.md b/content/advanced/hooks/example-in-python/write-unit-tests/index.md new file mode 100644 index 000000000..80c9d3a46 --- /dev/null +++ b/content/advanced/hooks/example-in-python/write-unit-tests/index.md @@ -0,0 +1,342 @@ +--- +title: "Write unit tests" +weight: 450 +--- + +You've written code to implement the business logic of your hook. As part of software development best practices, you'll now write unit tests to verify that key pieces of your hook work as you expect, thus increasing your level of confidence on your code's functional aspects. + +In addition to writing unit tests, you'll also write and run contract tests in this lab, and you'll also run end-to-end tests as well. Let's start with unit tests first. + +When you write unit tests, it is important to have a reasonable amount of key code being tested. For that, you use a software metric as an indicator, called [code coverage](https://en.wikipedia.org/wiki/Code_coverage), that expresses the percentage of code you're covering with your unit tests. While a 100% code coverage would be -ideally- desirable, it is not very easy or very practical to achieve -or even needed- in some cases. Most of the time, it makes sense to agree on a reasonable amount code coverage: for example, 80%. What really matters is which code you're covering with unit tests; think of what the important pieces of your code you want to cover are. + +To get started, you'll use [pytest](https://pytest.org/) with the [pytest-cov](https://pytest-cov.readthedocs.io/en/latest/index.html) plugin to run unit tests and to measure code coverage for your hook's code. You should already have installed `pytest-cov` as part of the prerequisites for this lab. Make sure you are in the `example-hook/` directory, and then create an empty code coverage configuration file, called `.coveragerc`: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +touch .coveragerc +::: + +Next, add this content to the `.coveragerc` file you just created: + +:::code{language=text showLineNumbers=false showCopyAction=true} +[report] +fail_under = 80 + +show_missing = True + + +[run] +branch = True + +include = + src/*/* + +omit = + */__init__.py + src/*/models.py + src/*/target_models/* + src/*/tests/* +::: + +Save the file. When you look at the file above, you note that you're telling `coverage.py` to: + +- fail unit tests under 80% of code coverage; +- show which code lines are not covered by your unit tests; +- enable coverage for branches you have in your code (for example, `if` and `else` blocks); +- include the `src/` code path, while excluding files generated by the CloudFormation CLI, and test files in the `tests/` directory. + +Next, make sure you're in the `example-hook/` directory; use the following commands to create the `tests` directory inside the `src/examplecompany_s3_versioningenabled/` path, and two empty files (you'll use one of them, `test_handlers.py`, later on to implement your tests): + +:::code{language=shell showLineNumbers=false showCopyAction=true} +mkdir src/examplecompany_s3_versioningenabled/tests +touch src/examplecompany_s3_versioningenabled/tests/__init__.py +touch src/examplecompany_s3_versioningenabled/tests/test_handlers.py +::: + +Next, add the following content to the `src/examplecompany_s3_versioningenabled/tests/test_handlers.py` empty file you just created: + +:::code{language=python showLineNumbers=false showCopyAction=true} +"""Tests: example hook to validate versioning is enabled for an S3 bucket.""" + +import re +import uuid +from typing import ( + Any, + MutableMapping, +) + +from unittest.mock import ( + patch, +) + +from cloudformation_cli_python_lib import ( # type: ignore + HandlerErrorCode, + HookContext, + HookInvocationPoint, + OperationStatus, +) + +from .. import handlers +from ..models import ( + HookHandlerRequest, + TypeConfigurationModel, +) + + +# Derive the src sub-directory folder name from the type config +# (example output for this hook: examplecompany_s3_versioningenabled) +HOOK_CODE_SRC_SUBDIR_NAME = re.sub("::", "_", handlers.TYPE_NAME.lower()) + +MOCK_ACCOUNT_ID = "111122223333" +MOCK_ARN_SUFFIX = "00000000-0000-0000-0000-000000000000" +MOCK_CALLBACK_CONTEXT: MutableMapping[str, Any] = {} +MOCK_HOOK_TYPE_VERSION = "00000001" +MOCK_REGION = "us-east-1" +MOCK_STACK_NAME = "example" +MOCK_TARGET = "AWS::S3::Bucket" +MOCK_TARGET_LOGICAL_ID = "ExampleBucket" + +MOCK_STACK_ID = f"arn:aws:cloudformation:{MOCK_REGION}::stack/{MOCK_STACK_NAME}/{MOCK_ARN_SUFFIX}" # noqa: E501 + +MOCK_BASE_HOOK_HANDLER_REQUEST = HookHandlerRequest( + clientRequestToken=str(uuid.uuid4()), + hookContext=HookContext( + awsAccountId=MOCK_ACCOUNT_ID, + hookTypeName=handlers.TYPE_NAME, + hookTypeVersion=MOCK_HOOK_TYPE_VERSION, + # Using CREATE_PRE_PROVISION as the invocation point also for + # tests on the update invocation point, since both create and + # update invocation points share the same handler code. + invocationPoint=HookInvocationPoint.CREATE_PRE_PROVISION, + stackId=MOCK_STACK_ID, + targetLogicalId=MOCK_TARGET_LOGICAL_ID, + targetModel=None, + targetName=MOCK_TARGET, + targetType=MOCK_TARGET, + ), +) + + +def test_when_ignore_s3_bucket_names_is_missing_if_compliant_succeed() -> ( # noqa: D103 E501 + None +): + MOCK_BASE_HOOK_HANDLER_REQUEST.hookContext.targetModel = { + "resourceProperties": { + "VersioningConfiguration": {"Status": "Enabled"}, + }, + } + + response = handlers._run_pre_create_pre_update_common_checks( + session=None, + request=MOCK_BASE_HOOK_HANDLER_REQUEST, + callback_context=MOCK_CALLBACK_CONTEXT, + type_configuration=TypeConfigurationModel(None), + ) + + assert response.message == "Bucket versioning is enabled." + assert response.status == OperationStatus.SUCCESS + assert response.errorCode is None + assert response.callbackContext is None + assert response.callbackDelaySeconds == 0 + + +def test_when_ignore_s3_bucket_names_is_missing_if_non_compliant_fail() -> ( # noqa: D103 E501 + None +): + MOCK_BASE_HOOK_HANDLER_REQUEST.hookContext.targetModel = { + "resourceProperties": { + "VersioningConfiguration": {"Status": "Suspended"}, + }, + } + + response = handlers._run_pre_create_pre_update_common_checks( + session=None, + request=MOCK_BASE_HOOK_HANDLER_REQUEST, + callback_context=MOCK_CALLBACK_CONTEXT, + type_configuration=TypeConfigurationModel(None), + ) + + assert response.message == "Bucket versioning is not enabled." + assert response.status == OperationStatus.FAILED + assert response.errorCode == HandlerErrorCode.NonCompliant + assert response.callbackContext is None + assert response.callbackDelaySeconds == 0 + + +def test_when_s3_bucket_versioning_status_is_enabled_then_succeed() -> ( # noqa: D103 E501 + None +): + MOCK_BASE_HOOK_HANDLER_REQUEST.hookContext.targetModel = { + "resourceProperties": { + "VersioningConfiguration": {"Status": "Enabled"}, + }, + } + + response = handlers._run_pre_create_pre_update_common_checks( + session=None, + request=MOCK_BASE_HOOK_HANDLER_REQUEST, + callback_context=MOCK_CALLBACK_CONTEXT, + type_configuration=TypeConfigurationModel( + IgnoreS3BucketNames="", + ), + ) + + assert response.message == "Bucket versioning is enabled." + assert response.status == OperationStatus.SUCCESS + assert response.errorCode is None + assert response.callbackContext is None + assert response.callbackDelaySeconds == 0 + + +def test_when_s3_bucket_versioning_status_is_not_enabled_then_fail() -> ( # noqa: D103 E501 + None +): + MOCK_BASE_HOOK_HANDLER_REQUEST.hookContext.targetModel = { + "resourceProperties": { + "VersioningConfiguration": {"Status": "Suspended"}, + }, + } + + response = handlers._run_pre_create_pre_update_common_checks( + session=None, + request=MOCK_BASE_HOOK_HANDLER_REQUEST, + callback_context=MOCK_CALLBACK_CONTEXT, + type_configuration=TypeConfigurationModel( + IgnoreS3BucketNames="", + ), + ) + + assert response.message == "Bucket versioning is not enabled." + assert response.status == OperationStatus.FAILED + assert response.errorCode == HandlerErrorCode.NonCompliant + assert response.callbackContext is None + assert response.callbackDelaySeconds == 0 + + +def test_when_s3_bucket_properties_are_missing_then_fail() -> ( # noqa: D103 + None +): + MOCK_BASE_HOOK_HANDLER_REQUEST.hookContext.targetModel = {} + + response = handlers._run_pre_create_pre_update_common_checks( + session=None, + request=MOCK_BASE_HOOK_HANDLER_REQUEST, + callback_context=MOCK_CALLBACK_CONTEXT, + type_configuration=TypeConfigurationModel( + IgnoreS3BucketNames="", + ), + ) + + assert response.message == "The S3 bucket has no properties set." + assert response.status == OperationStatus.FAILED + assert response.errorCode == HandlerErrorCode.NonCompliant + assert response.callbackContext is None + assert response.callbackDelaySeconds == 0 + + +def test_when_s3_bucket_versioning_property_is_missing_then_fail() -> ( # noqa: D103 E501 + None +): + MOCK_BASE_HOOK_HANDLER_REQUEST.hookContext.targetModel = { + "resourceProperties": { + "VersioningConfiguration": None, + }, + } + + response = handlers._run_pre_create_pre_update_common_checks( + session=None, + request=MOCK_BASE_HOOK_HANDLER_REQUEST, + callback_context=MOCK_CALLBACK_CONTEXT, + type_configuration=TypeConfigurationModel( + IgnoreS3BucketNames="", + ), + ) + + assert ( + response.message + == "The VersioningConfiguration property value is missing." + ) + assert response.status == OperationStatus.FAILED + assert response.errorCode == HandlerErrorCode.NonCompliant + assert response.callbackContext is None + assert response.callbackDelaySeconds == 0 + + +def test_when_exception_is_thrown_then_fail() -> None: # noqa: D103 + MOCK_BASE_HOOK_HANDLER_REQUEST.hookContext.targetModel = {} + + with patch( + f"{HOOK_CODE_SRC_SUBDIR_NAME}.handlers._get_target_model", + side_effect=ValueError("Example error."), + ): + response = handlers._run_pre_create_pre_update_common_checks( + session=None, + request=MOCK_BASE_HOOK_HANDLER_REQUEST, + callback_context=MOCK_CALLBACK_CONTEXT, + type_configuration=TypeConfigurationModel( + IgnoreS3BucketNames="", + ), + ) + + assert response.message == "Example error." + assert response.status == OperationStatus.FAILED + assert response.errorCode == HandlerErrorCode.InternalFailure + assert response.callbackContext is None + assert response.callbackDelaySeconds == 0 + + +def test_when_s3_bucket_name_is_not_ignored_then_if_non_compliant_fail() -> ( # noqa: D103 E501 + None +): + MOCK_BASE_HOOK_HANDLER_REQUEST.hookContext.targetModel = { + "resourceProperties": { + "BucketName": "my-non-ignored-bucket", + "VersioningConfiguration": {"Status": "Suspended"}, + }, + } + + response = handlers._run_pre_create_pre_update_common_checks( + session=None, + request=MOCK_BASE_HOOK_HANDLER_REQUEST, + callback_context=MOCK_CALLBACK_CONTEXT, + type_configuration=TypeConfigurationModel( + IgnoreS3BucketNames="my-ignored-bucket,my-other-ignored-bucket", + ), + ) + + assert response.message == "Bucket versioning is not enabled." + assert response.status == OperationStatus.FAILED + assert response.errorCode == HandlerErrorCode.NonCompliant + assert response.callbackContext is None + assert response.callbackDelaySeconds == 0 +::: + +Save the file. Look at the example unit test code you just added: can you recognize which parts of the code are covered? As you can see, in this file you first set some variables on top of the code, and you reference these variables in `MOCK_BASE_HOOK_HANDLER_REQUEST` that you reuse across unit test methods. In each method, you create a mock of the target model, and run the handler code to assert either success or failure scenarios. + +Next, type the following command from the `example-hook/` directory to run unit tests: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +pytest --cov +::: + +Congratulations! Your code coverage is slightly above 80%. There are some other lines of code that you could cover, but let's move on for now. + +Next, run `mypy` against your `test_handlers.py` file (make sure you are in the `example-hook/` directory): + +:::code{language=shell showLineNumbers=false showCopyAction=true} +mypy src/examplecompany_s3_versioningenabled/tests/test_handlers.py +::: + +You should see an output indicating no errors. Next, run `flake8` against the same file: + +:::code{language=shell showLineNumbers=false showCopyAction=true} +flake8 \ + --docstring-convention pep257 \ + --ignore=W503,W504 \ + --max-complexity=10 \ + --max-line-length=79 \ + src/examplecompany_s3_versioningenabled/tests/test_handlers.py +::: + +You should see no output messages, indicating no errors have occurred. + +Choose **Next** to continue! diff --git a/content/advanced/hooks/index.md b/content/advanced/hooks/index.md new file mode 100644 index 000000000..515d943c9 --- /dev/null +++ b/content/advanced/hooks/index.md @@ -0,0 +1,46 @@ +--- +title: "Hooks" +weight: 400 +--- + +### Introduction + +This part of the workshop focuses on how you can extend creation, provisioning, and management capabilities of [AWS CloudFormation](https://aws.amazon.com/cloudformation/) with proactive compliance validation controls you develop. + +[AWS CloudFormation Hooks](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/what-is-cloudformation-hooks.html) is a feature that allows you to create proactive controls (or to reuse existing ones) to validate that your CloudFormation resources are compliant with your company's best practices. For example, you could create a proactive validation control to check that an [Amazon Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/) bucket, whose desired state you describe in CloudFormation template(s), is set up by your users to have [versioning configuration](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3-bucket.html#cfn-s3-bucket-versioningconfiguration) enabled, or if [server-side encryption](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-s3-bucket.html#cfn-s3-bucket-bucketencryption) is enabled for S3 buckets you create, with CloudFormation, with an [encryption algorithm](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-s3-bucket-serversideencryptionbydefault.html#cfn-s3-bucket-serversideencryptionbydefault-ssealgorithm) you choose from the ones that are available. Those are just two examples and, as you can imagine, there can be many others. + +With the examples above using an S3 bucket, when you model your hook you choose to target the `AWS::S3::Bucket` resource type. When you then create or update a stack with a template that describes an S3 bucket, your hook gets invoked before CloudFormation attempts to create or update the bucket. When invoked, your hook validates that -for example- the versioning property for your bucket is set to the `Enabled` `Status`. If you were to have 2 S3 buckets in your template, each bucket would cause an instance of the hook getting invoked (in this example, you'll have 2 hook invocations, one for each bucket). + +A hook can encompass one or more resource type target for a given invocation point (such as, pre-create, pre-update, and pre-delete - + that is, before you create, update, or delete a CloudFormation stack). + +There are two discrete workflows for hooks, each one for a specific user persona/team of a given company: + +- the security team, that establishes which proactive controls to enable, and +- the application team(s), that describe the infrastructure for their applications, or for their workloads, with CloudFormation. + +In this lab, you'll start with the first workflow to build and test a sample hook, and then you'll create a stack to verify your hook works as you'd expect as part of the second workflow above. + +The Software Development Life Cycle (SDLC) process of a hook, that is part of the first workflow, can be described as follows: + +- install prerequisite tools you will use for development and testing of your hook; +- develop and run tests for your hook; +- when ready, submit the hook to the [AWS CloudFormation registry](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry.html) as a private extension for a given AWS account and region; +- manage the configuration of your hook: you describe the behavior of the hook (for example, whether to invoke the hook for stacks in your account in a given region, whether compliance validation errors yield to denying the provisioning of the non-compliant resource, or simply to a warning); +- if your hook needs user input configuration (that is, if the author of the hook has designed configuration values to be user-configurable), you'd configure the hook according to your needs. + +::alert[You have the choice to register your hook as a private or as a public extension in the CloudFormation registry: this lab covers private extension examples.]{type="info"} + +When you submit a private extension (such as a module, a resource type, or a hook), you make it available in the CloudFormation registry in your AWS account for a given AWS region: private extensions give you the ability to test the behavior of your resource type in a sandbox environment, such as in an AWS account you own, and that you use for testing/experimentation. Another use case for having a private extension is for validation logic that is company-specific or proprietary. + +For more information on private extensions, see [Using private extensions in CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry-register.html). For more information on public extensions, see [Publishing extensions to make them available for public use](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/publish-extension.html). + +::alert[Please refer to [AWS CloudFormation pricing](https://aws.amazon.com/cloudformation/pricing/) for information on charges to your account when you use hooks.]{type="info"} + + +### Key concepts + +Key concepts for developing a hook include: + +* [model](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/hooks-model.html): a document where you describe which resource type (or types) you wish to trigger a hook invocation, and at which lifecycle phase (pre-create, pre-update, or pre-delete). Moreover, if you plan to make AWS API calls from your hook to make additional validation checks, you can also specify the relevant permissions you need in the model; +* [handlers](https://docs.aws.amazon.com/cloudformation-cli/latest/hooks-userguide/hooks-model.html#model-hook-project-add-handler): the invocation points for your hook: at least one of `preCreate`, `preUpdate`, or `preDelete` is required. diff --git a/content/advanced/hooks/prerequisites/index.md b/content/advanced/hooks/prerequisites/index.md new file mode 100644 index 000000000..da09d9bac --- /dev/null +++ b/content/advanced/hooks/prerequisites/index.md @@ -0,0 +1,30 @@ +--- +title: "Prerequisites" +weight: 410 +--- + +### Hooks Development Tools +Before proceeding to the next section, choose to install the following prerequisites: + +* install the [AWS SAM CLI](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-reference.html#serverless-sam-cli) by following notes for your operating system in links shown next. When you install the SAM CLI, follow also notes to install Docker (unless you have already installed it), that is needed for running contract tests: + + - [AWS SAM CLI on Linux](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-linux.html) + - [AWS SAM CLI on Windows](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-windows.html) + - [AWS SAM CLI on macOS](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install-mac.html) + +* install the [CloudFormation Command Line Interface (CLI)](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html), and plugin(s) for supported languages that you wish to use. + + Use `pip` to install the CloudFormation CLI and language plugins supported for hooks: + :::code{language=shell showLineNumbers=false showCopyAction=true} + pip install cloudformation-cli cloudformation-cli-python-plugin cloudformation-cli-java-plugin + ::: + +::alert[If you already have version 1.0 of the CloudFormation CLI installed, it is recommended to upgrade it to version 2.0, and to upgrade language plugin(s) you use as well. For the upgrade, you can use the `--upgrade` option for the `pip install` command shown previously, and include language plugins you use or plan to use. For more information, see *Upgrading to CFN-CLI 2.0* further down on this [page](https://docs.aws.amazon.com/cloudformation-cli/latest/userguide/what-is-cloudformation-cli.html#resource-type-setup).]{type="info"} + +* for the [Example in Python](../example-in-python) lab, install the following packages (`cloudformation-cli-python-lib` and `pytest-cov` are needed for running unit tests for the sample application; you'll use the other packages as examples for maintaining the code for the hook you'll build): + + :::code{language=shell showLineNumbers=false showCopyAction=true} + pip install cloudformation-cli-python-lib flake8 flake8-docstrings mypy pytest-cov + ::: + +Choose **Next** to continue! From db4e037308a631aefaaa5c88c2aed313b43d7fbb Mon Sep 17 00:00:00 2001 From: Franco Rezabek <43790446+rezabekf@users.noreply.github.com> Date: Tue, 9 Jan 2024 18:41:26 +0000 Subject: [PATCH 5/9] Fix/missing index markdown (#261) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add JPN placeholder * Bump version: 3.4.0 → 3.4.1 --- .bumpversion.cfg | 2 +- .../advanced/hooks/example-in-python/challenge/index.ja.md | 6 ++++++ .../advanced/hooks/example-in-python/cleanup/index.ja.md | 6 ++++++ .../advanced/hooks/example-in-python/conclusion/index.ja.md | 6 ++++++ .../hooks/example-in-python/end-to-end-test/index.ja.md | 6 ++++++ content/advanced/hooks/example-in-python/index.ja.md | 6 ++++++ .../hooks/example-in-python/model-your-hook/index.ja.md | 6 ++++++ .../hooks/example-in-python/register-your-hook/index.ja.md | 6 ++++++ .../advanced/hooks/example-in-python/write-code/index.ja.md | 6 ++++++ .../example-in-python/write-contract-tests/index.ja.md | 6 ++++++ .../hooks/example-in-python/write-unit-tests/index.ja.md | 6 ++++++ content/advanced/hooks/index.ja.md | 6 ++++++ content/advanced/hooks/prerequisites/index.ja.md | 6 ++++++ 13 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 content/advanced/hooks/example-in-python/challenge/index.ja.md create mode 100644 content/advanced/hooks/example-in-python/cleanup/index.ja.md create mode 100644 content/advanced/hooks/example-in-python/conclusion/index.ja.md create mode 100644 content/advanced/hooks/example-in-python/end-to-end-test/index.ja.md create mode 100644 content/advanced/hooks/example-in-python/index.ja.md create mode 100644 content/advanced/hooks/example-in-python/model-your-hook/index.ja.md create mode 100644 content/advanced/hooks/example-in-python/register-your-hook/index.ja.md create mode 100644 content/advanced/hooks/example-in-python/write-code/index.ja.md create mode 100644 content/advanced/hooks/example-in-python/write-contract-tests/index.ja.md create mode 100644 content/advanced/hooks/example-in-python/write-unit-tests/index.ja.md create mode 100644 content/advanced/hooks/index.ja.md create mode 100644 content/advanced/hooks/prerequisites/index.ja.md diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 388a190ed..426149a7d 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,4 +1,4 @@ [bumpversion] -current_version = 3.4.0 +current_version = 3.4.1 commit = True tag = False diff --git a/content/advanced/hooks/example-in-python/challenge/index.ja.md b/content/advanced/hooks/example-in-python/challenge/index.ja.md new file mode 100644 index 000000000..828d0b650 --- /dev/null +++ b/content/advanced/hooks/example-in-python/challenge/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Challenge" +weight: 490 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/example-in-python/cleanup/index.ja.md b/content/advanced/hooks/example-in-python/cleanup/index.ja.md new file mode 100644 index 000000000..122e1a55c --- /dev/null +++ b/content/advanced/hooks/example-in-python/cleanup/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Cleanup" +weight: 495 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/example-in-python/conclusion/index.ja.md b/content/advanced/hooks/example-in-python/conclusion/index.ja.md new file mode 100644 index 000000000..d2729278f --- /dev/null +++ b/content/advanced/hooks/example-in-python/conclusion/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Conclusion" +weight: 499 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/example-in-python/end-to-end-test/index.ja.md b/content/advanced/hooks/example-in-python/end-to-end-test/index.ja.md new file mode 100644 index 000000000..317a047a2 --- /dev/null +++ b/content/advanced/hooks/example-in-python/end-to-end-test/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "End-to-end test" +weight: 480 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/example-in-python/index.ja.md b/content/advanced/hooks/example-in-python/index.ja.md new file mode 100644 index 000000000..e7e917711 --- /dev/null +++ b/content/advanced/hooks/example-in-python/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Example in Python" +weight: 420 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/example-in-python/model-your-hook/index.ja.md b/content/advanced/hooks/example-in-python/model-your-hook/index.ja.md new file mode 100644 index 000000000..a15b8d936 --- /dev/null +++ b/content/advanced/hooks/example-in-python/model-your-hook/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Model your hook" +weight: 430 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/example-in-python/register-your-hook/index.ja.md b/content/advanced/hooks/example-in-python/register-your-hook/index.ja.md new file mode 100644 index 000000000..eb45daae0 --- /dev/null +++ b/content/advanced/hooks/example-in-python/register-your-hook/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Register your hook" +weight: 470 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/example-in-python/write-code/index.ja.md b/content/advanced/hooks/example-in-python/write-code/index.ja.md new file mode 100644 index 000000000..3860f5c88 --- /dev/null +++ b/content/advanced/hooks/example-in-python/write-code/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Write code" +weight: 440 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/example-in-python/write-contract-tests/index.ja.md b/content/advanced/hooks/example-in-python/write-contract-tests/index.ja.md new file mode 100644 index 000000000..2b8ddc38a --- /dev/null +++ b/content/advanced/hooks/example-in-python/write-contract-tests/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Write contract tests" +weight: 460 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/example-in-python/write-unit-tests/index.ja.md b/content/advanced/hooks/example-in-python/write-unit-tests/index.ja.md new file mode 100644 index 000000000..66d4cda9f --- /dev/null +++ b/content/advanced/hooks/example-in-python/write-unit-tests/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Write unit tests" +weight: 450 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/index.ja.md b/content/advanced/hooks/index.ja.md new file mode 100644 index 000000000..5c46dc8a9 --- /dev/null +++ b/content/advanced/hooks/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Hooks" +weight: 400 +--- + +Japanese translation is not available yet. Please use the English version. diff --git a/content/advanced/hooks/prerequisites/index.ja.md b/content/advanced/hooks/prerequisites/index.ja.md new file mode 100644 index 000000000..c972f03cb --- /dev/null +++ b/content/advanced/hooks/prerequisites/index.ja.md @@ -0,0 +1,6 @@ +--- +title: "Prerequisites" +weight: 410 +--- + +Japanese translation is not available yet. Please use the English version. From 212509b9f20e2fe4b34e7d3400ea04b30205d97d Mon Sep 17 00:00:00 2001 From: awsarpit <122075856+awsarpit@users.noreply.github.com> Date: Fri, 10 May 2024 15:07:36 +0530 Subject: [PATCH 6/9] bug fixes (#262) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * bug fixes * bug fixes * bug fixes updated * Bump version: 3.4.1 → 3.4.2 --------- Co-authored-by: Rezabek --- .bumpversion.cfg | 2 +- .../templates/intrinsic-functions/index.md | 22 ++++++++++++++++++ .../prerequisites/local-development/index.md | 2 +- static/prerequisites/account/new-user-1.png | Bin 81022 -> 363931 bytes 4 files changed, 24 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 426149a7d..636632a50 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,4 +1,4 @@ [bumpversion] -current_version = 3.4.1 +current_version = 3.4.2 commit = True tag = False diff --git a/content/basics/templates/intrinsic-functions/index.md b/content/basics/templates/intrinsic-functions/index.md index 344fc15d8..b15b48bf5 100644 --- a/content/basics/templates/intrinsic-functions/index.md +++ b/content/basics/templates/intrinsic-functions/index.md @@ -182,6 +182,28 @@ aws cloudformation update-stack --stack-name cfn-workshop-intrinsic-functions -- To Verify, Go to the **Tags** tab on EC2 Console, verify that `InstanceType` tag has been created. :::::: +**Comparison between Ref and Fn::Sub** + +The intrinsic function Ref returns the value of the specified parameter or resource. When you are declaring a resource in a template and you need to specify another template resource by name, you can use the Ref to refer to that other resource. In general, Ref returns the name of the resource. + +Syntax for YAML template +``` +Ref: logicalName +``` +Syntax for the short form: +``` +!Ref logicalName +``` +The intrinsic function Fn::Sub substitutes variables in an input string with values that you specify. In your templates, you can use this function to construct commands or outputs that include values that aren't available until you create or update a stack. + +Syntax for YAML template +``` +Fn::Sub: + - String + - Var1Name: Var1Value + Var2Name: Var2Value +``` + ### Clean up Follow these steps to clean up created resources: diff --git a/content/prerequisites/local-development/index.md b/content/prerequisites/local-development/index.md index 6e10fac6a..e62acf9cc 100644 --- a/content/prerequisites/local-development/index.md +++ b/content/prerequisites/local-development/index.md @@ -6,7 +6,7 @@ weight: 300 _Setup Duration: ~15 minutes_ :::alert{type="info"} -This is only required if you are not using Cloud9 IDE for the workshop. +This is only required if you are not using Cloud9 IDE for the workshop. Else you can skip to the [Default VPC](https://catalog.workshops.aws/cfn101/en-US/prerequisites/default-vpc) section ::: Local development for this workshop requires a number of development tools. Please install and verify these are installed correctly before proceeding with the workshop. diff --git a/static/prerequisites/account/new-user-1.png b/static/prerequisites/account/new-user-1.png index 2913384c7470b47ab544b1f70b3f682adcae5f6b..8a0ae767275d8a3b3a26d39ddde34ec46a43c8d6 100644 GIT binary patch literal 363931 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%0DeJ-Jm8@Ypks^NHD9g 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

1j2gzr`WA*EqF+rwD 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 E0j;+)w*UYD literal 0 HcmV?d00001 diff --git a/static/intermediate/operations/stacksets/stackinstances.ja.png b/static/intermediate/operations/stacksets/stackinstances.ja.png new file mode 100644 index 0000000000000000000000000000000000000000..bc0424251c39cd8585d73871dc7264e86320fb2b GIT binary patch literal 128412 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