【AWS?Docker?】ポートフォリオで必要な知識を自分なりに分かりやすくまとめる【terraform?CircleCI?】


# この記事を書くにあたって

こんにちは。ポートフォリオ作成していますか？
ナウでモダンでめちゃくちゃ質の高いポートフォリオをみんな作っていて、やべえと思っている方。
DockerやAWS、terraformやCircleCIをエンジニアの常識として扱われていて焦っている方。

**めっちゃわかる。**

私もエンジニアとして生きているのに、その辺りが全く分からなくて正直焦っていました。
当たり前のように**「AWSがさぁ〜w」「terraform最高w」**とか言ってる人、マジで天才かよって思ってました。

ポートフォリオ作りました！みたいな記事はあるものの、めっちゃ凄い！それどうやって作るんだぁ〜って感じの記事だったり、逆にすごい難しい記事だったり、単体ではわかりやすい記事だけど総合的にわかんなくなったり・・・。

**terraformって、どんなん？
Dockerってどこで使うん？
AWSっていうけど、実際に何使うん？**

そんな疑問がいっぱいの駆け出しエンジニアの僕がこういうのあったら嬉しかったなぁって記事を復習がてら書いてみようと思いました。

本気でわからないと、どこから手をつけて良いか、どう検索したら良いかわからなくなりますよね。

