Help us understand the problem. What is going on with this article?

[AWS]EC2,RDS,Djangoを使ってみた。1から環境構築

はじめに

今回初めてバックエンドを触ることになり、かなり手惑いました。
次回作成時この記事を見ればすぐに作成できるようにと思い、自分用または同じように手惑っている方の為に作成しました。

初心者ですので間違っている箇所や、考え方がおかしい場所があるかもしれません。その際は、コメント欄で教えていただけると幸いです。

$             <- 自分のPCターミナルでのコマンド
[ec2-user] $  <- EC2にログイン中でのコマンド
MySQL >       <- MySQLにログイン中でのコマンド
#             <- 私のコメント
>>>           <- 実行結果(出力値)

前提条件

  • AWSアカウント作成済

[1] AWS環境設定

[1.1] VPC作成

VPCとはユーザー専用のプライベートなクラウド環境を提供するサービスのことです。
例えば、EC2同士を内部的に通信したい場合や、RDSとやり取りをしたり、内部と外部のネットワークを繋いだりと、多くのAWSはVPCを利用しています。

作成手順

  • [1] VPCの作成
  • [2] 名前タグを「VPCtest」
  • [3] IPv4 CIDR ブロックを 「10.0.0.0/16」
  • [4] タグキーを「Name」 値を「VPCtest」 とする

スクリーンショット 2020-09-27 12.56.03.png
スクリーンショット 2020-09-27 12.59.42.png

これでVPCの作成が完了です。

[1.1.2]サブネット作成

サブネットは最初にVPCによって作られているCIDRブロックを分割したネットワーク群のことです。 サブネットは、VPCの上限を超えなければ、いくらでも作ることが可能です。 サブネットには、主にパブリックサブネットプライベートサブネットがあります。

