クラウドサービス立ち上げ時のTODOリスト

社内で幾つかクラウドサービスの立ち上げをやったので、それをもとに「やること一覧」を作ってみました。プロジェクト立ち上げ時に、全体を通して何をやるべきか見通しを立てる際の参考になればと思います。
それぞれの項目について語りだすと長いので、一覧性を重視してなるべくシンプルに書いてみました(つもり)。一覧という意味では、目次をコピペするのがオススメ。
比較的お固い会社での事例を元にしているので、それぞれの組織風土にあわせてアレンジしていただければと思います。

**#クラウドサービス**
**#やることリスト**
**#アジャイルでもウォーターフォールでも**

自分でも今後サービス立ち上げの機会があれば、これを見ながらやることリストをざーっと書き出してスケジュール・人員確保のプランニングに役立てたいです。  
クラウドサービスと言っても、サービス形態はWebサービス・APIサービス・バックエンドサービスなど色々あるかと思いますが、今回はAPIサービスあたりを想定しています。  
サービス形態によってはWebUIやクライアントアプリなど、他に必要なものがあればこれに追加になります。
※記事は随時、加筆修正をしていく予定です。

# サービス概要を決める
まずはどんなサービスを作るのかを決めないと先に進めません。
[インセプションデッキのエレベーターピッチ](https://blog.nextscape.net/research/agile/inceptiondeck), [プロジェクト憲章](https://uhuru.co.jp/mclab/marketing/projectmanagement03/)など手法は様々ですが、下記のことを意識してどんなサービスにするかを決めます。

* 提供する価値は何か・強みは何か
* 顧客・ユーザーのニーズは何か、何を解決するのか
* 対象顧客はどんな人か
* 他の似たサービスとの差異・特長は何か

これらを整理し、人に説明ができるように文章化するなり資料をまとめておくと、この先プロジェクトについて人に説明する時の印象が良くなります。  
個人的にはパッとみてわかりやすい, 且つ使ってみたい！と思わせるような資料を作っておくと、今後発生する上司・上位組織へのお伺い, 人員(協力者)の確保, 顧客獲得などにプラスに働くので、ここでの資料作成にかける時間はけちらないほうが良い気がします。

# 顧客を想定・獲得
請負プロジェクトの場合は最初から顧客が決まっていますが、自発プロジェクトの場合は自ら顧客を獲得していかなければなりません。
「誰かが使ってくれるはず」のサービスより、最初の顧客が決まっている・目星がついている状態のほうが具体的な要件も出しやすく、プロジェクトのGoも降りやすいでしょう。
請負であってもConsumer向けサービスの場合は、プロダクトの機能やデザインを決めていく前にターゲット層を想定しておきたいです。

# 要件を決める
機能の要件はもちろん、品質やコストの要件も洗い出しておきたい。

* 機能要件
  * メイン機能
  * 認証系の機能(忘れがち)
* 非機能要件
  * パフォーマンス要件
    * キャパシティプランニング
  * 運用要件
    * SLAどうするのか, 24時間体制で障害対応する？
    * 運用体制はどうするのか(外注or自分たちで)など
  * セキュリティ要件
  * コスト

# ユースケース・シーケンスを書いてみる
概要レベルからユースケースを洗い出し、シーケンスを考えてみることで、足りない機能や破綻している部分が見えてきます。
主要なユースケースについて書き出してみて、概要や機能を見直しましょう。

# スケジュール・スコープを決める
ここまでで大体の機能セットや開発規模が見えてきます。
「いつまで」に「どこまで」やるのかを明確にし、大枠のスケジュールを決めましょう。

# チームメンバーを集める
どういうスキルセットの人が、どの時期に何人くらい必要なのかを計画します。
ここが予め決まっている場合は、メンバー事情に合わせて上記のスケジュール・スコープを決めます。
また、集められそうなメンバーのスキルセットも考慮して、後述の対象OSであったり、クラウドべンダーを選定することになるかと思います。

# 対象OSや開発言語・クラウドベンダーを選定する
想定顧客・最近のトレンドなどを加味して対象OS/開発言語を選定します。
また、今までのナレッジが自分たちにあるかどうかや、適したサービスが用意されているかなどを考慮してクラウドベンダーを選定します。
クラウドベンダーによって、コストを大幅に削減できたり、マネージドサービスが用意されていて開発・運用コストがほぼかからなかったりなど大きく違って来ることもあるので、余裕がある場合は次項のクラウドアーキテクチャ概要設計と合わせてコスト試算・パフォーマンスの見積などをしながらクラウドベンダーを比較選定できると良いです。

# クラウドアーキテクチャ概要設計
選定したクラウドベンダー上で、どういうアーキテクチャが良さそうかを検討します。
トレンドの移り変わりが激しく、2~3年前に「最先端！」と言っていた構成が「まだあれ使ってるの？」と言われちゃったりするので、少なくともこのタイミングではキャッチアップしておきたいところ。
とは言え、ちょっと枯れてきたくらいよく使われた構成のほうが、困った時に参考になる情報が多かったり変なバグ・トラブルを踏まなくて済むというのも事実。
機能実現性・可用性・コスト・パフォーマンス・スケーラビリティ・安定性・運用コスト・セキュリティ・etc... いろんな視点でレビューしながら設計します。

# API(IF)設計
顧客がいたりClientアプリケーションを開発したりする場合は、もっと早い段階で着手するかもしれませんが、各システムのAPI(IF)を決めます。
プロジェクトによっては一度出したものを変え難いこともあるので、そういう場合はよく吟味してから第一版を提供します。(顧客企業やClientが開発を始めてしまう、など)
WebAPIであれば、下記のようなパターンを参考にすると良いと思います。

* [REST](https://qiita.com/TakahiRoyte/items/949f4e88caecb02119aa)
* [GraphQL](https://qiita.com/bananaumai/items/3eb77a67102f53e8a1ad)

細かい話ですがIFという意味では、エラー定義やAPIのバージョン管理といった話も検討項目になります。

# 情報共有サイト・ソースコードリポジトリの検討
各種資料をまとめておいておくための情報共有サイト・ファイルシステムなどを用意します。(チームメンバーが少なくても、一人でも、Localではなく「ここ」というところに整理して置いておくと、後からメンバーが追加になったときや引き継ぎの時に慌てなくて済みます)
ソースコードをどこでどのように管理するかを決めます。
チーム内のコミュニケーションツールを検討します。

# コーディングなどの規約を策定
* コーディングルール
* レビュー規約
* その他開発プロセス

細かいことは最初から決めなくても良いと思います。が、最低限「commit前にこのツールをかけてコーディング規約違反を確認してね」とか、「マージ前にはレビューしようね」とかは決めておいたほうが良いです。

# 開発環境整備
チームの規模にもよりますが、開発環境がバラバラすぎるとハマリポイントが多くなってしまいます。例えば Windows/Linux/OS X 全部の環境で開発が行われているとすると、Localで動作させる際にそれぞれの環境での動作を検証しなければなりません。
好みや慣れもあると思いますが、ある程度は開発環境を揃えたほうがTotalとして環境に振り回される工数が少なくなり、開発効率は上がるでしょう。
最近では、開発環境自体をCloudで用意したりということもあるので、その波に乗ってしまうのもありかもしれません。ネットが使えない環境だと何もできなくなりますが・・・。

# 検証実装をしてみる
イテレーティブな開発ができる環境であれば、まずは検証を兼ねたラフな実装をしてみます。
ここでは、ユースケースやシーケンスを書いたときと同じように、API設計やシステム設計について、足りないものや破綻している部分を洗い出すのが一番の目的です。
更に、顧客やClientと同時開発している場合は、早い段階で一度使ってもらい、Feedbackをもらうことができます。
Webサービスを考えている場合は、エンドユーザー(相当の人)に触ってもらって、使い勝手やユーザーエクスペリエンスも含めたFeedbackを期待できます。※ただし、この場合は中の仕組みがどうとかAPIがどうとかよりも、デザイン・パフォーマンスが評価に大きく影響するので、[デザインスプリント](http://www.gv.com/sprint/)などで別途UX検証をする。

# 社内確認・調整
* 知財や法務への確認
* セキュリティ・プライバシー関連の確認
* あとは同じようなサービスを社内で実は既にやっていたりとか・・・の調整

# クラウドシステム詳細設計
* ネットワーク設計
* リトライポリシー
* サービスのスケール定義
* 冗長構成検討
* 監視・通知設計(システム)

などなど、アーキテクチャ設計でやらなかったもう少し細かい部分を詰めます。

# ソフトウェア設計
* 使用するFW
* 必要に応じてクラス図・シーケンス図
* 同期処理|非同期処理、シングルスレッド|マルチスレッドあたりはしっかり決めたほうが良い

個人的には設計書は作り込みすぎず、詳細なんかはどんどん変わっていくものなので方針だけ共有できるものがあれば良いと思います。
チームメンバーの力量や、一緒にやってきた経験の長さ（信頼関係）などに大きく左右されるところかと思いますので、必要と思われるものを見定めて作成・共有するのが大事。

# 開発
とにかく作ります。
テスト駆動開発にトライするか・mixでいい感じにやるか等々、色々と考えることはあると思いますが、ここでは「開発」で括ります。
ちなみに、単体テストはこの項目に含まれます。

# CI/CD検討
CI/CD（自動テスト・自動デプロイ）について検討します。開発と並行して作成・整えていくイメージです。

CI/CDについてまとまった記事があったのでこちら。
* [アジャイル開発を支えるためのCI/CD](https://qiita.com/newta/items/64e3d2dfd8dad69a3185)

AWSからもCI/CD用のサービスが提供されていますし、GCPでもそれっぽいものが出ています(SourceRepository/ContainerBuilder)。Jenkinsを使うのも手ですし、こういったクラウドベンダーが提供しているものを使ったり、CircleCIなど他のCI/CD専用のサービスを使うのもあり。
費用や頻度、システムの構成などを考えながら何をどう使うか検討します。
もちろんどうするかが決まったら、その環境を構築してCI/CDを回して下さい。

# 不具合管理システム検討
ある程度開発が進み、リリースに向けたテストが視野に入ってくると、発見した不具合をどう管理していくかが気になりだします。
これを決めないまま、場当たり的にチャットやメール・エクセルなんかで管理していると、どんな不具合が何件出て、どれに対応したのかしていないのかがわからなくなってしまいます。せっかくテストをしてもこれでは意味がありません。
社内で「これ」というツールが決まっていることもありますし、GitHubのissueで管理したり、Redmine/Trello/JIRA などなど、色々なツールがありますね。無料で使えるものも。不具合管理ツール・BTS(Bug Tracking System)なんかで検索するとたくさん出てきます。

# 監視・通知設計
サービスを継続的に提供し続けるには、システムになにかが起こった時にどうにかして検知して通知する必要があります。

* 何が起こり得るかをリストアップ
* それぞれどうやって検知をするか
  * 誰に・どういうツールで検知をするか
* レベル感は？緊急事態？お知らせ程度？

このあたりを決めていくのに必要なことを検討していきます。

**ログ設計**

* どういうエラーの時に、どういうログを出すかを検討する
* prefixなどを決めてレベルを管理するのが定石。これもとに通知の有無や通知対象を決定する

**障害管理ツール**

* 障害の通知・現在の障害のStatusが一覧できる・過去の障害履歴が見られるなどの機能を有する
* 通知の中でもエスカレーション機能があると良い
  * 今日担当のはずの人が諸事情により通知を受け取れ(ら)ない場合に、次の担当やチーム全体にエスカレーション通知を上げてくれる
* PagerDuty, VictorOps, OpsGenie, etc...

**可視化設計**

* システム運用的な観点からビジネス的な観点まで幅広く、何をどう可視化するかを検討する
* 可視化したい指標のために、ログ(Web/Client双方)を追加したりすることもある
* システム障害ではないが、APIの4xx系レスポンスが増えている、とか
* 今月のActiveUserは先月より多くなっているか、課金ユーザーは増えたか、など

# 機能テスト
単体テスト(UT)は実装とともに作成・実施されているとして、もう少し大きい目で見たテスト。
WebAPIであれば API界面でのRequest/Responseだけを確認、バックエンド機能であれば 入力データを入れて出力が期待通りかを確認するような、ブラックボックステストがメイン。
Consumer向けサービスの場合は、ユースケースに合わせて作成したシナリオベースのテストも効果的です。
何のテストで何を担保する、といったテスト種別と内容を検討し、それぞれのテスト項目をリストアップして実施します。自動化できるものは自動化してしまいたいですね。

# パフォーマンステスト
上記機能テストとは別に、パフォーマンス要件を満たしていることの確認や、システムの設定値・リソースを決めるために行います。
このテストを通じて、サービスイン時のシステムリソースレベル（インスタンスサイズやメモリなど）を決めたり、負荷が上がってきたときのスケール判断基準を定めたりします。
また、「パフォーマンス要件を満たす構成にするとコスト的に見合わない」など課題があった場合は、設定値やコードのチューニングを実施したり構成の変更を検討します。

# 運用手順書作成 & オペレーションテスト
クラウドベンダー側でフルマネージドなサービスが増えてきたこともあり、システムを運用するにあたって必要なオペレーションがどんどん減ってきています。
とは言え、何か起きたときの調査やリカバリ手順、サービスを緊急停止させる手順などは予め準備しておき、一度は商用環境相当の環境でテストとして実施しておきたいところ。
こちらも監視通知のときと同じく起こりうる事象をリストアップし、その中で対応が必要なもの・手順書を作成すべきものを選びます。
一昔前は、手順書といえばエクセルやワードが主流でしたが(今も業界によってはそうかも？)クラウドベンダー側の公式手順が既にある場合は、リンクだけ貼っておいて「参照してね」としたいので、htmlに変換できる形式がやりやすいなぁと思っています。特にWebConsoleでの作業なんかは、クラウドベンダー側のWebUIが変わるたびに追従なんてできないですし、そもそもベンダー側で提供しているものをコピペする意味もあまりないかと。外線にどうしても繋げない環境でしかオペレーションできない、など特殊な事情があるところはあるかと思いますが。

# セキュリティテスト
脆弱性診断。
専用の診断サービスを提供している企業が沢山ありますので、社内でどこに依頼するかを検討します。もちろん社内で提供していることもありますし、診断ツールを使って自分たちで診断しておしまい、ということもあるかと思います。
自分たちのサービスにはどの診断が必要で、どこまでテストしてもらう(する)かを、お財布とよく相談しながら決めます。診断の内容は多岐にわたり、それぞれの診断サービスを受けることで何が保証されるのかはしっかり認識したほうが良いです。

特にPenetrationTest(侵入テスト)を実施する場合には、クラウドベンダー側に一報を入れておく必要があるがあるので注意が必要です。
下記に主要クラウドベンダーのポリシーがまとまっていました。
[クラウドサービスを脆弱性診断する時のお作法](http://tigerszk.hatenablog.com/entry/2017/06/20/202335)

# OSSなどのライセンスの確認
開発時に留意しながら開発すべきなのですが、最悪このタイミングで使用しているOSSのライセンスを確認します。
今どき、Webやクラウドの開発をしていてOSSを全く使わないなんてことは流石にないでしょうから、何かしら使っているという前提で調査・リストアップします。

下記にライセンス一覧と特徴がまとめてありました。
* [たくさんあるオープンソースライセンスのそれぞれの特徴のまとめ](https://qiita.com/tukiyo3/items/58b8b3f51e9dc8e96886)

こっちのほうがより内容が充実(けどリストとしては↑のほうが見やすい)
* [さまざまなライセンスとそれらについての解説](https://www.gnu.org/licenses/license-list.ja.html)

商用利用NGではないか、自分たちがプロダクトを再配布しようとしている場合は再配布時に条件がないか、などを確認する必要があります。
基本的に、自プロジェクト用でサーバーサイドに配置しておくだけのソースにおいては、[AGPL](http://ounziw.com/2013/05/17/agpl/)が含まれていないかを意識すればよいかと思います。

# サービスインに向けた判定会
社内に「判定会」というプロセスがあれば、判定会に向けて判定材料を揃えていきます。偉い人の日程を抑えるのが大変だったり。
もし達成できていないこと・残課題があっても、サービスインにあたって問題ないと思っているならば、その根拠を示しつつ現状を正確に伝えます。（「全部できてまーす」と言ってしまうと、あとで辛い）

社内で判定会のプロセスがなくても、チェックリストを作って自分たちで確認位はしたほうが良いかと思います。

# サービスイン
ようやく ここまでこぎつけました。
ソフトローンチ（お客様がほぼ0の状態からスタート）なのか、他サービスからの移行でいきなりアクセスがドーンなのかはわかりませんが、どちらにせよ、サービスイン後はしばらくアクセスの様子を見たりシステムリソースやログを見たりしてそわそわして過ごします。
大きな問題がなさそうであれば日常の監視にシフトして完了。
サービスが育ってたくさん使われるといいですね。