次回作→[RailsとNuxtとCircleCIを使ってモダンですぐ開発出来る開発環境を構築（導入篇）](https://qiita.com/Shogo1222/items/d90b3fa01a2dca14aeeb)

# 自己紹介
凡エンジニア。Java,PHPでサーバサイドが多め、Javascriptはそこそこで生きてました。
今回は全く未経験の初めての知識で、自分がどこまでやれるか知りたくて挑戦しました。
制作期間は多分半年未満。

言語は Ruby(Rails)/Vue.js(Nuxt.js)→途中でRailsは5.2から6.0.3へアップデート
開発環境にDocker/DockerCompose/nginx/openssl/MySQL/Vagrant
本番環境にAWS/ECS/ECR/CircleCI/terraform
を使ってこんなポートフォリオを作りました。


メイン機能
![飲食店サーチ動画.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235522/2c0620d2-5005-f4cd-d1e9-0f13f5f851d5.gif)

ユーザーのタグ付与・検索
![プロフィール画面・ユーザタグ検索.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235522/544b7362-7308-0dae-9b09-65141ae9cc4d.gif)

コメント
![コメント・削除機能.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235522/decee242-e715-ca2a-6944-c622bb2e794e.gif)

お気に入り・訪問・自分のフォローからのレコメンド
![お気に入り・訪問機能.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235522/f8591166-8f4f-29cd-9bab-f403efbd6bd4.gif)

などなど

# この記事で目指すゴール
**サーバサイドにRailsとフロントエンドにNuxt.jsを使って、
gitにプッシュしたら自動的にCircleCIを動かして
terraformでコード化したインフラで構築したAWSのECRにイメージプッシュして
ECSを使って本番へデプロイする。**

という構成を作るにあたって、必要な知識をわかりやすく、
脳内でなんとなくイメージすることが出来る。

# 注意
私自身、未経験の身で考え出したインフラ構成・アプリなのであまり自信はありません。
もっともっと良い素晴らしい構成があると思います。これは一例として捉えてくだされば幸いです。
普通に「これ違うよ」ってところがあったら教えて頂きたいです。

あとめちゃくちゃ長くなります。目当ての部分へGO！

# 全体の構成

![Qiita用インフラ構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235522/5a4de171-651c-2345-98ef-3448a20f3127.png)

## 説明

- 開発環境にてDockerとDockerComposeにて開発。
- githubへpushすると、CircleCIが起動し、自動テスト・自動デプロイ実行。
- ECRへイメージをプッシュ。
- ECSのサービスを更新し、タスクを実行。

という流れになっています。

いきなりわけわかんねぇってならないで・・・。
それぞれの説明を頑張ってしていきます。

## A. 開発環境で使われている技術
### Docker　
Railsだったり、node.jsを動かすための仮想マシン。
ロゴにあるように、船の上にあるコンテナを運ぶクジラさんの感覚です。

![dockerlogo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235522/2d22d785-a1e6-2581-c369-30e8b46e5c99.png)

無理やり例えると、定食みたいな感じです。
お箸と、お皿と、お手拭き、料理が盛り付けられてお盆の上に乗っています。

Dockerは**「コンテナ」**という単位と**「イメージ」** という単位で称されます。
**イメージ**というのは、上記の例で言うと、お皿・お箸・お手拭きのようなものです。また、ご飯を盛り付けたりして作られます。
**コンテナ**というのは、それらを置くお盆のようなものです。

**イメージ**というのは、MySQL・ruby・node.js等。また、ソースコードを練り込んでイメージをビルド出来ます。
**コンテナ**というのは、イメージを含んだOS（centOS・Linux・alpine等）
OSは、macとかwindowsとかのことだよ。

### DockerCompose
上記のDockerの**コンテナ**をオーケストレーションするツール。
例えると、食べ物が盛り付けられた定食を、それぞれのテーブルに運んでくれるかわいいウェイトレスさんのようなイメージ。DockerComposeのタコさんのロゴがそのまんまのイメージですね。

MySQL・Rails・NuxtのDockerコンテナがあるとして、それらを同時に起動して
さらにそれらのポートをそれぞれ設定出来たり、起動時のコマンドの設定をdocker-compose.ymlというファイルで管理できます。
これら三つをDockerで動かすと、それぞれDockerコンテナをいちいち起動しなきゃいけなくて不便ですよね。
DockerComposeはそういった問題をクリアすることが出来ます。

![68747470733a2f2f71696974612d696d6167652d73746f72652e73332e616d617a6f6e6177732e636f6d2f302f3139313330342f62343162396562362d316663342d373433622d383863302d6635346638633763656532342e706e67.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235522/dadabf8a-d879-1ffa-bfcc-b5ceffb5a54f.png)

### MySQL
データベースのことです。
例えば、メモ帳アプリを作るとすれば、メモ帳のタイトルだったり内容だったりを保存します。

## B. github
頑張って書いたコードを保存する場所です。
更新する度に履歴が残り、間違えた！と言うときでも安心。すぐ戻せます。
使い方は、[サル先生のGit入門〜バージョン管理を使いこなそう](https://backlog.com/ja/git-tutorial/)このあたりを見れば一日でわかります。

## C. CircleCI
モダンな自社開発企業さんだと、高確率で導入されていますよね・・・。
Saas型のCI/CDサービス。

**CIとは、Continuous Integrationのこと。「継続的インテグレーション」といいます。**
integration = 統合のことで、
要は継続的に「統合」してテストしましょうねってことです。

**CDとは、Continuous Delivery or Deploymentのこと。「継続的デリバリー/デプロイ」といいます。**
Delivery =　本番環境へのデプロイを指します。
要は、継続的に「デプロイ可能な状態」にしましょうねってことです。

これらを上述したgithubと連携して実行できるサービス、それがCircleCIです。凄いぞCircleCI!
簡単に言うと、githubへ保存すると、あらら、勝手に統合テストしてくれて、勝手にデプロイしてくれんの？って感じのスーパーツール。
ただ、
>勝手に統合テストしてくれて、勝手にデプロイしてくれんの？

この部分は自分で設定しないとダメ。ほんと世知辛いですよね。はぁ。病み。
設定は、ymlファイルで読み取られます。
githubのリポジトリにCircleCIを連携し、そのymlファイルをアップロードすることで使用可能となります。
なんだか仰々しいですが、CircleCIで実行されるのはコマンドラインで実行されるコマンドと同義です。
例えば簡単に言うとrspecのテストを実行したいのであれば、`bundle exec rspec`などのコマンドをymlに記載するとそれが実行されます。

はぁ〜ん、コマンドラインで実行できるコマンドをymlの形式で書けばいい、そう考えると、わりと簡単そうじゃない？気楽に行こうぜ！

参考：
[いまさらだけどCircleCIに入門したので分かりやすくまとめてみた](https://qiita.com/gold-kou/items/4c7e62434af455e977c2)

## D. ECR
意外と簡単に噛み砕かれてないECR。
ECRとは、**Elastic Container Registry**のことです。

**Elastic** = AWSのサービスでよく出てきます。「柔軟」と言う意味。
**Container** = 先ほどDockerの説明で出てきましたね。そう、お盆です。
**Registry** = 「登録」という意味です。

要は、**柔軟に、コンテナー（お盆）に、イメージ（定食）を、登録出来る！**サービスです。
ECRには、リポジトリという単位が存在していて、そこにイメージを登録できます。

簡単に定食の例を使って手順を。

- ソースコードを書く。（ご飯を作ります。）
- Dockerを使って、イメージをビルドする。（綺麗に盛り付けます。）
- ECRに登録します。（盛り付けたご飯を、テーブルに置く。）

兎にも角にもイメージを保存しておくところなんです。
冷蔵庫みたいな感じ。ECSつかってチンして食べますぞ！

## E. ECS
これもあんまり簡単に説明されてない。人生甘く無い。
ECSとは、**Elastic Container Service**のことです。

**Elastic** = 省略
**Container** = 省略
**Service** = 曖昧すぎ

分解してもよくわからないですね。
簡単に言うと、**DockerComposeと同じような**オーケストレーションツールです。
ECRに登録してあるイメージを使用して、サーバーを立ち上げたりします。

さて、開発環境ではDockerとDockerComposeを使っていましたが、本番環境ではECRとECSを用います。
AWSではかっこよく英字三文字になっていますが、基本的に構造はあまり変わりません。（細かく見れば違うと思いますが）
イメージを使って、オーケストレーションツールで動かします。

ECSは、ECRより単純ではなく、複雑怪奇なので後々ゆっくり説明しようと思います。
まずは全体像を想像出来ることが大切！細かいことはあとからわかれば良いと思うんです。

参考：
[Amazon EC2 Container Service(ECS)の概念整理](https://qiita.com/NewGyu/items/9597ed2eda763bd504d7)

## F. Nuxt.js
今回フロントサイドで使用するVue.jsに基づいたプログレッシブフレームワークです。
ここではAPIを用いて、サーバサイドとの疎通・ユーザーが直接触れることのできる画面を実装します。

## G. Ruby on Rails
今回サーバサイドで使用するRubyのフレームワークです。
ここではフロントからのAPIリクエストを受け付け、レスポンスをjson形式で返します。
また、データベースとの疎通を行います。

## H. ALB
ALBとは、**Application Load Balancer**のことです。
アプリケーション（Nuxtとか、Railsとか）に対してのアクセスをうまい具合に振り分けてくれます。
一つのインスタンスにアクセスが集中し、ダウンしてしまった際などに、インスタンスを複数作成しておくとそちらに自動的にリクエストを流してくれます。
簡単に言うと、めっちゃスーパーすごいコールセンターのお姉さんみたいな感じです。

「ただいま●●部にお繋ぎいたします・・・。」

ELBと何がちゃうねん。って思ってました。ELBはALB、CLB、NLBを含んだ総称のようです。（元々は違うっぽいよ、下記参照）

>ELBとは「Elastic Load Balancing」の略称で、元々はこのELBがAWSにおけるロードバランシングサービスでした。
しかしのちにALBが追加オプションとして開発された際に、ELBはその名称を「Classic Load Balancer（CLB）」に変えることになります。
そしてALBとCLBのサービスをまとめた総称として、ELBが使われるようになったのです。
さらに今ではNetwork Load Balancer（NLB）も追加され、その内容がさらに充実しています。
つまりELBとは、ALB、CLB、NLBという3種類の魅力的なロードバランサーを持つAWSのロードバランシングサービスの総称のことなのです。

[【ALBとELBの違い】初心者でもわかる簡単 AWS 用語解説](https://www.wafcharm.com/blog/difference-between-alb-and-elb/)

## I. Route53
AWSアカウントにドメインを紐づけします。
お名前.comなどで取得したドメインを、AWS上で利用出来るようにします。
イメージがつきにくいですが、お名前.comにて、ネームサーバーという設定をRoute53で示されたネームサーバーに書き換えることでドメインとAWSを紐づけています。

## J. ACM
Route53で登録したドメインに、証明書を発行できます。なんと無料。すごい。
上述したRoute53に設定を追加することでそれが可能となります。
簡単に常時SSL化出来ます。SSL化っていうのは「http」じゃなくて「https」でアクセス出来るってことです。やったー。

## K. RDS
AWS上で利用出来るデータベースサーバーです。
EC２インスタンス上で起動します。

## L. terraform
AWSでぽちぽちして作る設定を、一元でコード管理できます。
terraformというコマンドツールがあり、そこで設定したterraformのファイルをAWS上に反映出来ます。
なんと、実験的に実行出来るコマンドも用意されており、書いた設定ファイルが間違っていないよな〜と事前に確認することもできるすごいツール。
ただ、初めからterraformから作る人は多分少ない・・・（熟練した人は出来る）ので、まずはぽちぽちで慣れたら良いと思います。

## M. VPC
VPCとは、**Amazon Virtual Private Cloud**のことです。
AWSアカウントに紐づく仮想ネットワークのことです。

例えるならば、箱庭のようなものです。柵で区別されたエリアというイメージです。
世界の中のエリアで分けられていて、ap-northeast（東京）などといった区分があります。

そのVPCという箱庭の中には、AZ（アベイラビリティゾーン）とサブネットという概念が含まれています。

**AZ**は、ap-northeast-1a、ap-northeast-1c、ap-northeast-1dといったように、複数のゾーンに分けられます。
これらのAZには、基本的には同じ内容のコピーが置かれます。もし、1aに災害が起こったときに、1cに置いてあるコピーにアクセス出来るように・・・といったような使い方がされます。

**サブネット**は、AZの中でさらに分けられたエリアのことです。サブネットはAZを跨ぐことができません。このサブネットに、EC2インスタンスなどを配置してネットワーク上にアサイン出来ます。すごい!
これらのサブネットには、みんなが見れるようにインターネットにアクセス出来るように設定した**パブリックサブネット**と、みんなが見れないようインターネットにアクセス出来ないように設定した**プライベートサブネット**という概念が存在します。

**VPC>AZ>サブネット**というレイヤーになっています。

東京ディズニーランドと、中国ディズニーランドがあって、東京が地震とかでいけなくなったら中国のディズニーランド行けるよねって感じの発想。トゥーンタウンとかがパブリックサブネットで、スタッフルームはプライベートサブネット。

## まとめ
駆け足でばばばっと書いてみました。
混乱してきたな〜って思ったときに、戻って参照してくれると嬉しいです。
未経験だけど、今後はサーバサイドやフロントだけではなく、AWSとかインフラ、UIUX多岐にわたって全般に関われる仕事出来たらいいなぁ〜と思います。（仕事ください・・・）

反響があれば、これらの構成のテンプレをgitに上げて作成手順の記事を書こうかなと思います。

### 参考にさせて頂いた記事
とりあえずこれ見たほうがいいよって感じのすごい記事
[【サーバーサイド一式】Docker + Rails + Circle CI + Terraformでインフラをコードで環境構築 & ECSへ自動コンテナデプロイ【前半】](https://qiita.com/kazukimatsumoto/items/fa448e002b0afd441b7c)

開発環境をひとまず整えて「世界よこんにちは」するならこれ
[Nuxt.js + Rails(API) on DockerのHello Worldするべ！](https://qiita.com/at-946/items/08de3c9d7611f62b1894)

ECSとECRがわけわかんなくなったらこれ
[初心者でもできる！ ECS × ECR × CircleCIでRailsアプリケーションをコンテナデプロイ
](https://qiita.com/saongtx7/items/f36909587014d746db73)

ECS利用中に、ネットワーキングで詰まったらこれ
[Docker の基本学習 ~ Docker のネットワーク](https://qiita.com/Arturias/items/b538e6bbf05dd3364397)

こんなんも書いてます。
[Vagrant+Docker+Rails+Nuxt.js+MySQL+SSL化](https://qiita.com/Shogo1992/items/545449cbe12f4b8a2dbe)