CloudFormationのテンプレートを速攻で探しやすく整理する（２）

[前回の記事](https://qiita.com/harashin-midnight-only/items/6c3c1a4ad7e02902668f)では、クラウドの設計監理ツール[ForkMe!（フォークミー）](https://reindeer.tech/ja/index.html#forkme)を使って、CloudFormationのテンプレートを見通しよく整理する方法をご紹介しました。
今回は引き続きForkMe!を使って、テンプレートを流用する際の探しやすさをもう一段レベルアップさせる方法をご紹介します。

#1. テンプレート探しで重要なのは「要件データ」
単純に考えると、大量アクセスを想定するサイトとそうでないもの、予算のある案件とそうでないもの、ECサイトと社内システムでは、設計が異なるはずです。よって[ForkMe!（フォークミー）](https://reindeer.tech/ja/index.html#forkme)では、以下のような要件データでテンプレートの検索、比較が行えるようになっています。

* 想定性能（rps）
* 見積価格
* ユーザー数やデータ送信サイズ
* 個人情報の取り扱い有無
* 利用者（アクター）と利用ケース（コンテキスト）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559449/7ecb7398-3901-6b97-d416-eb7fc6d0f7c7.png)

#2. 要件データの追加方法を確認する
しかし、前回の記事でご紹介したCloudFormationテンプレートのシンプルなアップロードでは、それらの情報がほとんどゼロないし未定義になってしまいます。なぜなら、CloudFormationテンプレートには要件データを記述する場所がないからです。
代案としてForkMe!では、クラウドの利用要件を定義するためのJSON/YAMLコードである[「クラウドデザイン仕様（CDS）」](https://docs.reindeer.tech/index_ja.html)が利用できるようになっています。CloudFormationテンプレートと一緒に同コードを設計に含めることで要件データが追加できるので、早速その書き方を確認してみましょう。

###2-1) 設計の詳細でファイルタブを選択します。
公開されている[「クラウド設計レシピ#1 落ちないサイト」](https://forkme.cloud/ja/?id=d4295600b6e6de95d34.53125555)を例にみていきましょう。詳細画面で「ファイル」タブを選択し、以下２種類のファイルが設計に含まれていることを確認します。

* 「cloudDesign.json」：クラウドデザイン仕様（CDS）形式のJSONファイル
* 「awsTemplate.json」：CloudFomationテンプレート形式のJSONファイル

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559449/5efa5d27-c2ad-7da5-a5e0-9c06400db1d9.png)

このうち「cloudDesign.json」が要件データを記述しているファイルです。ForkMe!で新しい設計を追加した際は、既にこのファイルが追加されているはずです。

###2-2) アクター（利用者）の定義箇所を確認します。
「アクター」タブを開くと、設計で定義されたAWSリソースの利用者が確認できます。
「サイト閲覧者」の「ソースコードを確認」をクリックして、アクターを定義しているコードをチェックしましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559449/c2014558-861c-ee22-ee60-528dfdf703a9.png)

```json:cloudDesign.json（アクター定義箇所の抜粋）
"actors": {
		"customer": {
			"type": "market",
			"title": {
				"en": "Viewer",
				"ja": "サイト閲覧者"
			},
			"description": {
				"en": "Anonymous visitors to the site",
				"ja": "不特定多数の訪問者"
			},
			"sourceIdentification": false,
			"market": {
				"num": 130000,
				"title": {
					"en": "Users of benchmark site",
					"ja": "ベンチマークサイトの月間ユーザー数"
				},
				"description": {
					"en": "Trafic statistics of the benchmark site at Sept.2020",
					"ja": "2020年9月のトラフィック統計サイトの値を参照"
				},
				"estimatedAt": 1599750000,
				"estimatedBy": "harashin"
			},
			"marketShare": 1
		}
	}
```

この例では、13万人のサイト閲覧者にサービスを提供するという要件が、actors>customer>market>numに書かれています。

###2-3) コンテキスト（用途）の定義箇所を確認します。
「コンテキスト」タブを開くと、設計で定義されたAWSリソースの用途が確認できます。
5つあるコンテキストのうち「サイト閲覧者への静的コンテンツ提供（通常時）」の「ソースコードを確認」をクリックしてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559449/7dad9e97-2fe0-b57e-1864-1a5b00dbfdf4.png)