最初はイメージがつきにくいと思うので...
広大な地球というインターネット空間自宅というVPCを作りました。
そこに風呂寝室など役割の違う部屋(サブネット)を作ったというイメージです。
まちがった考え方だったらごめんなさい(;´Д`)

パブリックサブネットとプライベートサブネットを作成します。
パブリックサブネットにはEC2
プライベートサブネットにはRDSを入れます。
RDSには異なるアベイラビリティゾーンを設定する必要がある為プライベートサブネットは2つ作成します。

作成手順

  • サブネットの作成
  • [1] パブリックtest作成
  • [1.1] VPCには先ほど作成した 「VPCtest」 を入れる
  • [1.2] アベイラビリティゾーンはとりあえず 「1a」 を選択
  • [1.3] IPv4 CIDRブロックは「10.0.1.0/24」
  • [2] プライベートtest作成
  • [2.1] [1.1][1.2]と同じ
  • [2.2] IPv4 CIDRブロックは「10.0.2.0/24」
  • [3] プライベートtest2作成
  • [3.1] [1.1]と同じ
  • [3.2] アベイラビリティゾーンは「1c」を選択([2.1]と異なるアベイラビリティゾーンならOK)
  • [3.3] IPv4 CIDRブロックは「10.0.200.0/24」

スクリーンショット 2020-09-27 13.34.18.png
スクリーンショット 2020-09-27 13.38.25.png
スクリーンショット 2020-09-27 17.40.58.png

これでサブネットの設定は完了です。

[1.1.3]ルートテーブル作成

ルートテーブルとは、サブネット内にあるインスタンス等がどこに通信にいくかのルールを定めたものです。つまり、ルートテーブルはパケットの宛先(IPアドレス)を見て、どこに通信を流すかが書かれている表です。この表をみてパケットを運ぶので、表にない宛先のものはパケットを送らないので、通信できません。サブネット毎にどこに通信ができるかを定めたものだというところがポイントです。 

作成手順

  • [1] ルートテーブルの作成
  • [2] 名前タグを 「ルートtest」
  • [3] VPCには先ほど作成した 「VPCtest」 を入れる

スクリーンショット 2020-09-27 13.50.30.png

次にインターネットゲートウェイの作成です。

[1.1.4]インターネットゲートウェイ作成

VPC内からインターネットに接続するためのゲートウェイです。これを使うことで、VPC内のシステムがグローバルIPを使えるようになります。

例えると自宅(VPC領域)に(インターネット)を入れる玄関のセキュリティ(鍵)の役割です。

作成手順

  • [1] インターネットゲートウェイ作成
  • [2] 名前タグを 「igw-test」 とする
  • [3] タグキーを「Name」 値を「igw-test」 とする
  • [4] VPCへアタッチする
  • [5] VPCには先ほど作成した 「VPCtest」 を入れる

スクリーンショット 2020-09-27 13.53.08.png
スクリーンショット 2020-09-27 13.53.24.png
スクリーンショット 2020-09-27 13.57.54.png

これでインターネットゲートウェイの設定は完了です。

[1.1.5]ルートテーブルに外部向けルートを追加

作成手順

  • [1] ルートの編集
  • [2] ルートの追加を押す
  • [3] 送信先は 「0.0.0.0/0」 にする
  • [4] ターゲットはInternet Gatewayから今回作成したインターネットゲートウェイを選択
  • [5] ルートの保存

スクリーンショット 2020-09-27 14.03.49.png
スクリーンショット 2020-09-27 14.06.17.png

これでルートテーブルの設定は完了です。

[1.1.6]サブネットにルートテーブルを紐付け

ルートテーブルの関連付けの編集を行います。

作成手順

  • [1] パブリックtestのルートテーブルの関連付けの編集
  • [2] ルートテーブルIDを今回作成した 「ルートtest」 に変更
  • [3] 保存

スクリーンショット 2020-09-27 14.11.14.png
スクリーンショット 2020-09-27 14.12.54.png

[1.2]EC2インスタンス作成

作成手順

  • [1] インスタンスを起動
  • [2] Amazon Linux2 AMI(HVM),SSD Volume Type を選択
  • [3] 無料利用枠のインスタンスタイプを選択後、次のステップ(詳細の設定)へ
  • [4] ネットワークを 「VPCtest」 、サブネットを 「パブリックtest」、 自動割り当てIPを 「有効」 後、次のステップ(ストレージ追加)へ
  • [5] 次のステップ(タグの追加)へ
  • [6] 別のタグを追加し、タグキーを「Name」 値を「webサーバーtest」 とした後、次のステップ(セキュリティグループ)へ
  • [7] 新しいセキュリティグループを作成し、名前を「webtest-sg」 とする
  • [7] 新しいキーペアの作成から キーペア名 「test-key」としキーペアのダウンロードを行う
  • [8] インスタンスの作成

スクリーンショット 2020-09-27 14.27.24.png
スクリーンショット 2020-09-27 14.30.28.png
スクリーンショット 2020-09-27 14.31.00.png
スクリーンショット 2020-09-27 14.36.09.png
スクリーンショット 2020-09-27 14.37.30.png
スクリーンショット 2020-09-27 14.38.53.png
スクリーンショット 2020-09-27 14.41.25.png
スクリーンショット 2020-09-27 14.42.22.png

EC2が起動できたか確認してみましょう
以下のコマンドを打ち込んでください

$ cd

$ cd (test-key.pemまでのPATH)
#意味がわからなければ $ cd Downloads でOKです

$ chmod 400 test-key.pem

$ ssh -i test-key.pem ec2-user@xxx.xxx.xxx.xxx
#xxxにはEC2のパブリックIPv4アドレスが入る

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

#上記のEC2の文字が表示されれば起動完了です

[ec2-user] $ exit
#終了

これでEC2を起動することができました。

[1.3]RDSの作成

作成手順

  • [1] データベースの作成
  • [2] エンジンのタイプ :MySQL
  • [3] テンプレート :無料利用枠
  • [4] DBインスタンス識別子:database-test
  • [5] マスターユーザー名 :お好きな名前
  • [6] マスターパスワード :お好きなパスワード
  • [7] 接続VPC : VPCtest
  • [8] 追加の接続設定タップ
  • [9] VPCセキュリティグループ :新規作成
  • [10] VPCセキュリティグループ名 :dbtest-SG
  • [11] データベースの作成

スクリーンショット 2020-09-27 17.16.52.png

[1.3.2]セキュリティグループ編集

セキュリティグループについてまだ学習量が少なくセキュリティがガバガバな設定かもしれません。
テスト環境のみで使用してみてください。

イメージとしては自宅などに65535個(ポート番号)の玄関がありセキュリティグループで許可した玄関だけ鍵が解除されるという感じでしょうか?
- HTTP通信はポート80を使用
- HTTPS通信はポート443を使用
など代表的なポート番号などが存在します。

セキュリティグループwebtest-sgの編集を行います

作成手順

  • [1] セキュリティグループから「webtest-sg」のインバウンドルールを編集
  • [2] ルールを2つ追加する
  • [3] 1つはタイプ 「HTTP」、ソース 「0.0.0.0/0」 とする
  • [4] もう1つはタイプ 「MYSQL/Aurora」、ソース 「0.0.0.0/0」 とし、ルールを保存
  • [5] 「dbtest-SG」のインバウンドルールを編集
  • [6] タイプ 「MYSQL/Aurora」、ソース 「0.0.0.0/0」 とし、ルールを保存

追記:[6]のソース「0.0.0.0/0」 はEC2のプライベートIPアドレスを指定するのが望ましい(セキュリティが堅い)が、もう少し理解した後に設定するのがいいでしょう。(いろいろ設定すると動かなくなった時に困惑すると思います。)

(sgを小文字に統一するの忘れてた(;´Д`))

