技術力向上のためのWebシステム構築プロジェクト

# プロジェクト概要
自分自身のこれまでのキャリアを振り返った時に主なスキルセットはインフラストラクチャ関連の技術に寄っていることを認識しました。今後のキャリアを考えた時にインフラストラクチャのスキルを活かしつつ、SRE/DevOpsのポジションにチャレンジしたいと考えた時に、不足しているスキルセットが可視化されました。その中で非常に基本的なことで必須事項であるWebシステムの開発に関連する技術に関して、技術力を向上する取り組みとしてWebサービスを新規構築してコンテナ管理基盤にデプロイすることを目標に実行しました。今回作成するWebシステムは汎用的に利用されている種類のサービスであることが、本プロジェクトの目的にあっていると考えられるため、いわゆる下記の機能を有する一般的なブログシステムを実装することにしました。
* 記事一覧表示機能
* 記事投稿機能
* 記事更新機能
* 記事削除機能
* 画像ファイルアップロード機能
* お気に入り登録機能
* ユーザ登録機能
* ログイン機能
* カテゴリ分類機能
* カテゴリ一覧表示機能
* 検索機能
* ページネーション機能

# プロジェクトにおける自身の役割
企画、要件定義、設計、コーディング、レビュー、テストの全ての工程を担当しました。

# 使用技術
EC2、VPC、IAM、RDS、S3、EKS、Docker、Kubernetes、SQL、Python、Django、Linux、gunicorn、Nginx、Bootstrap、CSS、HTML

# 課題と工夫した点、成果
### ・学習時間の捻出
本プロジェクトに取り組むにあたって最大の課題は各技術の学習時間を捻出することでした。業務外の時間を使用して取り組むのですが、業後に取り組むと疲れが残っている状態のため、学習効率が上がりませんでした。そこで、早く起きることで体力が十分に回復した状態で学習に取り組むことで学習効率を上げることにしました。初めのうちは習慣化出来ていないため、取り組み自体が辛いのですが３ヶ月ほど継続したところ習慣化が成功して歯磨きと同様の感覚で取り組むことができるようになりました。また、土日はなるべく他の予定を入れず8時間を本取り組みに継続してあてました。

### ・言語とWebフレームワークの選定
Webシステムの開発に取り組むにあたって、まず言語選定をする必要がありました。選択肢は無数にあるかと思いますが、なるべく一般的に用いられているプログラミング言語とWebフレームワークを選択することで、学習リソースの量とトラブルシューティングのしやすさを確保する考えに至りました。そして調査すると以下の組み合わせに絞り込むことが出来ました。
* ①Ruby + Ruby on Rails
* ②Python + Django
* ③PHP + Laravel

上記の言語の中から現職の中で携わることができる可能性(※)があったため ②Python + Djangoを選択しました。
※私はインフラ担当ですが、開発側の部署で使用されていました。

### ・開発環境を整える
開発を進めるにあたってエディタを選択しました。Pythonの開発では「Pycharm」が有名ですが、起動が高速であることを理由に「VSCode」を選択しました。他の言語に対応していますし、汎用的に使用できるところもメリットかと思いました。IDEを導入してインデントや構文エラーを自動で検出してくれるので、開発効率を向上することが出来ました。

### ・ブログシステムの開発
Python・Djangoの学習を終えた後、ブログシステムの開発に取り組みました。まず、Django構成要素のアーキテクチャを紙に書き出しました。「URLconf」「URLディスパッチャ」「フォーム」「ビュー」「テンプレート」「モデル」の構成要素がありますが、どのような構成でお互いにどのように働きかけるのか意識しながら開発できるようにすることで、今何をしているのか把握しやすくするためです。そして上記に記載している機能を実装して、試してはエラー、エラーの内容を見て、原因を特定して、解消して、試して、またエラー、と試行錯誤しながらですが、一つひとつ機能を実装していきました。ブログシステムの開発に着手して約１ヶ月程度経った頃でしょうか、ようやく上記に記載している実装予定だったブログシステムが完成しました。

### ・EC2へのデプロイ
上記の開発はローカル端末で完結していたのですが、EC2上にデプロイすることにしました。また、データベースはAWS RDSを使用することにしました。この取り組みを実施している時には既にAWSは業務で携わっていたこともあり、新たに学習する必要はありませんでした。業務の知識を活かせばよいだけでした。Webサーバに関してはローカル開発においては「runserver」と呼ばれるDjangoフレームワークに付属している開発用のWebサーバを使用していましたが、これは本番用ではなくセキュリティ的にも絶対に本番環境で使用してはいけないものなので、世界的にシェアをグングンと伸ばしている「Nginx」を採用することにしました。(2021年5月にWebサーバのシェアでNginxが世界一になる前の話です。)APサーバは「gunicorn」を採用しました。デプロイの方法に関する情報は検索すると沢山出てきました。以下の手順でデプロイを進めました。
* ①EC2(ubuntu 20.04)とRDS(MySQL 8.0)の構築
* ②必要なパッケージのインストール(Python3/Nginx/pip/virtualenv)
* ③仮想環境の構築(virtualenvアクティベート/DjangoインストールWebアプリケーションのclone/DB migration)
* ④Gunicornの設定(gunicorn.serviceの設定)
* ⑤Nginxの設定(ListenポートやサーバIPアドレス等の基本設定)
* ⑥EC2の設定(セキュリティグループ等)