```json:cloudDesign.json（コンテキスト定義箇所の抜粋）
	"contexts": {
		"customerWebAccess": {
			"title": {
				"en": "Static contents distribution",
				"ja": "サイト閲覧者への静的コンテンツ提供（通常時）"
			},
			"description": {
				"en": "Limited to static and publicly available pages (search function and posting form are not provided)",
				"ja": "静的かつ一般公開されたコンテンツの配信のみ（検索や投稿機能は提供しない）"
			},
			"trigger": {
				"type": "webAccess",
				"description": {
					"en": "Access to the site",
					"ja": "サイトへのアクセス"
				},
				"infoType": {
					"$ref": "#/components/infoTypes/public"
				},
				"ports": [
					443
				],
				"restriction": false,
				"internet": true,
				"pagesVisit": {
					"min": 2.5,
					"max": 2.5
				},
				"reqPage": {
					"min": 10,
					"max": 10
				},
				"kbPage": {
					"min": 50,
					"max": 50
				},
				"postsVisit": {
					"min": 0,
					"max": 0
				},
				"kbPost": {
					"min": 0,
					"max": 0
				},
				"busyHours": {
					"min": 8,
					"max": 8
				},
				"dau": {
					"min": 0.009,
					"max": 0.009
				},
				"storedRatio": {
					"min": 0,
					"max": 0
				},
				"endpointTitle": {
					"en": "Cache (Speed&SSL)",
					"ja": "キャッシュサーバ（高速化とSSL）"
				},
				"start": {
					"$ref": "#/actors/customer"
				},
				"end": [{
						"$ref": "awsTemplate.json#/resources/CacheServer"
					},
					{
						"$ref": "awsTemplate.json#/resources/mycert"
					}
				]
			},
			"traffics": {
				"origin": {
					"type": "passThroughRatio",
					"internet": true,
					"description": {
						"en": "Get static contents",
						"ja": "静的コンテンツの読み込み"
					},
					"infoType": {
						"$ref": "#/components/infoTypes/public"
					},
					"ports": [
						80
					],
					"restriction": false,
					"source": {
						"$ref": "#/contexts/customerWebAccess/trigger"
					},
					"end": [{
							"$ref": "awsTemplate.json#/resources/RootBucket"
						},
						{
							"$ref": "awsTemplate.json#/resources/BucketPolicy"
						}
					],
					"passThroughReqRatio": {
						"max": 0.1,
						"min": 0.01
					},
					"compositResRatio": {
						"max": 0.1,
						"min": 0.01
					},
					"endpointTitle": {
						"en": "Contents server",
						"ja": "静的コンテンツ配信サーバ"
					},
					"storedRatio": {
						"min": 0,
						"max": 0
					},
					"storedInfoType": {
						"$ref": "#/components/infoTypes/public"
					}
				}
			}
		}
}
```
コンテキストでは、用途ごとにAWSリソースの利用開始点を示すトリガー（trigger）と、トリガー以降の通信経路を示すトラフィック（traffics）の組み合わせることで、データの流れを表現できるようになっています。この例では、以下のデータ構造が確認できます。

trigger：「サイトへのアクセス」を用途の開始点とする
　　|- start：アクター「サイト閲覧者」がサイト利用を開始
　　|- end：AWSリソース「キャッシュサーバ」と「SSL証明書」を利用
　　|- dauなど：アクターがDAU0.9%かつ訪問あたり2.5ページを利用、ページあたり50KBで10リクエストを要求、それらのアクセスは1日8時間の範囲で分散

traffics：用途の通信経路
　　|- origin：キャッシュ元へのアクセス
　　　　|- source: 「trigger」のendにあたるキャッシュサーバとSSL証明書が通信を開始
　　　　|- end：AWSリソース「S3バケット」と「バケットポリシー」に接続
　　　　|- passThroughReqRatioなど：サイト閲覧者からキャッシュサーバに送られたリクエストのうち10%をS3が受信し、キャッシュサーバがサイト閲覧者に返すレスポンスの10%をS3が返却する
 


###2-4) 「リソース」タブの値は自動計算
「リソース」タブをを開いて、AWSリソースの情報を確認してみます。ここに表示されている情報はForkMe!が自動的に計算した結果です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1559449/719a638a-c358-326a-4cb8-bf1bd69d4bfd.png)

CloudFrontの「CacheServer」では、2rpsの性能が期待され、月間922,140リクエスト、1GBの受信、5GBの送信で概算コストが179円とわかります。これらは先に登録したアクター（利用者）、コンテキスト（用途）から自動算定された情報です。CloudFrontは通信料に応じて課金されるため、要件データが登録されたことによってはじめて、この試算が可能になっています。

#3. 最後に
以上のように、アクターとコンテキストの書き方を覚えれば設計に要件データが追加できます。
新たなクラウド環境を設計しようとするとき、似たような性能やコスト感、用途構成でテンプレートを検索、流用できれば、より効率的に作業が進められるのではないでしょうか。
ぜひ[クラウドデザイン仕様（CDS）](https://docs.reindeer.tech/index_ja.html)を使って、要件データを記録してみてください！

#4. 参考
[前回の記事「CloudFormationのテンプレートを速攻で探しやすく整理する（１）」](https://qiita.com/harashin-midnight-only/items/6c3c1a4ad7e02902668f)
ForkMe!について　　　　https://reindeer.tech/ja/index.html#forkme
ForkMe!会員登録ページ　https://forkme.cloud/ja/signup/
ForkMe!トップページ　　https://forkme.cloud/ja/
ForkMe!マニュアル　　　https://docs.reindeer.tech/forkme_ja.html
クラウドデザイン仕様　　https://docs.reindeer.tech/index_ja.html