

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

# モダナイゼーション
<a name="modernization-pattern-list"></a>

**Topics**
+ [DynamoDB TTL を使用して項目を Amazon S3 に自動的にアーカイブする](automatically-archive-items-to-amazon-s3-using-dynamodb-ttl.md)
+ [Amazon OpenSearch Service におけるマルチテナントサーバーレスアーキテクチャの構築](build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service.md)
+ [AWS CDK と TypeScript を使用してマルチスタックのアプリケーションをデプロイする](deploy-multiple-stack-applications-using-aws-cdk-with-typescript.md)
+ [AWS SAM を使用してネストされたアプリケーションのデプロイを自動化](automate-deployment-of-nested-applications-using-aws-sam.md)
+ [AWS Lambda トークン自動販売機を使用して Amazon S3 の SaaS テナント分離を実装する](implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine.md)
+ [AWS Step Functions を使用して、サーバーレス Saga パターンを実装する](implement-the-serverless-saga-pattern-by-using-aws-step-functions.md)
+ [AWS CDK で Amazon ECS Anywhere を設定して、オンプレミスコンテナアプリケーションを管理します。](manage-on-premises-container-applications-by-setting-up-amazon-ecs-anywhere-with-the-aws-cdk.md)
+ [ASP.NET ウェブフォームアプリケーションを AWS で最新化](modernize-asp-net-web-forms-applications-on-aws.md)
+ [C\$1 と AWS CDK を使用するサイロモデル用の SaaS アーキテクチャでのテナントオンボーディング](tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.md)
+ [CQRS とイベントソーシングを使用してモノリスをマイクロサービスに分解する](decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.md)
+ [その他のパターン](modernization-more-patterns-pattern-list.md)

# DynamoDB TTL を使用して項目を Amazon S3 に自動的にアーカイブする
<a name="automatically-archive-items-to-amazon-s3-using-dynamodb-ttl"></a>

*Tabby Ward、Amazon Web Services*

## 概要
<a name="automatically-archive-items-to-amazon-s3-using-dynamodb-ttl-summary"></a>

このパターンでは、サーバー群を管理しなくても、Amazon DynamoDB テーブルから古いデータを削除し、Amazon Web Services (AWS) の Amazon Simple Storage Service (Amazon S3) バケットにアーカイブする手順を示します。 

このパターンでは、Amazon DynamoDB の Time-toLive (TTL) を使用して古い項目を自動的に削除し、Amazon DynamoDB Streams を使用して TTL の有効期限が切れた項目をキャプチャします。次に DynamoDB Streams を AWS Lambda に接続し、サーバーをプロビジョニングしたり管理したりせずにコードを実行します。 

DynamoDB ストリームに新しい項目が追加されると、Lambda 関数が開始され、Amazon Data Firehose 配信ストリームにデータが書き込まれます。Firehose は、データをアーカイブとして Amazon S3 にロードするためのシンプルでフルマネージド型のソリューションを提供します。

DynamoDB は、ウェブページのクリックストリームデータや、センサーや接続されたデバイスからのモノのインターネット (IoT) データなどの時系列データを保存するためによく使用されます。アクセス頻度の低い項目を削除するのではなく、監査目的でアーカイブしたいと考えるお客様が多くいます。TTL は、タイムスタンプ属性に基づいてアイテムを自動的に削除することで、このアーカイブを簡素化します。 

