S3「 お゛め゛ぇ゛に゛権゛限゛ね゛ぇ゛がら゛！」

# はじめ

この記事は「[本番環境でやらかしちゃった人 Advent Calendar 2020]
(https://qiita.com/advent-calendar/2020/yarakashi-production)」25日目の記事です。
本日はクリスマスですね。メリークリスマス🎅🎄

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/f146a683-0e3e-482f-b403-bbe62ad2ab24.png)

タイトルでふざけてしまい申し訳ございません。
既に[元ネタ](https://dic.nicovideo.jp/a/%E3%81%8A%E3%82%81%E3%83%BC%E3%81%AE%E5%B8%AD%E3%81%AD%E3%81%87%E3%81%8B%E3%82%89%21)が通じなくなって来ているかもしれないですが、、、(元ネタのドラマ [ライフ](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%82%A4%E3%83%95_(%E6%BC%AB%E7%94%BB)#%E3%83%86%E3%83%AC%E3%83%93%E3%83%89%E3%83%A9%E3%83%9E)は13年前ですし。。)

インフラエンジニア4年目の[tsumita](https://twitter.com/tsumita7)と申します。
最近は主にAWS基盤の要件定義〜テストをして生計を立てております。

# やらかしちゃったこと
### 3行でわかるまとめ
- CloudFront(CDN)とS3を使ってSPA([SinglePageApplication](https://ja.wikipedia.org/wiki/%E3%82%B7%E3%83%B3%E3%82%B0%E3%83%AB%E3%83%9A%E3%83%BC%E3%82%B8%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3))を配信する基盤へのリリース作業時にやらかしちゃった
- リリース作業中に**なぜか**CloudFront-->S3へのアクセス権限を変更してしまった
- エンドユーザがアクセスすると「 お゛め゛ぇ゛に゛権゛限゛ね゛ぇ゛がら゛！」と言われる状態になり、SPAを取得出来なくなった(障害発生)

### 詳しい解説
#### 構成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/69f2d2cd-d4ee-de68-304d-dffc949f56ce.png)

#### 仕組み解説
エンドユーザがアクセスするとRoute53で名前解決が行われてCloudFrontにアクセスします。
CloudFrontにキャッシュがあればキャッシュからSPAを返却し、なければCloudFrontがS3からSPAを取得してエンドユーザに返却するという仕組みです。
S3への直接アクセスは禁止しており、CloudFrontを介したアクセスのみ許可していました。

`リリース作業手順`
1. ローカルでSPAをビルドする
2. S3の特定パス(s3://\~~S3バケット名~\~/YYYYMMDDNN)にビルドしたSPAをアップロードする
3. CloudFrontの[OriginPath](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/distribution-web-values-specify.html#DownloadDistValuesOriginPath)(ドキュメントルート的なもの)を`2.`でアップロードした/YYYYMMDDNNに変更する
4. CloudFrontのキャッシュをクリアする

上記手順`3.`のOriginPathを変更する際に、[オリジンアクセスアイデンティティ(OAI)](https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/private-content-restricting-access-to-s3.html)の設定を変更してしまい、CloudFront-->S3へのアクセス権限を削除してしまったことが今回の原因です。
具体的には下記画像の`Restrict Bucket Access`の項目をYes-->Noに変更してしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/3effce84-8ab3-48f3-7b9d-3986ca3d9d82.png)

`Restrict Bucket Access`の項目をYes-->Noに変更してしまった結果、S3に「お゛め゛ぇ゛に゛権゛限゛ね゛ぇ゛がら゛！」と言われてしまいました。。

**`Restrict Bucket Access`がYesの時**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/d44f0a2f-e54a-d74f-90ab-5623b86f14fa.png)

**`Restrict Bucket Access`がNoの時**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/441ad059-ab01-257b-ec10-da7a4976b852.png)

幸い、手順`4.`のCloudFrontのキャッシュクリア後すぐに動作確認を行い障害に気付けました。
その後数分で`Restrict Bucket Access`の設定をYesに戻せたので大事には至りませんでした。

# 惨劇はなぜおこってしまったのか
### 根本的な原因
- 1人でリリースをしていた
- 変更部分のみのパラメータを確認する手順としていた
- 手動でリリースをしていた

# 二度と惨劇を起こさないためにどうしたのか
### 暫定対策
- 必ず2人以上で作業することにした
本来2人以上で作業するべきなのですが、そういう決まりが無かったので2人以上でリリースすることにしました。
`作業者`と`確認者`の役割を設けて`作業者`は`確認者`が確認するまでは次の画面に遷移(確認ボタンや確定ボタンを押す行為)をしない決まりにしました。

- 変更箇所以外のパラメータも確認する手順とした
やらかしの原因である意図しないパラメータが変更されないように、変更箇所以外のパラメータも確認する手順にしました。

### 恒久対策
- CI/CDを実装して人の手が介入できるところを減らした  
今回のやらかしについては完全にヒューマンエラーだったので、人が介入できる箇所をデプロイ承認作業のみにしました。 
具体的にはCodePipelineを利用して、CodeCommitの特定ブランチにPushされた際に自動的にDeployされるようにしました。加えて、Deploy状況がわかるようにCodePipelineからCloudWatch-->SNS-->Lambdaを利用してSlackへ通知するようにしました。 

#### 恒久対策後構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/87bb9261-b671-c7a4-4b0b-332779bc3358.png)

#### Slack通知例
**特定ブランチPush時(CodePipeline開始時)**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/1c4fbefd-c13f-731a-9e14-eece342f72c5.png)

**手動承認時**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/299739/abd2557b-ded9-197c-bd78-b63a72828fcf.png)

[AWS Chatbot](https://aws.amazon.com/jp/chatbot/)を利用することも考えたのですが、Slack通知メッセージのカスタマイズ(特定時のみメンションを付与)を行いたかったので今回は見送りました。

# おわり
**人はミスを犯すもの**ということを身を持って体験しました。
今後、基盤設計する際は(コストの兼ね合いもありますが)なるべく人の手が介入出来ないような基盤設計をしていこうと思います。
私のやらかしを後悔(公開)することで、同じようなやらかしをする人が一人でも減ることを心より祈っています。  

[Advent Calendar 2020](https://qiita.com/advent-calendar/2020/yarakashi-production)関係者の皆様お疲れ様でした。
記事を読んで下さった皆様にとって来年も素敵な年になることを切に願っています！
良いお年をお迎えください！