トライアンドエラーをしてAWS EC2とRDSの環境にブログシステムをデプロイすることが出来ました。ブラウザからアクセスできた時は感無量でした。

### ・Docker化
EC2へデプロイできたので、次はDockerを使用してコンテナ化しました。Dockerに関する知識が無かったので、Dockerファイルを作れるレベルまで学習しました。Dockerの原則として、１コンテナ1プロセスがあるので、Nginxで1つのコンテナ、Gunicorn + Django + Webアプリケーションで1つのコンテナ、のように分割するアーキテクチャにしました。NginxとGunicornの連携で苦戦しつつも、こちらもトライアンドエラーでなんとかコンテナ化に成功しました。

### ・KubernetesとEKSへのデプロイ
この取り組みの目標としていたところにようやく来ました。ラスボスのKubernetesです。難しいだの学習コストがかかるだの世間では言われていますが、やってみないと分からないのでやりました。取り掛かるにあたって、いつもの通りまずは学習です。Kubernetesの歴史や概要から始まり、基本的なアーキテクチャ(etcd/kube-apiserver/kubelet等)、各リソース(Pod/ReplicaSet/Deployment等)、各サービス(ClusterIP/ExternalIP/NodePort等)、ストレージ(Secret/ConfigMap/PV/PVC等)、、なるほど、、難易度が高いと言われる理由が分かりました。理由は単純で登場人物が多いからです。しかし、暗記する必要など無いのでどんどん次に進みました。ある程度のところで本での学習から、ハンズオンの学習に切り替えました。学習の順序的に「①本での学習」「②ハンズオンでの学習」でやってよかったと思います。ある程度知識がある状態で手を動かすことで、ハンズオンでの学習がスムーズでしたし、Kubernetesの理解がグッと上がったと思います。ハンズオンでの学習も終えて、ある程度のkubectlコマンドも使いこなせるようになった状態で、、次の学習です。まだ残ってました。AWS EKSです。こちらもハンズオン形式で学習しました。aws cliでEKSクラスタを作り、ブラウザからIngress経由でPodのNginxにアクセスできるようになった状態で、ようやくブログシステムのデプロイに取り掛かりました。EKSクラスタを作り、NodeはEC2を使用しました。(はじめからFargateタイプだとエラー対処に苦労すると思ったからです。)EC2に2つのPodを用意します。一つはNginxコンテナ用でもう一つがGunicorn + Django + Webアプリケーション用です。作業は順調でしたが、結果的にものすごい単純なことで約10時間の貴重な時間を費やすことになりました。その原因がAWS RDSとの連携です。なぜか、ブラウザからアプリケーションにアクセスすると「502 Bad Gateway」のメッセージが表示されて上手くいきません。gunicornのエラーメッセージを見てもTimeoutが表示されていてそれ以上の原因を特定することが出来ませんでした。stack overflowやteratailで質問してみましたが、解決にはたどり着けませんでした。そして一旦諦めることにしました。シャワー中に閃くことが多いように、諦めることで視野が広くなり解決に繋がることに期待しました。結果、閃いたというか、ものすごい単純なことに気がつきました。EKSクラスタとRDSのVPCが異なってました。。。この時はAWSインフラを生業としている身として、非常にショックを受けました。ですが、頭が固くなっている時はこういうことはよくあります。一晩、寝て気を取り直せるのが自分の長所です。結果、合計で半年程度かけた本プロジェクトの取り組みはゴールに辿り着きました。

### ・本取り組みでの成果は何か
この半年間の取り組みで本で学習しているだけでは、得られない経験が出来ました。それは技術知識ももちろん向上しましたが、それ以上に誰かに言われたのではなく、自分自身にやろうと言って取り組んだことはこんなにも「楽しいこと」なんだと気がつきました。誰かに見られているわけでもありませんし、褒められるわけでもありません。全ての問題が解決するわけでもありません。何も大きく変わらないですが、小さな成長をしている実感があるととても楽しいです。小さな成長だけで一生楽しく生きていける気がします。この取り組みの中でそんな単純なこと気がつけたことが成果だと思いました。