TTL によって削除された項目は DynamoDB Streams で識別できます。DynamoDB Streams は、DynamoDB Streams で識別できます。DynamoDB Streams は、項目レベルの変更に関するシーケンスを時間順にキャプチャし、そのシーケンスを最大 24 時間ログに保存します。このデータは Lambda 関数で使用して Amazon S3 バケットにアーカイブすることで、ストレージコストを削減できます。コストをさらに削減するために、[Amazon S3 ライフサイクルルール](https://docs.aws.amazon.com/AmazonS3/latest/userguide/object-lifecycle-mgmt.html)を作成して、データを自動的に (作成後すぐに) 最低コストの[ストレージクラス](https://aws.amazon.com/s3/storage-classes/)に移行できます。

## 前提条件と制限事項
<a name="automatically-archive-items-to-amazon-s3-using-dynamodb-ttl-prereqs"></a>

**前提条件**
+ アクティブなAWS アカウント
+ macOS、Linux、または Windows にインストールおよび設定されている [AWS コマンドラインインターフェイス (AWS CLI) バージョン 1.7 以降](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html)。
+ [Python 3.7](https://www.python.org/downloads/release/python-370/) 以降。
+ インストールおよび設定されている [Booto3](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)。Boto3 がまだインストールされていない場合は、`python -m pip install boto3` コマンドを実行してインストールします。

## アーキテクチャ
<a name="automatically-archive-items-to-amazon-s3-using-dynamodb-ttl-architecture"></a>

**テクノロジースタック**
+ Amazon DynamoDB
+ Amazon DynamoDB Streams
+ Amazon Data Firehose
+ AWS Lambda
+ Amazon S3

![\[DynamoDB から S3 バケットへの 4 ステップのプロセス。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9dbc833f-cf3c-4574-8f09-d0b81134fe41/images/50d9da65-5398-4a99-bc8f-58afc80e9d7b.png)


1. アイテムは TTL によって削除されます。

1. DynamoDB ストリームトリガーは Lambda ストリームプロセッサ関数を呼び出します。

1. Lambda 関数は、Firehose 配信ストリームにレコードをバッチ形式で格納します。

1. データレコードは S3 バケットにアーカイブされます。

## ツール
<a name="automatically-archive-items-to-amazon-s3-using-dynamodb-ttl-tools"></a>
+ [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) – AWS コマンドラインインターフェイス (AWS CLI) は、AWS のサービスを管理するための統合ツールです。
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) – Amazon DynamoDB は、どのような規模でも一桁のミリ秒単位のパフォーマンスを実現するキーバリューおよびドキュメントデータベースです。
+ [Amazon DynamoDB Time to Live (TTL)](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/howitworks-ttl.html) – Amazon DynamoDB TTL は、項目ごとのタイムスタンプを定義して、項目がいつ不要になるかを判断するのに役立ちます。
+ [Amazon DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/APIReference/API_Types_Amazon_DynamoDB_Streams.html) – Amazon DynamoDB Streams は、DynamoDB テーブル内の項目レベルの変更の時系列シーケンスをキャプチャし、この情報をログに最大 24 時間保存します。
+ [Amazon Data Firehose](https://docs.aws.amazon.com/firehose/latest/dev/what-is-this-service.html) – Amazon Data Firehose は、ストリーミングデータをデータレイク、データストア、分析サービスに確実にロードする最も簡単な方法です。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) – AWS Lambda を使用すると、サーバーのプロビジョニングや管理を必要とせずにコードを実行できます。支払いは、使用したコンピューティング時間に対する料金のみになります。
+ [Amazon S3](https://docs.aws.amazon.com/AmazonS3/latest/dev/Welcome.html) – Amazon Simple Storage Service (Amazon S3) は、業界をリードするスケーラビリティ、データ可用性、セキュリティ、パフォーマンスを提供するオブジェクトストレージサービスです。

**コード**

このパターンのコードは、GitHub 内の「[Archive items to S3 using DynamoDB TTL](https://github.com/aws-samples/automatically-archive-items-to-s3-using-dynamodb-ttl)」リポジトリで利用できます。

## エピック
<a name="automatically-archive-items-to-amazon-s3-using-dynamodb-ttl-epics"></a>

### DynamoDB テーブル、TTL、および DynamoDB ストリームをセットアップする
<a name="set-up-a-dynamodb-table-ttl-and-a-dynamodb-stream"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| DynamoDB テーブルを作成します。 | AWS CLI を使用して、`Reservation` というテーブルを DynamoDB に作成します。ランダムな読み取りキャパシティユニット (RCU) と書き込みキャパシティユニット (WCU) を選択し、テーブルに 2 つの属性 (`ReservationID` と `ReservationDate`) を与えます。 <pre>aws dynamodb create-table \<br />--table-name Reservation \<br />--attribute-definitions AttributeName=ReservationID,AttributeType=S AttributeName=ReservationDate,AttributeType=N \<br />--key-schema AttributeName=ReservationID,KeyType=HASH AttributeName=ReservationDate,KeyType=RANGE \<br />--provisioned-throughput ReadCapacityUnits=100,WriteCapacityUnits=100 </pre>`ReservationDate` は、TTL を有効にするために使用されるエポックタイムスタンプです。 | クラウドアーキテクト、アプリ開発者 | 
| DynamoDB TTL を有効にする。 | AWS CLI を使用して `ReservationDate` 属性の DynamoDB TTL を有効にします。<pre>aws dynamodb update-time-to-live \<br />--table-name Reservation\<br />  --time-to-live-specification Enabled=true,AttributeName=ReservationDate</pre> | クラウドアーキテクト、アプリ開発者 | 
| DynamoDB ストリームをオンにする。 | AWS CLI を使用して、`NEW_AND_OLD_IMAGES` ストリームタイプを使用して `Reservation` テーブルの DynamoDB ストリームを有効にします。 <pre>aws dynamodb update-table \<br />--table-name Reservation \<br />  --stream-specification StreamEnabled=true,StreamViewType=NEW_AND_OLD_IMAGES</pre>このストリームには、新しい項目、更新された項目、削除された項目、および TTL によって削除された項目のレコードが含まれます。TTL によって削除されたアイテムのレコードには、手動で削除されたアイテムと区別するためのメタデータ属性が追加されています。TTL 削除の `userIdentity` フィールドは、DynamoDB サービスが削除アクションを実行したことを示します。 このパターンでは、TTL によって削除されたアイテムのみがアーカイブされますが、`eventName` が `REMOVE` で、`userIdentity` に `dynamodb.amazonaws.com` に等しい `principalId` が含まれるレコードのみをアーカイブすることもできます。 | クラウドアーキテクト、アプリ開発者 | 

### S3 バケットの作成と設定
<a name="create-and-configure-an-s3-bucket"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| S3 バケットを作成する。 | AWS CLI を使用して AWS リージョンに宛先 S3 バケットを作成し、`us-east-1` をリージョンに、amzn-s3-demo-destination-bucket をバケットの名前に置き換えます。 <pre>aws s3api create-bucket \<br />--bucket amzn-s3-demo-destination-bucket \<br />--region us-east-1</pre>名前空間はすべての AWS アカウントによって共有されているので、S3 バケット名はグローバルに一意であることを確認します。 | クラウドアーキテクト、アプリ開発者 | 
| S3 バケットの 30 日間のライフサイクルポリシーを作成する。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/automatically-archive-items-to-amazon-s3-using-dynamodb-ttl.html) | クラウドアーキテクト、アプリ開発者 | 

### Firehose 配信ストリームを作成する
<a name="create-a-akf-delivery-stream"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Firehose 配信ストリームを作成して設定する。 | GitHub リポジトリから `CreateFireHoseToS3.py` コードサンプルをダウンロードして編集します。 このコードは Python で記述されており、Firehose デリバリーストリームと AWS Identity and Access Management (IAM) ロールを作成する方法を示しています。IAM ロールには、Firehose が宛先 S3 バケットに書き込むために使用できるポリシーが含まれます。スクリプトを実行するには、次のコマンドとコマンドライン引数を使用します。引数 1= `<Your_S3_bucket_ARN>`、先ほど作成したバケットの Amazon リソースネーム (ARN) です引数 2= Firehose 名前 (このパイロットでは `firehose_to_s3_stream` を使用)引数 3= IAM ロール名 (このパイロットでは `firehose_to_s3` を使用) <pre>python CreateFireHoseToS3.py <Your_S3_Bucket_ARN> firehose_to_s3_stream firehose_to_s3</pre>指定した IAM ロールが存在しない場合、スクリプトは信頼できる関係ポリシーと、十分な Amazon S3 アクセス権限を付与するポリシーを使用してアサインロールを作成します。これらのポリシーの例については、「*追加情報*」セクションを参照してください。 | クラウドアーキテクト、アプリ開発者 | 
| Firehose 配信ストリームを確認する。 | AWS CLI を使用して Firehose 配信ストリームを記述し、配信ストリームが正常に作成されたことを確認します。<pre>aws firehose describe-delivery-stream --delivery-stream-name firehose_to_s3_stream </pre> | クラウドアーキテクト、アプリ開発者 | 

### Firehose 配信ストリームを処理する Lambda 関数を作成する
<a name="create-a-lambda-function-to-process-the-akf-delivery-stream"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Lambda 関数の信頼ポリシーを作成する。 | 次の情報を使用して信頼ポリシーファイルを作成します。<pre> {<br />     "Version": "2012-10-17",		 	 	 <br />     "Statement": [<br />      {<br />          "Effect": "Allow",<br />          "Principal": {<br />              "Service": "lambda.amazonaws.com"<br />           },<br />           "Action": "sts:AssumeRole"<br />      }<br />    ]<br />  } </pre>これにより、関数に AWS リソースへのアクセス権限が付与されます。 | クラウドアーキテクト、アプリ開発者 | 
| Lambda 関数の実行ロールを作成する。 | 実行ロールを作成するには、次のコードを実行します。<pre>aws iam create-role --role-name lambda-ex --assume-role-policy-document file://TrustPolicy.json</pre> | クラウドアーキテクト、アプリ開発者 | 
| ロールにアクセス権限を追加します。 | ロールにアクセス権限を追加するには、`attach-policy-to-role` コマンドを使用します。<pre>aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole<br />aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaDynamoDBExecutionRole<br />aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/AmazonKinesisFirehoseFullAccess<br />aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/IAMFullAccess </pre> | クラウドアーキテクト、アプリ開発者 | 
| Lambda 関数を作成する。 | 次のコマンドを実行して、コードリポジトリから `LambdaStreamProcessor.py` ファイルを圧縮します。<pre>zip function.zip LambdaStreamProcessor.py</pre>Lambda 関数を作成するときは、Lambda 実行ロール ARN が必要になります。ARN を取得するには、次のコードを実行します。<pre>aws iam get-role \<br />--role-name lambda-ex </pre>Lambda 関数を作成するには、次のコードを実行します。<pre># Review the environment variables and replace them with your values.<br /><br />aws lambda create-function --function-name LambdaStreamProcessor \<br />--zip-file fileb://function.zip --handler LambdaStreamProcessor.handler --runtime python3.8 \<br />--role {Your Lamda Execution Role ARN}\<br />  --environment Variables="{firehose_name=firehose_to_s3_stream,bucket_arn = <Your_S3_bucket_ARN>,iam_role_name = firehose_to_s3, batch_size=400}"</pre> | クラウドアーキテクト、アプリ開発者 | 
| Lambda 関数のトリガーを設定する。 | AWS CLI を使用して Lambda 関数を呼び出すトリガー (DynamoDB Streams) を設定します。バッチサイズを 400 にするのは、Lambda の同時実行の問題が発生しないようにするためです。<pre>aws lambda create-event-source-mapping --function-name LambdaStreamProcessor \<br />--batch-size 400 --starting-position LATEST \<br />--event-source-arn <Your Latest Stream ARN From DynamoDB Console></pre> | クラウドアーキテクト、アプリ開発者 | 

### 関数をテストする
<a name="test-the-functionality"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| タイムスタンプが期限切れの項目を Reservation テーブルに追加する。 | 機能をテストするには、エポックタイムスタンプが期限切れの項目を `Reservation` テーブルに追加します。TTL はタイムスタンプに基づいて自動的に項目を削除します。 Lambda 関数は DynamoDB ストリームのアクティビティ時に開始され、イベントをフィルタリングして `REMOVE` アクティビティや削除された項目を識別します。次に、Firehose 配信ストリームにレコードをバッチ形式で格納します。Firehose デリバリーストリームは、`firehosetos3example/year=current year/month=current month/ day=current day/hour=current hour/` プレフィックスが付いた送信先 S3 バケットにアイテムを転送します。データ取得を最適化するには、「*追加情報*」セクションで詳しく説明されている `Prefix` と `ErrorOutputPrefix` を使用して Amazon S3 を設定します。 | クラウドアーキテクト  | 

### リソースをクリーンアップする
<a name="clean-up-the-resources"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| すべてのリソースを削除する。 | 使用していないサービスに対して課金されることがないように、リソースをすべて削除します。  | クラウドアーキテクト、アプリ開発者 | 

## 関連リソース
<a name="automatically-archive-items-to-amazon-s3-using-dynamodb-ttl-resources"></a>
+ [Managing your storage lifecycle](https://docs.aws.amazon.com/AmazonS3/latest/user-guide/create-lifecycle.html)
+ [Amazon S3 ストレージクラス](https://aws.amazon.com/s3/storage-classes/)
+ [AWS SDK for Python (Boto3) documentation](https://boto3.amazonaws.com/v1/documentation/api/latest/index.html)

## 追加情報
<a name="automatically-archive-items-to-amazon-s3-using-dynamodb-ttl-additional"></a>

**Firehose 配信ストリームを作成および設定する – ポリシー例**

*Firehose 信頼関係ポリシーのサンプルドキュメント*

```
firehose_assume_role = {
        'Version': '2012-10-17',
        'Statement': [
            {
                'Sid': '',
                'Effect': 'Allow',
                'Principal': {
                    'Service': 'firehose.amazonaws.com'
                },
                'Action': 'sts:AssumeRole'
            }
        ]
    }
```

S3 アクセス権限ポリシーの例

```
s3_access = {
        "Version": "2012-10-17",		 	 	 
        "Statement": [
            {
                "Sid": "",
                "Effect": "Allow",
                "Action": [
                    "s3:AbortMultipartUpload",
                    "s3:GetBucketLocation",
                    "s3:GetObject",
                    "s3:ListBucket",
                    "s3:ListBucketMultipartUploads",
                    "s3:PutObject"
                ],
                "Resource": [
                    "{your s3_bucket ARN}/*",
                    "{Your s3 bucket ARN}"
                ]
            }
        ]
    }
```

**機能のテスト – Amazon S3 の設定**

データ取得を最適化するために、次の `Prefix` および`ErrorOutputPrefix` を備えた Amazon S3 の設定が選択されています。 

*Prefix*

```
firehosetos3example/year=! {timestamp: yyyy}/month=! {timestamp:MM}/day=! {timestamp:dd}/hour=!{timestamp:HH}/
```

Firehose は最初に S3 バケットの直下に `firehosetos3example` という名前のベースフォルダを作成します。次に、`!{timestamp:yyyy}`、`!{timestamp:MM}`、`!{timestamp:dd}` および `!{timestamp:HH}` という式を評価し、Java [DateTimeFormatter](https://docs.oracle.com/javase/8/docs/api/java/time/format/DateTimeFormatter.html) フォーマットを使用して年、月、日、時間に変換します。

例えば、Unix エポックタイムでのおよその到着タイムスタンプが 1604683577 の場合、`year=2020`、`month=11`、`day=06` および `hour=05` と評価されます。したがって、データレコードが配信される Amazon S3 内の場所は `firehosetos3example/year=2020/month=11/day=06/hour=05/` と評価されます。

ErrorOutputPrefix

```
firehosetos3erroroutputbase/!{firehose:random-string}/!{firehose:error-output-type}/!{timestamp:yyyy/MM/dd}/
```

`ErrorOutputPrefix` により、S3 バケットの直下に `firehosetos3erroroutputbase` という名前のベースフォルダが作成されます。式 `!{firehose:random-string}` は、`ztWxkdg3Thg` などの 11 文字のランダムな文字列として評価されます。失敗したレコードが配信される Amazon S3 オブジェクトの場所は、`firehosetos3erroroutputbase/ztWxkdg3Thg/processing-failed/2020/11/06/` と評価される可能性があります。

# Amazon OpenSearch Service におけるマルチテナントサーバーレスアーキテクチャの構築
<a name="build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service"></a>

*Tabby Ward、Nisha Gambhir (Amazon Web Services)*

## 概要
<a name="build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service-summary"></a>

Amazon OpenSearch Service は、ポピュラーなオープンソース検索および分析エンジンである Elasticsearch を簡単にデプロイ、運用、スケールするためのマネージド型サービスです。OpenSearch Service は、ログやメトリクスなどのストリーミングデータの自由なテキスト検索や、ほぼリアルタイムの取り込みやダッシュボードを提供します。

Software as a Service (SaaS) プロバイダーは、複雑さとダウンタイムを軽減しながら、スケーラブルかつセキュアな方法で顧客インサイトを得るなど、幅広いユースケースに対応するために、OpenSearch Service を頻繁に利用しています。

OpenSearch Service をマルチテナント環境で使用する場合、SaaS ソリューションのパーティショニング、隔離、デプロイ、および管理に影響を与えるさまざまな考慮事項が発生します。SaaS プロバイダーは、絶えず変化するワークロードに合わせて Elasticsearch クラスターを効果的にスケールする方法を検討する必要があります。また、階層化やノイズの多い隣接条件が、パーティショニングモデルにどのような影響を与えるかを考慮する必要があります。

このパターンでは、Elasticsearch コンストラクトを使用して、テナントデータを表現および隔離するために使用されるモデルを検討します。さらに、このパターンでは、マルチテナント環境で OpenSearch Service を使用してインデックス作成と検索を実演する例として、シンプルなサーバーレスリファレンスアーキテクチャに焦点を当てています。これにより、すべてのテナント間で同じインデックスを共有しながら、テナントのデータ分離を維持するプールデータパーティショニングのモデルが実現されます。このパターンでは、Amazon API Gateway、 AWS Amazon Simple Storage Service (Amazon S3) AWS Lambda、OpenSearch Service の各サービスを使用します。 Amazon API Gateway

プールモデルとその他のデータパーティショニングモデルの詳細については、「[追加情報](#build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service-additional)」セクションを参照してください。

## 前提条件と制限事項
<a name="build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service-prereqs"></a>

**前提条件**
+ アクティブな AWS アカウント
+ [AWS Command Line Interface (AWS CLI) バージョン 2.x](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)、macOS、Linux、または Windows にインストールおよび設定
+ [Python バージョン 3.9](https://www.python.org/downloads/release/python-3921/)
+ [pip3](https://pip.pypa.io/en/stable/) — Python ソースコードは .zip ファイルとして提供され、Lambda 関数にデプロイされます。コードをローカルで使用またはカスタマイズする場合は、次の手順に従ってソースコードを開発して再コンパイルします。

  1. Python スクリプトと同じディレクトリでコマンド `pip3 freeze > requirements.txt` を実行して `requirements.txt` ファイルを生成します。

  1. 依存関係 `pip3 install -r requirements.txt` をインストールします。

**制限事項**
+ このコードは Python で実行され、現在、他のプログラミング言語はサポートされていません。 
+ サンプルアプリケーションには、 AWS クロスリージョンまたはディザスタリカバリ (DR) サポートは含まれません。 
+ このパターンは、デモンストレーションのみを目的としています。実稼働環境では使用しないでください。

## アーキテクチャ
<a name="build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service-architecture"></a>

以下の図に、このパターンのアーキテクチャについて概要を示します。このアーキテクチャには、以下の項目が含まれます。
+ コンテンツのインデックス作成とクエリを実行する Lambda 
+ 検索を実行する OpenSearch Service 
+ ユーザーとの API インタラクションを提供する API Gateway
+ (インデックスが付いていない) 未処理のデータを保存するための Amazon S3
+ ログをモニタリングする Amazon CloudWatch
+ AWS Identity and Access Management テナントロールとポリシーを作成するための (IAM)

![\[高レベルのマルチテナントのサーバーレスアーキテクチャ\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/750196bb-03f6-4b6e-92cd-eb7141602547/images/1a8501e7-0776-4aca-aed3-28e3ada1d15d.png)


**自動化とスケール**

わかりやすく AWS CLI するために、このパターンでは を使用してインフラストラクチャをプロビジョニングし、サンプルコードをデプロイします。 CloudFormation テンプレートまたは AWS Cloud Development Kit (AWS CDK) スクリプトを作成して、パターンを自動化できます。

## ツール
<a name="build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service-tools"></a>

**AWS のサービス**
+ [AWS CLI](https://aws.amazon.com/cli/) は、コマンドラインシェルでコマンドを使用して AWS のサービス および リソースを管理するための統合ツールです。
+ [Lambda](https://aws.amazon.com/lambda/) はサーバーをプロビジョニングしたり管理しなくてもコードを実行できるコンピューティングサービスです。Lambda は必要に応じてコードを実行し、1 日あたり数個のリクエストから 1 秒あたり数千のリクエストまで自動的にスケールします。
+ [API Gateway](https://aws.amazon.com/api-gateway/) は、REST、HTTP、WebSocket APIsで作成、公開、保守、モニタリング、保護 AWS のサービス するための です。
+ [Amazon S3](https://aws.amazon.com/s3/) は、ウェブ上のどこからでも、任意の量のデータをいつでも保存して取得できるようにするオブジェクトストレージサービスです。
+ [OpenSearch Service](https://aws.amazon.com/opensearch-service/) は、大規模かつコスト効率の高い方法で、Elasticsearch のデプロイ、セキュリティ保護、実行を簡単に行えるフルマネージドサービスです。

**Code**

添付ファイルには、このパターンのサンプルが記載されています。具体的には次のとおりです。
+ `index_lambda_package.zip` — プールモデルを使用して OpenSearch Service のデータにインデックスを付けるための Lambda 関数。
+ `search_lambda_package.zip` — OpenSearch Service 内のデータを検索するための Lambda 関数。
+ `Tenant-1-data` — Tenant-1 の (インデックスが付いていない) 未処理のデータをサンプリングします。
+ `Tenant-2-data` — Tenant-2 の (インデックスが付いていない) 未処理のデータをサンプリングします。

**重要**  
このパターンのストーリーには、Unix、Linux、macOS 用にフォーマットされた AWS CLI コマンド例が含まれています。Windows の場合は、各行末のバックスラッシュ (\$1) Unix 連結文字をキャレット (^) に置き換えてください。

**注記**  
 AWS CLI コマンドで、角括弧 (<>) 内のすべての値を正しい値に置き換えます。

## エピック
<a name="build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service-epics"></a>

### S3 バケットの作成と設定
<a name="create-and-configure-an-s3-bucket"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| S3 バケットを作成する。 | に S3 バケットを作成します AWS リージョン。このバケットには、インデックスが付いていないサンプルアプリケーションのテナントデータが格納されます。　 名前空間はすべての によって共有されるため、S3 バケットの名前がグローバルに一意であることを確認してください AWS アカウント。S3 バケットを作成するには、次のように AWS CLI [create-bucket](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/create-bucket.html) コマンドを使用します。<pre>aws s3api create-bucket \<br />  --bucket <tenantrawdata> \<br />  --region <your-AWS-Region></pre>`tenantrawdata` は S3 バケット名です。(「[バケット命名ガイドライン](https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html)」に従った任意の一意の名前を使用できます)。 | クラウドアーキテクト、クラウド管理者 | 

### Elasticsearch クラスターの作成と設定
<a name="create-and-configure-an-elasticsearch-cluster"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| OpenSearch Service ドメインを作成します。 |  AWS CLI [create-elasticsearch-domain](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/es/create-elasticsearch-domain.html) コマンドを実行して、OpenSearch Service ドメインを作成します。<pre>aws es create-elasticsearch-domain \<br />  --domain-name vpc-cli-example \<br />  --elasticsearch-version 7.10 \<br />  --elasticsearch-cluster-config InstanceType=t3.medium.elasticsearch,InstanceCount=1 \<br />  --ebs-options EBSEnabled=true,VolumeType=gp2,VolumeSize=10 \<br />  --domain-endpoint-options "{\"EnforceHTTPS\": true}" \<br />  --encryption-at-rest-options "{\"Enabled\": true}" \<br />  --node-to-node-encryption-options "{\"Enabled\": true}" \<br />  --advanced-security-options "{\"Enabled\": true, \"InternalUserDatabaseEnabled\": true, \<br />    \"MasterUserOptions\": {\"MasterUserName\": \"KibanaUser\", \<br />    \"MasterUserPassword\": \"NewKibanaPassword@123\"}}" \<br />  --vpc-options "{\"SubnetIds\": [\"<subnet-id>\"], \"SecurityGroupIds\": [\"<sg-id>\"]}" \<br />  --access-policies "{\"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \ <br />    \"Principal\": {\"AWS\": \"*\" }, \"Action\":\"es:*\", \<br />    \"Resource\": \"arn:aws:es:<region>:<account-id>:domain\/vpc-cli-example\/*\" } ] }"</pre>テスト用ドメインであるため、インスタンス数は 1 に設定されています。ドメインの作成後は、詳細を変更できないため、`advanced-security-options` パラメータを使用してきめ細かいアクセス制御を有効にする必要があります。 このコマンドは、Kibana コンソールにログインできるマスターユーザー名 (`KibanaUser`) とパスワードを作成します。このドメインは仮想プライベートクラウド (VPC) の一部であるため、使用するアクセスポリシーを指定して、必ず Elasticsearch インスタンスにアクセスする必要があります。詳細については、 AWS ドキュメント[の「VPC 内での Amazon OpenSearch Service ドメインの起動](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-vpc.html)」を参照してください。 | クラウドアーキテクト、クラウド管理者 | 
| 踏み台ホストをセットアップします。 | Kibana コンソールにアクセスするための踏み台ホストとして、Amazon Elastic Compute Cloud (Amazon EC2) Windows インスタンスをセットアップします。Elasticsearch セキュリティグループは、Amazon EC2 セキュリティグループからのトラフィックを許可する必要があります。　 手順については、ブログ記事「[踏み台サーバーを使用して EC2 インスタンスへのネットワークアクセスを制御する](https://aws.amazon.com/blogs/security/controlling-network-access-to-ec2-instances-using-a-bastion-server/)」を参照してください。踏み台ホストがセットアップされ、インスタンスに関連付けられているセキュリティグループが利用可能になったら、 AWS CLI [authorize-security-group-ingress](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/authorize-security-group-ingress.html) コマンドを使用して Elasticsearch セキュリティグループにアクセス許可を追加して、Amazon EC2 (踏み台ホスト) セキュリティグループからのポート 443 を許可します。<pre>aws ec2 authorize-security-group-ingress \<br />  --group-id <SecurityGroupIdfElasticSearch> \ <br />  --protocol tcp \<br />  --port 443 \<br />  --source-group <SecurityGroupIdfBashionHostEC2></pre> | クラウドアーキテクト、クラウド管理者 | 

### Lambda 関数の作成と設定
<a name="create-and-configure-the-lam-index-function"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Lambda 実行ロールを作成する |  AWS CLI [create-role](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-role.html) コマンドを実行して、Lambda インデックス関数に AWS のサービス および リソースへのアクセスを許可します。<pre>aws iam create-role \<br />  --role-name index-lambda-role \<br />  --assume-role-policy-document file://lambda_assume_role.json</pre>ここで、`lambda_assume_role.json` は JSON ドキュメントで、以下のように Lambda 関数に `AssumeRole` 権限を付与します。<pre>{<br />     "Version": "2012-10-17",		 	 	 <br />     "Statement": [<br />         {<br />             "Effect": "Allow",<br />             "Principal": {<br />                 "Service": "lambda.amazonaws.com"<br />               },<br />             "Action": "sts:AssumeRole"<br />         }<br />     ]<br /> }</pre> | クラウドアーキテクト、クラウド管理者 | 
| マネージドポリシーを Lambda ロールにアタッチする |  AWS CLI [attach-role-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/attach-role-policy.html) コマンドを実行して、前のステップで作成したロールに管理ポリシーをアタッチします。これらの 2 つのポリシーは、Elastic Network Interface を作成し、CloudWatch Logs にログを書き込む権限をロールに与えます。<pre>aws iam attach-role-policy \<br />  --role-name index-lambda-role \<br />  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole<br /><br />aws iam attach-role-policy \<br />  --role-name index-lambda-role \<br />  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole </pre> | クラウドアーキテクト、クラウド管理者 | 
| Lambda インデックス関数に、S3 オブジェクトの読み取り権限を与えるポリシーを作成する |  AWS CLI [create-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-policy.html) コマンドを に実行して、Lambda インデックス関数に S3 バケット内のオブジェクトを読み取る`s3:GetObject`アクセス許可を付与します。<pre>aws iam create-policy \<br />  --policy-name s3-permission-policy \<br />  --policy-document file://s3-policy.json</pre>ファイル `s3-policy.json` は次に示す JSON ドキュメントで、S3 オブジェクトへの読み取りアクセスを許可する `s3:GetObject` 権限を付与します。S3 バケットを作成するときに別の名前を使用した場合は、`Resource ` セクションで正しいバケット名を指定します。<pre>{<br />    "Version": "2012-10-17",		 	 	 <br />    "Statement": [<br />        {<br />           "Effect": "Allow",<br />           "Action": "s3:GetObject",<br />           "Resource": "arn:aws:s3:::<tenantrawdata>/*"<br />        }<br />    ]<br />}</pre> | クラウドアーキテクト、クラウド管理者 | 
| Amazon S3 のアクセス許可ポリシーを Lambda 実行ロールにアタッチする |  AWS CLI [attach-role-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/attach-role-policy.html) コマンドを実行して、前のステップで作成した Amazon S3 アクセス許可ポリシーを Lambda 実行ロールにアタッチします。<pre>aws iam attach-role-policy \<br />  --role-name index-lambda-role \<br />  --policy-arn <PolicyARN></pre>ここで、`PolicyARN` は Amazon S3 のアクセス許可ポリシーの Amazon リソースネーム (ARN) です。前のコマンド出力からこの値を取得できます。 | クラウドアーキテクト、クラウド管理者 | 
| Lambda インデックス関数の作成 |  AWS CLI [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html) コマンドを実行して、OpenSearch Service にアクセスする Lambda インデックス関数を作成します。<pre>aws lambda create-function \<br />  --function-name index-lambda-function \<br />  --zip-file fileb://index_lambda_package.zip \<br />  --handler lambda_index.lambda_handler \<br />  --runtime python3.9 \<br />  --role "arn:aws:iam::account-id:role/index-lambda-role" \<br />  --timeout 30 \<br />  --vpc-config "{\"SubnetIds\": [\"<subnet-id1\>", \"<subnet-id2>\"], \<br />    \"SecurityGroupIds\": [\"<sg-1>\"]}"</pre> | クラウドアーキテクト、クラウド管理者 | 
| Amazon S3 が Lambda インデックス関数を呼び出すことを許可する |  AWS CLI [add-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-permission.html) コマンドを実行して、Lambda インデックス関数を呼び出すアクセス許可を Amazon S3 に付与します。<pre>aws lambda add-permission \<br />  --function-name index-lambda-function \<br />  --statement-id s3-permissions \<br />  --action lambda:InvokeFunction \<br />  --principal s3.amazonaws.com \<br />  --source-arn "arn:aws:s3:::<tenantrawdata>" \<br />  --source-account "<account-id>" </pre> | クラウドアーキテクト、クラウド管理者 | 
| Amazon S3 イベントの Lambda トリガーを追加する | Amazon S3 `ObjectCreated`イベントが検出されたときに Lambda インデックス関数に通知を送信するには、 AWS CLI [put-bucket-notification-configuration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3api/put-bucket-notification-configuration.html) コマンドを実行します。インデックス関数は、オブジェクトが S3 バケットにアップロードされるたびに実行されます。　 <pre>aws s3api put-bucket-notification-configuration \<br />  --bucket <tenantrawdata> \<br />  --notification-configuration file://s3-trigger.json</pre>ファイル `s3-trigger.json` は現在のフォルダにある JSON ドキュメントで、Amazon S3 `ObjectCreated` イベントが発生したときにリソースポリシーを Lambda 関数に追加します。 | クラウドアーキテクト、クラウド管理者 | 

### Lambda 検索関数の作成と設定
<a name="create-and-configure-the-lam-search-function"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Lambda 実行ロールを作成する |  AWS CLI [create-role](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-role.html) コマンドを実行して、Lambda 検索関数に AWS のサービス および リソースへのアクセスを許可します。<pre>aws iam create-role \<br />  --role-name search-lambda-role \<br />  --assume-role-policy-document file://lambda_assume_role.json</pre>ここで、`lambda_assume_role.json` は現在フォルダ内にある JSON ドキュメントで、以下のように、Lambda 関数に `AssumeRole` の権限を付与します。<pre>{<br />     "Version": "2012-10-17",		 	 	 <br />     "Statement": [<br />         {<br />             "Effect": "Allow",<br />             "Principal": {<br />                 "Service": "lambda.amazonaws.com"<br />               },<br />             "Action": "sts:AssumeRole"<br />         }<br />     ]<br /> }</pre> | クラウドアーキテクト、クラウド管理者 | 
| マネージドポリシーを Lambda ロールにアタッチする |  AWS CLI [attach-role-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/attach-role-policy.html) コマンドを実行して、前のステップで作成したロールに管理ポリシーをアタッチします。これらの 2 つのポリシーは、Elastic Network Interface を作成し、CloudWatch Logs にログを書き込む権限をロールに与えます。<pre>aws iam attach-role-policy \<br />  --role-name search-lambda-role \<br />  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole<br /><br />aws iam attach-role-policy \<br />  --role-name search-lambda-role \<br />  --policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole </pre> | クラウドアーキテクト、クラウド管理者 | 
| Lambda 検索関数を作成する |  AWS CLI [create-function](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/create-function.html) コマンドを実行して、OpenSearch Service にアクセスする Lambda 検索関数を作成します。<pre>aws lambda create-function \<br />  --function-name search-lambda-function \<br />  --zip-file fileb://search_lambda_package.zip \<br />  --handler lambda_search.lambda_handler \<br />  --runtime python3.9 \<br />  --role "arn:aws:iam::account-id:role/search-lambda-role" \<br />  --timeout 30 \<br />  --vpc-config "{\"SubnetIds\": [\"<subnet-id1\>", \"<subnet-id2>\"], \<br />    \"SecurityGroupIds\": [\"<sg-1>\"]}"</pre> | クラウドアーキテクト、クラウド管理者 | 

### IAM ロールを作成および設定
<a name="create-and-configure-tenant-roles"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| テナントの IAM ロールを作成する |  AWS CLI [create-role](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-role.html) コマンドを実行して、検索機能のテストに使用される 2 つのテナントロールを作成します。<pre>aws iam create-role \<br />  --role-name Tenant-1-role \<br />  --assume-role-policy-document file://assume-role-policy.json</pre><pre>aws iam create-role \<br />  --role-name Tenant-2-role \<br />  --assume-role-policy-document file://assume-role-policy.json</pre>この `assume-role-policy.json` ファイルは、現在のフォルダ内にある JSON ドキュメントで、Lambda 実行ロールに `AssumeRole` のアクセス権限を付与します。<pre>{<br />    "Version": "2012-10-17",		 	 	 <br />    "Statement": [<br />        {<br />            "Effect": "Allow",<br />            "Principal": {<br />                 "AWS": "<Lambda execution role for index function>",<br />                 "AWS": "<Lambda execution role for search function>"<br />             },<br />            "Action": "sts:AssumeRole"<br />        }<br />    ]<br />}</pre> | クラウドアーキテクト、クラウド管理者 | 
| 新規 IAM ポリシーを作成する |  AWS CLI [create-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-policy.html) コマンドを実行して、Elasticsearch オペレーションへのアクセスを許可するテナントポリシーを作成します。<pre>aws iam create-policy \<br />  --policy-name tenant-policy \<br />  --policy-document file://policy.json</pre>この `policy.json` ファイルは、現在のフォルダ内の JSON ドキュメントで、Elasticsearch にアクセス権限を付与します。<pre>{<br />    "Version": "2012-10-17",		 	 	 <br />    "Statement": [<br />        {<br />            "Effect": "Allow",<br />            "Action": [<br />                "es:ESHttpDelete",<br />                "es:ESHttpGet",<br />                "es:ESHttpHead",<br />                "es:ESHttpPost",<br />                "es:ESHttpPut",<br />                "es:ESHttpPatch"<br />            ],<br />            "Resource": [<br />                "<ARN of Elasticsearch domain created earlier>"<br />            ]<br />        }<br />    ]<br />}</pre> | クラウドアーキテクト、クラウド管理者 | 
| テナント IAM ポリシーをテナントロールにアタッチする |  AWS CLI [attach-role-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/attach-role-policy.html) コマンドを実行して、前のステップで作成した 2 つのテナントロールにテナント IAM ポリシーをアタッチします。<pre>aws iam attach-role-policy \<br />  --policy-arn arn:aws:iam::account-id:policy/tenant-policy \<br />  --role-name Tenant-1-role<br /><br />aws iam attach-role-policy \<br />  --policy-arn arn:aws:iam::account-id:policy/tenant-policy \<br />  --role-name Tenant-2-role</pre>ポリシー ARN は、前のステップの出力から取得されます。 | クラウドアーキテクト、クラウド管理者 | 
| Lambda にロールを引き受ける権限を付与する IAM ポリシーを作成する |  AWS CLI [create-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-policy.html) コマンドを実行して、Lambda がテナントロールを引き受けるポリシーを作成します。<pre>aws iam create-policy \<br />  --policy-name assume-tenant-role-policy \<br />  --policy-document file://lambda_policy.json</pre>この `lambda_policy.json` ファイルは、現在のフォルダ内にある JSON ドキュメントで、`AssumeRole` にアクセス権限を付与します。<pre>{<br />    "Version": "2012-10-17",		 	 	 <br />    "Statement": [<br />       {<br />            "Effect": "Allow",<br />            "Action":  "sts:AssumeRole",<br />            "Resource": "<ARN of tenant role created earlier>"<br />       }<br />    ]<br />}</pre>`Resource` には、ワイルドカード文字を使用すると、テナントごとに新しいポリシーを作成する必要がなくなります。 | クラウドアーキテクト、クラウド管理者 | 
| Lambda インデックスロールに Amazon S3 へのアクセスを許可する IAM ポリシーを作成する |  AWS CLI [create-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/create-policy.html) コマンドを実行して、S3 バケット内のオブジェクトにアクセスするアクセス許可を Lambda インデックスロールに付与します。<pre>aws iam create-policy \<br />  --policy-name s3-permission-policy \<br />  --policy-document file://s3_lambda_policy.json</pre>この `s3_lambda_policy.json` ファイルは、現在のフォルダ内にある JSON ポリシードキュメントです。<pre>{<br />    "Version": "2012-10-17",		 	 	 <br />    "Statement": [<br />        {<br />            "Effect": "Allow",<br />            "Action": "s3:GetObject",<br />            "Resource": "arn:aws:s3:::tenantrawdata/*"<br />        }<br />    ]<br />}</pre> | クラウドアーキテクト、クラウド管理者 | 
| ポリシーを Lambda 実行ロールにアタッチする |  AWS CLI [attach-role-policy](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/iam/attach-role-policy.html) コマンドを実行して、前のステップで作成したポリシーを、前に作成した Lambda インデックスと検索実行ロールにアタッチします。<pre>aws iam attach-role-policy \<br />  --policy-arn arn:aws:iam::account-id:policy/assume-tenant-role-policy \<br />  --role-name index-lambda-role<br /><br />aws iam attach-role-policy \<br />  --policy-arn arn:aws:iam::account-id:policy/assume-tenant-role-policy \<br />  --role-name search-lambda-role<br /><br />aws iam attach-role-policy \<br />  --policy-arn arn:aws:iam::account-id:policy/s3-permission-policy \<br />  --role-name index-lambda-role</pre>ポリシー ARN は、前のステップの出力から取得されます。 | クラウドアーキテクト、クラウド管理者 | 

### 検索ドメインを作成して設定する
<a name="create-and-configure-a-search-api"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| API ゲートウェイで REST API を作成する |  AWS CLI [create-rest-api](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/apigateway/create-rest-api.html) コマンドを実行して REST API リソースを作成します。<pre>aws apigateway create-rest-api \<br />  --name Test-Api \<br />  --endpoint-configuration "{ \"types\": [\"REGIONAL\"] }"</pre>エンドポイント設定タイプでは、`REGIONAL` ではなく `EDGE` を指定して、特定の AWS リージョンではなくエッジロケーションを使用できます。コマンド出力の `id` フィールドの値に注目してください。これは、以降のコマンドで使用する API ID です。 | クラウドアーキテクト、クラウド管理者 | 
| API リソースの検索を作成する | API リソースを検索し、Lambda 検索関数をリソース名 `search` で起動します。(Lambda インデックス関数の API は、オブジェクトが S3 バケットにアップロードされると自動的に実行されるため、作成する必要はありません)。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service.html) | クラウドアーキテクト、クラウド管理者 | 
| 検索 API の GET メソッドを作成する |  AWS CLI [put-method](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/apigateway/put-method.html) コマンドを実行して、検索 API の`GET `メソッドを作成します。<pre>aws apigateway put-method \<br />  --rest-api-id <API-ID> \<br />  --resource-id <ID from the previous command output> \<br />  --http-method GET \<br />  --authorization-type "NONE" \<br />  --no-api-key-required</pre>`resource-id` では、`create-resource` コマンドの ID を指定します。 | クラウドアーキテクト、クラウド管理者 | 
| 検索 API のメソッドレスポンスを作成する | put AWS CLI [put-method-response](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/apigateway/put-method-response.html) コマンドを実行して、検索 API のメソッドレスポンスを追加します。<pre>aws apigateway put-method-response \<br />  --rest-api-id <API-ID> \<br />  --resource-id  <ID from the create-resource command output> \<br />  --http-method GET \<br />  --status-code 200 \<br />  --response-models "{\"application/json\": \"Empty\"}"</pre>`resource-id` には、前の `create-resource` コマンドから出力された ID を指定します。 | クラウドアーキテクト、クラウド管理者 | 
| 検索 API のプロキシ Lambda 統合を設定する |  AWS CLI [put-integration](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/apigateway/put-integration.html) コマンドを実行して、Lambda 検索関数との統合を設定します。<pre>aws apigateway put-integration \<br />  --rest-api-id <API-ID> \<br />  --resource-id  <ID from the create-resource command output> \<br />  --http-method GET \<br />  --type AWS_PROXY \<br />  --integration-http-method GET \<br />  --uri arn:aws:apigateway:region:lambda:path/2015-03-31/functions/arn:aws:lambda:<region>:<account-id>:function:<function-name>/invocations</pre>`resource-id` では、前の `create-resource` コマンドの ID を指定します。 | クラウドアーキテクト、クラウド管理者 | 
| API ゲートウェイに Lambda 検索関数を呼び出す権限を付与する |  AWS CLI [add-permission](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/add-permission.html) コマンドを実行して、検索関数を使用するアクセス許可を API Gateway に付与します。<pre>aws lambda add-permission \<br />  --function-name <function-name> \<br />  --statement-id apigateway-get \<br />  --action lambda:InvokeFunction \<br />  --principal apigateway.amazonaws.com \<br />  --source-arn "arn:aws:execute-api:<region>:<account-id>:api-id/*/GET/search</pre>`search` ではなく別の API リソース名を使用している場合は、`source-arn` パスを変更します。 | クラウドアーキテクト、クラウド管理者 | 
| 検索 API をデプロイする |  AWS CLI [create-deployment](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/apigateway/create-deployment.html) コマンドを実行して、 という名前のステージリソースを作成します`dev`。<pre>aws apigateway create-deployment \<br />  --rest-api-id <API-ID> \<br />  --stage-name dev</pre>API を更新する場合は、同じ AWS CLI コマンドを使用して同じステージに再デプロイできます。 | クラウドアーキテクト、クラウド管理者 | 

### Kibana ロールの作成と設定
<a name="create-and-configure-kibana-roles"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Kibana コンソールにログインする | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service.html) | クラウドアーキテクト、クラウド管理者 | 
| Kibana ロールの作成と設定 | データを隔離し、あるテナントが別のテナントのデータを取得できないようにするには、ドキュメントセキュリティを使用する必要があります。ドキュメントセキュリティを使用すると、テナントがテナント ID を含むドキュメントのみにアクセスできるようになります。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service.html) | クラウドアーキテクト、クラウド管理者 | 
| ユーザーをロールにマッピングします。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service.html)テナントのオンボーディング時に、テナントロールと Kibana ロールの作成を自動化することをお勧めします。 | クラウドアーキテクト、クラウド管理者 | 
| テナント-データ インデックスを作成します。 | ナビゲーションペインの **[管理]** で **[開発ツール]** を選択し、次のコマンドを実行します。このコマンドは、`TenantId` プロパティのマッピングを定義する `tenant-data` インデックスを作成します。<pre>PUT /tenant-data<br />{<br />  "mappings": {<br />    "properties": {<br />      "TenantId": { "type": "keyword"}<br />    }<br />  }<br />}</pre> | クラウドアーキテクト、クラウド管理者 | 

### Amazon S3 と の VPC エンドポイントを作成する AWS STS
<a name="create-vpc-endpoints-for-s3-and-sts"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Amazon S3 の VPC エンドポイントを作成する |  AWS CLI [create-vpc-endpoint](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/create-vpc-endpoint.html) コマンドを実行して、Amazon S3 の VPC エンドポイントを作成します。エンドポイントにより、VPC の Lambda インデックス関数が Amazon S3 にアクセスできるようになります。<pre>aws ec2 create-vpc-endpoint \<br />  --vpc-id <VPC-ID> \<br />  --service-name com.amazonaws.us-east-1.s3 \<br />  --route-table-ids <route-table-ID></pre>`vpc-id` には、Lambda インデックス関数に使用している VPC を指定します。`service-name` には、Amazon S3 エンドポイントの正しい URL を使用します。`route-table-ids` には、VPC エンドポイントに関連付けられているルートテーブルを指定します。 | クラウドアーキテクト、クラウド管理者 | 
| の VPC エンドポイントを作成します AWS STS。 |  AWS CLI [create-vpc-endpoint](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/ec2/create-vpc-endpoint.html) コマンドを実行して、 AWS Security Token Service () の VPC エンドポイントを作成しますAWS STS。エンドポイントにより、VPC の Lambda インデックス関数と Lambda 検索関数が AWS STSにアクセスできるようになります。関数は、IAM ロールを引き受ける AWS STS ときに を使用します。<pre>aws ec2 create-vpc-endpoint \<br />  --vpc-id <VPC-ID> \<br />  --vpc-endpoint-type Interface \<br />  --service-name com.amazonaws.us-east-1.sts \<br />  --subnet-id <subnet-ID> \<br />  --security-group-id <security-group-ID></pre>`vpc-id` には、Lambda インデックス関数と Lambda 検索関数に使用している VPC を指定します。`subnet-id` には、このエンドポイントを作成するサブネットを指定します。`security-group-id` には、このエンドポイントを関連付けるセキュリティグループを指定します。(Lambda が使用するセキュリティグループと同じである可能性があります)。　 | クラウドアーキテクト、クラウド管理者 | 

### マルチテナンシーとデータ隔離のテスト
<a name="test-multi-tenancy-and-data-isolation"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| インデックス関数と検索関数の Python ファイルを更新する | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service.html)Elasticsearch エンドポイントは OpenSearch Service コンソールの **[概要]** タブから取得できます。これは、`<AWS-Region>.es.amazonaws.com` という形式です。 | クラウドアーキテクト、アプリ開発者 | 
| Lambda コードを作成する | Python ファイルに加えた変更で Lambda コードを更新するには、 AWS CLI [update-function-code](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/lambda/update-function-code.html) コマンドを使用します。<pre>aws lambda update-function-code \<br />  --function-name index-lambda-function \<br />  --zip-file fileb://index_lambda_package.zip<br /><br />aws lambda update-function-code \<br />  --function-name search-lambda-function \<br />  --zip-file fileb://search_lambda_package.zip</pre> | クラウドアーキテクト、アプリ開発者 | 
| S3 バケットに未処理のデータをアップロードする | Tenant-1 および Tenant-2 オブジェクトのデータを`tenantrawdata`バケットにアップロードするには、 AWS CLI [cp](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/s3/cp.html) コマンドを使用します (この目的のために作成した S3 バケットの名前を指定します）。<pre>aws s3 cp tenant-1-data s3://tenantrawdata<br />aws s3 cp tenant-2-data s3://tenantrawdata</pre>S3 バケットは、データがアップロードされるたびに Lambda インデックス関数を実行するように設定されているため、ドキュメントには Elasticsearch でインデックスが付けられます。 | クラウドアーキテクト、クラウド管理者 | 
| Kibana コンソールからデータを検索する | Kibana コンソールで、以下のクエリを実行します。<pre>GET tenant-data/_search</pre>このクエリは、Elasticsearch でインデックスに登録されているすべてのドキュメントを表示します。この場合、Tenant-1 と Tenant-2 の 2 つのドキュメントが別々に表示されます。 | クラウドアーキテクト、クラウド管理者 | 
| API ゲートウェイ から検索 API をテストする | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service.html)画面の図については、「[追加情報](#build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service-additional)」セクションを参照してください。 | クラウドアーキテクト、アプリ開発者 | 
| リソースをクリーンアップします。 | アカウントへの追加料金が発生しないように、作成したすべてのリソースをクリーンアップします。 | AWS DevOps、クラウドアーキテクト、クラウド管理者 | 

## 関連リソース
<a name="build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service-resources"></a>
+ [AWS SDK for Python (Boto)](https://aws.amazon.com/sdk-for-python/)
+ [AWS Lambda ドキュメント](https://docs.aws.amazon.com/lambda/)
+ [API Gateway ドキュメント](https://docs.aws.amazon.com/apigateway/)
+ 「[Amazon S3 ドキュメント](https://docs.aws.amazon.com/s3/)」
+ 「[Amazon OpenSearch Service](https://docs.aws.amazon.com/elasticsearch-service/)」
  + 「[Amazon OpenSearch Service のきめ細かなアクセスコントロール](https://docs.amazonaws.cn/en_us/elasticsearch-service/latest/developerguide/fgac.html)」
  + 「[Amazon OpenSearch Service を用いて検索アプリケーションを作成する](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/search-example.html)」
  + 「[VPC 内で Amazon OpenSearch Service ドメインを起動する](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/es-vpc.html)」

## 追加情報
<a name="build-a-multi-tenant-serverless-architecture-in-amazon-opensearch-service-additional"></a>

**データパーティショニングのモデル**

マルチテナントシステムで使用される一般的なデータパーティショニングモデルには、サイロ、プール、ハイブリッドの 3 つがあります。選択するモデルは、環境のコンプライアンス、ノイジーネイバー、運用、隔離の要件によって異なります。

サイロモデル

サイロモデルでは、各テナントのデータをテナントデータが混在しない個別のストレージエリアに保存します。OpenSearch Service のサイロモデルを実装するには、「テナントごとのドメイン」と「テナントごとのインデックス」という 2 つの方法があります。
+ **テナントごとのドメイン** — テナントごとに個別の OpenSearch Service ドメイン (Elasticsearch クラスターと同義) を使用できます。各テナントを独自のドメインに配置することで、データをスタンドアロンコンストラクトに配置することに関連するすべてのメリットが得られます。しかし、このアプローチでは、管理とアジリティの面で課題が生じています。隔離型であるため、テナントの運営状況や活動を集計して評価することが難しくなっています。これはコストのかかるオプションであり、各 OpenSearch Service ドメインには、実稼働環境のワークロード用に最低でも 3 つのマスターノードと 2 つのデータノードが必要です。

![\[マルチテナントのサーバーレスアーキテクチャのための「テナントごとのドメイン」サイロモデル\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/750196bb-03f6-4b6e-92cd-eb7141602547/images/c2195f82-e5ed-40bb-b76a-3b0210bf1254.png)


 
+ **テナントごとのインデックス** — OpenSearch Service クラスター内の個別のインデックスにテナントデータを配置できます。このアプローチでは、テナント識別子をインデックス名にあらかじめ付けておくことで、インデックスを作成して名前を付けるときにテナント識別子を使用できます。テナントごとにインデックスを付けるアプローチでは、テナントごとに完全に分離したクラスターを導入しなくても、サイロの目標を達成できます。　 しかし、インデックスの数が増えると、このアプローチではより多くのシャードが必要になり、マスターノードがより多くの割り当てとリバランスを処理する必要があるため、メモリの負荷がかかる可能性があります。

![\[マルチテナントのサーバーレスアーキテクチャのための「テナントごとのインデックス」サイロモデル\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/750196bb-03f6-4b6e-92cd-eb7141602547/images/354a9463-25bb-422b-84de-d4875a7c8ea2.png)


 

**サイロモデルでの隔離** — サイロモデルでは、IAM ポリシーを使用して、各テナントのデータを保持するドメインまたはインデックスを隔離します。これらのポリシーは、あるテナントが別のテナントのデータにアクセスすることを防止します。サイロ隔離モデルを実装するには、テナントリソースへのアクセスを制御するリソースベースのポリシーを作成できます。通常、これはドメインアクセスポリシーで、Elasticsearch インデックスや API など、プリンシパルがドメインのサブリソースに対して実行できるアクションを指定します。IAM アイデンティティベースのポリシーでは、OpenSearch Service 内のドメイン、インデックス、または API に対して*許可*または*拒否する*アクションを指定できます。IAM ポリシーの `Action` 要素は、ポリシーによって許可または拒否される特定のアクションを記述し、`Principal ` 要素は、影響を受けるアカウント、ユーザー、またはロールを指定します。

以下のサンプルポリシーは、`es:*` で指定された `tenant-1` ドメイン上のサブリソースへの完全なアクセス権を Tenant-1 にのみ付与します。`Resource` 要素の末尾に付いた `/*` は重要であり、このポリシーがドメイン自体ではなく、ドメインのサブリソースに適用されることを示します。このポリシーが有効な場合、テナントは新しいドメインの作成や、既存のドメイン設定を変更できません

```
{
   "Version": "2012-10-17",		 	 	 
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": {
            "AWS": "arn:aws:iam::<aws-account-id>:user/Tenant-1"
         },
         "Action": "es:*",
         "Resource": "arn:aws:es:<Region>:<account-id>:domain/tenant-1/*"
      }
   ]
}
```

「インデックスごとのテナント」サイロモデルを実装するには、このサンプルポリシーを変更して、インデックス名を指定することで、Tenant-1 を指定された 1 つ以上のインデックスにさらに制限する必要があります。次のサンプルポリシーでは、Tenant-1 を `tenant-index-1` インデックスに制限しています。 

```
{
   "Version": "2012-10-17",		 	 	 
   "Statement": [
      {
         "Effect": "Allow",
         "Principal": {
            "AWS": "arn:aws:iam::123456789012:user/Tenant-1"
         },
         "Action": "es:*",
         "Resource": "arn:aws:es:<Region>:<account-id>:domain/test-domain/tenant-index-1/*"
      }
   ]
}
```

*プールモデル*

プールモデルでは、すべてのテナントデータが同じドメイン内のインデックスに保存されます。　 テナント識別子はデータ (ドキュメント) に含まれ、パーティションキーとして使用されるため、どのデータがどのテナントに属しているか判断できます。このモデルでは、管理オーバーヘッドが削減されます。プールインデックスの操作と管理は、複数のインデックスを管理するよりも容易で効率的です。しかし、テナントデータが同じインデックスに混在しているため、サイロモデルが提供する自然なテナント隔離が失われます。このアプローチでは、ノイジーネイバー効果によりパフォーマンスが低下する可能性もあります。

![\[マルチテナントのサーバーレスアーキテクチャのためのプールモデル\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/750196bb-03f6-4b6e-92cd-eb7141602547/images/c2c3bb0f-6ccd-47a7-ab67-e7f3f8c7f289.png)


 

**プールモデルでのテナント隔離** — 一般的に、テナント隔離をプールモデルに実装するのは困難です。サイロモデルで使用されている IAM メカニズムでは、ドキュメントに保存されているテナント ID に基づいて隔離を記述することはできません。

代わりに、Open Distro for Elasticsearch で提供される[きめ細かなアクセス制御](https://docs.aws.amazon.com/elasticsearch-service/latest/developerguide/fgac.html) (FGAC) サポートを使用する方法があります。FGAC では、インデックス、ドキュメント、またはフィールドレベルでアクセス許可を制御できます。　 FGAC は、リクエストごとに、ユーザーの認証情報を評価し、ユーザーを認証するか、アクセスを拒否します。FGAC がユーザーを認証すると、そのユーザーにマッピングされているすべてのロールを取得し、アクセス許可のセット一式を使用してリクエストの処理方法を決定します。 

プールされたモデルで必要な隔離を実現するには、「[ドキュメントレベルのセキュリティ](https://opendistro.github.io/for-elasticsearch-docs/docs/security/access-control/document-level-security/)」を使用できます。これにより、ロールをインデックス内のドキュメントのサブセットに制限できます。以下のサンプルロールは、クエリを Tenant-1 に制限します。このロールを Tenant-1 に適用することで、必要な隔離を実現できます。　 

```
{
   "bool": {
     "must": {
       "match": {
         "tenantId": "Tenant-1"
       }
     }
   }
 }
```

*ハイブリッドモデル*

ハイブリッドモデルでは、同じ環境でサイロモデルとプールモデルを組み合わせて、各テナントレイヤー (無料、標準、プレミアム階層など) に独自のエクスペリエンスを提供します。各層は、プールモデルで使用されているのと同じセキュリティプロファイルに従います。

 

![\[マルチテナントのサーバーレスアーキテクチャのためのハイブリッドモデル\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/750196bb-03f6-4b6e-92cd-eb7141602547/images/e7def98a-38ef-435a-9881-7e95ae4d4940.png)


**ハイブリッドモデルでのテナント隔離** — ハイブリッドモデルでは、ドキュメントレベルで FGAC セキュリティモデルを使用することでテナントを隔離できるプールモデルと同じセキュリティプロファイルに従います。この戦略はクラスター管理を簡素化し、アジリティを提供しますが、アーキテクチャの他の側面が複雑になります。例えば、どのモデルを各テナントに関連付けるか決めるには、コードをさらに複雑化する必要があります。また、単一テナントのクエリによってドメイン全体が飽和状態になり、他のテナントのエクスペリエンスが低下しないようにする必要があります。 

**API ゲートウェイでのテスト**

*Tenant-1 クエリのテストウィンドウ*

![\[Tenant-1 クエリのテストウィンドウ\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/750196bb-03f6-4b6e-92cd-eb7141602547/images/a6757d3f-977a-4ecc-90cb-83ab7f1c3588.png)


Tenant-2 クエリのテストウィンドウ

 

![\[Tenant-2 クエリのテストウィンドウ\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/750196bb-03f6-4b6e-92cd-eb7141602547/images/31bfd656-33ca-4750-b6e6-da4d703c2071.png)


## アタッチメント
<a name="attachments-750196bb-03f6-4b6e-92cd-eb7141602547"></a>

このドキュメントに関連する追加コンテンツにアクセスするには、次のファイルを解凍してください。「[attachment.zip](samples/p-attach/750196bb-03f6-4b6e-92cd-eb7141602547/attachments/attachment.zip)」

# AWS CDK と TypeScript を使用してマルチスタックのアプリケーションをデプロイする
<a name="deploy-multiple-stack-applications-using-aws-cdk-with-typescript"></a>

*Dr. Rahul Sharad Gaikwad、Amazon Web Services*

## 概要
<a name="deploy-multiple-stack-applications-using-aws-cdk-with-typescript-summary"></a>

このパターンは、AWS Cloud Development Kit (AWS CDK) と TypeScript を使用して、Amazon Web Services (AWS) にアプリケーションをデプロイするための段階的なアプローチを示しています。例として、このパターンはサーバーレスのリアルタイム分析アプリケーションをデプロイします。

このパターンはネストされたスタックアプリケーションをビルドしてデプロイします。親の AWS CloudFormation スタックは、子スタックまたはネストされたスタックを呼び出します。 各子スタックは、CloudFormation スタックで定義されている AWS リソースをビルドしてデプロイします。コマンドラインインターフェイス (CLI) コマンド `cdk` である AWS CDK ツールキットは、CloudFormation スタックの主要なインターフェイスです。

## 前提条件と制限事項
<a name="deploy-multiple-stack-applications-using-aws-cdk-with-typescript-prereqs"></a>

**前提条件**
+ アクティブな AWS アカウント
+ 既存の仮想プライベートクラウド (VPC) とサブネット
+ インストールおよび設定済みの AWS CDK Toolkit。
+ 管理者権限とアクセスキーセットを持つユーザー。
+ Node.js
+ AWS コマンドラインインターフェイス (AWS CLI)

**制限事項**
+ AWS CDK は AWS CloudFormation を使用しているため、AWS CDK アプリケーションには CloudFormation サービスクォータが適用されます。詳細については、「[AWS CloudFormation のクォータ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html)」を参照してください。

**製品バージョン**

このパターンは、以下のツールとバージョンを使用して構築され、テストされています。
+ AWS CDK ツールキット 1.83.0
+ Node.js 14.13.0
+ npm 7.0.14

このパターンは、AWS CDK または npm のどのバージョンでも機能するはずです。Node.js のバージョン 13.0.0 から 13.6.0 は AWS CDK と互換性がないことに注意してください。

## アーキテクチャ
<a name="deploy-multiple-stack-applications-using-aws-cdk-with-typescript-architecture"></a>

**ターゲットテクノロジースタック**
+ AWS Amplify Console
+ Amazon API Gateway
+ AWS CDK
+ Amazon CloudFront
+ Amazon Cognito
+ Amazon DynamoDB
+ Amazon Data Firehose
+ Amazon Kinesis Data Streams
+ AWS Lambda
+ Amazon Simple Storage Service (Amazon S3)

**ターゲットアーキテクチャ**

次の図は、AWS CDK と TypeScript を使用したマルチスタックのアプリケーションのデプロイを示しています。

![\[VPC のスタックアーキテクチャです。親スタックと、リソースを含む 2 つの子スタックがあります。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/0ac29a11-1362-4084-92ed-6b85205763ca/images/8f92e86a-aa3d-4f8a-9b11-b92c52a7226c.png)


 

次の図は、サンプルサーバーレスリアルタイムアプリケーションのアーキテクチャを示します。

![\[リージョンのアプリケーションアーキテクチャ。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/0ac29a11-1362-4084-92ed-6b85205763ca/images/2df00faf-f871-4aec-9655-19ba2eb14cf8.png)


 

## ツール
<a name="deploy-multiple-stack-applications-using-aws-cdk-with-typescript-tools"></a>

**ツール**
+ [AWS Amplify Console](https://docs.aws.amazon.com/amplify/latest/userguide/welcome.html) は、フルスタックのウェブおよびモバイルアプリケーションを AWS にデプロイするためのコントロールセンターです。Amplify コンソールホスティングは、継続的なデプロイでフルスタックのサーバーレス Web アプリをホストするための Git ベースのワークフローを提供します。Admin UI は、フロントエンドのウェブ開発者やモバイル開発者が AWS コンソールの外部でアプリケーションのバックエンドを作成および管理するためのビジュアルインターフェイスです。
+ [Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html) は、あらゆる規模の REST、HTTP、WebSocket API を作成、公開、管理、モニタリング、保護するための AWS のサービスです。
+ [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/latest/guide/home.html) は、AWS クラウドインフラストラクチャをコードで定義してプロビジョニングするのに役立つソフトウェア開発フレームワークです。
+ [AWS CDK Toolkit](https://docs.aws.amazon.com/cdk/latest/guide/cli.html) は、AWS CDK アプリとの対話に役立つコマンドラインのクラウド開発キットです。`cdk` CLI コマンドは、AWS CDK アプリケーションを操作するための主要なツールです。アプリを実行し、定義したアプリケーションモデルを調べ、AWS CDK によって生成された AWS CloudFormation テンプレートを作成してデプロイします。
+ [Amazon CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html) は、.html、.css、.js、画像ファイルなどの静的および動的 Web コンテンツの配布を高速化する Web サービスです。CloudFront は、エッジロケーションと呼ばれるデータセンターの世界規模のネットワークを通じてコンテンツを配信し、レイテンシーを短縮し、パフォーマンスを向上させます。
+ [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html) は、ウェブおよびモバイルアプリの認証、認可、およびユーザー管理機能を提供します。ユーザーは、直接サインインしても、サードパーティを介してサインインしてもかまいません。
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) は、フルマネージド NoSQL データベースサービスであり、シームレスなスケーラビリティを備えた高速で予測可能なパフォーマンスを提供します。
+ [Amazon Data Firehose](https://docs.aws.amazon.com/firehose/latest/dev/what-is-this-service.html) は、Amazon S3、Amazon Redshift、Amazon OpenSearch Service、Splunk、カスタム HTTP エンドポイント、またはサポートされているサードパーティのサービスプロバイダーが所有する HTTP エンドポイントなどの宛先に、リアルタイムの[ストリーミングデータ](https://aws.amazon.com/streaming-data/)を配信するフルマネージドサービスです。
+ [Amazon Kinesis Data Streams](https://docs.aws.amazon.com/streams/latest/dev/introduction.html) は、データレコードの大規模なストリームをリアルタイムで収集および処理するためのサービスです。
+ 「[AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)」 – AWS Lambda はサーバーのプロビジョニングや管理を行わずにコードの実行を支援できるコンピューティングサービスです。Lambda は必要に応じてコードを実行し、1 日あたり数個のリクエストから 1 秒あたり数千のリクエストまで自動的にスケールします。課金は実際に消費したコンピューティング時間に対してのみ発生します。コードが実行されていない場合、料金は発生しません。
+ [Amazon Simple Storage Service (Amazon S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) は、あらゆる量のデータを保存、保護、取得できるクラウドベースのオブジェクトストレージサービスです。

**コード**

このパターンのコードは添付されています。

## エピック
<a name="deploy-multiple-stack-applications-using-aws-cdk-with-typescript-epics"></a>

### AWS CDK ツールキットをインストール
<a name="install-aws-cdk-toolkit"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| AWS CDK ツールキットをインストールします。 | AWS CDK Toolkit をグローバルにインストールするには、次のコマンドを実行します。`npm install -g aws-cdk` | DevOps | 
| バージョンを確認します。 | AWS CDK Toolkit のバージョンを確認するには、次のコマンドを実行します。 `cdk --version` | DevOps | 

### AWS 認証情報の設定
<a name="set-up-aws-credentials"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 認証情報を設定します。 | 認証情報を設定するには、`aws configure` コマンドを実行し、プロンプトに従います。<pre>$aws configure<br />AWS Access Key ID [None]: <br />AWS Secret Access Key [None]: your_secret_access_key<br />Default region name [None]:<br />Default output format [None]:</pre> | DevOps | 

### プロジェクトコードのダウンロード
<a name="download-the-project-code"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 添付のプロジェクトコードをダウンロードしてください。 | ディレクトリとファイル構造の詳細については、「*追加情報*」セクションを参照してください。 | DevOps | 

### AWS CDK 環境を起動する
<a name="bootstrap-the-aws-cdk-environment"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 環境を起動します。 | 使用したいアカウントと AWS リージョンに AWS CloudFormation テンプレートをデプロイするには、次のコマンドを実行します。`cdk bootstrap <account>/<Region>`詳細については、[AWS ドキュメント](https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html)を参照してください。 | DevOps | 

### プロジェクトの構築とデプロイ
<a name="build-and-deploy-the-project"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| プロジェクトをビルドします。 | プロジェクトコードをビルドするには、`npm run build` コマンドを実行します。 | DevOps | 
| プロジェクトをデプロイします。 | プロジェクトコードをデプロイするには、`cdk deploy` コマンドを実行します。 |  | 

### 出力の確認
<a name="verify-outputs"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| スタックの作成を確認します。 | AWS マネジメントコンソールで、**[CloudFormation]** を選択します。プロジェクトのスタックで、親スタックと 2 つの子スタックが作成されていることを確認します。 | DevOps | 

### アプリケーションをテストする
<a name="test-the-application"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| データを Kinesis Data Streams に送信します。 | Amazon Kinesis Data Generator (KDG) を使用して KinKinesis Data Streams にデータを送信するように AWS アカウントを設定します。詳細については、「[Amazon Kinesis Data Generator](https://awslabs.github.io/amazon-kinesis-data-generator/web/help.html)」を参照してください。 | DevOps | 
| Amazon Cognito ユーザーを作成します。 | Amazon Cognito ユーザーを作成するには、[Kinesis Data Generator のヘルプページ](https://awslabs.github.io/amazon-kinesis-data-generator/web/help.html)の「*Amazon Cognito ユーザーの作成*」セクションから cognito-setup.json CloudFormation テンプレートをダウンロードしてください。テンプレートを起動し、Amazon Cognito の**ユーザー名**と**パスワード**を入力します。**[出力]** タブには Kinesis Data Generator URL が一覧表示されます。 | DevOps | 
| Kinesis Data Generator にログイン | KDG にログインするには、指定した Amazon Cognito 認証情報と Kinesis データジェネレーター URL を使用します。 | DevOps | 
| アプリケーションをテストします。 | KDG の **[レコードテンプレート]**、**[テンプレート 1]** に「*追加情報*」セクションのテストコードを貼り付け、**[データを送信]** を選択します。 | DevOps | 
| API Gateway をテストします。 | データが取り込まれたら、`GET` メソッドを使用してデータを取得して API ゲートウェイをテストします。 | DevOps | 

## 関連リソース
<a name="deploy-multiple-stack-applications-using-aws-cdk-with-typescript-resources"></a>

**リファレンス**
+ [AWS クラウド開発キット](https://aws.amazon.com/cdk/)
+ [AWS CDK on GitHub](https://github.com/aws/aws-cdk)
+ [ネストされたスタックの操作](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-cfn-nested-stacks.html)
+ [AWS サンプル例 - サーバーレスリアルタイム分析](https://github.com/aws-samples/serverless-realtime-analytics)

## 追加情報
<a name="deploy-multiple-stack-applications-using-aws-cdk-with-typescript-additional"></a>

**ディレクトリとファイルの詳細**

このパターンでは、次の 3 つのスタックが設定されます。
+ `parent-cdk-stack.ts` – このスタックは親スタックとして機能し、2 つの子アプリケーションをネストされたスタックとして呼び出します。 
+ `real-time-analytics-poc-stack.ts` – このネストされたスタックには、インフラストラクチャとアプリケーションコードが含まれています。
+ `real-time-analytics-web-stack.ts` – このネストされたスタックには、静的な Web アプリケーションコードのみが含まれます。

重要なファイルとその機能
+ `bin/real-time-analytics-poc.ts` – AWS CDK アプリケーションのエントリポイント。`lib/` で定義されたすべてのスタックをロードします。
+ `lib/real-time-analytics-poc-stack.ts` – AWS CDK アプリケーションのスタックの定義 (`real-time-analytics-poc`)。
+ `lib/real-time-analytics-web-stack.ts` – AWS CDK アプリケーションのスタックの定義 (`real-time-analytics-web-stack`)。
+ `lib/parent-cdk-stack.ts` – AWS CDK アプリケーションのスタックの定義 (`parent-cdk`)。
+ `package.json` – npm モジュールマニフェスト。アプリケーション名、バージョン、依存関係が含まれます。
+ `package-lock.json` – npm が管理します。
+ `cdk.json` – アプリケーションを実行するためのツールキット。
+ `tsconfig.json` – プロジェクトの TypeScript を設定します。
+ `.gitignore` – Git がソースコントロールから除外すべきファイルのリスト。
+ `node_modules` – npm が管理します。プロジェクトの依存関係を含みます。

親スタックの次のコードセクションでは、子アプリケーションをネストされた AWS CDK スタックとして呼び出します。

```
import * as cdk from '@aws-cdk/core';
import { Construct, Stack, StackProps } from '@aws-cdk/core';
import { RealTimeAnalyticsPocStack } from './real-time-analytics-poc-stack';
import { RealTimeAnalyticsWebStack } from './real-time-analytics-web-stack';


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


    new RealTimeAnalyticsPocStack(this, 'RealTimeAnalyticsPocStack');
    new RealTimeAnalyticsWebStack(this, 'RealTimeAnalyticsWebStack');
  }
}
```

**テスト用のコード**

```
session={{date.now('YYYYMMDD')}}|sequence={{date.now('x')}}|reception={{date.now('x')}}|instrument={{random.number(9)}}|l={{random.number(20)}}|price_0={{random.number({"min":10000, "max":30000})}}|price_1={{random.number({"min":10000, "max":30000})}}|price_2={{random.number({"min":10000, "max":30000})}}|price_3={{random.number({"min":10000, "max":30000})}}|price_4={{random.number({"min":10000, "max":30000})}}|price_5={{random.number({"min":10000, "max":30000})}}|price_6={{random.number({"min":10000, "max":30000})}}|price_7={{random.number({"min":10000, "max":30000})}}|price_8={{random.number({"min":10000, "max":30000})}}|
```

**API ゲートウェイのテスト**

API ゲートウェイコンソールで、`GET` メソッドを使用して API ゲートウェイをテストします。

![\[OPTIONS で GET が選択された API Gateway コンソールです。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/0ac29a11-1362-4084-92ed-6b85205763ca/images/452e5b8f-6d61-401d-8484-e5a436cb6f1b.png)


 

## アタッチメント
<a name="attachments-0ac29a11-1362-4084-92ed-6b85205763ca"></a>

このドキュメントに関連する追加コンテンツにアクセスするには、次のファイルを解凍してください。「[attachment.zip](samples/p-attach/0ac29a11-1362-4084-92ed-6b85205763ca/attachments/attachment.zip)」

# AWS SAM を使用してネストされたアプリケーションのデプロイを自動化
<a name="automate-deployment-of-nested-applications-using-aws-sam"></a>

*Amazon Web Services、Dr. Rahul Sharad Gaikwad、Ishwar Chauthaiwale、Dmitry Gulin、Tabby Ward*

## 概要
<a name="automate-deployment-of-nested-applications-using-aws-sam-summary"></a>

Amazon Web Services (AWS) では、AWS サーバーレスアプリケーションモデル (AWS SAM) は関数、API、データベース、およびイベントソースマッピングを表現するための省略構文を提供するオープンソースフレームワークです。リソースごとに数行入力するだけで、必要なアプリケーションを定義し、YAML を使用してモデル化できます。デプロイ時に、SAM は SAM 構文を AWS CloudFormation 構文に変換して拡張します。これにより、サーバーレスアプリケーションをより迅速に構築できます。

AWS SAM は、AWS プラットフォームでのサーバーレスアプリケーションの開発、デプロイ、管理を簡素化します。標準化されたフレームワーク、迅速なデプロイ、ローカルテスト特徴量、リソース管理、開発ツールとのシームレスな統合、支援コミュニティを提供します。これらの特徴量により、サーバーレスアプリケーションを効率的かつ効果的に構築するための貴重なツールとなっています。

このパターンでは、AWS SAM テンプレートを使用して、ネストされたアプリケーションのデプロイを自動化します。ネストされたアプリケーションは、別のアプリケーション内のアプリケーションです。親アプリケーションは子アプリケーションを呼び出します。これらはサーバーレスアーキテクチャのコンポーネントとして疎結合されています。 

ネストされたアプリケーションを使用すると、独自に作成および管理されているが、AWS SAM とServerless Application Repository を使用して構成されているサービスまたはコンポーネントを再利用することで、高度に洗練されたサーバーレスアーキテクチャを迅速に構築できます。ネストされたアプリケーションは、より強力なアプリケーションを構築し、作業の重複を避け、チームや組織全体で一貫性とベストプラクティスを確保するのに役立ちます。ネストされたアプリケーションを示すために、このパターンでは「[AWS サーバーレスショッピングカートアプリケーションの例をデプロイします](https://github.com/aws-samples/aws-sam-nested-stack-sample)」。

## 前提条件と制限事項
<a name="automate-deployment-of-nested-applications-using-aws-sam-prereqs"></a>

**前提条件**
+ アクティブなAWS アカウント
+ 既存の仮想プライベートクラウド (VPC) とサブネット
+ Visual Studio Code などの統合開発環境 (詳細については、「[AWS で構築するためのツール](https://aws.amazon.com/getting-started/tools-sdks/#IDE_and_IDE_Toolkits)」を参照してください)
+ pip install wheel を使用してインストールされた Python ホイールライブラリ (まだインストールされていない場合)

**制限事項**
+ サーバーレスアプリケーションでネストできるアプリケーションの最大数は 200 です。
+ ネストされたアプリケーションで使用できるパラメータの最大数は 60 です。

**製品バージョン**
+ このソリューションは AWS SAM コマンドラインインターフェイス (AWS SAM CLI) バージョン 1.21.1 上に構築されていますが、このアーキテクチャは新しい AWS SAM CLI バージョンでも動作するはずです。

## アーキテクチャ
<a name="automate-deployment-of-nested-applications-using-aws-sam-architecture"></a>

**ターゲットテクノロジースタック**
+ Amazon API Gateway
+ AWS SAM
+ Amazon Cognito
+ Amazon DynamoDB
+ AWS Lambda
+ Amazon Simple Queue Service (Amazon SQS) キュー

**ターゲットアーキテクチャ**

次の図は、API を呼び出してショッピングサービスにユーザーリクエストを送信する方法を示しています。必要なすべての情報を含むユーザーのリクエストは、Amazon API Gatewayと Amazon Cognito オーソライザーに送信されます。Amazon Cognito オーソライザーは API の認証と認可のメカニズムを実行します。

DynamoDB で項目を追加、削除、または更新すると、DDynamoDB Streams にイベントが送信され、次に Lambda 関数が開始されます。同期ワークフローの一部として古い項目がすぐに削除されないように、メッセージは SQS キューに入れられ、メッセージを削除するワーカー関数が開始されます。

![\[API Gateway から Lambda 関数、DynamoDB および Product Service への POST および PUT オペレーション。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/218adecc-b5b8-4193-9012-b5d584e2e128/images/5b454bae-5fd4-405d-a37d-6bafc3fcf889.png)


このソリューションセットアップでは、AWS SAM CLI が AWS CloudFormation スタックのインターフェイスとして機能します。AWS SAM テンプレートはネストされたアプリケーションを自動的にデプロイします。親 SAM テンプレートが子テンプレートを呼び出し、親 CloudFormation スタックが子スタックをデプロイします。各子スタックは、AWS SAM CloudFormation テンプレートで定義されている AWS リソースを構築します。

![\[親と 3 つの子 CloudFormation スタックで AWS SAM CLI を使用する 4 ステップのプロセス。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/218adecc-b5b8-4193-9012-b5d584e2e128/images/5828026e-72ad-4a3f-a5f2-bffac0f13e42.png)


1. スタックを構築してデプロイします。

1. Auth CloudFormation スタックには Amazon Cognito が含まれています。

1. プロダクトCloudFormation スタックには Lambda 関数と Amazon API Gateway が含まれています。

1. Shopping CloudFormation スタックには、Lambda 関数、Amazon API Gateway、SQS キュー、Amazon DynamoDB データベースが含まれています。

## ツール
<a name="automate-deployment-of-nested-applications-using-aws-sam-tools"></a>

**ツール**
+ 「[Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html)」は、任意のスケールで REST、HTTP、WebSocket API を作成、公開、維持、監視、保護する上で役立ちます。
+ [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) を使用すると、AWS リソースをセットアップし、迅速かつ一貫したプロビジョニングを行い、AWS アカウントとリージョン全体でライフサイクル全体にわたってリソースを管理できます。
+ [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html) は、ウェブおよびモバイルアプリの認証、認可、およびユーザー管理機能を提供します。
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) は、フルマネージド NoSQL データベースサービスです。高速かつ予測可能でスケーラブルなパフォーマンスを発揮します。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) は、サーバーのプロビジョニングや管理を行うことなくコードを実行できるコンピューティングサービスです。必要に応じてコードを実行し、自動的にスケーリングするため、課金は実際に使用したコンピューティング時間に対してのみ発生します。
+ 「[AWS Serverless Application Model (AWS SAM)](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/what-is-sam.html)」は、 AWS クラウドのサーバーレスアプリケーションを構築するために支援するオープンソースフレームワークです。
+ [Amazon Simple Queue Service (Amazon SQS)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html) は、分散したソフトウェアシステムとコンポーネントの統合と切り離しを支援し、セキュアで耐久性があり、利用可能なホスト型キューを提供します。

**コード**

このパターンのコードは、GitHub 内の「[AWS SAM ネストスタックのサンプル](https://github.com/aws-samples/aws-sam-nested-stack-sample)」リポジトリで利用できます。

## エピック
<a name="automate-deployment-of-nested-applications-using-aws-sam-epics"></a>

### AWS SAM CLI のインストール
<a name="install-aws-sam-cli"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| AWS SAM CLI をインストールします。 | AWS SAM CLI をインストールするには、「[AWS SAM ドキュメント](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli-install.html)」の手順を参照してください。 | DevOps エンジニア | 
| AWS 認証情報を設定します。 | AWS SAM CLI がユーザーに代わって AWS サービスを呼び出せるように AWS 認証情報を設定するには、`aws configure` コマンドを実行してプロンプトに従います。<pre>$aws configure<br />AWS Access Key ID [None]: <your_access_key_id><br />AWS Secret Access Key [None]: your_secret_access_key<br />Default region name [None]:<br />Default output format [None]:</pre>認証情報をセットアップする詳細情報については、「[権限とアクセス承認情報](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-authentication.html)」を参照してください。 | DevOps エンジニア | 

### AWS SAM プロジェクトを初期化する
<a name="initialize-the-aws-sam-project"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| AWS SAM コードリポジトリを複製します。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/automate-deployment-of-nested-applications-using-aws-sam.html) | DevOps エンジニア | 
| テンプレートをデプロイしてプロジェクトを初期化します。 | プロジェクトを初期化するには、`SAM init` コマンドを実行します。テンプレートソースを選択するよう求められたら、`Custom Template Location` を選択します。 | DevOps エンジニア | 

### SAM テンプレートコードをコンパイルしてビルドする。
<a name="compile-and-build-the-sam-template-code"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| AWS SAM アプリケーションテンプレートを確認します。 | ネストされたアプリケーションのテンプレートを確認します。この例では、以下のネストされたアプリケーションテンプレートを使用しています。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/automate-deployment-of-nested-applications-using-aws-sam.html) | DevOps エンジニア | 
| 親テンプレートを見直します。 | ネストされたアプリケーションテンプレートを呼び出すテンプレートを確認します。この例では、親テンプレートは `template.yml` です。個別のアプリケーションはすべて単一の親テンプレート `template.yml` にネストされています。 | DevOps エンジニア | 
| AWS SAM テンプレートコードをコンパイルしてビルドします。 | AWS SAM CLI を使用して、次のコマンドを実行します。<pre>sam build</pre> | DevOps エンジニア | 

### AWS SAM テンプレートをデプロイする
<a name="deploy-the-aws-sam-template"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| アプリケーションをデプロイします。 | ネストされたアプリケーション CloudFormation を作成して AWS 環境にコードをスタックしてデプロイする SAM テンプレートコードを起動するには、以下のコマンドを実行します。<pre>sam deploy --guided --stack-name shopping-cart-nested-stack --capabilities CAPABILITY_IAM CAPABILITY_AUTO_EXPAND</pre>コマンドを実行すると、いくつかの質問が表示されます。すべての質問に `y` で答えてください。 | DevOps エンジニア | 

### デプロイメントを確認する
<a name="verify-the-deployment"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| スタックを確認する | AWS SAM テンプレートで定義された AWS CloudFormation スタックと AWS リソースを確認するには、次の手順を実行します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/automate-deployment-of-nested-applications-using-aws-sam.html) | DevOps エンジニア | 

## 関連リソース
<a name="automate-deployment-of-nested-applications-using-aws-sam-resources"></a>

リファレンス
+ 「[AWS サーバーレスアプリケーションモデル (AWS SAM)](https://aws.amazon.com/serverless/sam/#:~:text=The%20AWS%20Serverless%20Application%20Model,and%20model%20it%20using%20YAML.)」 
+ 「[GitHub の AWS SAM](https://github.com/aws/serverless-application-model)」
+ 「[サーバーレスショッピングカートマイクロサービス](https://github.com/aws-samples/aws-serverless-shopping-cart)」 (AWS サンプルアプリケーション)

**チュートリアルと動画**
+ 「[サーバーレスアプリケーションの構築](https://youtu.be/Hv3YrP8G4ag)」
+ 「[AWS オンラインテックトーク:AWS SAM によるサーバーレスアプリケーションの構築とデプロイ](https://youtu.be/1NU7vyJw9LU)」

## 追加情報
<a name="automate-deployment-of-nested-applications-using-aws-sam-additional"></a>

コードがすべて揃うと、この例は次のようなディレクトリ構造になります。
+ 「[sam\$1stacks](https://docs.aws.amazon.com/lambda/latest/dg/chapter-layers.html)」 — このフォルダーには `shared.py` レイヤーが含まれています。レイヤーは、ライブラリ、カスタムランタイム、その他の依存関係などを含むファイルアーカイブです。レイヤーを使用することで、関数のライブラリを使用することができます。デプロイパッケージに含める必要はありません。
+ *product-mock-service* – このフォルダには、製品に関連するすべての Lambda 関数とファイルが含まれています。
+ *shopping-cart-service* – このフォルダには、ショッピング関連のすべての Lambda 関数とファイルが含まれています。

# AWS Lambda トークン自動販売機を使用して Amazon S3 の SaaS テナント分離を実装する
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine"></a>

*Amazon Web Services、Tabby Ward、Thomas Davis、および Sravan Periyathambi*

## 概要
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-summary"></a>

マルチテナントSaaSアプリケーションは、テナントの分離が維持されるようにシステムを実装する必要があります。複数のテナントが同じ Amazon Simple Storage Service (Amazon S3) バケットにデータを保存する場合など、テナントデータを同じ AWS リソースに保存する場合は、クロステナントアクセスが発生しないようにする必要があります。トークン自動販売機 (TVM) は、テナントデータを分離する 1 つの方法です。これらのマシンは、トークンの生成方法の複雑さを抽象化しながら、トークンを取得するメカニズムを提供します。開発者は、TVM がどのようにトークンを生成するかについての詳細な知識がなくても使用できます。

このパターンは、 を使用して TVM を実装します AWS Lambda。TVM は、S3 バケット内の 1 つの SaaS テナントのデータへのアクセスを制限する一時的なセキュリティトークンサービス (STS) 認証情報で構成されるトークンを生成します。

TVMsおよびこのパターンで提供されるコードは、通常、JSON ウェブトークン (JWTs) から派生したクレームで使用され、 AWS リソースのリクエストをテナントスコープ AWS Identity and Access Management (IAM) ポリシーに関連付けます。このパターンのコードを基礎として使用して、JWT トークンで提供されるクレームに基づいてスコープ付きの一時的な STS 認証情報を生成する SaaS アプリケーションを実装できます。

## 前提条件と制限事項
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-prereqs"></a>

**前提条件**
+ アクティブ AWS アカウント。
+ AWS Command Line Interface (AWS CLI) [バージョン 1.19.0 以降](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv1.html)。macOS、Linux、または Windows にインストールおよび設定されています。または、 AWS CLI [バージョン 2.1 以降](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)を使用することもできます。

**制限事項**
+ このコードは Java で実行され、現在他のプログラミング言語はサポートされていません。 
+ サンプルアプリケーションには、 AWS クロスリージョンまたはディザスタリカバリ (DR) サポートは含まれません。 
+ このパターンは、SaaS アプリケーション用の Lambda TVM がスコープ付きのテナントアクセスを提供する方法を示しています。このパターンは、特定のアプリケーションまたはユースケースの一部として追加のセキュリティテストを行わずに本番環境で使用することを意図したものではありません。

## アーキテクチャ
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-architecture"></a>

**ターゲットテクノロジースタック**
+ AWS Lambda
+ Amazon S3
+ IAM
+ AWS Security Token Service (AWS STS)

**ターゲットアーキテクチャ**

![\[S3 バケット内のデータにアクセスするための一時的な STS 認証情報を取得するためのトークンを生成します。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/97a34c8e-d04e-40b6-acbf-1baa176d22a9/images/14d0508a-703b-4229-85e6-c5094de7fe01.png)


 

## ツール
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-tools"></a>

**AWS のサービス**
+ [AWS Command Line Interface (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) は、コマンドラインシェルのコマンド AWS のサービス を使用して を操作するのに役立つオープンソースツールです。
+ [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) は、誰を認証し、誰に使用する権限を付与するかを制御することで、 AWS リソースへのアクセスを安全に管理するのに役立ちます。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) は、サーバーのプロビジョニングや管理を行うことなくコードを実行できるコンピューティングサービスです。必要に応じてコードを実行し、自動的にスケーリングするため、課金は実際に使用したコンピューティング時間に対してのみ発生します。
+ [AWS Security Token Service (AWS STS)](https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html) は、ユーザーの権限が制限された一時的な認証情報をリクエストするのに役立ちます。
+ [Amazon Simple Storage Service (Amazon S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) は、あらゆる量のデータを保存、保護、取得できるクラウドベースのオブジェクトストレージサービスです。

**コード**

このパターンのソースコードは添付ファイルとして提供され、以下のファイルが含まれています。
+ `s3UploadSample.jar`は、JSON ドキュメントを S3 バケットにアップロードする Lambda 関数のソースコードを提供します。
+ `tvm-layer.zip`には、Lambda 関数が S3 バケットにアクセスして JSON ドキュメントをアップロードするためのトークン (STS 一時認証情報) を提供する再利用可能な Java ライブラリが用意されています。
+ `token-vending-machine-sample-app.zip`は、これらのアーティファクトの作成に使用されるソースコードとコンパイル手順を提供します。

これらのファイルを使用するには、次のセクションの指示に従います。

## エピック
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-epics"></a>

### 可変値の決定
<a name="determine-variable-values"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 可変値を決定します。 | このパターンの実装には、一貫して使用しなければならない変数名がいくつか含まれています。各変数に使用すべき値を決定し、以降のステップで要求されたらその値を指定します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine.html) | クラウド管理者 | 

### S3 バケットを作成する
<a name="create-an-s3-bucket"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| サンプルアプリケーション用の S3 バケット環境を作成します。 | S3 バケットを作成するには、次の AWS CLI コマンドを使用します。コードスニペットで `<sample-app-bucket-name>`** **の値を指定します。<pre>aws s3api create-bucket --bucket <sample-app-bucket-name></pre>Lambda サンプルアプリケーションは JSON ファイルをこのバケットにアップロードします。 | クラウド管理者 | 

### IAM TVM ロールとポリシーを作成する
<a name="create-the-iam-tvm-role-and-policy"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| TVM ロールを作成します。 | IAM ロールを作成するには、次のいずれかの AWS CLI コマンドを使用します。コマンドで `<sample-tvm-role-name>`** **値を指定します。macOS または Linux 上の Bash シェルの場合：<pre>aws iam create-role \<br />--role-name <sample-tvm-role-name> \<br />--assume-role-policy-document '{<br />    "Version": "2012-10-17",		 	 	 <br />    "Statement": [<br />        {<br />            "Effect": "Allow",<br />            "Action": [<br />                "sts:AssumeRole"<br />            ],<br />            "Principal": {<br />                "Service": [<br />                    "lambda.amazonaws.com"<br />                ]<br />            },<br />            "Condition": {<br />                "StringEquals": {<br />                    "aws:SourceAccount": "<AWS Account ID>"<br />                }<br />            }<br />        }<br />    ]<br />}'</pre>Windows コマンドラインの場合：<pre>aws iam create-role ^<br />--role-name <sample-tvm-role-name> ^<br />--assume-role-policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"sts:AssumeRole\"], \"Principal\": {\"Service\": [\"lambda.amazonaws.com\"]}, \"Condition\": {\"StringEquals\": {\"aws:SourceAccount\": \"<AWS Account ID>\"}}}]}"</pre>Lambda サンプルアプリケーションは、アプリケーションが呼び出されるとこのロールを引き受けます。スコープポリシーを使用してアプリケーションロールを引き受けることができるため、S3 バケットにアクセスするための幅広いアクセス権限がコードに付与されます。 | クラウド管理者 | 
| インライン TVM ロールポリシーを作成します。 | IAM ポリシーを作成するには、次のいずれかの AWS CLI コマンドを使用します。コマンドで、`<sample-tvm-role-name>`、****`<AWS Account ID>`、および `<sample-app-role-name>` の値を指定します。macOS または Linux 上の Bash シェルの場合：<pre>aws iam put-role-policy \<br />--role-name <sample-tvm-role-name> \<br />--policy-name assume-app-role \<br />--policy-document '{<br />    "Version": "2012-10-17",		 	 	  <br />    "Statement": [<br />        {<br />            "Effect": "Allow", <br />            "Action": "sts:AssumeRole", <br />            "Resource": "arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>"<br />        }<br />    ]}'</pre>Windows コマンドラインの場合：<pre>aws iam put-role-policy ^<br />--role-name <sample-tvm-role-name> ^<br />--policy-name assume-app-role ^<br />--policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": \"sts:AssumeRole\", \"Resource\": \"arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>\"}]}"</pre>このポリシーは、TVM ロールにアタッチされます。これにより、S3 バケットにアクセスするための幅広い権限を持つアプリケーションロールを引き受けることができるようコードに付与されます。 | クラウド管理者 | 
| マネージド Lambda ポリシーをアタッチします。 | IAM ポリシーを`AWSLambdaBasicExecutionRole`アタッチするには、次の AWS CLI コマンドを使用します。コマンドで `<sample-tvm-role-name>` 値を指定します。<pre>aws iam attach-role-policy \<br />--role-name <sample-tvm-role-name> \<br />--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole</pre>Windows コマンドラインの場合：<pre>aws iam attach-role-policy ^<br />--role-name <sample-tvm-role-name> ^<br />--policy-arn arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole</pre>この管理ポリシーは TVM ロールにアタッチされ、Lambda が Amazon CloudWatch にログを送信することを許可します。 | クラウド管理者 | 

### IAM アプリケーションロールとポリシーを作成する。
<a name="create-the-iam-application-role-and-policy"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| アプリケーションロールを作成します。 | IAM ロールを作成するには、次のいずれかの AWS CLI コマンドを使用します。コマンドで、`<sample-app-role-name>`、`<AWS Account ID>`、および `<sample-tvm-role-name>` の値を指定します。macOS または Linux 上の Bash シェルの場合：<pre>aws iam create-role \<br />--role-name <sample-app-role-name> \<br />--assume-role-policy-document '{<br />    "Version": "2012-10-17",		 	 	  <br />    "Statement": [<br />        {<br />            "Effect": <br />            "Allow",<br />            "Principal": {<br />                "AWS": "arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name>"<br />            },<br />            "Action": "sts:AssumeRole"<br />        }<br />    ]}'</pre>Windows コマンドラインの場合：<pre>aws iam create-role ^<br />--role-name <sample-app-role-name> ^<br />--assume-role-policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\",\"Principal\": {\"AWS\": \"arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name>\"},\"Action\": \"sts:AssumeRole\"}]}"</pre>Lambda サンプルアプリケーションは、S3 バケットへのテナントベースのアクセスを取得するためのスコープポリシーを使用してこのロールを引き受けます。 | クラウド管理者 | 
| インラインアプリケーションロールポリシーを作成します。 | 次のいずれかの AWS CLI mmands を使用して IAM ポリシーを作成します。コマンドで、`<sample-app-role-name>` および `<sample-app-bucket-name>`** ** の値を指定します。macOS または Linux 上の Bash シェルの場合：<pre>aws iam put-role-policy \<br />--role-name <sample-app-role-name> \<br />--policy-name s3-bucket-access \<br />--policy-document '{<br />    "Version": "2012-10-17",		 	 	  <br />    "Statement": [<br />        {<br />            "Effect": "Allow", <br />            "Action": [<br />                "s3:PutObject", <br />                "s3:GetObject", <br />                "s3:DeleteObject"<br />            ], <br />            "Resource": "arn:aws:s3:::<sample-app-bucket-name>/*"<br />        }, <br />        {<br />            "Effect": "Allow", <br />            "Action": ["s3:ListBucket"], <br />            "Resource": "arn:aws:s3:::<sample-app-bucket-name>"<br />        }<br />    ]}'</pre>Windows コマンドラインの場合：<pre>aws iam put-role-policy ^<br />--role-name <sample-app-role-name> ^<br />--policy-name s3-bucket-access ^<br />--policy-document "{\"Version\": \"2012-10-17\", \"Statement\": [{\"Effect\": \"Allow\", \"Action\": [\"s3:PutObject\", \"s3:GetObject\", \"s3:DeleteObject\"], \"Resource\": \"arn:aws:s3:::<sample-app-bucket-name>/*\"}, {\"Effect\": \"Allow\", \"Action\": [\"s3:ListBucket\"], \"Resource\": \"arn:aws:s3:::<sample-app-bucket-name>\"}]}"</pre>このポリシーは、アプリケーションロールにアタッチされます。S3 バケット内のオブジェクトに幅広くアクセスできます。サンプルアプリケーションが役割を引き受けると、これらの権限は TVM の動的に生成されたポリシーによって特定のテナントに限定されます。 | クラウド管理者 | 

### TVM を使用して Lambda サンプルアプリケーションを作成する
<a name="create-the-lam-sample-application-with-tvm"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| コンパイルされたソースファイルをダウンロードします。 | 添付ファイルとして含まれている`s3UploadSample.jar`および`tvm-layer.zip`** **ファイルをダウンロードします。これらのアーティファクトの作成に使用されたソースコードとコンパイル手順は、`token-vending-machine-sample-app.zip`に記載されています。 | クラウド管理者 | 
| Lambda コードを作成します。 | 次の AWS CLI コマンドを使用して Lambda レイヤーを作成します。これにより、TVM が Lambda にアクセスできるようになります。 ` tvm-layer.zip` をダウンロードした場所からこのコマンドを実行しない場合は、`--zip-file` パラメータに `tvm-layer.zip` への正しいパスを指定してください。 <pre>aws lambda publish-layer-version \<br />--layer-name sample-token-vending-machine \<br />--compatible-runtimes java11 \<br />--zip-file fileb://tvm-layer.zip</pre>Windows コマンドラインの場合：<pre>aws lambda publish-layer-version ^<br />--layer-name sample-token-vending-machine ^<br />--compatible-runtimes java11 ^<br />--zip-file fileb://tvm-layer.zip</pre>このコマンドは、再利用可能な TVM ライブラリを含む Lambda レイヤーを作成します。 | クラウド管理者、アプリ開発者 | 
| Lambda 関数の作成 | 次の AWS CLI コマンドを使用して Lambda 関数を作成します。コマンドで、`<sample-app-function-name>`、`<AWS Account ID>`、`<AWS Region>`、`<sample-tvm-role-name>`、`<sample-app-bucket-name>`、および `<sample-app-role-name>` の値を指定します。 `s3UploadSample.jar` をダウンロードした場所からこのコマンドを実行しない場合は、`--zip-file` パラメータに `s3UploadSample.jar` への正しいパスを指定してください。 <pre>aws lambda create-function \<br />--function-name <sample-app-function-name>  \<br />--timeout 30 \<br />--memory-size 256 \<br />--runtime java11 \<br />--role arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name> \<br />--handler com.amazon.aws.s3UploadSample.App \<br />--zip-file fileb://s3UploadSample.jar \<br />--layers arn:aws:lambda:<AWS Region>:<AWS Account ID>:layer:sample-token-vending-machine:1 \<br />--environment "Variables={S3_BUCKET=<sample-app-bucket-name>,<br />ROLE=arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>}"</pre>Windows コマンドラインの場合：<pre>aws lambda create-function ^<br />--function-name <sample-app-function-name>  ^<br />--timeout 30 ^<br />--memory-size 256 ^<br />--runtime java11 ^<br />--role arn:aws:iam::<AWS Account ID>:role/<sample-tvm-role-name> ^<br />--handler com.amazon.aws.s3UploadSample.App ^<br />--zip-file fileb://s3UploadSample.jar ^<br />--layers arn:aws:lambda:<AWS Region>:<AWS Account ID>:layer:sample-token-vending-machine:1 ^<br />--environment "Variables={S3_BUCKET=<sample-app-bucket-name>,ROLE=arn:aws:iam::<AWS Account ID>:role/<sample-app-role-name>}"</pre>このコマンドは、サンプルアプリケーションコードと TVM レイヤーをアタッチした Lambda 関数を作成します。また、`S3_BUCKET`と`ROLE`の 2 つの環境変数も設定します。サンプルアプリケーションでは、これらの変数を使用して、引き受けるロールと JSON ドキュメントをアップロードする S3 バケットを決定します。 | クラウド管理者、アプリ開発者 | 

### サンプルアプリケーションをデプロイしてテストする
<a name="test-the-sample-application-and-tvm"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Lambda サンプルアプリケーションを呼び出します。 | 次のいずれかの AWS CLI コマンドを使用して、予想されるペイロードで Lambda サンプルアプリケーションを起動します。コマンドで、`<sample-app-function-name>` および `<sample-tenant-name>` の値を指定します。macOS および Linux システムの場合：<pre>aws lambda invoke \<br />--function <sample-app-function-name> \<br />--invocation-type RequestResponse \<br />--payload '{"tenant": "<sample-tenant-name>"}' \<br />--cli-binary-format raw-in-base64-out response.json</pre>Windows コマンドラインの場合：<pre>aws lambda invoke ^<br />--function <sample-app-function-name> ^<br />--invocation-type RequestResponse ^<br />--payload "{\"tenant\": \"<sample-tenant-name>\"}" ^<br />--cli-binary-format raw-in-base64-out response.json</pre>このコマンドは Lambda 関数を呼び出し、結果を`response.json`ドキュメントに返します。多くの UNIX ベースのシステムでは、`response.json`を`/dev/stdout`に変更すると、別のファイルを作成せずに結果をシェルに直接出力できます。 この Lambda 関数の後続の呼び出しで `<sample-tenant-name>` の値を変更すると、JSON ドキュメントの場所とトークンが提供するアクセス許可が変更されます。 | クラウド管理者、アプリ開発者 | 
| S3 バケットを表示して、作成されたオブジェクトを確認します。 | 先ほど作成した S3 バケット（`<sample-app-bucket-name>`）を参照します。このバケットには、`<sample-tenant-name>` 値の S3 オブジェクトのプレフィックスが含まれています。そのプレフィックスの下に、UUID が付いた名前の JSON ドキュメントがあります。サンプルアプリケーションを複数回呼び出すと、JSON ドキュメントがさらに追加されます。 | クラウド管理者 | 
| CloudWatch Logs でサンプルアプリケーションのログを表示します。 | CloudWatch Logs で `<sample-app-function-name>` という名前の Lambda 関数に関連付けられているログを表示します。手順については、Lambda ドキュメントの「[Lambda 関数ログを CloudWatch Logs に送信する](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs.html)」を参照してください。TVM によって生成されたテナントスコープのポリシーは、これらのログで確認できます。このテナントを対象とするポリシーは、Amazon S3 「**PutObject**」、「**GetObject**」、「**DeleteObject**」および「**ListBucket**」 の API にサンプルアプリケーションのアクセス許可を付与しますが、`<sample-tenant-name>` に関連するオブジェクトプレフィックスのアクセス許可のみを付与します。それ以降のサンプルアプリケーションの呼び出しで `<sample-tenant-name>` を変更すると、TVM は呼び出しペイロードで指定されたテナントに対応するスコープポリシーを更新します。この動的に生成されたポリシーは、SaaS アプリケーションで TVM を使用してテナントスコープのアクセスを維持する方法を示しています。 TVM 機能は Lambda レイヤーで提供されるため、コードを複製しなくても、アプリケーションで使用される他の Lambda 関数に接続できます。動的に生成されるポリシーの図については、「[追加情報](#implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-additional)」セクションを参照してください。 | クラウド管理者 | 

## 関連リソース
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-resources"></a>
+ [動的に生成される IAM ポリシーによるテナントの分離 (ブログ記事](https://aws.amazon.com/blogs/apn/isolating-saas-tenants-with-dynamically-generated-iam-policies/))
+ [Applying Dynamically Generated Isolation Policies in SaaS Environments](https://aws.amazon.com/blogs/apn/applying-dynamically-generated-isolation-policies-in-saas-environments/) (ブログ記事)
+ [での SaaS AWS](https://aws.amazon.com/saas/)

## 追加情報
<a name="implement-saas-tenant-isolation-for-amazon-s3-by-using-an-aws-lambda-token-vending-machine-additional"></a>

次のログは、このパターンで TVM コードによって生成された、動的に生成されたポリシーを示しています。このスクリーンショットでは、`<sample-app-bucket-name>` は `DOC-EXAMPLE-BUCKET` で、`<sample-tenant-name>` は `test-tenant-1` となります。このスコープポリシーによって返される STS 認証情報は、オブジェクトkey prefix `test-tenant-1` に関連付けられているオブジェクトを除き、S3 バケット内のオブジェクトに対してアクションを実行できません。

![\[TVM コードによって生成された、動的に生成されたポリシーを示すログ。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/97a34c8e-d04e-40b6-acbf-1baa176d22a9/images/d4776ebe-fb8f-41ac-b8c5-b4f97a821c8c.png)


## アタッチメント
<a name="attachments-97a34c8e-d04e-40b6-acbf-1baa176d22a9"></a>

このドキュメントに関連する追加コンテンツにアクセスするには、次のファイルを解凍してください。「[attachment.zip](samples/p-attach/97a34c8e-d04e-40b6-acbf-1baa176d22a9/attachments/attachment.zip)」

# AWS Step Functions を使用して、サーバーレス Saga パターンを実装する
<a name="implement-the-serverless-saga-pattern-by-using-aws-step-functions"></a>

*Amazon Web Services、Tabby Ward、Joe Kern、および Rohan Mehta*

## 概要
<a name="implement-the-serverless-saga-pattern-by-using-aws-step-functions-summary"></a>

マイクロサービスアーキテクチャの主な目標は、アプリケーションの俊敏性、柔軟性、および市場投入までの時間を短縮するために、分離された独立したコンポーネントを構築することです。デカップリングにより、各マイクロサービスコンポーネントには独自のデータ永続化レイヤーが設けられます。分散型アーキテクチャでは、ビジネストランザクションが複数のマイクロサービスにまたがる可能性があります。これらのマイクロサービスは単一のアトミック性、一貫性、分離、耐久性 (ACID) トランザクションを使用できないため、部分的なトランザクションになってしまう可能性があります。この場合、すでに処理されたトランザクションを元に戻すには、何らかの制御ロジックが必要です。ディストリビュートサガパターンは、通常、この目的のために使用されます。 

サガパターンは、分散アプリケーションの一貫性を確立し、複数のマイクロサービス間のトランザクションを調整してデータ整合性を維持するのに役立つ障害管理パターンです。サガパターンを使用すると、トランザクションを実行するすべてのサービスがイベントをパブリッシュし、後続のサービスがチェーン内の次のトランザクションを実行するようトリガーします。これはチェーン内の最後のトランザクションが完了するまで続きます。ビジネストランザクションが失敗した場合、sagaは一連の補償トランザクションを組織し、それまでのトランザクションによって行われた変更を取り消します。

このパターンは、AWS Step Functions、AWS Lambda、Amazon DynamoDB などのサーバーレステクノロジーを使用して、サンプルアプリケーション (旅行の予約を処理する) の設定とデプロイを自動化する方法を示しています。サンプルアプリケーションでは、Saga 実行コーディネーターを実装するために Amazon API Gateway と Amazon Simple Notiﬁcation Service (Amazon SNS) も使用します。パターンは、AWS Cloud Development Kit (AWS CDK)、AWS サーバーレスアプリケーションモデル (AWS SAM)、Terraform などのinfrastructure as code (IaC フレームワークを使用してデプロイできます。

## 前提条件と制限事項
<a name="implement-the-serverless-saga-pattern-by-using-aws-step-functions-prereqs"></a>

**前提条件**
+ アクティブな AWS アカウント。
+ AWS CloudFormation スタックを作成するための権限。詳細については、「ACK ドキュメント」の「[Install an ACK Controller](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/using-iam-template.html)」を参照してください。
+ 任意の IaC フレームワーク (AWS CDK、AWS SAM、または Terraform) を AWS アカウントで設定することで、フレームワーク CLI を使用してアプリケーションをデプロイできます。
+ NodeJSは、アプリケーションの構築とローカルでの実行に使用されます。
+ 任意のコードエディター (Visual Studio Code、Sublime、Atom など)。

**製品バージョン**
+ [NodeJS バージョン 14](https://nodejs.org/en/download/)
+ [AWS CDK バージョン 2.37.1](https://docs.aws.amazon.com/cdk/v2/guide/getting_started.html#getting_started_install)
+ [AWS SAM バージョン 1.71.0](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/install-sam-cli.html)
+ [Terraform バージョン 1.3.7](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli)

**制限事項**

イベントソーシングは、すべてのコンポーネントがゆるく結合されていて互いに直接認識できないマイクロサービスアーキテクチャに saga オーケストレーションパターンを実装する自然な方法です。トランザクションのステップ数が少ない (3 ～ 5) 場合は、サガパターンが最適かもしれません。ただし、マイクロサービスの数とステップの数が増えるにつれて、複雑さも増します。 

この設計を使用すると、トランザクションパターンをシミュレートするためにすべてのサービスを実行する必要があるため、テストとデバッグが難しくなる可能性があります。

## アーキテクチャ
<a name="implement-the-serverless-saga-pattern-by-using-aws-step-functions-architecture"></a>

**ターゲットアーキテクチャ**

提案されたアーキテクチャでは、AWS Step Functions を使用して、フライトの予約、レンタカーの予約、休暇の支払い処理といったサガパターンを構築しています。

以下のワークフロー図は、旅行予約システムの一般的なフローを示しています。ワークフローは、航空旅行の予約 (「ReserveFlight」)、車の予約 (「ReserveCarRental」)、支払いの処理 (「ProcessPayment」)、フライトの予約の確認 (「ConfirmFlight」)、レンタカーの確認 (「ConfirmCarRental」) で構成され、これらのステップが完了すると成功通知が送られます。ただし、これらのトランザクションのいずれかを実行中にエラーが発生すると、システムは逆方向にフェイルオーバーし始めます。例えば、支払い処理 (「ProcessPayment」) でエラーが発生すると返金 (「RefundPayment」) がトリガーされ、レンタカーとフライトのキャンセル (「CancelRentalReservation」と「CancelFlightReservation」) がトリガーされ、トランザクション全体が失敗メッセージで終了します。

このパターンでは、図で強調表示されているタスクごとに個別の Lambda 関数がデプロイされるほか、フライト、レンタカー、支払い用の 3 つの DynamoDB テーブルもデプロイされます。各 Lambda 関数は、トランザクションが確認されたかロールバックされたかに応じて、それぞれの DynamoDB テーブルの行を作成、更新、または削除します。このパターンでは、Amazon SNS を使用してサブスクライバーにテキスト (SMS) メッセージを送信し、トランザクションが失敗または成功したことを通知します。 

![\[saga パターンに基づく旅行予約システムのワークフロー。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/fec0789c-d9b1-4d80-b179-dd9a7ecbec07/images/daad3e8e-6e6b-41c2-95c1-ca79d53ead64.png)


 

**自動化とスケール**

IaC フレームワークのいずれかを使用して、このアーキテクチャの構成を作成できます。お好みの Iac について、以下のリンクの 1 つを使用します。
+ [AWS CDK によるデプロイ](https://serverlessland.com/workflows/saga-pattern-cdk)
+ [AWS SAM によるデプロイ](https://serverlessland.com/workflows/saga-pattern-sam)
+ [テラフォームによるデプロイ](https://serverlessland.com/workflows/saga-pattern-tf)

## ツール
<a name="implement-the-serverless-saga-pattern-by-using-aws-step-functions-tools"></a>

**AWS サービス**
+ [AWS Step Functions](https://aws.amazon.com/step-functions/)は、AWS Lambda 関数と他のサービスを組み合わせてビジネスクリティカルなアプリケーションを構築できるサーバーレスオーケストレーションサービスです。Step Functions のグラフィカルコンソールでは、アプリケーションのワークフローを一連のイベント駆動型ステップとして確認できます。
+ Amazon DynamoDB は、フルマネージド NoSQL データベースサービスであり、シームレスなスケーラビリティを備えた高速で予測可能なパフォーマンスを提供します。DynamoDB を使用して、任意の量のデータを保存および取得できるデータベーステーブルを作成し、任意のレベルのリクエストトラフィックを処理できます。
+ AWS Lambda はサーバーをプロビジョニングしたり管理しなくてもコードを実行できるコンピューティングサービスです。Lambda は必要に応じてコードを実行し、1 日あたり数個のリクエストから 1 秒あたり数千のリクエストまで自動的にスケールします。
+ Amazon API Gateway は、あらゆる規模の REST、HTTP、WebSocket API を作成、公開、管理、モニタリング、保護するための AWS のサービスです。
+ [Amazon Simple Notiﬁcation Service (Amazon SNS)](https://aws.amazon.com/sns/) は、パブリッシャーからサブスクライバーへのメッセージ配信を提供するマネージドサービスです。
+ 「[AWS Cloud Development Kit (AWS CDK)](https://aws.amazon.com/cdk/)」は、TypeScript、JavaScript、Python、Java、C\$1/.Net などの使い慣れたプログラミング言語を使用してクラウドアプリケーションリソースを定義するためのソフトウェア開発フレームワークです。
+ [AWS サーバーレスアプリケーションモデル (AWS SAM)](https://aws.amazon.com/serverless/sam/) は、サーバーレスアプリケーションを構築するためのオープンソースフレームワークです。関数、API、データベース、イベントソースマッピングを表現するための省略構文を提供します。

**コード**

IaC テンプレート (AWS CDK、AWS SAM、または Terraform)、Lambda 関数、DynamoDB テーブルなど、サガパターンを示すサンプルアプリケーションのコードは、次のリンクにあります。最初のエピックの指示に従って、これらをインストールします。
+ [AWS CDK によるデプロイ](https://serverlessland.com/workflows/saga-pattern-cdk)
+ [AWS SAM によるデプロイ](https://serverlessland.com/workflows/saga-pattern-sam)
+ [テラフォームによるデプロイ](https://serverlessland.com/workflows/saga-pattern-tf)

## エピック
<a name="implement-the-serverless-saga-pattern-by-using-aws-step-functions-epics"></a>

### パッケージのインストール、コンパイル、ビルド
<a name="install-packages-compile-and-build"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
|  npm パッケージをインストールします。 | 新しいディレクトリを作成し、ターミナルでそのディレクトリに移動し、このパターンの前の「*コード*」セクションから選択したGitHub リポジトリをクローンします。`package.json`ファイルが含まれているルートフォルダで、次のコマンドを実行して、すべての Node Package Manager (NPM) パッケージをダウンロードしてインストールします。<pre>npm install</pre> | 開発者、クラウドアーキテクト | 
| Compile Script | ルートフォルダで、次のコマンドを実行して、必要なすべての JavaScript ファイルを作成するように TypeScript トランスパイラーに指示します。<pre>npm run build</pre> | 開発者、クラウドアーキテクト | 
| 変更を監視して再コンパイルする。 | ルートフォルダで、別のターミナルウィンドウで次のコマンドを実行してコードの変更を監視し、変更が検出されたらコードをコンパイルします。<pre>npm run watch</pre> | 開発者、クラウドアーキテクト | 
| ユニットテストを実行します (AWS CDK のみ)。 | AWS CDK を使用している場合は、ルートフォルダで次のコマンドを実行して Jest ユニットテストを実行します。<pre>npm run test</pre> | 開発者、クラウドアーキテクト | 

### ターゲット AWS アカウントにリソースをデプロイ
<a name="deploy-resources-to-the-target-aws-account"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| デモスタックを AWS にデプロイします。 | アプリケーションは AWS リージョンに依存しません。プロファイルを使用する場合は、「[AWS コマンドラインインターフェイス (AWS CLI) プロファイル](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html)」または 「[AWS CLI 環境変数](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html)」を使用してリージョンを明示的に宣言する必要があります。ルートフォルダで、次のコマンドを実行してデプロイアセンブリを作成し、デフォルトの AWS アカウントとリージョンにデプロイします。AWS CDK<pre>cdk bootstrap<br />cdk deploy</pre>AWS SAM<pre>sam build<br />sam deploy --guided</pre>Terraform<pre>terraform init<br />terraform apply</pre>この処理は、完了まで数分、またはそれ以上かかる場合があります。このコマンドは、AWS CLI に設定されたデフォルトの認証情報を使用します。デプロイの完了後にコンソールに表示される API ゲートウェイ URL をメモしておきます。この情報は Saga 実行フローをテストする際に必要になります。 | 開発者、クラウドアーキテクト | 
| デプロイされたスタックを現在の状態と比較します。 | ルートフォルダで以下のコマンドを実行して、ソースコードに変更を加えた後、デプロイされたスタックを現在の状態と比較します。AWS CDK<pre>cdk diff</pre>AWS SAM<pre>sam deploy</pre>Terraform<pre>terraform plan</pre> | 開発者、クラウドアーキテクト | 

### 実行フローのテスト
<a name="test-the-execution-flow"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Saga 実行フローをテストします。 | スタックをデプロイしたときに前のステップで書き留めた API ゲートウェイ URL に移動します。この URL により、ステートマシンが起動します。さまざまな URL パラメータを渡してステートマシンのフローを操作する方法の詳細については、「[追加情報](#implement-the-serverless-saga-pattern-by-using-aws-step-functions-additional)」セクションを参照してください。結果を表示するには、AWS マネジメントコンソールにサインインし、Step Functions コンソールに移動します。ここでは、Saga ステートマシンのすべてのステップを確認できます。DynamoDB テーブルを表示して、挿入、更新、削除されたレコードを確認することもできます。画面を頻繁に更新すると、トランザクションのステータスが`pending`から`confirmed`に変わるのを確認できます。 予約が成功または失敗したときに SMS メッセージを受信するように、`stateMachine.ts`ファイル内のコードを携帯電話番号で更新することで SNS トピックを購読できます。詳細については、「[追加情報](#implement-the-serverless-saga-pattern-by-using-aws-step-functions-additional)」セクションの「*Amazon SNS*」を参照してください。 | 開発者、クラウドアーキテクト | 

### クリーンアップ
<a name="clean-up"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| リソースをクリーンアップします。 | このアプリケーションにデプロイされたリソースをクリーンアップするには、次のコマンドの 1 つを使用します。AWS CDK<pre>cdk destroy</pre>AWS SAM<pre>sam delete</pre>Terraform<pre>terraform destroy</pre> | アプリ開発者、クラウドアーキテクト | 

## 関連リソース
<a name="implement-the-serverless-saga-pattern-by-using-aws-step-functions-resources"></a>

**テクニカルペーパー**
+ [AWS でのマイクロサービスの実装](https://docs.aws.amazon.com/pdfs/whitepapers/latest/microservices-on-aws/microservices-on-aws.pdf)
+ [サーバーレスアプリケーションレンズ](https://docs.aws.amazon.com/wellarchitected/latest/serverless-applications-lens/welcome.html)

**AWS サービスのドキュメント**
+ [AWS CDK の使用開始](https://docs.aws.amazon.com/cdk/latest/guide/getting_started.html)」
+ [AWS SAM の使用開始](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html)
+ [AWS Step Functions](https://docs.aws.amazon.com/step-functions/)
+ [Amazon DynamoDB](https://docs.aws.amazon.com/dynamodb/)
+ [ Lambda](https://docs.aws.amazon.com/lambda/)
+ [Amazon API Gateway](https://docs.aws.amazon.com/apigateway/)
+ [Amazon SNS](https://docs.aws.amazon.com/sns/)

**チュートリアル**
+ [サーバーレスコンピューティングのハンズオンワークショップ](https://aws.amazon.com/serverless-workshops/)

## 追加情報
<a name="implement-the-serverless-saga-pattern-by-using-aws-step-functions-additional"></a>

**コード**

テスト目的で、このパターンは API ゲートウェイ と、Step Functions ステートマシンをトリガーするテスト Lambda 関数をデプロイします。Step Functions を使用すると、「ReserveFlight」、「ReserveCarRental」、「ProcessPayment」、「ConfirmFlight」、「ConfirmCarRental」の障害を模倣する `run_type` パラメータを渡すことで、旅行予約システムの機能を制御できます。

`saga`Lambda 関数 (`sagaLambda.ts`) は API ゲートウェイ URL のクエリパラメータから入力を受け取り、次の JSON オブジェクトを作成し、それをStep Functions に渡して実行させます。

```
let input = {
"trip_id": tripID, //  value taken from query parameter, default is AWS request ID
"depart_city": "Detroit",
"depart_time": "2021-07-07T06:00:00.000Z",
"arrive_city": "Frankfurt",
"arrive_time": "2021-07-09T08:00:00.000Z",
"rental": "BMW",
"rental_from": "2021-07-09T00:00:00.000Z",
"rental_to": "2021-07-17T00:00:00.000Z",
"run_type": runType // value taken from query parameter, default is "success"
};
```

次の URL パラメータを渡すことで、Step Functions ステートマシンのさまざまなフローを試すことができます。
+ **実行成功** ─ https://\$1api gateway url\$1
+ **リザーブフライトの失敗** ─ https://\$1api gateway url\$1?**runType=failFlightsReservation**
+ **フライト確認の失敗** ─ https://\$1api gateway url\$1?**runType=failFlightsConfirmation**
+ **レンタカー予約の失敗** ─ https://\$1api gateway url\$1?**runType=failCarRentalReservation**
+ **レンタカー確認の失敗** ─ https：//\$1API ゲートウェイ url\$1? **runType=レンタカー確認失敗**
+ **支払い処理失敗** ─ https://\$1api gateway url\$1?**runType=failPayment**
+ **トリップ ID を渡す** ─ https://\$1api gateway url\$1?**tripID=**\$1by default, trip ID will be the AWS request ID\$1

**IaC テンプレート**

リンクされたリポジトリには、サンプル旅行予約アプリケーション全体を作成するのに使用できる IaC テンプレートが含まれています。
+ [AWS CDK によるデプロイ](https://serverlessland.com/workflows/saga-pattern-cdk)
+ [AWS SAM によるデプロイ](https://serverlessland.com/workflows/saga-pattern-sam)
+ [テラフォームによるデプロイ](https://serverlessland.com/workflows/saga-pattern-tf)

**DynamoDB テーブル**

フライト、レンタカー、支払いテーブルのデータモデルは次のとおりです。

```
Flight Data Model:
 var params = {
      TableName: process.env.TABLE_NAME,
      Item: {
        'pk' : {S: event.trip_id},
        'sk' : {S: flightReservationID},
        'trip_id' : {S: event.trip_id},
        'id': {S: flightReservationID},
        'depart_city' : {S: event.depart_city},
        'depart_time': {S: event.depart_time},
        'arrive_city': {S: event.arrive_city},
        'arrive_time': {S: event.arrive_time},
        'transaction_status': {S: 'pending'}
      }
    };

Car Rental Data Model:
var params = {
      TableName: process.env.TABLE_NAME,
      Item: {
        'pk' : {S: event.trip_id},
        'sk' : {S: carRentalReservationID},
        'trip_id' : {S: event.trip_id},
        'id': {S: carRentalReservationID},
        'rental': {S: event.rental},
        'rental_from': {S: event.rental_from},
        'rental_to': {S: event.rental_to},
        'transaction_status': {S: 'pending'}
      }
    };

Payment Data Model:
var params = {
      TableName: process.env.TABLE_NAME,
      Item: {
        'pk' : {S: event.trip_id},
        'sk' : {S: paymentID},
        'trip_id' : {S: event.trip_id},
        'id': {S: paymentID},
        'amount': {S: "750.00"}, // hard coded for simplicity as implementing any monetary transaction functionality is beyond the scope of this pattern
        'currency': {S: "USD"},
        'transaction_status': {S: "confirmed"}
      }
    };
```

**Lambda 関数**

Step Functions でのステートマシンフローと実行をサポートするために、以下の関数が作成されます。
+ **フライトを予約**：フライトを予約するために、`transaction_status`が`pending`であるレコードをDynamoDB Flightsテーブルに挿入します。
+ **フライトを確認**：DynamoDB フライトテーブルのレコードを更新して`transaction_status`を`confirmed`に設定し、フライトを確認します。
+ **フライト予約をキャンセル**：DynamoDB フライトテーブルからレコードを削除して、保留中のフライトをキャンセルします。
+ **レンタカーを予約する**：レンタカーを予約するために、`transaction_status`が`pending`であるレコードをDynamoDB CarRentalsテーブルに挿入します。
+ **レンタカーの確認**：DynamoDB CarRentals テーブルのレコードを更新して`transaction_status`を`confirmed`に設定し、レンタカーを確認します。
+ **レンタカーの予約をキャンセル：**DynamoDB CarRentals テーブルからレコードを削除して、保留中のレンタカーをキャンセルします。
+ **支払い処理**：支払いのレコードを DynamoDB 支払いテーブルに挿入します。
+ **支払いをキャンセル**：DynamoDB ペイメントテーブルから支払いのレコードを削除します。

**Amazon SNS**

サンプルアプリケーションでは、SMS メッセージを送信したり、予約の成功または失敗を顧客に通知したりするために、次のトピックとサブスクリプションを作成します。サンプルアプリケーションのテスト中にテキストメッセージを受信したい場合は、ステートマシン定義ファイル内の有効な電話番号で SMS サブスクリプションを更新してください。

AWS CDK スニペット (次のコードの 2 行目に電話番号を追加)：

```
const topic = new  sns.Topic(this, 'Topic');
topic.addSubscription(new subscriptions.SmsSubscription('+11111111111'));
const snsNotificationFailure = new tasks.SnsPublish(this ,'SendingSMSFailure', {
topic:topic,
integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE,
message: sfn.TaskInput.fromText('Your Travel Reservation Failed'),
});
 
const snsNotificationSuccess = new tasks.SnsPublish(this ,'SendingSMSSuccess', {
topic:topic,
integrationPattern: sfn.IntegrationPattern.REQUEST_RESPONSE,
message: sfn.TaskInput.fromText('Your Travel Reservation is Successful'),
});
```

AWS SAM スニペット (`+1111111111`文字列を有効な電話番号に置き換える)：

```
  StateMachineTopic11111111111:
    Type: 'AWS::SNS::Subscription'
    Properties:
      Protocol: sms
      TopicArn:
        Ref: StateMachineTopic
      Endpoint: '+11111111111'
    Metadata:
      'aws:sam:path': SamServerlessSagaStack/StateMachine/Topic/+11111111111/Resource
```

Terraform スニペット (`+111111111`文字列を有効な電話番号に置き換える)：

```
resource "aws_sns_topic_subscription" "sms-target" {
  topic_arn = aws_sns_topic.topic.arn
  protocol  = "sms"
  endpoint  = "+11111111111"
}
```

**予約成功**

以下のフローは、「ReserveFlight」、「ReserveCarRental」、「ProcessPayment」の後に「ConfirmFlight」と「ConfirmCarRental」の順で予約が成功するフローです。予約が成功したことは、SNS トピックの購読者に送信される SMS メッセージを通じてお客様に通知されます。

![\[saga パターンを使用して Step Functions によって実装された予約の成功例。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/fec0789c-d9b1-4d80-b179-dd9a7ecbec07/images/f58c894e-7721-4bc7-8f7d-29f23faa5dc1.png)


**予約失敗**

このフローは、サガ・パターンの失敗の一例です。フライトやレンタカーの予約後に「ProcessPayment」が失敗すると、手順は逆の順序でキャンセルされます。 予約が解除され、SNS トピックのサブスクライバーに送信される SMS メッセージを通じてお客様に障害が通知されます。

![\[saga パターンを使用して Step Functions によって実装された予約の失敗例。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/fec0789c-d9b1-4d80-b179-dd9a7ecbec07/images/7c64d326-be27-42c3-b03f-d677efedb9a7.png)


# AWS CDK で Amazon ECS Anywhere を設定して、オンプレミスコンテナアプリケーションを管理します。
<a name="manage-on-premises-container-applications-by-setting-up-amazon-ecs-anywhere-with-the-aws-cdk"></a>

*Amazon Web Services、Dr. Rahul Sharad Gaikwad*

## 概要
<a name="manage-on-premises-container-applications-by-setting-up-amazon-ecs-anywhere-with-the-aws-cdk-summary"></a>

「[Amazon ECS Anywhere](https://aws.amazon.com/ecs/anywhere/)」は、Amazon Elastic Container Service (Amazon ECS) の拡張機能です。ECS Anywhere を使用して、ネイティブの Amazon ECS タスクをオンプレミス環境または顧客管理型環境にデプロイできます。この機能は、コストを削減し、複雑なローカルコンテナのオーケストレーションと操作を軽減することに役立ちます。ECS Anywhere を使用して、オンプレミス環境とクラウド環境の両方でコンテナアプリケーションをデプロイして実行できます。これにより、チームが複数のドメインやスキルセットを習得しまたは複雑なソフトウェアを独自に管理しする必要がなくなります。

このパターンは、AWS Cloud Development Kit (「[AWS CDK](https://aws.amazon.com/cdk/)」) スタックを使用して ECS Anywhere を設定する手順を示しています。

## 前提条件と制限事項
<a name="manage-on-premises-container-applications-by-setting-up-amazon-ecs-anywhere-with-the-aws-cdk-prereqs"></a>

**前提条件**
+ アクティブなAWS アカウント
+ AWS コマンドラインインターフェイス (AWS CLI)は、「インストール」および「設定」されています。(AWS CLI ドキュメントの「[AWS CLI のインストール、更新、アンインストール](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html)」を参照してください)。 
+ AWS CDK Toolkit がインストールされ、設定されています。(AWS CDK ドのキュメントの「[AWS CDK Toolkit](https://docs.aws.amazon.com/cdk/v2/guide/cli.html)」を参照し、指示に従ってバージョン 2 をグローバルにインストールします。)
+ ノードパッケージマネージャー (npm) は、TypeScript で AWS CDK 用にインストールし設定されています。（npm ドキュメントの「[Node.js と npm のダウンロードとインストール](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)」を参照してください。）

**制限事項**
+ 制限と考慮事項については、「Amazon ECS のドキュメント」の「[外部インスタンス (Amazon ECS Anywhere)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/ecs-anywhere.html#ecs-anywhere-considerations)」を参照してください。

**製品バージョン**
+ AWS CDK Toolkit バージョン 2
+ npm バージョン 7.20.3 以降
+ Node.js バージョン 16.6.1 以降

## アーキテクチャ
<a name="manage-on-premises-container-applications-by-setting-up-amazon-ecs-anywhere-with-the-aws-cdk-architecture"></a>

**ターゲットテクノロジースタック**
+ AWS CloudFormation
+ AWS CDK
+ Amazon ECS Anywhere
+ AWS Identity and Access Management (IAM)

**ターゲットアーキテクチャ**

次の図は、このパターンで実装されたように、TypeScript でAWS CDK を使用する ECS Anywhere 設定の高レベルのシステムアーキテクチャを示しています。

1. AWS CDK スタックをデプロイする場合、AWS に CloudFormation スタックが作成されます。

1. CloudFormation スタックは Amazon ECS クラスターと関連する AWS リソースをプロビジョニングします。

1. Amazon ECS クラスターに外部インスタンスを登録するには、仮想マシン (VM) に AWS Systems Manager Agent (SSM Agent) をインストールし、その VM を AWS Systems Manager 管理型インスタンスとして登録する必要があります。 

1. また、Amazon ECS コンテナエージェントと Docker を VM にインストールして、Amazon ECS クラスターの外部インスタンスとして登録する必要があります。

1. 外部インスタンスを Amazon ECS クラスターに登録して設定すると、外部インスタンスとして登録された VM 上で複数のコンテナを実行できます。

![\[TypeScript とともに AWS CDK を使用した ECS Anywhere のセットアップ。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/3ed63c00-40e7-4831-bb9d-63049c3490aa/images/ff7dc774-830d-4b9f-8262-7314afe7a033.png)


 

**自動化とスケール**

このパターンで提供される「[GitHub リポジトリ](https://github.com/aws-samples/amazon-ecs-anywhere-cdk-samples/)」、AWS CDK をInfrastructure as Code (IaC) ツールとして使用して、このアーキテクチャの設定を作成します。AWS CDK は、リソースのオーケストレーションと ECS Anywhere のセットアップに役立ちます。

## ツール
<a name="manage-on-premises-container-applications-by-setting-up-amazon-ecs-anywhere-with-the-aws-cdk-tools"></a>
+ [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/latest/guide/home.html) は、AWS クラウドインフラストラクチャをコードで定義してプロビジョニングするのに役立つソフトウェア開発フレームワークです。
+ 「[AWS コマンドラインインターフェイス (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)」は、オープンソースのツールであり、コマンドラインシェルのコマンドを使用して AWS サービスとやり取りすることができます。

**Code**

このパターンのソースコードは、「[Amazon ECS Anywhere CDK Samples](https://github.com/aws-samples/amazon-ecs-anywhere-cdk-samples)」リポジトリにある GitHub で利用できます。リポジトリをクローンして使用するには、次のセクションの指示に従います。

## エピック
<a name="manage-on-premises-container-applications-by-setting-up-amazon-ecs-anywhere-with-the-aws-cdk-epics"></a>

### AWS CDK の設定を確認
<a name="verify-aws-cdk-configuration"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| AWS CDK のバージョンを確認します。 | 以下のコマンドを使用して、AWS CDK Toolkit のバージョンを確認します。<pre>cdk --version</pre>このパターンには AWS CDK バージョン 2 が必要です。旧バージョンの AWS CDK を使用している場合は、「[AWS CDK のドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/cli.html)」の指示に従って更新してください。 | DevOps エンジニア | 
| AWS 認証情報を設定します。 | 認証情報を設定するには、`aws configure` コマンドを実行し、プロンプトに従ってください。<pre>$aws configure<br />AWS Access Key ID [None]: <your-access-key-ID><br />AWS Secret Access Key [None]: <your-secret-access-key><br />Default region name [None]: <your-Region-name><br />Default output format [None]:</pre> | DevOps エンジニア | 

### AWS CDK 環境の起動
<a name="bootstrap-the-aws-cdk-environment"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| AWS SAM コードリポジトリを複製します。 | 以下のコマンドを使用して、このパターンの GitHub コードリポジトリを複製します。<pre>git clone https://github.com/aws-samples/amazon-ecs-anywhere-cdk-samples.git</pre> | DevOps エンジニア | 
| 環境を起動します。 | 使用したいアカウントと AWS リージョンに AWS CloudFormation テンプレートをデプロイするには、以下のコマンドを実行します。<pre>cdk bootstrap <account-number>/<Region></pre>詳細については、AWS CDK ドキュメントの「[ブートストラップ](https://docs.aws.amazon.com/cdk/latest/guide/bootstrapping.html)」を参照してください。 | DevOps エンジニア | 

### プロジェクトを構築してデプロイ
<a name="build-and-deploy-the-project"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| パッケージの依存関係をインストールし、TypeScript ファイルをコンパイルします。 | パッケージの依存関係をインストールし、次のコマンドを実行して TypeScript ファイルをコンパイルします。<pre>$cd amazon-ecs-anywhere-cdk-samples<br />$npm install<br />$npm fund </pre>これらのコマンドは、すべてのパッケージをサンプルリポジトリからインストールします。 パッケージが見つからないというエラーが表示される場合は、以下のいずれかのコマンドを使用してください。<pre>$npm ci   </pre>-または-<pre>$npm install -g @aws-cdk/<package_name></pre>詳細については、npm のドキュメントの「[npm ci](https://docs.npmjs.com/cli/v7/commands/npm-ci)」と「[npm install](https://docs.npmjs.com/cli/v7/commands/npm-install)」を参照してください。 | DevOps エンジニア | 
| プロジェクトをビルドします。 | プロジェクト コードをビルドするには、次のコマンドを実行します。<pre>npm run build</pre>プロジェクトの構築とデプロイの詳細については、「AWS CDK のドキュメント」の「[初めての AWS CDK アプリケーション](https://docs.aws.amazon.com/cdk/latest/guide/hello_world.html#:~:text=the%20third%20parameter.-,Synthesize%20an%20AWS%20CloudFormation%20template,-Synthesize%20an%20AWS)」を参照してください。 | DevOps エンジニア | 
| プロジェクトをデプロイします。 | プロジェクトコードをデプロイするには、コマンドを実行します。<pre>cdk deploy</pre> | DevOps エンジニア | 
| スタックの作成と出力を検証します。 | 「[https://console.aws.amazon.com/cloudformation](https://console.aws.amazon.com/cloudformation/)」で** **AWS CloudFormation コンソールを開き、`EcsAnywhereStack` スタックを選択します。**[出力]** タブに、外部 VM で実行するコマンドが表示されます。 | DevOps エンジニア | 

### オンプレミスマシンの設定
<a name="set-up-an-on-premises-machine"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Vagrant を使用して VM を設定します。 | デモンストレーションの目的で、「[HashiCorp Vagrant](https://www.vagrantup.com/)」を使用して VM を作成できます。Vagrant は、ポータブルな仮想ソフトウェア開発環境を構築し保守するためのオープンソースユーティリティです。Vagrantfile が置かれているルートディレクトリから  `vagrant up`  コマンドを実行して Vagrant VM を作成します。詳細については、「Vagrant のドキュメント」を参照してください。 | DevOps エンジニア | 
| VM を外部インスタンスとして登録します。 | 1. `vagrant ssh` コマンドを使用して Vagrant VM にログインします。詳細については、「Vagrant のドキュメント」を参照してください。2. VM を AWS Systems Manager に登録しまたは外部インスタンスをアクティブ化するために使用できるアクティベーションコードと ID を作成します。このコマンドからの出力に、  `ActivationId` と  `ActivationCode` 値が含まれます。 <pre>aws ssm create-activation --iam-role EcsAnywhereInstanceRole | tee ssm-activation.json</pre>3. アクティベーション ID とコード値を出力します。<pre>export ACTIVATION_ID=<activation-ID><br />export ACTIVATION_CODE=<activation-code></pre>4. オンプレミスのサーバーまたは仮想マシン (VM) で、インストールスクリプトをダウンロードします。<pre>curl -o "ecs-anywhere-install.sh" "https://amazon-ecs-agent.s3.amazonaws.com/ecs-anywhere-install-latest.sh" && sudo chmod +x ecs-anywhere-install.sh</pre>5. オンプレミス サーバーまたは VM でインストール スクリプトを実行します。<pre>sudo ./ecs-anywhere-install.sh \<br />    --cluster test-ecs-anywhere \<br />     --activation-id $ACTIVATION_ID \<br />     --activation-code $ACTIVATION_CODE \<br />    --region <Region></pre>VM の設定と登録の詳細については、「Amazon ECS のドキュメント」の「[クラスターへの外部インスタンスの登録](https://docs.amazonaws.cn/en_us/AmazonECS/latest/developerguide/ecs-anywhere-registration.html)」を参照してください。 | DevOps エンジニア | 
| ECS Anywhere と外部 VM のステータスを確認してください。 | 仮想ボックスが Amazon ECS コントロールプレーンに接続され、実行中になっているかを確認するには、以下のコマンドを使用します。<pre>aws ssm describe-instance-information<br />aws ecs list-container-instances --cluster $CLUSTER_NAME</pre> | DevOps エンジニア | 

### クリーンアップ
<a name="clean-up"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| リソースをクリーンアップして削除する。 | このパターンを確認したら、追加料金が発生しないように、作成したリソースを削除する必要があります。クリーンアップするには、以下のコマンドを実行します。<pre>cdk destroy</pre> | DevOps エンジニア | 

## 関連リソース
<a name="manage-on-premises-container-applications-by-setting-up-amazon-ecs-anywhere-with-the-aws-cdk-resources"></a>
+ 「[Amazon ECS Anywhere のドキュメント](https://aws.amazon.com/ecs/anywhere/)」 
+ 「[Amazon ECS Anywhere デモ](https://www.youtube.com/watch?v=-eud6yUXsJM)」
+ 「[Amazon ECS Anywhere Workshop Samples](https://github.com/aws-samples/aws-ecs-anywhere-workshop-samples)」

# ASP.NET ウェブフォームアプリケーションを AWS で最新化
<a name="modernize-asp-net-web-forms-applications-on-aws"></a>

*Amazon Web Services、Vijai Anand Ramalingam、Sreelaxmi Pai*

## 概要
<a name="modernize-asp-net-web-forms-applications-on-aws-summary"></a>

このパターンでは、従来のモノリス型の ASP.NET Web フォームアプリケーションを AWS の ASP.NET Core に移行してモダナイズする手順を説明しています。

ASP.NET ウェブフォームアプリケーションを ASP.NET Core に移行すると、Linux のパフォーマンスの利点、コスト削減、Linuxの強固なエコシステムを活用できます。ただし、これは手作業による多大な労力がかかる可能性があります。このパターンでは、レガシーアプリケーションは段階的なアプローチを使用して段階的に最新化され、その後 AWS クラウドにコンテナ化されます。

ショッピングカートのレガシー全体のアプリケーションを検討します。ASP.NET Web フォームアプリケーションとして作成され、コードビハインド (`aspx.cs`) ファイルを含む［.aspx］ページで構成されていると仮定してみましょう。最新化プロセスには、3 つのステップがあります。

1. 適切な分解パターンを使用して、モノリスをマイクロサービスに分割します。詳細については、AWS 規範ガイダンスのウェブサイトにある「[モノリスをマイクロサービスに分解する](https://docs.aws.amazon.com/prescriptive-guidance/latest/modernization-decomposing-monoliths/)」ガイドを参照してください。

1. レガシー ASP.NET ウェブフォーム (.NET フレームワーク) アプリケーションを.NET 5 以降の ASP.NET Core に移行します。このパターンでは、Porting Assistant for .NET でASP.NET Web フォームアプリケーションをスキャンし、ASP.NET Core との非互換性を確認します。これにより、手動での移行作業が軽減されます。

1. React を使用して Web Forms UI layer を再開発します。このパターンには UI の再開発が含まれていません。手順については、「React のドキュメント」の「[React アプリを作成](https://reactjs.org/docs/create-a-new-react-app.html)」を参照してください。

1. ウェブフォームのコードビハインドファイル (ビジネスインターフェイス) を ASP.NET Core web API として再開発します。このパターンでは、NDepend レポートで必要なファイルと依存関係を識別しやすくなります。

1. Porting Assistant for .NET で、レガシーアプリケーション内のビジネスロジックやデータアクセスなどの共有プロジェクトや共通プロジェクトを .NET 5 以降にアップグレードします。 

1. AWS サービスを追加してアプリケーションを補完します。例えば、「[Amazon CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html)」を使用して、アプリケーションのログのモニタリング、保存、アクセスを行うことができます。また、「[AWS Systems Manager](https://aws.amazon.com/systems-manager/)」を使用して、アプリケーションの設定を保存できます。

1. 最新のASP.NET Core Applicationsをコンテナ化します。このパターンでは、Visual Studio の Linux を対象とする Docker ファイルを作成し、Docker Desktop でローカルでテストします。このステップは、レガシーアプリケーションがオンプレミスまたは Amazon Elastic Compute Cloud (Amazon EC2) Windows インスタンスで既に実行されていることを前提としています。詳細については、「[Amazon EC2 Linux インスタンスで ASP.NET Core web API Docker コンテナを実行する」というパターン](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/run-an-asp-net-core-web-api-docker-container-on-an-amazon-ec2-linux-instance.html)」を参照してください。

1. 最新の ASP.NET Core アプリケーションを、Amazon Elastic Container Service (Amazon ECS) にデプロイします。このパターンはデプロイステップには適用されません。手順については、「[Amazon ECS Workshop](https://ecsworkshop.com/)」を参照してください。

**注記**  
このパターンには、UI 開発、データベースの近代化、コンテナデプロイのステップは含まれていません。

## 前提条件と制限事項
<a name="modernize-asp-net-web-forms-applications-on-aws-prereqs"></a>

**前提条件**
+ 「[Visual Studio](https://visualstudio.microsoft.com/downloads/)」または「[Visual Studio Code](https://code.visualstudio.com/download)」をダウンロードし、インストールします。
+ AWS マネジメントコンソールと AWS コマンドラインインターフェイス (AWS CLI) バージョン 2 で AWS アカウントにアクセスします。(「[AWS CLI の設定手順](https://docs.aws.amazon.com/cli/latest/userguide/install-cliv2.html)」を参照してください。)
+ AWS Toolkit for Visual Studio (「[セットアップ手順](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/setup.html)」をを参照)。
+ 「[ダウンロード済み](https://www.docker.com/products/docker-desktop)」でインストール済みのDocker デスクトップ。
+ 「[ダウンロード済み](https://download.visualstudio.microsoft.com/download/pr/4263dc3b-dc67-4f11-8d46-cc0ae86a232e/66782bbd04c53651f730b2e30a873f18/dotnet-sdk-5.0.203-win-x64.exe)」でインストール済みの .NET SDK、。
+ 「[ダウンロード済み](https://www.ndepend.com/download)」でインストール済みの NDepend ツール。Visual Studio 用の NDepend 拡張機能をインストールするには、`NDepend.VisualStudioExtension.Installer` を実行します ([手順を参照](https://www.ndepend.com/docs/getting-started-with-ndepend#Part1))。ご要件に応じて、Visual Studio 2019 または 2022 を選択できます。 
+ 「[ ダウンロード済みでインストール済み ](https://aws.amazon.com/porting-assistant-dotnet/)」の Porting Assistant for .NET。

## アーキテクチャ
<a name="modernize-asp-net-web-forms-applications-on-aws-architecture"></a>

ショッピングカートアプリケーションの最新化

次の図は、従来の ASP.NET ショッピングカートアプリケーションの最新化プロセスを示しています。

![\[レガシーショッピングカートアプリケーションの最新化\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/36cda8e6-f2cb-4f1a-b37f-fa3045cc5ba1/images/4367e259-9bb3-4eb6-a54d-1c1e2dece7d4.png)


**ターゲットアーキテクチャ**

次の図は、AWS の最新のショッピングカートアプリケーションのアーキテクチャを示しています。ASP.NET Core Web API は、Amazon ECS クラスターにデプロイされます。記録と設定サービスは Amazon CloudWatch Logs と AWS Systems Manager により、提供されています。

![\[AWS 上の ASP.NET ウェブフォームアプリケーションのターゲットアーキテクチャ\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/36cda8e6-f2cb-4f1a-b37f-fa3045cc5ba1/images/ed6d65ec-0dc9-43ab-ac07-1f172e089399.png)


## ツール
<a name="modernize-asp-net-web-forms-applications-on-aws-tools"></a>

**AWS サービス**
+ 「[Amazon ECS](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html)」— Amazon Elastic Container Service (Amazon ECS) は、クラスターでコンテナの実行、停止、管理に使用される、高度にスケーラブルで高速のコンテナ管理サービスです。AWS Fargate が管理するサーバーレスインフラ上でタスクやサービスを実行できます。または、インフラストラクチャをより詳細に制御するために、管理する EC2 インスタンスのクラスターでタスクとサービスを実行できます。
+ 「[Amazon CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html)」— Amazon CloudWatch Logs により、使用中のすべてのシステム、アプリケーション、AWS のサービスからのログを、一元管理することができます。ログを表示したり、特定のエラーコードやパターンを検索したり、特定のフィールドに基づいてフィルタリングしたり、将来の分析のために安全にアーカイブしたりできます。
+ 「[AWS Systems Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/what-is-systems-manager.html)」— AWS Systems Manager は、AWS でインフラストラクチャの表示と制御に使用できる AWS サービスです。Systems Manager コンソールを使用すると、複数の AWS サービスからの運用データを表示し、AWS リソース全体の運用タスクを自動化できます。Systems Manager は、マネージドインスタンスをスキャンし、検出されるポリシー違反を報告（または是正措置を講じる）して、セキュリティとコンプライアンスを維持できます。

**ツール**
+ 「[Visual Studio](https://visualstudio.microsoft.com/)」または「[Visual Studio Code](https://code.visualstudio.com/)」— .NET アプリケーション、ウェブ APIおよびその他のプログラムを構築するためのツール。
+ 「[AWS Toolkit for Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html)」— AWS サービスを使用する .NET アプリケーションの開発、デバッグ、デプロイに役立つ Visual Studio の拡張機能。
+ 「[Docker Desktop](https://www.docker.com/products/docker-desktop)」— コンテナ化されたアプリケーションの構築とデプロイを簡単にするツール。
+ 「[NDepend](https://www.ndepend.com/features/)」— .NET コードの依存関係、品質問題、コード変更をモニタリングするアナライザー。
+ 「[Porting Assistant for .NET](https://aws.amazon.com/porting-assistant-dotnet/)」— .NET コードをスキャンして.NET Core との非互換性を特定し、移行作業を見積もる分析ツール。

## エピック
<a name="modernize-asp-net-web-forms-applications-on-aws-epics"></a>

### レガシーアプリケーションを .NET 5 以降のバージョンに移行
<a name="port-your-legacy-application-to-net-5-or-later-version"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| .NET Framework のレガシーアプリケーションを.NET 5 にアップグレードします。 | Porting Assistant for .NET で、従来の ASP.NET Web フォームアプリケーションを.NET 5 以降に変換できます。「[Porting Assistant for .NET のドキュメント](https://docs.aws.amazon.com/portingassistant/latest/userguide/porting-assistant-getting-started.html)」の指示に従ってください。 | アプリ開発者 | 
| NDepend レポートを生成します。 | ASP.NET Web フォームアプリケーションをマイクロサービスに分解して最新化すると、レガシーアプリケーションのすべての［.cs］ファイルが必要なくなる場合があります。NDepend を使用すると、任意のコードビハインド (.cs) ファイルのレポートを生成して、すべての呼び出し元と呼び出し先を取得できます。このレポートは、マイクロサービス内の必要なファイルのみを特定して使用するのに役立ちます。NDepend をインストールしたら (「[前提条件](#modernize-asp-net-web-forms-applications-on-aws-prereqs)」セクションを参照)、Visual Studio でレガシーアプリケーションのソリューション (.sln ファイル) を開き、次の手順に従います。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/modernize-asp-net-web-forms-applications-on-aws.html)このプロセスにより、すべての呼び出し元と呼び出し先を一覧表示するコードビハインドファイルのレポートが生成されます。ディペンデンシーグラフについて、詳細は、「[NDepend のドキュメント](https://www.ndepend.com/docs/visual-studio-dependency-graph)」を参照してください。 | アプリ開発者 | 
| 新しい .NET 5 ソリューションを作成します。 | 最新の ASP.NET Core web API 用の新しい .NET 5 (またはそれ以降) 構造を作成するには:[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/modernize-asp-net-web-forms-applications-on-aws.html)プロジェクトとソリューションの作成について、詳細は、「[Visual Studio のドキュメント](https://docs.microsoft.com/en-us/visualstudio/ide/creating-solutions-and-projects)」を参照してください。ソリューションを構築して機能を検証する際、NDepend が特定したファイルに加えて、ソリューションに追加するファイルをいくつか特定する場合があります。 | アプリ開発者 | 

### アプリケーションコードを更新します。
<a name="update-your-application-code"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| ASP.NET Core でウェブ API を実装します。 | 従来のモノリスショッピングカートアプリケーションで特定したマイクロサービスの 1 つが*製品*だと仮定しましょう。前のエピックで*製品*用の ASP.NET Core Web API プロジェクトを新規作成しました。このステップでは、*製品*に関連するすべての Web フォーム (.aspx ページ) を識別してモダナイズします。前述の「[アーキテクチャ](#modernize-asp-net-web-forms-applications-on-aws-architecture)」セクションで説明したように、*製品*が 4 つのウェブフォームで構成されていると仮定します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/modernize-asp-net-web-forms-applications-on-aws.html)各 ウェブフォームを分析し、何らかのロジックを実行するためにデータベースに送信されるすべてのリクエストを識別し、応答を取得する必要があります。各リクエストをウェブ API エンドポイントとして実装できます。ウェブフォームを考慮すると、*製品*には以下のエンドポイントを設定できます。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/modernize-asp-net-web-forms-applications-on-aws.html)前述のように、ビジネスロジック、データアクセス、共有/共通プロジェクトなど、.NET 5 にアップグレードした他のすべてのプロジェクトを再利用できます。 | アプリ開発者 | 
| Amazon CloudWatch Logs を設定します。 | 「[Amazon CloudWatch Logs](https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/WhatIsCloudWatchLogs.html)」を使用して、アプリケーションのログのモニタリング、保存、アクセスを行うことができます。AWS SDK で Amazon CloudWatch Logs にデータを記録できます。また、「[NLog](https://www.nuget.org/packages/AWS.Logger.NLog/)」、「[Log4Net](https://www.nuget.org/packages/AWS.Logger.Log4net/)」、「[ASP.NET Core ロギングフレームワーク](https://www.nuget.org/packages/AWS.Logger.AspNetCore/)」など一般的な.NET ロギングフレームワークを使用して、.NET アプリケーションを CloudWatch Logs と統合することもできます。このステップの詳細については、ブログ記事の「[Amazon CloudWatch Logs と.NET ロギングフレームワーク](https://aws.amazon.com/blogs/developer/amazon-cloudwatch-logs-and-net-logging-frameworks/)」を参照してください。 | アプリ開発者 | 
| AWS Systems Manager Parameter Store を設定します。 | 「[AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html)」で、接続文字列などのアプリケーション設定をアプリケーションコードとは別に保存できます。NuGet パッケージ「[Amazon.Extensions.Configuration.SystemsManager](https://www.nuget.org/packages/Amazon.Extensions.Configuration.SystemsManager/)」を使用すると、アプリケーションがこれらの設定を AWS Systems Manager Parameter Store から .NET Core 設定システムにロードする方法が簡単になります。 このステップの詳細については、ブログ記事の「[AWS Systems Manager向けの.NET Core 設定](https://aws.amazon.com/blogs/developer/net-core-configuration-provider-for-aws-systems-manager/)」を参照してください。 | アプリ開発者 | 

### 認証と認可の追加
<a name="add-authentication-and-authorization"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 認証には共有 Cookie を使用してください。 | 従来のモノリスアプリケーションの最新化は反復的なプロセスであり、モノリスと最新化されたバージョンが共存する必要があります。共有 Cookie を使用すると、2 つのバージョン間でシームレスな認証を実現できます。最新の ASP.NET Core アプリケーションが Cookie を検証している間、従来の ASP.NET アプリケーションは引き続きユーザーの認証情報を検証して Cookie を発行します。 手順とサンプルコードについては、「[サンプル GitHub プロジェクト](https://github.com/aws-samples/dotnet-share-auth-cookie-between-monolith-and-modernized-apps)」を参照してください。 | アプリ開発者 | 

### コンテナをローカルで構築して実行
<a name="build-and-run-the-container-locally"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Visual Studio を使用して Docker イメージを作成します。 | このステップでは、Visual Studio for .NET Core web API を使用して Docker ファイルを作成します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/modernize-asp-net-web-forms-applications-on-aws.html)Visual Studio はお客様のプロジェクト用の Docker ファイルを作成します。サンプル Docker ファイルについては、Microsoft のウェブサイトで「[Docker 用 Visual Studio Container Tools](https://docs.microsoft.com/en-us/visualstudio/containers/overview)」を参照してください。 | アプリ開発者 | 
| Docker Desktop を使用してコンテナを構築して実行します。 | これで Docker Desktop でコンテナを構築、作成、実行できるようになりました。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/modernize-asp-net-web-forms-applications-on-aws.html) | アプリ開発者 | 

## 関連リソース
<a name="modernize-asp-net-web-forms-applications-on-aws-resources"></a>
+ 「[Amazon EC2 Linux インスタンスで ASP.NET Core web API Docker コンテナを実行する](https://docs.aws.amazon.com/prescriptive-guidance/latest/patterns/run-an-asp-net-core-web-api-docker-container-on-an-amazon-ec2-linux-instance.html)」(AWS 規範ガイダンス)
+ 「[Amazon ECS Workshop](https://ecsworkshop.com/)」
+ 「[AWS CloudFormation を使用したCodeDeploy による ECS ブルー/グリーンデプロイの実行](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/blue-green.html)」(AWS CloudFormationドキュメント)
+ 「[NDepend で使用開始](https://www.ndepend.com/docs/getting-started-with-ndepend)」(NDepend のドキュメント)
+ 「[Porting Assistant for .NET](https://aws.amazon.com/porting-assistant-dotnet/)」

## 追加情報
<a name="modernize-asp-net-web-forms-applications-on-aws-additional"></a>

次の表は、従来のショッピングカートアプリケーションのサンプルプロジェクトと、最新の ASP.NET Core アプリケーションの同等のプロジェクトの例を示します。

レガシーソリューション：


| 
| 
| [Project name] (プロジェクト名) | プロジェクトテンプレート | Target framework | 
| --- |--- |--- |
| ビジネスインターフェイス  | クラスライブラリ  | 特定のランタイムライブラリまたは .NET Framework の最小バージョンが必要です。 | 
| BusinessLogic  | クラスライブラリ  | 特定のランタイムライブラリまたは .NET Framework の最小バージョンが必要です。 | 
| WebApplication  | ASP.NET フレームワークアプリケーション  | 特定のランタイムライブラリまたは .NET Framework の最小バージョンが必要です。 | 
| UnitTests  | NUnit Test Project  | 特定のランタイムライブラリまたは .NET Framework の最小バージョンが必要です。 | 
| 共有 -> 共通  | クラスライブラリ  | 特定のランタイムライブラリまたは .NET Framework の最小バージョンが必要です。 | 
| 共有-> フレームワーク  | クラスライブラリ  | 特定のランタイムライブラリまたは .NET Framework の最小バージョンが必要です。 | 

新しいソリューション：


| 
| 
| [Project name] (プロジェクト名) | プロジェクトテンプレート | Target framework | 
| --- |--- |--- |
| BusinessLogic  | クラスライブラリ  | .NET 5.0  | 
| <WebAPI>  | ASP.NET Core Web API  | .NET 5.0  | 
| <WebAPI>.UnitTests  | NUnit 3 Test Project  | .NET 5.0  | 
| 共有 -> 共通  | クラスライブラリ  | .NET 5.0  | 
| 共有-> フレームワーク  | クラスライブラリ  | .NET 5.0  | 

# C\$1 と AWS CDK を使用するサイロモデル用の SaaS アーキテクチャでのテナントオンボーディング
<a name="tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk"></a>

*Amazon Web Services、Tabby Ward、Susmitha Reddy Gankidi、Vijai Anand Ramalingam*

## 概要
<a name="tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk-summary"></a>

Software as a service (SaaS) アプリケーションは、さまざまなアーキテクチャモデルで構築できます。*サイロモデル*とは、テナントに専用のリソースを提供するアーキテクチャを指します。

SaaS アプリケーションは、新しいテナントを環境に導入する際に摩擦のないモデルに依存しています。新しいテナントを作成するのに必要なすべての要素を正常にプロビジョニングして構成するには、多くの場合、多数のコンポーネントのオーケストレーションが必要になります。SaaS アーキテクチャでは、このプロセスをテナントオンボーディングと呼びます。オンボーディングは、オンボーディングプロセスのコードとしてのインフラストラクチャを活用して、すべての SaaS 環境で完全に自動化する必要があります。

このパターンでは、Amazon Web Services (AWS) でテナントを作成し、そのテナントの基本インフラストラクチャをプロビジョニングする例を紹介します。パターンは、C\$1 と AWS Cloud Development Kit (AWS CDK) を使用します。

このパターンでは課金アラームが発生するため、スタックを米国東部 (バージニア北部) または us-east-1、AWS リージョンにデプロイすることをお勧めします。詳細については、[AWS ドキュメント](https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/monitor_estimated_charges_with_cloudwatch.html)を参照してください。

## 前提条件と制限事項
<a name="tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk-prereqs"></a>

前提条件
+ アクティブな [AWS アカウント](https://aws.amazon.com/account/)。
+ このパターンの AWS リソースを作成するのに十分な IAM アクセス権を持つ AWS Identity and Access Management (IAM) プリンシパル。詳細については、「[IAM ロール](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)」を参照してください。
+ 「[Amazon Command Line Interface (AWS CLI) をインストール](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)」し、AWS CDK のデプロイを実行するように「[AWS CLI を設定](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)」します。
+ 「[Visual Studio 2022](https://visualstudio.microsoft.com/downloads/)」をダウンロードしてインストールするか、「[Visual Studio Code](https://code.visualstudio.com/download)」をダウンロードしてインストールしました。
+ 「[AWS Toolkit for Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/setup.html)」のセットアップ。
+ 「[.NET Core 3.1 またはそれ以降](https://dotnet.microsoft.com/download/dotnet-core/3.1)」(C\$1 AWS CDK アプリケーションには必須)
+ 「[Amazon.Lambda.Tools](https://github.com/aws/aws-extensions-for-dotnet-cli#aws-lambda-amazonlambdatools)」がインストールされました。

制限事項
+ AWS CDK は「[AWS CloudFormation](https://aws.amazon.com/cloudformation/)」を使用しているため、AWS CDK アプリケーションには CloudFormation サービスクォータが適用されます。詳細については、「[AWS CloudFormation のクォータ](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/cloudformation-limits.html)」を参照してください。 
+ テナントの CloudFormation スタックは CloudFormation サービスロール `infra-cloudformation-role` を使用して作成され、アクション (`sns`\$1 と `sqs*`) にはワイルドカード文字が使用されますが、リソースは `tenant-cluster` プレフィックスにロックされます。実稼働環境での使用では、この設定を評価し、このサービスロールへの必要なアクセス権のみを提供してください。また、`InfrastructureProvision` Lambda 関数はワイルドカード文字 (`cloudformation*`) を使用して CloudFormation スタックをプロビジョニングしますが、リソースは `tenant-cluster` プレフィックスにロックダウンされます。
+ このサンプルコードの docker ビルドは、`linux/amd64` ベースイメージを強制するために `--platform=linux/amd64` に使用されています。これは、最終的なイメージアーティファクトが、デフォルトで x86-64 アーキテクチャを使用する Lambda に適したものになるようにするためです。ターゲット Lambda アーキテクチャを変更する必要がある場合は、必ず Dockerfiles と AWS CDK コードの両方を変更してください。詳細については、ブログ記事「[AWS Lambda 関数を ARM ベースの AWS Graviton2 プロセッサーに移行する](https://aws.amazon.com/blogs/compute/migrating-aws-lambda-functions-to-arm-based-aws-graviton2-processors/)」を参照してください。
+ スタックの削除プロセスでは、スタックによって生成された CloudWatch Logs (ロググループとログ) はクリーンアップされません。AWS マネジメントコンソール、Amazon CloudWatch コンソール、または API を使用して、ログを手動でクリーンアップする必要があります。

このパターンは例として設定されています。本番環境で使用する場合は、以下の設定を評価し、ビジネス要件に基づいて変更を加えます。
+ この例では、「[AWS Simple Storage Service (Amazon S3)](https://aws.amazon.com/s3/)」バケットでは、わかりやすくするためにバージョニングが有効になっていません。セットアップを評価し、必要に応じて更新してください。
+ この例では、簡単にするために、認証、認可、またはスロットリングなしで [Amazon API Gateway](https://aws.amazon.com/api-gateway/) REST API エンドポイントを設定します。本番環境での使用には、システムをビジネスセキュリティインフラストラクチャと統合することをお勧めします。この設定を評価し、必要に応じて必要なセキュリティ設定を追加してください。
+ このテナントインフラストラクチャの例では、「[Amazon Simple Notification Service (Amazon SNS)](https://aws.amazon.com/sns/)」と「[Amazon Simple Queue Service (Amazon SQS)](https://aws.amazon.com/sqs/)」のセットアップは最小限です。各テナントの「[AWS Key Management Service (AWS KMS)](https://aws.amazon.com/kms/)」は、「[AWS KMS キーポリシー](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-key-management.html#compatibility-with-aws-services)」に基づいて使用するアカウントの「[Amazon CloudWatch](https://aws.amazon.com/cloudwatch/)」サービスと Amazon SNS サービスが利用できるように開放されます。セットアップは単なるプレースホルダーです。ビジネスユースケースに基づいて、必要に応じて設定を調整してください。
+ API エンドポイントと AWS CloudFormation を使用したバックエンドテナントのプロビジョニングと削除を含むがこれらに限定されないセットアップ全体は、基本的なハッピーパスの場合のみを対象としています。ビジネスニーズに基づいて、必要な再試行ロジック、追加のエラー処理ロジック、セキュリティロジックを使用してセットアップを評価し、更新してください。
+ このサンプルコードは、この記事の執筆時点でポリシーを確認するために最新の「[cdk-nag](https://github.com/cdklabs/cdk-nag)」でテストされています。将来、新しいポリシーが施行される可能性があります。これらの新しいポリシーでは、スタックをデプロイする前に、推奨事項に基づいてスタックを手動で変更する必要がある場合があります。既存のコードを見直して、ビジネス要件に合っていることを確認してください。
+ このコードは、作成されるほとんどのリソースに静的に割り当てられた物理名に頼るのではなく、AWS CDK を使用してランダムなサフィックスを生成します。この設定は、これらのリソースが一意であり、他のスタックと競合しないようにするためです。詳細については、「[AWS CDK ドキュメント](https://docs.aws.amazon.com/cdk/v2/guide/resources.html#resources_physical_names)」を参照してください。ビジネス要件に基づいて調整してください。
+ このサンプルコードは、.NET Lambda アーティファクトを Docker ベースのイメージにパッケージ化し、Lambda が提供する「[コンテナイメージランタイム](https://docs.aws.amazon.com/lambda/latest/dg/csharp-image.html)」で実行されます。コンテナイメージランタイムには、標準的な転送および保存メカニズム (コンテナレジストリ) と、より正確なローカルテスト環境 (コンテナイメージを使用) という利点があります。「[Lambda が提供する .NET ランタイム](https://docs.aws.amazon.com/lambda/latest/dg/lambda-csharp.html)」を使用するようにプロジェクトを切り替えて Docker イメージのビルド時間を短縮することもできますが、その場合は転送メカニズムと保存メカニズムを設定し、ローカルセットアップが Lambda セットアップと一致することを確認する必要があります。ユーザーのビジネス要件に合わせてコードを調整してください。

**製品バージョン**
+ AWS CDK バージョン 2.45.0 またはそれ以降
+ Visual Studio 2022

## アーキテクチャ
<a name="tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk-architecture"></a>

**テクノロジースタック**
+ Amazon API Gateway
+ AWS CloudFormation
+ Amazon CloudWatch
+ Amazon DynamoDB
+ AWS Identity and Access Management (IAM)
+ AWS KMS
+ AWS Lambda
+ Amazon S3
+ Amazon SNS
+ Amazon SQS

**アーキテクチャ**

次の図に、テナントスタックの作成フローを示します。コントロールプレーンとテナントテクノロジースタックの詳細については、「*追加情報*」セクションを参照してください。

![\[テナントを作成し、AWS でテナントの基本インフラストラクチャをプロビジョニングするワークフロー。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/5baef800-fe39-4eb8-b11d-2c23eb3175fc/images/0b579484-b87c-4acb-8c60-8c33c18370e3.png)


テナントスタックの作成フロー

1. ユーザーは、新しいテナントペイロード (テナント名、テナントの説明) を含む POST API リクエストを JSON 形式で Amazon API Gateway がホストする REST API に送信します。API Gateway はリクエストを処理し、バックエンドの Lambda テナントオンボーディング機能に転送します。この例では、認可も認証もありません。実稼働環境では、この API を SaaS インフラストラクチャセキュリティシステムと統合する必要があります。

1. テナントオンボーディング機能がリクエストを検証します。次に、テナント名、生成されたテナントユニバーサルユニーク識別子 (UUID)、テナントの説明を含むテナントレコードを Amazon DynamoDB テナントオンボーディングテーブルに保存しようとします。 

1. DynamoDB がレコードを保存すると、DynamoDB ストリームはダウンストリームの Lambda テナントインフラストラクチャ機能を開始します。

1. テナントインフラストラクチャ Lambda 関数は、受信した DynamoDB ストリームに基づいて動作します。ストリームが INSERT イベント用である場合、関数はストリームの NewImage セクション (最新の更新レコード、テナント名フィールド) を使用して CloudFormation を呼び出し、S3 バケットに保存されているテンプレートを使用して新しいテナントインフラストラクチャを作成します。CloudFormation テンプレートには、テナント名パラメーターが必要です。 

1. AWS CloudFormation は、CloudFormation テンプレートと入力パラメータに基づいてテナントインフラストラクチャを作成します。

1. 各テナントインフラストラクチャ設定には、CloudWatch アラーム、請求アラーム、およびアラームイベントがあります。

1. アラームイベントは SNS トピックへのメッセージになり、テナントの AWS KMS キーによって暗号化されます。

1. SNS トピックは、受信したアラームメッセージを SQS キューに転送し、その SQS キューは、テナントの AWS KMS によって暗号化キーとして暗号化されます。

他のシステムを Amazon SQS と統合して、キュー内のメッセージに基づいてアクションを実行できます。この例では、コードを汎用的に保つため、受信メッセージはキューに残り、手動で削除する必要があります。

テナントスタックの削除フロー

1. ユーザーは、新しいテナントペイロード (テナント名、テナントの説明) を含む DELETE API リクエストを JSON 形式で Amazon API Gateway がホストする REST API に送信します。このリクエストは Amazon API Gateway がホストする REST API で処理され、テナントオンボーディング機能に転送されます。この例では、認可も認証もありません。実稼働環境では、この API は SaaS インフラストラクチャセキュリティシステムと統合されます。

1. テナントオンボーディング機能はリクエストを確認し、テナントオンボーディングテーブルからテナントレコード (テナント名) を削除しようとします。 

1. DynamoDB がレコードを正常に削除すると (レコードはテーブルに存在し、削除された)、DynamoDB ストリームはダウンストリーム Lambda テナントインフラストラクチャ関数を開始します。

1. テナントインフラストラクチャ Lambda 関数は、受信した DynamoDB ストリームレコードに基づいて動作します。ストリームが REMOVE イベント用である場合、関数はレコードの OldImage セクション (最新の変更 (削除) の前のレコード情報と Tenant Name フィールド) を使用して、そのレコード情報に基づいて既存のスタックの削除を開始します。

1. AWS CloudFormation は、入力に従ってターゲットテナントスタックを削除します。

## ツール
<a name="tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk-tools"></a>

**AWS サービス**
+ 「[Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html)」は、任意のスケールで REST、HTTP、WebSocket API を作成、公開、維持、監視、保護する上で役立ちます。
+ [AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/v2/guide/home.html) は、AWS クラウドインフラストラクチャをコードで定義してプロビジョニングするのに役立つソフトウェア開発フレームワークです。
+ [AWS CDK Toolkit](https://docs.aws.amazon.com/cdk/v2/guide/cli.html) は、AWS Cloud Development Kit (AWS CDK) アプリケーションの操作に役立つコマンドラインクラウド開発キットです。
+ 「[AWS コマンドラインインターフェイス (AWS CLI)](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html)」は、オープンソースのツールであり、コマンドラインシェルのコマンドを使用して AWS サービスとやり取りすることができます。
+ [AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html) を使用すると、AWS リソースをセットアップし、迅速かつ一貫したプロビジョニングを行い、AWS アカウントとリージョン全体でライフサイクル全体にわたってリソースを管理できます。
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) は、フルマネージド NoSQL データベースサービスです。高速かつ予測可能でスケーラブルなパフォーマンスを提供します。
+ 「[AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html)」は、AWS リソースへのアクセスを安全に管理し、誰が認証され、使用する権限があるかを制御するのに役立ちます。
+ [AWS Key Management Service (AWS KMS)](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) は、データの保護に役立つ暗号キーを作成および管理する上で役立ちます。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) は、サーバーのプロビジョニングや管理を行うことなくコードを実行できるコンピューティングサービスです。必要に応じてコードを実行し、自動的にスケーリングするため、課金は実際に使用したコンピューティング時間に対してのみ発生します。
+ [Amazon Simple Storage Service (Amazon S3)](https://docs.aws.amazon.com/AmazonS3/latest/userguide/Welcome.html) は、量にかかわらず、データを保存、保護、取得するのに役立つクラウドベースのオブジェクトストレージサービスです。
+ 「[Amazon Simple Notiﬁcation Service (Amazon SNS)](https://docs.aws.amazon.com/sns/latest/dg/welcome.html)」は、ウェブサーバーやメールアドレスなど、パブリッシャーとクライアント間のメッセージの交換を調整および管理するのに役立ちます。
+ 「[Amazon Simple Queue Service (Amazon SQS)](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/welcome.html)」は、分散したソフトウェアシステムとコンポーネントの統合と分離を支援し、安全で耐久性があり、利用可能なホスト型キューを提供します。
+ 「[AWS Toolkit for Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html)」は Visual Studio 統合開発環境 (IDE) 用のプラグインです。Toolkit for Visual Studio は、AWS サービスを使用する.NET アプリケーションの開発、デバッグ、およびデプロイをサポートします。

その他のツール
+ 「[Visual Studio](https://docs.microsoft.com/en-us/visualstudio/ide/whats-new-visual-studio-2022?view=vs-2022)」は、コンパイラー、コード補完ツール、グラフィカルデザイナー、およびソフトウェア開発をサポートするその他の機能を備えた IDE です。

**Code**

このパターンのコードは、「[SaaS Architecture for Silo Model APG 例のテナントオンボーディング](https://github.com/aws-samples/tenant-onboarding-in-saas-architecture-for-silo-model-apg-example)」リポジトリにあります。

## エピック
<a name="tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk-epics"></a>

### AWS CDK のセットアップ
<a name="set-up-aws-cdk"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Node.js がインストールされていることを確認してください。 | Node.js がローカルマシンにインストールされていることを確認するには、次のコマンドを実行します。<pre>node --version</pre> | AWS 管理者、AWS DevOps | 
| AWS CDK Toolkit をインストールします。 | AWS CDK Toolkit をローカルマシンにインストールするには、次のコマンドを実行します。<pre>npm install -g aws-cdk</pre>npm がインストールされていない場合は、「[Node.js サイト](https://nodejs.org/en/download/package-manager/)」からインストールできます。 | AWS 管理者、AWS DevOps | 
| AWS CDK ツールキットのバージョンを確認します。 | AWS CDK Toolkit のバージョンがマシンに正しくインストールされていることを確認するには、次のコマンドを実行します。 <pre>cdk --version</pre> | AWS 管理者、AWS DevOps | 

### テナントオンボーディング (コントロールプレーン) のコードを確認してください。
<a name="review-the-code-for-the-tenant-onboarding-control-plane"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| リポジトリのクローン作成 | 「[リポジトリ](https://github.com/aws-samples/tenant-onboarding-in-saas-architecture-for-silo-model-apg-example)」をクローンし、`\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example` フォルダに移動します。Visual Studio 2022 で `\src\TenantOnboardingInfra.sln` ソリューションファイルを開きます。`TenantOnboardingInfraStack.cs` ファイルを開き、コードを確認します。このスタックの一部として、以下のリソースが作成されます。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.html) | AWS 管理者、AWS DevOps | 
| CloudFormation のテンプレートを確認してください。 | `\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\template` フォルダーで、`infra.yaml` を開き、CloudFormation テンプレートを確認します。このテンプレートは、テナントオンボーディング DynamoDB テーブルから取得したテナント名でハイドレイトされます。このテンプレートはテナント固有のインフラストラクチャをプロビジョニングします。この例では、AWS KMS キー、Amazon SNS、Amazon SQS、および CloudWatch アラームのプロビジョニングを行います。 | アプリ開発者、AWS DevOps | 
| テナントオンボーディング機能を確認してください。 | `Function.cs` を開き、テナントオンボーディング関数のコードを確認してください。この関数は Visual Studio AWS Lambda Project (.NET Core- C\$1) テンプレートと.NET 6 (コンテナイメージ) ブループリントを使用して作成されています。`Dockerfile` を開き、コードを確認します。`Dockerfile` は、Lambda コンテナイメージを構築するための手順を含むテキストファイルです。次の NuGet パッケージが依存関係として `TenantOnboardingFunction` プロジェクトに追加されることに注意してください。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.html) | アプリ開発者、AWS DevOps | 
| テナントのインフラストラクチャプロビジョニング機能を確認してください。 | `\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\src\InfraProvisioningFunction` に移動します。`Function.cs` を開き、テナントインフラストラクチャプロビジョニング関数のコードを確認してください。この関数は Visual Studio AWS Lambda Project (.NET Core- C\$1) テンプレートと.NET 6 (コンテナイメージ) ブループリントを使用して作成されています。`Dockerfile` を開き、コードを確認します。次の NuGet パッケージが依存関係として `InfraProvisioningFunction` プロジェクトに追加されることに注意してください。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.html) | アプリ開発者、AWS DevOps | 

### AWS リソースをデプロイする
<a name="deploy-the-aws-resources"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| ソリューションをビルドします。 | ソリューションを構築するには、以下のステップを実行します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.html)ソリューションをビルドする前に、必ず `\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example\src\TenantOnboardingInfra` プロジェクト内の `Amazon.CDK.Lib NuGet` パッケージを最新バージョンに更新してください。 | アプリ開発者 | 
| AWS CDK 環境をブートストラップします。 | Windows コマンドプロンプトを開き、`cdk.json` ファイルがある AWS CDK アプリケーションのルートフォルダに移動します (`\tenant-onboarding-in-saas-architecture-for-silo-model-apg-example`)。ブートストラップの場合は、次のコマンドを実行します。<pre>cdk bootstrap </pre>認証情報用の AWS プロファイルを作成した場合は、プロファイルでコマンドを使用してください。<pre>cdk bootstrap --profile <profile name><br />  </pre> | AWS 管理者、AWS DevOps | 
| AWS CDK スタックを一覧表示します。 | このプロジェクトの一部として作成されるスタックをすべて一覧表示するには、次のコマンドを実行します。<pre>cdk ls<br />cdk ls --profile <profile name></pre>認証情報用の AWS プロファイルを作成した場合は、プロファイルでコマンドを使用してください。<pre>cdk ls --profile <profile name></pre> | AWS 管理者、AWS DevOps | 
| どの AWS リソースが作成されるかを確認してください。 | このプロジェクトの一部として作成されるすべての AWS リソースを確認するには、以下のコマンドを実行します。<pre>cdk diff</pre>認証情報用の AWS プロファイルを作成した場合は、プロファイルでコマンドを使用してください。<pre>cdk diff --profile <profile name></pre> | AWS 管理者、AWS DevOps | 
| AWS CDK を使用してすべての AWS リソースをデプロイします。 | すべての AWS リソースをデプロイするには、次のコマンドを実行します。<pre>cdk deploy --all --require-approval never</pre>認証情報用の AWS プロファイルを作成した場合は、プロファイルでコマンドを使用してください。<pre>cdk deploy --all --require-approval never --profile <profile name></pre>デプロイが完了したら、次の例に示すように、コマンドプロンプトの出力セクションから API URL をコピーします。<pre>Outputs:<br />TenantOnboardingInfraStack.TenantOnboardingAPIEndpoint42E526D7 = https://j2qmp8ds21i1i.execute-api.us-west-2.amazonaws.com/prod/</pre> | AWS 管理者、AWS DevOps | 

### 機能性の検証
<a name="verify-the-functionality"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 新しいテナントを作成する。 | 新しいテナントを作成するには、次の curl リクエストを送信します。<pre>curl -X POST <TenantOnboardingAPIEndpoint* from CDK Output>tenant -d '{"Name":"Tenant123", "Description":"Stack for Tenant123"}'</pre>次の例に示すように、プレースホルダー `<TenantOnboardingAPIEndpoint* from CDK Output>` を AWS CDK の実際の値に変更します。<pre>curl -X POST https://j2qmp8ds21i1i.execute-api.us-west-2.amazonaws.com/prod/tenant -d '{"Name":"Tenant123", "Description":"test12"}'</pre>以下の例は出力を示しています。<pre>{"message": "A new tenant added - 5/4/2022 7:11:30 AM"}</pre> | アプリ開発者、AWS 管理者、AWS DevOps | 
| DynamoDB で新しく作成されたテナントの詳細を確認します。 | DynamoDB で新しく作成されたテナントの詳細を確認するには、次のステップを実行します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.html) | アプリ開発者、AWS 管理者、AWS DevOps | 
| 新しいテナントのスタックの作成を確認します。 | 新しいスタックが正常に作成され、CloudFormation テンプレートに従って新しく作成されたテナントのインフラストラクチャでプロビジョニングされたことを確認します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.html) | アプリ開発者、AWS 管理者、AWS DevOps | 
| テナントスタックを削除します。 | テナントスタックを削除するには、次の curl リクエストを送信します。<pre>curl -X DELETE <TenantOnboardingAPIEndpoint* from CDK Output>tenant/<Tenant Name from previous step></pre>次の例のように、プレースホルダー `<TenantOnboardingAPIEndpoint* from CDK Output>` を AWS CDK の実際の値に変更し、`<Tenant Name from previous step>` を前のテナント作成ステップの実際の値に変更します。<pre>curl -X DELETE https://j2qmp8ds21i1i.execute-api.us-west-2.amazonaws.com/prod/tenant/Tenant123</pre>以下の例は出力を示しています。<pre>{"message": "Tenant destroyed - 5/4/2022 7:14:48 AM"}</pre> | アプリ開発者、AWS DevOps、AWS 管理者 | 
| 既存のテナントのスタックの削除を確認します。 | 既存のテナントスタックが削除されたことを確認するには、次のステップを実行します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.html) | アプリ開発者、AWS 管理者、AWS DevOps | 

### クリーンアップ
<a name="clean-up"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 環境を破壊する。 | スタックをクリーンアップする前に、次の点を確認してください。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk.html)テストが完了したら、次のコマンドを実行することで、AWS CDK を使用してすべてのスタックと関連リソースを破棄できます。<pre>cdk destroy --all;</pre>認証情報用の AWS プロファイルを作成した場合は、そのプロファイルを使用してください。スタックの削除プロンプトを確認して、スタックを削除します。 | AWS 管理者、AWS DevOps | 
| Amazon CloudWatch Logs をクリーンアップします。 | スタックの削除プロセスでは、スタックによって生成された CloudWatch Logs (ロググループとログ) はクリーンアップされません。CloudWatch コンソールまたは API を使用して、CloudWatch リソースを手動でクリーンアップします。 | アプリ開発者、AWS DevOps、AWS 管理者 | 

## 関連リソース
<a name="tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk-resources"></a>
+ 「[AWS CDK .NET ワークショップ](https://cdkworkshop.com/40-dotnet.html)」
+ 「[C\$1 で AWS CDK を操作する](https://docs.aws.amazon.com/cdk/v2/guide/work-with-cdk-csharp.html)」
+ 「[CDK .NET リファレンス](https://docs.aws.amazon.com/cdk/api/v2/dotnet/api/index.html)」

## 追加情報
<a name="tenant-onboarding-in-saas-architecture-for-the-silo-model-using-c-and-aws-cdk-additional"></a>

コントロールプレーンテクノロジースタック

.NET で記述された CDK コードは、以下のリソースで構成されるコントロールプレーンインフラストラクチャのプロビジョニングに使用されます。

1. **API Gateway**

   コントロールプレーンスタックの REST API エントリポイントとして機能します。

1. テナントオンボーディング Lambda 関数

   この Lambda 関数は、m メソッドを使用して API Gateway によって開始されます。

   POST メソッドの API リクエストにより、(`tenant name`、`tenant description`) が DynamoDB `Tenant Onboarding` テーブルに挿入されます。

   このコード例では、テナント名はテナントスタック名とそのスタック内のリソース名の一部としても使用されています。これは、これらのリソースを識別しやすくするためです。このテナント名は、競合やエラーを避けるため、セットアップで一意である必要があります。入力検証の詳細な設定については、[IAM ロールのドキュメント](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles.html)と「*制限事項*」セクションで説明されています。

   DynamoDB テーブルへの永続化プロセスは、テナント名がテーブル内の他のレコードで使用されていない場合にのみ成功します。

   `PutItem` 条件式として使用できるのはパーティションキーだけなので、この場合のテナント名がこのテーブルのパーティションキーになります。

   テナント名が以前に記録されたことがなければ、レコードはテーブルに正常に保存されます。

   ただし、テナント名がテーブル内の既存のレコードですでに使用されている場合、操作は失敗し、DynamoDB `ConditionalCheckFailedException` 例外が開始されます。この例外は、テナント名が既に存在することを示す失敗メッセージ (`HTTP BadRequest`) を返すために使用されます。

   `DELETE` メソッド API リクエストは、`Tenant Onboardin` g テーブルから特定のテナント名のレコードを削除します。

   この例の DynamoDB レコードの削除は、レコードが存在しなくても成功します。

   ターゲットレコードが存在して削除されると、DynamoDB ストリームレコードが作成されます。それ以外の場合は、ダウンストリームレコードは作成されません。

1. Amazon DynamoDB Streams を有効にしたテナントによる DynamoDB のオンボーディング

   これによりテナントのメタデータ情報が記録され、レコードを保存または削除すると、ストリームが下流の `Tenant Infrastructure` Lambda 関数に送信されます。 

1. テナントインフラストラクチャ Lambda 関数

   この Lambda 関数は、前のステップの DynamoDB ストリームレコードによって開始されます。レコードが `INSERT` イベントの場合は、AWS CloudFormation を呼び出して、S3 バケットに保存されている CloudFormation テンプレートを使用して新しいテナントインフラストラクチャを作成します。レコードが `REMOVE` の場合、ストリームレコードの `Tenant Name` フィールドに基づいて既存のスタックの削除を開始します。

1. **S3 バケット**

   これは CloudFormation テンプレートを保存するためのものです。

1. 各 Lambda 関数の IAM ロールと CloudFormation のサービスロール

   各 Lambda 関数には、そのタスクを実行するための「[最小特権](https://docs.aws.amazon.com/IAM/latest/UserGuide/best-practices.html#grant-least-privilege)」アクセス許可を持つ固有の IAM ロールがあります。たとえば、`Tenant On-boarding` Lambda 関数には DynamoDB への読み取り/書き込みアクセス権があり、`Tenant Infrastructure` Lambda 関数は DynamoDB ストリームのみを読み取ることができます。

   テナントスタックのプロビジョニング用にカスタム CloudFormation サービスロールが作成されます。このサービスロールには、CloudFormation スタックプロビジョニングの追加権限 (AWS KMS キーなど) が含まれています。これにより、ロールが Lambda と CloudFormation に分割され、1 つのロール (インフラストラクチャ Lambda ロール) にすべてのアクセス許可が割り当てられることがなくなります。

   強力なアクション (CloudFormation スタックの作成や削除など) を許可する権限はロックされ、`tenantcluster-` で始まるリソースにのみ許可されます。リソースの命名規則のため、例外は AWS KMS です。API から取り込まれたテナント名は、他の検証チェックと一緒に `tenantcluster-` で付加されます (ハイフン付きの英数字のみ。ほとんどの AWS リソース命名に当てはまるように 30 文字未満に制限されています)。これにより、テナント名によってコアインフラストラクチャスタックやリソースが誤って中断されることがなくなります。

テナントテクノロジースタック

CloudFormation のテンプレートは S3 バケットに保存されます。テンプレートは、テナント固有の AWS KMS キー、CloudWatch アラーム、SNS トピック、SQS キュー、および「[SQS ポリシー](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-using-identity-based-policies.html)」をプロビジョニングします。

AWS KMS キーは、Amazon SNS と Amazon SQS によるメッセージのデータ暗号化に使用されます。「[AWSSolutions-SNS2 と AWSSolutions-SQS2](https://github.com/cdklabs/cdk-nag/blob/main/RULES.md)」のセキュリティプラクティスでは、Amazon SNS と Amazon SQS を暗号化して設定することを推奨しています。ただし、AWS マネージドキーを使用する場合、CloudWatch アラームは Amazon SNS では機能しないため、この場合はカスタマー管理のキーを使用する必要があります。詳細については、「[AWS ナレッジセンター](https://aws.amazon.com/premiumsupport/knowledge-center/cloudwatch-receive-sns-for-alarm-trigger/)」を参照してください。

SQS ポリシーは Amazon SQS キューで使用され、作成された SNS トピックがメッセージをキューに配信できるようにします。SQS ポリシーがないと、アクセスは拒否されます。詳細については、「[Amazon SNS ドキュメント](https://docs.aws.amazon.com/sns/latest/dg/subscribe-sqs-queue-to-sns-topic.html#SendMessageToSQS.sqs.permissions)」を参照してください。

# CQRS とイベントソーシングを使用してモノリスをマイクロサービスに分解する
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing"></a>

*Amazon Web Services、Rodolfo Jr. Cerrada、Dmitry Gulin、Tabby Ward*

## 概要
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-summary"></a>

このパターンは、コマンドクエリ責任分離 (CQRS) パターンとイベントソーシングパターンの両方を使用する 2 つのパターンを組み合わせたものです。CQRS パターンは、コマンドモデルとクエリモデルの責任を分離します。イベントソーシングパターンは、非同期のイベント駆動型通信を利用して、全体的なユーザーエクスペリエンスを向上させます。

CQRS とAmazon Web Services(AWS)サービスを使用して、モノリスアプリケーションをマイクロサービスアーキテクチャにリファクタリングしながら、各データモデルを個別に維持およびスケーリングできます。その後、イベントソーシングパターンを使用して、コマンドデータベースのデータをクエリデータベースに同期できます。

このパターンでは、最新バージョンの Visual Studio を使用して開くことができるソリューション (\$1.sln) ファイルを含むサンプルコードを使用しています。この例には、AWS のサーバーレスアプリケーション、従来型アプリケーション、オンプレミスアプリケーションで CQRS とイベントソーシングがどのように機能するかを紹介する Reward API コードが含まれています。

CQRS とイベントソーシングの詳細については、[追加情報](#decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional) セクションを参照してください。

## 前提条件と制限事項
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-prereqs"></a>

**前提条件**
+ アクティブなAWS アカウント
+ Amazon CloudWatch
+ Amazon DynamoDB テーブル
+ Amazon DynamoDB Streams
+ AWS Identity and Access Management (IAM) アクセスキーとシークレットキー。詳細については、*関連リソース*セクションのビデオを参照してください。
+ AWS Lambda
+ Visual Studio に精通していること
+ AWS Toolkit for Visual Studio に精通していること。詳細については、*関連リソース*セクションの*AWS Toolkit for Visual Studio のデモビデオ*を参照してください。

**製品バージョン**
+ [Visual Studio 2019 コミュニティエディション](https://visualstudio.microsoft.com/downloads/)。
+ [AWS Toolkit for Visual Studio](https://aws.amazon.com/visualstudio/)。
+ .NET Core 3.1 このコンポーネントは Visual Studio インストレーションのオプションです。インストール中に.NET Core を含めるには、**NET Core クロスプラットフォーム開発を選択します**。

**制限事項**
+ 従来のオンプレミスアプリケーション (ASP.NET Core Web API とデータアクセスオブジェクト) のサンプルコードにはデータベースは付属していません。ただし、このコードにはモックデータベースとして機能する `CustomerData` インメモリオブジェクトが付属しています。用意されているコードはパターンをテストするのに十分です。

## アーキテクチャ
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-architecture"></a>

**ソーステクノロジースタック**
+ ASP.NET Core Web API プロジェクト
+ IIS Web サーバー
+ データアクセスオブジェクト
+ CRUD モデル

**ソースアーキテクチャ**

ソースアーキテクチャでは、CRUD モデルには 1 つのアプリケーションにコマンドインターフェースとクエリインターフェースの両方が含まれています。コード例については、`CustomerDAO.cs` (添付) を参照してください。

![\[アプリケーション、サービスインターフェイス、カスタマー CRUD モデル、データベース間の接続。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/1cd3a84c-12c7-4306-99aa-23f2c53d3cd3.png)


**ターゲット テクノロジー スタック**
+ Amazon DynamoDB
+ Amazon DynamoDB Streams
+ AWS Lambda
+ (オプション) Amazon API Gateway API ゲートウェイ
+ Amazon Simple Notiﬁcation Service (Amazon SNS)

**ターゲット アーキテクチャ**

ターゲットアーキテクチャでは、コマンドインターフェイスとクエリインターフェイスは分離されています。次の図に示されているアーキテクチャは、API ゲートウェイと Amazon SNS を使用して拡張できます。詳細については、[追加情報](#decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional) セクションを参照してください。

![\[サーバーレスのカスタマーコマンドおよびカスタマークエリマイクロサービスと接続するアプリケーション。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/1c665697-e3ac-4ef4-98d0-86c2cbf164c1.png)


1. コマンド Lambda 関数は、データベースに対して作成、更新、削除などの書き込み操作を実行します。

1. クエリ Lambda 関数は、データベースに対して get や select などの読み取り操作を実行します。

1. この Lambda 関数は、Command データベースからの DynamoDB ストリームを処理し、変更があった場合はクエリデータベースを更新します。

## ツール
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-tools"></a>

**ツール**
+ [Amazon DynamoDB](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Introduction.html) – Amazon DynamoDB は、フルマネージド NoSQL データベースサービスであり、シームレスなスケーラビリティを備えた高速で予測可能なパフォーマンスを提供します。
+ [Amazon DynamoDB Streams](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Streams.html) – Amazon DynamoDB Streams は、Amazon DynamoDB テーブル内の項目レベルでの変更を時系列順にキャプチャする のサービスです。このサービスは、この情報を最大 24 時間ログに保存します。保管時の暗号化では、DynamoDB Streams のデータが暗号化されます。
+ 「[AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html)」 – AWS Lambda はサーバーのプロビジョニングや管理を行わずにコードの実行を支援できるコンピューティングサービスです。Lambda は必要に応じてコードを実行し、1 日あたり数個のリクエストから 1 秒あたり数千のリクエストまで自動的にスケールします。課金は実際に消費したコンピューティング時間に対してのみ発生します。コードが実行されていない場合、料金は発生しません。
+ [AWS Management Console](https://docs.aws.amazon.com/awsconsolehelpdocs/latest/gsg/learn-whats-new.html) – AWS マネジメントコンソールは、AWS のサービスを管理するための広範なサービスコンソールコレクションへのアクセスを提供するウェブアプリケーションです。
+ [Visual Studio 2019 コミュニティエディション](https://visualstudio.microsoft.com/downloads/) — Visual Studio 2019 は統合開発環境 (IDE) です。コミュニティエディションは、オープンソースのコントリビューターには無料で提供されます。このパターンでは、Visual Studio 2019 コミュニティエディションを使用してサンプルコードを開き、コンパイル、実行します。表示のみの場合は、任意のテキストエディターまたは [Visual Studio Code](https://docs.aws.amazon.com/toolkit-for-vscode/latest/userguide/welcome.html) を使用できます。
+ [AWS Toolkit for Visual Studio](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html) – AWS Toolkit for Visual Studio は Visual StudioIDE へのプラグインです。AWS Toolkit for Visual Studio を使用すると、AWS サービスを使用する .NET アプリケーションの開発、デバッグ、および展開が容易になります。

**コード**

サンプルコードは添付されています。サンプルコードを展開する手順については、「*エピック*」セクションを参照してください。

## エピック
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-epics"></a>

### ソリューションのオープンと構築
<a name="open-and-build-the-solution"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
|  セクションを開きます。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリ開発者 | 
| ソリューションを構築します。 | ソリューションのコンテキスト (右クリック) メニューを開き、**ソリューションをビルドする** を選択します。これにより、ソリューション内のすべてのプロジェクトがビルドされ、コンパイルされます。正常にコンパイルされるはずです。Visual Studio ソリューションエクスプローラーにはディレクトリ構造が表示されるはずです。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリ開発者 | 

### DynamoDB テーブルを構築する
<a name="build-the-dynamodb-tables"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
|  認証情報の提供 | アクセスキーをまだお持ちでない場合は、*関連リソース*セクションの動画をご覧ください。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリケーション開発者、データエンジニア、DBA | 
| プロジェクトをビルドします。 | プロジェクトをビルドするには、**AwS.APG.CQRSES.Build** プロジェクトのコンテキスト (右クリック) メニューを開き、 **ビルド**を選択します。 | アプリケーション開発者、データエンジニア、DBA | 
| テーブルを作成してデータを入力します。 | テーブルを作成してシードデータを入力するには、**AwS.APG.CQRSES.Build** プロジェクトのコンテキスト (右クリック) メニューを開き、 **デバッグ**、**新規インスタンスの開始**を選択します。 | アプリケーション開発者、データエンジニア、DBA | 
| テーブルコンストラクトとデータを検証します。 | 確認するには、**AWS Explorer**,￥に移動し、**Amazon DynamoDB** を展開します。テーブルが表示されるはずです。各テーブルを開いて、サンプルデータを表示します。 | アプリケーション開発者、データエンジニア、DBA | 

### ローカルテストを実行する
<a name="run-local-tests"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Go プロジェクトを構築します。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリ開発者、テストエンジニア | 
| イベントソーシングプロジェクトを構築います。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリ開発者、テストエンジニア | 
| テストの実行 | すべてのテストを実行するには、**表示**、**テストエクスプローラー**、**すべてのテストを表示で実行**の順に選択します。すべてのテストに合格するはずです。合格すると緑色のチェックマークアイコンが表示されます。  | アプリ開発者、テストエンジニア | 

### CQRS Lambda 関数を AWS に公開する
<a name="publish-the-cqrs-lambda-functions-to-aws"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Lambda 関数を発行します。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリ開発者、DevOps エンジニア | 
| 関数のアップロードを検証します。 | (オプション) 関数が正常にロードされたことを確認するには、AWS Explorer に移動して **AWS Lambda** を展開します。テストウィンドウを開くには、Lambda 関数を選択します (ダブルクリック)。 | アプリ開発者、DevOps エンジニア | 
| Lambda 関数をテストします。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html)すべての CQRS Lambda プロジェクトは、`CQRS AWS Serverless\CQRS\Command Microservice` および ` CQRS AWS Serverless\CQRS\Command Microservice` ソリューションフォルダーにあります。ソリューションディレクトリとプロジェクトについては、[追加情報](#decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional) セクションの**ソースコードディレクトリ**を参照してください。 | アプリ開発者、DevOps エンジニア | 
| 残りの関数を公開します。 | 次のプロジェクトに対して、前のステップを繰り返します。[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリ開発者、DevOps エンジニア | 

### イベントリスナーとしての Lambda 関数の設定
<a name="set-up-the-lambda-function-as-an-event-listener"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| 顧客 Lambda イベントハンドラーとリワード Lambda イベントハンドラーを公開します。 | 各イベントハンドラーを公開するには、前のエピックの手順に従います。プロジェクトは `CQRS AWS Serverless\Event Source\Customer Event` および `CQRS AWS Serverless\Event Source\Reward Event` ソリューションフォルダーにあります。詳細については、[追加情報](#decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional)セクションの*ソースコードディレクトリ*を参照してください。 | アプリ開発者 | 
| イベントソーシング Lambda イベントリスナーをアタッチします。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html)リスナーが DynamoDB テーブルに正常にアタッチされると、Lambda デザイナーページに表示されます。 | アプリ開発者 | 
| EventSourceReward Lambda 関数をパブリッシュしてアタッチします。 | `EventSourceReward` Lambda 関数をパブリッシュしてアタッチするには、**DynamoDB テーブル** のドロップダウンリストから **cqrses-reward-cmd** を選択して、前の 2 つのストーリーの手順を繰り返します。 | アプリ開発者 | 

### DynamoDB ストリームと Lambda トリガーのテストと検証
<a name="test-and-validate-the-dynamodb-streams-and-lambda-trigger"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| ストリームと Lambda トリガーをテストします。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリ開発者 | 
| DynamodDB 報酬クエリテーブルを使用して検証します。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリ開発者 | 
| CloudWatch Logs を使用して検証します。 | [\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing.html) | アプリ開発者 | 
| EventSourceCustomer トリガーを検証します。 | `EventSourceCustomer` トリガーを検証するには、`EventSourceCustomer` トリガーのそれぞれの顧客テーブルと CloudWatch ログを使用して、このエピックの手順を繰り返します。 | アプリ開発者 | 

## 関連リソース
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-resources"></a>

**リファレンス**
+ [Visual Studio 2019 Community Editionのダウンロード](https://visualstudio.microsoft.com/downloads/)。
+ [AWS Toolkit for Visual Studioのダウンロード](https://aws.amazon.com/visualstudio/)
+ [AWS Toolkit for Visual Studio ユーザーガイド](https://docs.aws.amazon.com/toolkit-for-visual-studio/latest/user-guide/welcome.html)
+ [AWS でのサーバーレス](https://aws.amazon.com/serverless/)
+ [DynamoDB のユースケースとデザインパターン](https://aws.amazon.com/blogs/database/dynamodb-streams-use-cases-and-design-patterns/)
+ [マーティン ファウラー (CQRS)](https://martinfowler.com/bliki/CQRS.html)
+ [マーティン ファウラー イベント ソーシング](https://martinfowler.com/eaaDev/EventSourcing.html)

**動画**
+ [AWS Toolkit for Visual Studioのデモビデオ](https://www.youtube.com/watch?v=B190tcu1ERk)
+ [新しい IAM ユーザーのアクセスキー ID を作成する方法を教えてください。](https://www.youtube.com/watch?v=665RYobRJDY)

## 追加情報
<a name="decompose-monoliths-into-microservices-by-using-cqrs-and-event-sourcing-additional"></a>

**CQRS とイベントソーシング**

*CQRS*

CQRS パターンは、データアクセスオブジェクトの単一 CRUD (作成、読み取り、更新、削除) モデルなどの単一の概念操作モデルを、コマンド操作モデルとクエリ操作モデルに分離します。コマンドモデルとは、作成、更新、削除など、状態を変更するあらゆる操作を指します。クエリモデルとは、値を返すあらゆる操作を指します。

![\[サービス インターフェース、CRUD モデル、データベースを備えたアーキテクチャ。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/3f64756d-681e-4f0e-8034-746263d857b2.png)


1. Customer CRUD モデルには以下のインターフェースが含まれます。
   + `Create Customer()`
   + `UpdateCustomer()`
   + `DeleteCustomer()`
   + `AddPoints()`
   + `RedeemPoints()`
   + `GetVIPCustomers()`
   + `GetCustomerList()`
   + `GetCustomerPoints()`

要件が複雑になれば、この単一モデルのアプローチから移行できます。CQRS はコマンドモデルとクエリモデルを使用して、データの書き込みと読み取りの責任を分離します。そうすることで、データを独立して維持管理できます。責任が明確に分離されていれば、各モデルを強化しても他のモデルには影響しません。この分離によってメンテナンスとパフォーマンスが向上し、アプリケーションが大きくなるにつれて複雑さが軽減されます。

![\[アプリケーションはコマンドモデルとクエリモデルに分離され、1 つのデータベースを共有していました。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/12db023c-eb81-4c27-bbb9-b085b13176ae.png)


 

1. 顧客 コマンド モデルのインターフェース：
   + `Create Customer()`
   + `UpdateCustomer()`
   + `DeleteCustomer()`
   + `AddPoints()`
   + `RedeemPoints()`

1. 顧客 コマンド モデルのインターフェース：
   + `GetVIPCustomers()`
   + `GetCustomerList()`
   + `GetCustomerPoints()`
   + `GetMonthlyStatement()`

コード例については、「*ソースコードディレクトリ*」を参照してください。

次に、CQRS パターンによってデータベースが切り離されます。この分離は、マイクロサービスアーキテクチャの主要要素である各サービスの完全な独立性につながります。

![\[コマンドモデルとクエリモデル用のデータベースを分ける。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/016dbfa8-3bd8-42ee-afa1-38a98986c7d5.png)


 AWS クラウドで CQRS を使用すると、各サービスをさらに最適化できます。たとえば、さまざまなコンピューティング設定を設定したり、サーバーレスまたはコンテナベースのマイクロサービスのどちらかを選択できます。オンプレミスのキャッシュを Amazon ElastiCache に置き換えることができます。オンプレミスでメッセージングをパブリッシュ/サブスクライブメッセージングしている場合は、そのメッセージを Amazon Simple Notiﬁcation Service (Amazon SNS) に置き換えることができます。さらに、従量制料金の料金設定や、使用した分だけ支払うさまざまな AWS サービスを利用できます。

CQRS には次の利点があります。
+ 独立スケーリング — 各モデルのスケーリング戦略は、サービスの要件と需要に合わせて調整できます。高性能アプリケーションと同様に、読み取りと書き込みを分離することで、それぞれの需要に合わせてモデルを個別にスケーリングできます。また、コンピュートリソースを追加または削減して、一方のモデルのスケーラビリティ要求に応えることもできますが、もう一方のモデルには影響しません。
+ 独立したメンテナンス — クエリモデルとコマンドモデルを分離することで、モデルの保守性が向上します。一方のモデルにコードを変更したり拡張したりしても、もう一方のモデルには影響しません。
+ セキュリティ — 権限とポリシーを別々のモデルに適用して読み取りと書き込みを行う方が簡単です。
+ 読み込みの最適化 — クエリ用に最適化されたスキーマを定義できます。たとえば、集計データにはスキーマを定義し、ファクトテーブルには別のスキーマを定義できます。
+ 統合 — CQRS はイベントベースのプログラミングモデルによく合います。
+ 複雑さの管理 — クエリモデルとコマンドモデルへの分離は、複雑な分野に適しています。

 Local を使用する場合は、次の点に留意してください。
+ CQRS パターンはアプリケーションの特定の部分にのみ適用され、アプリケーション全体には適用されません。パターンに合わないドメインに実装すると、生産性が低下し、リスクが高まり、複雑さが増す可能性があります。
+ このパターンは、読み取りと書き込みの操作が不均衡な、頻繁に使用されるモデルに最適です。
+ 処理に時間がかかる大規模なレポートなど、読み取りの多いアプリケーションでは、CQRS では適切なデータベースを選択し、集約データを保存するスキーマを作成することができます。これにより、レポートデータを 1 回だけ処理して集計テーブルにダンプすることで、レポートの読み取りと表示の応答時間を短縮できます。
+ 書き込みの多いアプリケーションでは、書き込み操作用にデータベースを設定し、書き込みの需要が高まったときにコマンド microservice が独立してスケーリングできるようにすることができます。例については、`AWS.APG.CQRSES.CommandRedeemRewardLambda` および `AWS.APG.CQRSES.CommandAddRewardLambda` マイクロサービスを参照してください。

*イベントソーシング*

次のステップは、コマンドが実行されたときに、イベントソーシングを使用してクエリデータベースを同期することです。例えば、次の事項を検討します。
+ 顧客報酬ポイントが追加され、クエリデータベース内の顧客の合計または集計された報酬ポイントを更新する必要があります。
+ 顧客の姓がコマンドデータベースで更新されるため、クエリデータベース内の代理顧客情報を更新する必要があります。

従来の CRUD モデルでは、トランザクションが完了するまでデータをロックすることでデータの一貫性を確保していました。イベントソーシングでは、一連のイベントをパブリッシュすることでデータが同期され、サブスクライバーはそのイベントを消費してそれぞれのデータを更新します。

イベントソーシングパターンでは、データに対して実行された一連のアクションをすべて確認して記録し、一連のイベントを通じて公開します。これらのイベントはデータに加えられた一連の変更を表しており、そのイベントの購読者は記録を最新の状態に保つために処理する必要があります。これらのイベントはサブスクライバーによって処理され、サブスクライバーのデータベース上のデータが同期されます。この場合は、それがクエリデータベースです。

次の図は、AWS 上の CQRS で使用されるイベントソーシングを示しています。

![\[CQRS と AWS サーバーレスサービスを使用したイベントソーシングパターン用のマイクロサービスアーキテクチャ。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/cc9bc84a-60b4-4459-9a5c-2334c69dbb4e.png)


1. コマンド Lambda 関数は、データベースに対して作成、更新、削除などの書き込み操作を実行します。

1. クエリ Lambda 関数は、データベースに対して get や select などの読み取り操作を実行します。

1. この Lambda 関数は、Command データベースからの DynamoDB ストリームを処理し、変更があった場合はクエリデータベースを更新します。また、この機能を使用して Amazon SNS にメッセージを発行し、サブスクライバー がデータを処理できるようにすることもきます。

1. (オプション) Lambda イベントサブスクライバーは Amazon SNS によって発行されたメッセージを処理し、クエリデータベースを更新します。

1. (オプション) Amazon SNS は書き込みオペレーションの E メール通知を送信します。

AWS では、クエリデータベースは DynamoDB Streams によって同期できます。DynamoDB は、DynamoDB テーブル内の項目レベルの変更に関するシーケンスを時間順にキャプチャし、その情報を 24 時間以内に永続的に保存します。

DynamoDB Streams をアクティブ化すると、データベースはイベントソーシングパターンを可能にする一連のイベントを公開できます。イベントソーシングパターンによってイベントサブスクライバーが追加されます。イベントサブスクライバーアプリケーションはイベントを消費し、サブスクライバーの責任に応じて処理します。前の図では、イベントサブスクライバーが変更を Query DynamoDB データベースにプッシュして、データの同期を維持しています。Amazon SNS、メッセージブローカー、イベントサブスクライバーアプリケーションを使用することで、アーキテクチャは切り離された状態に保たれます。

イベントソーシングには次の利点があります。
+ トランザクションデータの一貫性
+ データに加えられたアクションのモニタリングに使用できる、信頼性の高い監査証跡とアクション履歴
+ マイクロサービスなどの分散アプリケーションが、環境全体でデータを同期できるようにします。
+ 状態が変化しても、確実にイベントを発行できます。
+ 過去の状態の再構築または再生
+ モノリシックなアプリケーションからマイクロサービスへの移行のためのイベントを交換する疎結合エンティティ
+ 同時更新による競合の軽減。イベントソーシングにより、データストア内のオブジェクトを直接更新する必要がなくなります。
+ タスクとイベントを切り離すことによる柔軟性と拡張性
+ 外部システム更新
+ 1 回のイベントで複数のタスクを管理

イベントソーシングを使用する場合は、次の点に注意してください。
+ ソースサブスクライバーデータベース間のデータの更新には多少の遅延があるため、変更を取り消す唯一の方法は、イベントストアに補償イベントを追加することです。
+ イベントソーシングの実装はプログラミングスタイルが異なるため、習得には時間がかかります。

**テストデータ**

デプロイが成功したら、次のテストデータを使用して Lambda 関数をテストします。

**CommandCreate Customer**

```
{  "Id":1501,  "Firstname":"John",  "Lastname":"Done",  "CompanyName":"AnyCompany",  "Address": "USA",  "VIP":true }
```

**CommandUpdate Customer**

```
{  "Id":1501,  "Firstname":"John",  "Lastname":"Doe",  "CompanyName":"Example Corp.",  "Address": "Seattle, USA",  "VIP":true }
```

**CommandDelete Customer**

顧客 ID をリクエストデータとして入力します。たとえば、顧客 ID が 151 の場合、リクエストデータとして 151 と入力します。

```
151
```

**QueryCustomerList**

これは空白です。呼び出されると、すべての顧客が返されます。

**CommandAddReward**

これにより、ID 1 (リチャード) のお客様 (リチャード) に 40 ポイント加算されます。

```
{
  "Id":10101,
  "CustomerId":1,
  "Points":40
}
```

**CommandRedeemReward**

これにより、ID 1 (リチャード) の顧客に 15 ポイント差し引れます。

```
{
  "Id":10110,
  "CustomerId":1,
  "Points":15
}
```

クエリー/リワード

顧客の ID を入力します。たとえば、リチャードには 1、アーナビには 2、シャーリーの場合は 3 と入力します。

```
2 
```

**ソースコードディレクトリ**

Visual Studio ソリューションのディレクトリ構造のガイドとして次の表を使用してください。 

*CQRS オンプレミスコードサンプルソリューションディレクトリ*

![\[コマンドサービスとクエリサービスを含むソリューションディレクトリが拡張されました。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/4811c2c0-643b-410f-bb87-0b86ec5e194c.png)


**顧客 CRUD モデル**

CQRS オンプレミスコードサンプル\$1 CRUD モデル\$1 AWS.APG.CQRSES.DAL プロジェクト

**顧客 CRUD モデルの CQRS バージョン**
+ 顧客コマンド：`CQRS On-Premises Code Sample\CQRS Model\Command Microservice\AWS.APG.CQRSES.Command` プロジェクト
+ 顧客クエリ：`CQRS On-Premises Code Sample\CQRS Model\Query Microservice\AWS.APG.CQRSES.Query` プロジェクト

**Command and Query microservices**

Command マイクロサービスはソリューションフォルダー `CQRS On-Premises Code Sample\CQRS Model\Command Microservice` にあります。
+ `AWS.APG.CQRSES.CommandMicroservice` ASP.NET Core API プロジェクトは、コンシューマーがサービスとやり取りするエントリポイントとして機能します。
+ `AWS.APG.CQRSES.Command` .NET Core プロジェクトは、コマンド関連のオブジェクトとインターフェイスをホストするオブジェクトです。

Command マイクロサービスはソリューションフォルダー `CQRS On-Premises Code Sample\CQRS Model\Query Microservice` にあります。
+ `AWS.APG.CQRSES.QueryMicroservice` ASP.NET Core API プロジェクトは、コンシューマーがサービスとやり取りするエントリポイントとして機能します。
+ `AWS.APG.CQRSES.Query` .NET Core プロジェクトは、コマンド関連のオブジェクトとインターフェイスをホストするオブジェクトです。

*CQRS AWS サーバーレスコードソリューションディレクトリ*

![\[マイクロサービスとイベントソースの両方が拡張されていることを表示しているソリューションディレクトリ。\]](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9f1bc700-def4-4201-bb2d-f1fa27404f15/images/23f8655c-95ad-422c-b20a-e29dc145e995.png)


 

このコードは、AWS サーバーレスサービスを使用するオンプレミスコードの AWS バージョンです。

C\$1 .NET Core では、各 Lambda 関数は 1 つの.NET Core プロジェクトによって表されます。このパターンのサンプルコードでは、コマンドモデルとクエリモデルのインターフェースごとに個別のプロジェクトがあります。

**AWS のサービスの使用**

AWS サーバーレスサービスを使用するCQRSのルートソリューションディレクトリは、この `CQRS AWS Serverless\CQRS` フォルダーにあります。この例には、顧客と報酬という 2 つのモデルが含まれています。

顧客とリワードのLambda関数のコマンドは、`CQRS\Command Microservice\Customer` および `CQRS\Command Microservice\Reward` フォルダーにあります。これらには以下の Lambda プロジェクトが含まれています。
+ 顧客コマンド：`CommandCreateLambda`、`CommandDeleteLambda`、`CommandUpdateLambda`
+ リワードコマンド：`CommandAddRewardLambda` と `CommandRedeemRewardLambda`

顧客とリワードのクエリ Lambda 関数は、`CQRS\Query Microservice\Customer` および `CQRS\QueryMicroservice\Reward` フォルダーにあります。これらには以下の `QueryCustomerListLambda` と `QueryRewardLambda` Lambda プロジェクトが含まれています。

**CQRS テストプロジェクト**

テストプロジェクトは `CQRS\Tests` フォルダーの下にあります。このプロジェクトには、CQRS Lambda 関数のテストを自動化するテストスクリプトが含まれています。

**AWS サービスを使用したイベントソーシング**

次の Lambda イベントハンドラーは、Customer と Reward DynamoDB ストリームによって開始され、クエリテーブル内のデータを処理および同期します。
+ `EventSourceCustomer` Lambda 関数は顧客テーブル (`cqrses-customer-cmd`) の DynamoDB ストリームにマップされます。
+ `EventSourceReward` Lambda 関数は顧客テーブル (`cqrses-reward-cmd`) の DynamoDB ストリームにマップされます。

## アタッチメント
<a name="attachments-9f1bc700-def4-4201-bb2d-f1fa27404f15"></a>

このドキュメントに関連する追加コンテンツにアクセスするには、次のファイルを解凍してください。「[attachment.zip](samples/p-attach/9f1bc700-def4-4201-bb2d-f1fa27404f15/attachments/attachment.zip)」

# その他のパターン
<a name="modernization-more-patterns-pattern-list"></a>

**Topics**
+ [AWS PrivateLink と Network Load Balancer を使用して、Amazon EKS 上のコンテナアプリケーションにプライベートアクセスします。](access-container-applications-privately-on-amazon-eks-using-aws-privatelink-and-a-network-load-balancer.md)
+ [AWS Systems Manager を使用して Windows レジストリエントリの追加または更新を自動化する](automate-adding-or-updating-windows-registry-entries-using-aws-systems-manager.md)
+ [DR Orchestrator Framework を使用してクロスリージョンのフェイルオーバーとフェイルバックを自動化](automate-cross-region-failover-and-failback-by-using-dr-orchestrator-framework.md)
+ [CI/CD パイプラインを使用して Amazon EKS へ Java アプリケーションを自動的にビルドし、デプロイする](automatically-build-and-deploy-a-java-application-to-amazon-eks-using-a-ci-cd-pipeline.md)
+ [AWS CDK を使用してマイクロサービス用の CI/CD パイプラインと Amazon ECS クラスターを自動的に構築する](automatically-build-ci-cd-pipelines-and-amazon-ecs-clusters-for-microservices-using-aws-cdk.md)
+ [BMC AMI Cloud を使用したメインフレームデータを Amazon S3 にバックアップおよびアーカイブ](back-up-and-archive-mainframe-data-to-amazon-s3-using-bmc-ami-cloud-data.md)
+ [Amazon EC2 Auto Scaling と Systems Manager を搭載した Micro Focus Enterprise Server PAC を構築する](build-a-micro-focus-enterprise-server-pac-with-amazon-ec2-auto-scaling-and-systems-manager.md)
+ [Amazon DataZone を使用してエンタープライズデータメッシュを構築する AWS CDK AWS CloudFormation](build-enterprise-data-mesh-amazon-data-zone.md)
+ [Blu Age によってモダナイズされたメインフレームワークロードをコンテナ化](containerize-mainframe-workloads-that-have-been-modernized-by-blu-age.md)
+ [Python を使用して AWS 上で EBCDIC データを ASCII に変換および解凍する](convert-and-unpack-ebcdic-data-to-ascii-on-aws-by-using-python.md)
+ [Micro Focusを使用して複雑なレコードレイアウトのメインフレームデータファイルを変換](convert-mainframe-data-files-with-complex-record-layouts-using-micro-focus.md)
+ [、Angular AWS Amplify、および Module Federation を使用してマイクロフロントエンド用のポータルを作成する](create-amplify-micro-frontend-portal.md)
+ [Elastic Beanstalk を使用してコンテナをデプロイする](deploy-containers-by-using-elastic-beanstalk.md)
+ [PostgreSQL 互換の Aurora グローバルデータベースを使用して Oracle DR をエミュレート](emulate-oracle-dr-by-using-a-postgresql-compatible-aurora-global-database.md)
+ [Quick Sight で AWS Mainframe Modernization と Amazon Q を使用してデータインサイトを生成する](generate-data-insights-by-using-aws-mainframe-modernization-and-amazon-q-in-quicksight.md)
+ [Quick Sight で AWS Mainframe Modernization と Amazon Q を使用して Db2 z/OS データインサイトを生成する](generate-db2-zos-data-insights-aws-mainframe-modernization-amazon-q-in-quicksight.md)
+ [Amazon ECR リポジトリに移行するときに、重複するコンテナイメージを自動的に識別する](identify-duplicate-container-images-automatically-when-migrating-to-ecr-repository.md)
+ [K8sGPT と Amazon Bedrock の統合を利用して AI を活用した Kubernetes の診断とトラブルシューティングを実装する](implement-ai-powered-kubernetes-diagnostics-and-troubleshooting-with-k8sgpt-and-amazon-bedrock-integration.md)
+ [AWS Blu Age モダナイズされたメインフレームアプリケーションで Microsoft Entra ID ベースの認証を実装する](implement-entra-id-authentication-in-aws-blu-age-modernized-mainframe-application.md)
+ [Amazon API Gateway でカスタムドメインを使用してパスベースの API バージョニングを実装する](implement-path-based-api-versioning-by-using-custom-domains.md)
+ [Oracle SQL Developer と AWS SCT を使用して Amazon RDS for Oracle から Amazon RDS for PostgreSQL に段階的に移行](incrementally-migrate-from-amazon-rds-for-oracle-to-amazon-rds-for-postgresql-using-oracle-sql-developer-and-aws-sct.md)
+ [Stonebranch ユニバーサルコントローラーと AWS Mainframe Modernizationを統合](integrate-stonebranch-universal-controller-with-aws-mainframe-modernization.md)
+ [複数の AWS アカウントと AWS リージョンで AWS Service Catalog 製品を管理](manage-aws-service-catalog-products-in-multiple-aws-accounts-and-aws-regions.md)
+ [AWS メンバーアカウントを から に移行する AWS Organizations AWS Control Tower](migrate-an-aws-member-account-from-aws-organizations-to-aws-control-tower.md)
+ [Precisely からのConnect を使用して VSAM ファイルを Amazon RDS または Amazon MSK に移行およびレプリケート](migrate-and-replicate-vsam-files-to-amazon-rds-or-amazon-msk-using-connect-from-precisely.md)
+ [AWS DMS を使用して SAP ASE から Amazon RDS for SQL Server）に移行する](migrate-from-sap-ase-to-amazon-rds-for-sql-server-using-aws-dms.md)
+ [Oracle 外部テーブルを Amazon Aurora PostgreSQL 互換に移行](migrate-oracle-external-tables-to-amazon-aurora-postgresql-compatible.md)
+ [を使用して CardDemo メインフレームアプリケーションをモダナイズする AWS Transform](modernize-carddemo-mainframe-app.md)
+ [と Terraform を使用してメインフレームアプリケーションをモダナイズ AWS Transform およびデプロイする](modernize-mainframe-app-transform-terraform.md)
+ [Rocket Enterprise Server と LRS VPSX/MFI を使用して AWS 、 でメインフレームのバッチ印刷ワークロードをモダナイズする](modernize-mainframe-batch-printing-workloads-on-aws-by-using-rocket-enterprise-server-and-lrs-vpsx-mfi.md)
+ [Micro Focus Enterprise ServerとLRS VPSX/MFIを使用して、AWS 上のメインフレームのオンライン印刷ワークロードを最新化](modernize-mainframe-online-printing-workloads-on-aws-by-using-micro-focus-enterprise-server-and-lrs-vpsx-mfi.md)
+ [Rocket Enterprise Server と LRS PageCenterX AWS を使用してメインフレーム出力管理をモダナイズする](modernize-mainframe-output-management-on-aws-by-using-rocket-enterprise-server-and-lrs-pagecenterx.md)
+ [Transfer Family を使用して、メインフレームファイルを Amazon S3 に直接移動する](move-mainframe-files-directly-to-amazon-s3-using-transfer-family.md)
+ [AWS CDK および GitHub Actions ワークフローを使用してマルチアカウントサーバーレスデプロイを最適化する](optimize-multi-account-serverless-deployments.md)
+ [AWS Blu Age モダナイズされたアプリケーションのパフォーマンスを最適化する](optimize-performance-aws-blu-age-modernized-application.md)
+ [IaC 原則を使用して Amazon Aurora Global Database のブルー/グリーンデプロイを自動化する](p-automate-blue-green-deployments-aurora-global-databases-iac.md)
+ [Precisely Connect を使用してメインフレームデータベースを AWS にレプリケート](replicate-mainframe-databases-to-aws-by-using-precisely-connect.md)
+ [Amazon ECS Anywhere を使用して Amazon WorkSpaces で Amazon ECS タスクを実行する](run-amazon-ecs-tasks-on-amazon-workspaces-with-amazon-ecs-anywhere.md)
+ [から OpenSearch AWS Lambda にテレメトリデータを送信してリアルタイムの分析と視覚化を行う](send-telemetry-data-from-lambda-to-opensearch-for-analytics-visualization.md)
+ [マルチリージョン、マルチアカウント組織で CloudFormation ドリフト検出を設定する](set-up-aws-cloudformation-drift-detection-in-a-multi-region-multi-account-organization.md)
+ [AWS Lambda を使用して六角形アーキテクチャで Python プロジェクトを構築する](structure-a-python-project-in-hexagonal-architecture-using-aws-lambda.md)
+ [LocalStack および Terraform テストを使用して AWS インフラストラクチャをテストする](test-aws-infra-localstack-terraform.md)
+ [AWS Transform カスタムを使用して Easytrieve を最新の言語に変換する](transform-easytrieve-modern-languages.md)
+ [SAP ペースメーカークラスターを ENSA1 から ENSA2 にアップグレード](upgrade-sap-pacemaker-clusters-from-ensa1-to-ensa2.md)
+ [Amazon Q Developer をコーディングアシスタントとして使用して生産性を高める](use-q-developer-as-coding-assistant-to-increase-productivity.md)
+ [Account Factory for Terraform (AFT) のコードをローカルで検証する](validate-account-factory-for-terraform-aft-code-locally.md)