Webサービスを新規開発をする時にやっておいたほうがよいこと（Rails+AWS）

新規開発というタイトルにしましたが、特に新規開発でなく既存サービスの開発でも取り入れると良いものです。ただ０ベースの開発だからこそ導入がしやすいというのはあるので、新規開発で意識できるといいですね。


RailsアプリケーションでインフラはAWSを使うことを想定してます。


- [アプケーションコード](https://qiita.com/ykyk1218/items/dbf33c757df42839b493#%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B3%E3%83%BC%E3%83%89)
- [インフラ](https://qiita.com/ykyk1218/items/dbf33c757df42839b493#%E3%82%A4%E3%83%B3%E3%83%95%E3%83%A9)
- [セキュリティ](https://qiita.com/ykyk1218/items/dbf33c757df42839b493#%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3)
- [DevOps](https://qiita.com/ykyk1218/items/dbf33c757df42839b493#devops)
- [計測](https://qiita.com/ykyk1218/items/dbf33c757df42839b493#%E8%A8%88%E6%B8%AC)

です


# アプリケーションコード

- linterの導入
- テストコード
- 逃げる場合
- エラー通知

## linter、rubocopの導入

ソースコードは綺麗に保ちたいですよね。
汚くしたい、なんていう人はいないと思います。
linterやrubocopはあとから導入しようとするとめちゃくちゃ辛いです。
とても辛いです。
辛くて諦めてしまいそうになります。:dizzy_face:

除外設定をして既存プロジェクトに導入するやりかたはありますが、すでにイケてないコードがプロジェクト全体を蝕んでしまっていたら、導入できたところで効果が期待できません。

是非最初にいれましょう。

- CSS: stylelint
- JavaScript: eslint（coffeelint、tslint）
- Ruby: rubocop
- view template: slim-lint

### ルールについて

見た目の部分（インデントの入れ方、()をつけるのかつけないのかなど）は、よしなに調整をしても良いのですが `MaxLength` や`ABCSize` といったコードのロジックに影響しそうなところは...できればそのままでいきたいですね。


stylelintはデフォルトのルールがないようなので、設定する必要があります。

基本ルールと呼ばれるのが別であるので、面倒であればこれを導入しちゃってもよいかもしれません。
https://github.com/stylelint/stylelint-config-standard

#### エディターへの導入
今どきのエディターであれば、自動でrubocopなりeslintなりが走るように設定できるはずです。
コードを書きながら怒られるため効率がよいです。
是非導入しましょう。

ちなみに僕はvimmerなので、こいつを導入してます。
https://github.com/w0rp/ale


## テストコード
テストコードは是非最初から書きましょう。
これもあとから追加は辛いです。心が折れます。:persevere:

網羅的にできればよいのですが、実際スケジュールの問題や開発メンバーのスキルの問題などで難しいシーンはあることでしょう。
まずは現実的な最低限のテストコードのカバー範囲の共通認識をメンバー間で持てるようにしておくと良いと思います。
（リクエストテストとモデルメソッドは最低限テストコード書こう！！ みたいな）

### フィーチャースペックについて
seleniumやcapybaraを使ったフィーチャースペックは、無理に最初は導入しなくてもよいかもと思ってます。
フィーチャースペックはUIの変更に左右されてしまうことが多いので、UIが固まりきってない状態でテストを書いてもメンテが辛くなりそうなイメージがあります。


## 逃げる場合 :runner_tone2:
rspecを書くのもrubocopに対応するのももちろん大事なのは分かってる。でもどうしてもリリースまでの時間がないんだ...:sob: 
ということは、よくある話かなと思います。 

どうしても時間がなくて、対応できない場合、そんな時はその時の気持ちをコメントに残しておきましょう。

rubocopはメソッド単位などで個別にdisableの設定ができます

<img width="369" alt="Search_·_逃げちゃだめだ.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/bcc1a186-7664-f92d-5b46-cd182e7b471a.png">

最終手段です。

## エラー通知 :eyes:
 
エラーが発生しても通知されず、しばらく時間が経過してから発覚してしまう状態は危険です。
エラーが発生したらすぐに気づけるように、通知の仕組みを入れておきましょう。
通知先は自分たちが普段よく使っているコミュニケーションツール（slackなど）が良いです。

### アプリケーションコードのエラー通知
アプリケーションコードのエラー通知に [Sentry](https://sentry.io/welcome/) を導入します。

導入手順
https://qiita.com/mikaji/items/74fac3be5e1235e0b762

### Cronの実行エラー
意外と忘れがちなのがCron実行エラー時の通知。
Cronに記載したコマンドが実行後にエラーになる場合は上記に紹介したSentryを設定しておけば通知が飛びます。
ただCronのコマンド実行そのものが失敗した場合は通知が飛びません。
（パスが間違ってしまっていたとか、サーバの何らかのトラブルとか...）

その場合は `MAILTO=hogehoge@example.com` の設定をしておく必要があります。

RailsアプリケーションであればCronの設定は `whenever` のgemを使うパターンが多いかと思いますが、その場合は `config/schedule.rb` に

```
env :MAILTO, "hogehoge@example.com"
``` 

を設定しておくと、cronの実行時エラーの時に指定したメールにエラーメールが飛びます。

# インフラ

- Infrastructer as Code
- 監視
- 命名規則
- 削除保護

## Infrastructer as Code
ChefやAnsibleなどで、インフラをコードで管理できるようにしましょう。
シンプルな構成の場合はitamaeがおすすめです。
[Chef脱落者が、Itamaeで快適インフラ生活する話](https://qiita.com/zaru/items/8ae6182e544aac6f6d79)

一度本番稼働をした後はコマンド実行で環境構築するのがちょっと怖くなってしまいます。:ghost:

「もしかして設定ファイルから必要な設定が消えてしまうのでは...」
「余計なパッケージをインストールしてしまうのでは...」
等々...

本番リリース前の状態からchefやitamaeと言ったプロビジョニングツールを使って環境を構築しておけば、そうした心配事はなくなりますね。

## 監視
監視はリリース後でも問題ないと思いますが、うっかり忘れがちなのでリリース前からしっかり準備をしておくと良いでしょう。

監視対象は

- サーバそのものの死活監視
- サーバリソース（CPUとかメモリ）
- サービスに必要なプロセス（sidekiqやunicorn）

特にプロセスの監視は忘れがちなので、気をつけましょう

### 監視サービス

#### Mackerel
多少お金かかりますが、設定簡単でいい感じです。
プロセス監視もメジャーなプロセスであればプラグインを使って監視をすることができます。

[プラグイン一覧](https://github.com/mackerelio/mackerel-agent-plugins)


## 命名規則
インフラで命名規則？っていう感じですが、awsのサービスを使う時、いろんな場面で名前をつけることがありますよね？
この名前を無秩序につけていくと、

「これ何に使っていたっけ...？」
「これ本当に使ってる？」

みたいなことが起きてしまいます。
後サーバが増えた時の一覧性も悪いですよね。

そこで最初から命名規則のルールを決めて、そのルールにしたがって名前をつけていくようにしましょう。

**命名規則の例**

```
ServiceName-Stage-Role-Date
```

```
Qiita-staging-web-20181001
```
みたいな感じですね

## 削除保護

AWSのEC2インスタンスは削除保護設定ができるので、productionで使うインスタンス達には絶対設定しましょう。
[AWS EC2：削除保護の設定](https://techjournal.tech/aws_ec2-0003.html)

（僕は間違って本番インスタンスを削除してしまった現場を見てしまった経験があります😱)

RDSも削除保護ができるのでこちらも設定しましょう。
[RDS および Aurora に削除保護機能がつきました！](https://dev.classmethod.jp/cloud/aws/rds-and-aurora-deletion-protection/)

（こちらも間違って本番RDSインスタンスを削除してしまった現場を見てしまった経験があります😱😱😱)

# セキュリティ 

- アプリケーションコード
- AWSのセキュリティ
- バックアップ 

うっかりするとおろそかになってしまうセキュリティ対策。
悲劇を生み出さないためにもしっかり対策をしておきましょう。

## アプリケーションコードのセキュリティ対策
コードのセキュリティ対応は **breakman** というgemでチェックできます。
[breakman](https://github.com/presidentbeef/brakeman)

これだけやっておけばアプリケーション側でのコードの脆弱性はある程度防げると思います。

## AWSのセキュリティ対策

AWSに関連するセキュリティ対策は色々あるのですが、まずは
**Trusted Advisor** を使ってチェックしてみましょう。
[Trusted Advisor](https://console.aws.amazon.com/trustedadvisor/home#/dashboard)


実行すると、色々怒られると思うので必要な対策を随時やっていきます。
ここの対応をしておけば完璧っていう訳でもないですが、
「セキュリティグループで不要に解放されているポートがないか」、「S3のバケットが公開されていないか」、など必要最低限のセキュリティチェックはできると思います。

## バックアップ
GithubやRDSを使っていれば、それ程バックアップを意識せずとも自然にバックアップされる状態になります。

データベースのデータやコード以外に消えてしまった時に問題があるデータは自動バックアップの仕組みを用意しておき、復旧ができない状態にならないようにしましょう。

### S3のバージョン管理
AWSを使ったWebサービス開発では、外部ストレージとしてS3を使う場面が多いかと思います。
S3のファイルは操作ミスなどで削除や上書きしてしまう可能性があるので、必要に応じてバージョニングの設定をしておきましょう。

Amazon S3 > [S3バケット] > プロパティ
からバージョニングの設定ができます。

<img width="575" alt="スクリーンショット 2018-10-14 18.58.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/6808/20711f9d-7f81-2841-45aa-504ae37f2cc6.png">


# DevOps

- 開発環境
- 継続的インテグレーション

## 開発環境
初めのうちに開発環境を誰でも簡単に構築できるように手順をまとめておきましょう。
リリース間際で助っ人を頼む場合、環境構築で手間取ってしまうと勿体無いですよね。

ただ手順を作る場合、ややこしくならないようDockerやVagrantを使ってなるべく少ない手順で構築できるようにしましょう。

## CI（継続的インテグレーション）

ビルド、テスト、デプロイを全て自動化しておきましょう。
最初の方に書いたlinter導入もCIに組み込むようにします。


# 計測

ここでいう計測はWebサービスを分析するための数値を取れる状態にしておくことです。
標準的なWebサービスであれば、 `Google Analytics` （以下GA）でサイトを分析することが多いと思いますので、GAの設定をリリース前に済ませておきましょう。

## イベント計測のルール

クリックイベントやビュースルーイベントを仕込んで、サイト分析することもあるかと思います。
ここのイベント計測に関しては、後から必要に応じて追加でもいいのですが最初にルールを決めておかないと、イベント名の付け方がバラバラになってしまい分析に苦労をしてしまいます。
ルールだけは最初に決めておくと良いでしょう。

**ルールの例**

GAのイベント計測で設定が必要なのは
<カテゴリ名>、<アクション名>、<ラベル名>
です。
![Web 1920 – 1.png](https://qiita-image-store.s3.amazonaws.com/0/6808/39298d63-0f9b-85dc-8882-1a8be50c0904.png)
カテゴリ名は要素の位置によって変えて（上記画像参考）
アクション名は「閲覧」、「クリック」
ラベル名は遷移先のURLやタイトルとする

という簡単なルールだけでも決めておけば、無秩序にな状態にならなくて済みますね。
この辺りは実際に分析をしてくれる担当と相談しながら決めましょう。

# 最後に

ここのリリース前チェックリスト使うと設定漏れを無くせると思います！
https://qiita.com/zaru/items/71900d0e4b2afaaa955b#%E3%83%AA%E3%83%AA%E3%83%BC%E3%82%B9%E5%89%8D%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%83%AA%E3%82%B9%E3%83%88