スクリーンショット 2020-09-27 20.35.45.png
スクリーンショット 2020-09-27 20.37.22.png
スクリーンショット 2020-09-27 20.24.41.png
スクリーンショット 2020-09-27 20.23.15.png

RDSが起動できたか確認してみましょう
以下のコマンドを打ち込んでください

$ cd

$ cd (test-key.pemまでのPATH)

$ ssh -i test-key.pem ec2-user@xxx.xxx.xxx.xxx

[ec2-user] $ sudo yum install mysql -y

[ec2-user] $ mysql -h DBエンドポイント -u DBマスターユーザー名 -p
# パスワードを要求されるので入力(文字は表示されないが打ち込めています)(コピペ可)

>>> Welcome to the MariaDB monitor.
# が表示されればRDSのMySQLに接続ができた

#データベース内一覧を表示(小文字でも可 show database;)
MySQL > SHOW databases;

#「dbtest」という名前のデータベースを作成
MySQL > CREATE DATABASE dbtest;

#終了
MySQL > exit

これでRDSの設定は完了です。

[2]Django環境構築

[2.1]Python3をインストールするための準備

#yumをアップデート
[ec2-user] $ sudo yum update -y

#yumでgitをインストールします
[ec2-user] $ sudo yum install git -y

#次にgithubのリポジトリからpyenvをクローンしてきます
[ec2-user] $ git clone https://github.com/yyuu/pyenv.git ~/.pyenv

#パスを通してコマンドが打てるようにします
[ec2-user] $ echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
[ec2-user] $ echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
[ec2-user] $ echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
[ec2-user] $ source ~/.bash_profile

#######まとめてコピペできます
echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.bash_profile
echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.bash_profile
echo 'eval "$(pyenv init -)"' >> ~/.bash_profile
source ~/.bash_profile
#################

#pyenvが入ったか確認
[ec2-user] $ pyenv -v
>>> pyenv 1.2.20-7-gdd62b0d1

[2.1.2]Python3のインストール

現在入っているPythonのバージョンの確認
Python 2系 は2020年1月1日にサービスを終了した
Python2系について詳しくはこの記事から

#Pythonのバージョンを確認
[ec2-user] $ python --version
>>> Python 2.7.18

