AWS Elastic Beanstalk と Python3+Django そしてデプロイ

# AWS Elastic Beanstalk と Python3+Django そしてデプロイ

## はじめに

AWS Elastic Beanstalkを使用して、Djangoの環境を作ろうとしてた時
「どうすれば[Hello World]までいけんねん!!」
となったので、その奮闘をまとめ。あとついでに新人説明用。

### 対象者

以下の人を対象者としてますが、リンク張っておくので一読すればオッケー
特に「Django Girl」はインターネットの基礎から書いてあるので復習がてらにどうぞ。

- とりあえずPython3で「Hello world」くらいは作って実行はできる。
  - ここに関して色々環境の違いもあるので好きな環境でやっていただければ
  - [Python チュートリアル](https://docs.python.jp/3/tutorial/)
- Djangoの名前を聞いたことがある。
  - [Django Girls Japan](https://djangogirlsjapan.gitbooks.io/workshop_tutorialjp/content/how_the_internet_works/index.html)
- PaaSについてなんとなく知っている。
  - [AWSのPaaS, SaaSを利用して開発を効率化する](https://qiita.com/siro33950/items/f693d8acf9116c0f1319)
- AWSのアカウントを持っている。
  - ここに関しては自分で調べよう。いかは参考のリンク
  - [[AWS 1]AWSアカウント取得後にする大切なこと！先ずIAMへ行け！](https://qiita.com/HOKARI_Yutaka/items/df34941c4db0fcde9e8d)
  - [Amazon Web Services実践入門(参考書籍)](https://www.amazon.co.jp/Amazon-Web-Services%E5%AE%9F%E8%B7%B5%E5%85%A5%E9%96%80-PRESS-plus/dp/4774176737/ref=pd_sbs_14_4?_encoding=UTF8&pd_rd_i=4774176737&pd_rd_r=eb07335d-cbef-11e8-88de-0d15af0d7bc2&pd_rd_w=k3xIg&pd_rd_wg=UFHZX&pf_rd_i=desktop-dp-sims&pf_rd_m=AN1VRQENFRJN5&pf_rd_p=cda7018a-662b-401f-9c16-bd4ec317039e&pf_rd_r=0X5TFTM4GAQXY9PVVXNZ&pf_rd_s=desktop-dp-sims&pf_rd_t=40701&psc=1&refRID=0X5TFTM4GAQXY9PVVXNZ)
  - [Amazon Web Servicesではじめる新米プログラマのためのクラウド超入門(参考書籍)](https://www.amazon.co.jp/Amazon-Web-Services%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E6%96%B0%E7%B1%B3%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%82%AF%E3%83%A9%E3%82%A6%E3%83%89%E8%B6%85%E5%85%A5%E9%96%80-CodeZine-BOOKS/dp/479814469X/ref=sr_1_5?ie=UTF8&qid=1539109115&sr=8-5&keywords=aws+%E6%9C%AC)


## 1. Elastic Beanstalkとは？

まずはじめに「Elastic Beanstalk」とは何かから。
何はなくとも公式ドキュメントは見るべきである。

> Elastic Beanstalk を使用すると、アプリケーションを実行しているインフラストラクチャについて心配することなく、AWS クラウドでアプリケーションのデプロイと管理を簡単に行うことができます。[AWS Elastic Beanstalk とは?](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/Welcome.html)

何を言ってるがわからないが、とりあえず使い方を学べば流行(?)のAWSでデプロイが簡単にできると認識した。これがすべての過ちだったかもしれない・・・

## 2. チュートリアル地獄

世の中の人たちは色々なチュートリアルを作ってくれている。  
公式が作っているチュートリアルはもはや盲目的に信じても、僕は問題ないと思っている。(人を信じる事からはじめよう)) 
先人達に感謝しつつチュートリアルを進めよう。

### 2-1. Django チュートリアル

「Django Girl」を読み、かつ実行まで試した人は読みとばしてまったく問題ない。
とりあえずここではDjangoの基礎から
[はじめての Django アプリ作成、その 1](https://docs.djangoproject.com/ja/2.1/intro/tutorial01/)

基本的にはチュートリアルのとおりやって問題ない。

### 2-1. Elastic Beanstalk チュートリアル その1

Djangoの「HelloWorld」まではまったく問題なかった人は多いのではなかろうか。  
鬼門はまさにここからと言える。
次は使うためのウォーミングアップのようなものだ、慌ててはいけない。

さて、なにはなくともチュートリアルだ。以下のリンクは下記のステップを「GUI」で行うステップだ。  

1. サービスへのサインアップ
2. アプリケーションの作成
3. 環境に関する情報の表示
4. 新しいアプリケーションバージョンのデプロイ
5. 設定の変更する
6. クリーンアップ

[Elastic Beanstalk の使用開始](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/GettingStarted.html)

最後は消すステップまであるので、作成する環境をPythonにする必要はない。
ここでの目的はGUIでの操作になれることだ。

最終的にはCLIコマンドで行う事が多いが、このステップをGUIでやるかCLIでやるかの違いだけだ。

### 2-2. Elastic Beanstalk チュートリアル その2

ここからはCLIコマンドで「Elastic Beanstalk」を使用して実際にDjangoアプリをデプロイする。

「Elastic Beanstalk」で以下リンクを参考にインストールしよう。
(Pythonで作られているのでpipでいける)

[Elastic Beanstalk コマンドラインインターフェイス（EB CLI）のインストール](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/eb-cli3-install.html)

さてお待ちかね、次はDjangoのデプロイだ。
AWSの公式チュートリアルはPython2で作成しているが、Python3で環境を作成すれば問題ない。

チュートリアルを上からやっていくだけでは嵌る事が多いので  ステップ毎に注意点を交えながら進む事としよう。
[Elastic Beanstalk への Django アプリケーションのデプロイ](https://docs.aws.amazon.com/ja_jp/elasticbeanstalk/latest/dg/create-deploy-python-django.html)

ステップ

1. 前提条件
2. Django で Python 仮想環境を設定する
3. Django プロジェクトを作成する
4. Elastic Beanstalk 用に Django をアプリケーションを設定する
5. EB CLI でサイトをデプロイする
6. アプリケーションの更新
7. クリーンアップと次のステップ

#### 2-2-1 前提条件

このステップでは以下のような事が書いてあるが、
[Djangoのチュートリアル]と[Elastic Beanstalk コマンドラインインターフェイス（EB CLI）のインストール]を終えていれば恐れる事はない。
読み飛ばそう。

>このチュートリアルを実行するには、以下のパッケージを含む、インストールされている Python の一般的な前提条件をすべて満たす必要があります。

#### 2-2-2 Django で Python 仮想環境を設定する

[Djangoのチュートリアル]を終えていれば問題ない。
一応 pip freeze コマンドを実行して、Djangoが入っていることを確認しよう。

`$ pip freeze`

#### 2-2-3 Django プロジェクトを作成する

このステップも[Djangoのチュートリアル]を終えていれば問題ない。
一応 runserver コマンドを実行して動作することを確認しよう。

`$ python manage.py runserver`

#### 2-2-4 Elastic Beanstalk 用に Django をアプリケーションを設定する

ここは重要なステップだ。作らなければならないファイルは以下の2つだ。

- requirements.txt

EC2インスタンスにインストールされるパッケージを指定する。
ファイル場所はプロジェクトディレクトリの直下

- .ebextensions/django.config

Elastic Beanstalk が使用する WSGI スクリプトの場所を指定する。
ファイル場所は.ebextensionsディレクトリを作成し、その中に配置する
[WSGIとは？PythonとWebアプリケーション](https://hombre-nuevo.com/python/python0007/)

#### 2-2-5 EB CLI でサイトをデプロイする

ここは少し慎重になろう。  
※eb コマンドを実行する際は、自動で作成されるファイルが多いため、プロジェクトディレクトリで行うように。

##### 2-2-5-1 環境の作成

チュートリアルでは、以下のコマンドを使用しているが

`$ eb init -p python-2.7 django-tutorial`

以下のコマンドのほうが使い勝手がいいので、オプションなしで使用する。

`$ eb init`

まず、どこのリージョンで使用でアプリケーションを作成するのか聞かれる。 
素直に東京のリージョンにする。

```cmd
$ eb init

Select a default region
...
1) ap-northeast-1 : Asia Pacific (Tokyo)
...
(default is 3): 9
```

次は、aws_access_key_id と aws_secret_access_key を聞かれるので 
IAMユーザーを作成した時に作られるアクセスキーの情報を入力する。 
この情報は~/.AWS/configというファイルに**平文**で保存されるので、取り扱いには十分気をつけるべし。 
次からebコマンドを使用する際、このファイルを参照するので入力は必要なくなる。

```cmd
You have not yet set up your credentials or your credentials are incorrect
You must provide your credentials.
(aws-access-id):
(aws-secret-key):
```

作成するアプリケーション名を聞かれるので、任意のアプリ名を入力。

```cmd
Select an application to use
1) [ Create new Application ]
(default is 1): 1
```

どのPythonを使用するか聞かれるので、3.6にしておく。

```cmd
It appears you are using Python. Is this correct?
(Y/n): y

Select a platform version.
1) Python 3.6
2) Python 3.4
3) Python 3.4 (Preconfigured - Docker)
4) Python 2.7
5) Python
(default is 1): 1
Cannot setup CodeCommit because there is no Source Control setup, continuing with initialization
```

接続用SSH keypairを作るか聞かれるので作成を選択。

```cmd
Do you want to set up SSH for your instances?
(Y/n): y

Select a keypair.
1) [ Create new KeyPair ]
(default is 1): 1
```

上記の入力が終われば、Elastic Beanstalkコンソール画面から 環境が作成中なのが確認できる。 
作成したこれらの環境情報は以下ディレクトリに作成される。

.elasticbeanstalk/config.yml

##### 2-2-5-2 アプリケーションのデプロイ

さて、環境が整った。やっとアプリケーションのデプロイだ
ここでは「django-env」という名前のアプリケーションを作成する
(チュートリアルと同じ名前を使用)

以下コマンドを実行する

`$ eb create django-env`

これでアプリケーションが作成された。
次はDjangoの[ALLOWED_HOSTS]に記入する情報を取得しよう。
(GUIコンソールからでも確認できるが、あまり手間はかけたくない。)

以下コマンドを実行する

```cmd
$ eb status
Environment details for: django-env
  Application name: django-tutorial
  ...
  CNAME: eb-django-app-dev.elasticbeanstalk.com
  ...
```

CNAME: **eb-django-app-dev.elasticbeanstalk.com**
この情報がドメイン名だ。
[settings.py]にこの情報を記入しよう。

```Python
...
ALLOWED_HOSTS = ['eb-django-app-dev.elasticbeanstalk.com']
...
```

よしよし、これでようやくすべての準備が整ったわけだ。  

自分の信じる神プログラマーに祈って以下コマンドを実行する。
(僕はウォズニアックに祈ることが多い)

`$ eb deploy`

すべてが環境の更新プロセスが完了したのを見届け、以下コマンドを実行

`$ eb open`

どうだろうか、Djangoのウェブサイトが表示されただろうか？ 
されていたのであればおめでとう！

されていなければ、とりあえずElastic Beanstalkコンソール画面のログから原因を探ってみよう。

最後に僕がやりがちなミスを書いておく。

- [.ebextensions/django.config]のWSGIパスを間違えている。
- [ALLOWED_HOSTS]の記載を間違えている
- [requirements.txt]に必要な情報がない。

最後まで読んでくれた事に感謝を。