#Python3に移行する

#必要な依存関係のインストール
[ec2-user] $ sudo yum install gcc zlib-devel bzip2 bzip2-devel readline readline-devel sqlite sqlite-devel openssl openssl-devel libffi-devel -y
>>>(略) 完了しました!

#現在ダウンロードできるPythonのバージョンを確認
[ec2-user] $ pyenv install -l
>>>(略) 
    3.8.5 
    3.8.6
   (略)


#現時点(R2,9/26)での最新版3.8.6をインストール
[ec2-user] $ pyenv install 3.8.6
>>> Downloading Python-3.8.6.tar.xz...
    -> https://www.python.org/ftp/python/3.8.6/Python-3.8.6.tar.xz
    Installing Python-3.8.6...
#少し時間がかかります
    Installed Python-3.8.6 to /home/ec2-user/.pyenv/versions/3.8.6


#Pythonのバージョン2系から3系へ切り替え
[ec2-user] $ pyenv global 3.8.6
[ec2-user] $ pyenv rehash

[ec2-user] $ python --version
>>> Python 3.8.6

#後に必要になってくるパッケージ
[ec2-user] $ pip install --upgrade pip
[ec2-user] $ sudo yum install python-devel mysql-devel -y
[ec2-user] $ pip install mysqlclient

#以上でPython3への移行が完了した

[2.2]Djangoの環境構築

pipはEC2(Linux2)に元から入っている

#pipバージョンの確認
[ec2-user] $ pip -V
>>> pip 20.2.1 from /home/ec2-user/.pyenv/versions/3.8.6/lib/python3.8/site-packages/pip (python 3.8)

#Djangoをインストール
[ec2-user] $ pip install django

#もし以下のエラーが出たら内容にしたがってシングルクォーテーション('xxxx')内をコピペして再度Djangoをインストールしてください
>>> WARNING: You are using pip version 20.2.1; however, version 20.2.3 is available.
You should consider upgrading via the 'xxxx' command.

#Djangoのバージョン確認
[ec2-user] $ python -m django --version

#「testDjango」という名前のプロジェクトを作る
[ec2-user] $ django-admin startproject testDjango

#確認すると生成されているはずである
[ec2-user] $ ls

>>> testDjango/
        manage.py
        testDjango/
            __init__.py
            settings.py
            urls.py
            asgi.py
            wsgi.py
  • トップのmysite・・・ルートディレクトリで任意の名前で作成できる。変更も可。
  • manage.py・・・Djangoプロジェクトの様々な操作を行うためのコマンドラインユーティリティ。
  • mysite・・・このプロジェクトのパッケージ。
  • mysite/init.py・・・このディレクトリがpythonであることの空ファイル。
  • mysite/settings.py・・・プロジェクトの設定ファイル。
  • mysite/urls.py・・・URLを宣言。
  • mysite/asgi.py・・・プロジェクトを提供するASGI互換WEBサーバーのエントリポイント。
  • mysite/wsgi.py・・・プロジェクトをサーブするためのWSGI互換WEBサーバーのエントリポイント。

[2.3]FileZillaをダウンロードする

testDjangoのコードを編集するためにSSHで直接vimを使って編集もできるが今回はFailZilaを使ってみようと思う
超初心者向け!FileZilla(ファイルジラ)の使い方

Win版FileZilaダウンロード
Mac版FileZilaダウンロード

インストールして開き,左上のサーバーボタンを押すと以下の画面が現れる

設定手順

  • [1] プロトコルは 「SFTP」 を選択 (FTPでは通信を暗号化していないため)
  • [2] ホストは 「EC2のオープンIPアドレス」 を入力
  • [3] ログオンタイプは 「鍵ファイル」
  • [4] ユーザー 「EC2にログインする時の名前」
  • [5] 鍵ファイル 「EC2にログインする時の鍵のPATH」
  • [6] ポート は空白でOK
  • [7] 接続

スクリーンショット 2020-09-26 13.10.24.png
スクリーンショット 2020-09-26 13.23.08.png

設定が完了したのち、上記の画面が現れる
左はローカルサイト(自分のPC内)
右はリモートサイト(EC2内)
ここでファイルの受け渡しや書き換えなどが行える。
とりあえず作ったtestDjangoをローカルサイトに複製をしておく

編集したいファイルを右クリック後、表示編集で編集が行える
次の[2.4]でPyCharmで編集できるようにする

[2.4]PyCharmをダウンロードする

最強のPython統合開発環境PyCharm

PyCharmを関連つけるには

  • [1] Finderから.pyのファイルを右クリック
  • [2] このアプリケーションで開くをPyCharmに設定
  • [3] すべてを変更

スクリーンショット 2020-09-26 13.35.35.png

[2.5]Django設定

[ec2-user] $ cd
[ec2-user] $ cd testDjango
[ec2-user] $ python manage.py startapp polls
settings.py
...
()
...

# DATABASES = {
#     'default': {
#         'ENGINE': 'django.db.backends.sqlite3',
#         'NAME': BASE_DIR / 'db.sqlite3',
#     }
# }

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'dbtest',
        'USER': 'DBマスターユーザー',
        'PASSWORD': 'DBマスターユーザーパスワード',
        'HOST': 'DBエンドポイント',
        'PORT': '3306',
    }
}

...
()
...

#LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ja'

# TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Tokyo'

[1.3.2]に'NAME': 'dbtest'の作成が書いています。

FileZillaでアップロード

[ec2-user] $ cd
[ec2-user] $ cd testDjango
[ec2-user] $ python manage.py migrate
#ここでエラーが起きた場合考えられる原因は以下に記します。

[ec2-user] $ python manage.py dbshell

エラー原因

  • FileZillaを開いてアップロードしたか
  • 打ち込み忘れているコマンドはないか
  • errorのまま放置したダウンロード失敗のコマンドはないか
  • python --version で 3以上になっているか
  • [2.1.2]のコマンド打つ順番を守ったか
  • setting.pyでNAMEはMySQLで作成したDB名か(DB識別子ではない)
  • sqlite3のバージョンが足りない的なエラーはRDSのMySQLを使うことで解決した

その他
pipenvのinstall時に、No module named '_ctypes'が発生する
CentOS7.2 + MySQL5.6 + Python3 - pip install mysqlclient で mysql_config not found が出る

もう無理だと感じた方は1からインスタンスを作り直すか、
EC2インスタンスを選択した状態でアクションを押し、同様のものを起動で
同じ設定のインスタンスが生成されます。

以上でEC2,RDS,Djangoの設定が完了しました。

おわりに

今回名前のつけ方が下手すぎました。( ´︵` )
たとえば、ブログの名前がxblogなら
xblog-vpc
xblog-public-subnet
xblog-ec2
xblog-rtb
xblog-ec2-sg
xblog-db-sg
などにした方がわかりやすいかと思います。

この記事で誰かの役に立っていただければ幸いです。

次回これにAPIを実装してみようと思います。

参考サイト

以下と本記事の途中に非常に参考にさせていただいたサイトを紹介しています。
ありがとうございました。

[1] EC2サーバにPython3環境構築
[2] djangoを用いてWEBアプリケーション開発 ~開発その1~
[3] AWS EC2 + RDS 環境で Django, syncdbするところまで
[4] EC2上のDjangoからAmazon RDSに接続する
[5] AWSのEC2(+RDS(+S3))でDjangoアプリケーション(+MySQL)を公開するまで
[6] (Djangoメモ)データベースにMySQLを設定
[7] MySQLでデータベースを作成しよう
[8] Django2.2で開発サーバー起動時にSQLite3のエラーが出た場合の対応
[9] Vim初心者に捧ぐ実践的入門
[10] AWSのルートテーブルって何よ?VPCとサブネット踏まえて簡単に説明してみる

akidon0000
四国の大学生、専門分野:化学
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away