Webアプリケーション on EC2 and RDS

AWSを使ってみた
無償枠でより多くの機能を使ってみたい

とりあえずは基本のEC2とRDSを連携させたWebアプリケーションを構築してみる。
WEB/AP - DBの構成

機能

  • ログイン
    • データベースに登録されたID/PASSと一致した場合、アカウント一覧画面を表示する
    • データベースに登録されたID/PASSと一致しない場合、ログイン画面を再表示して、エラーメッセージを表示する
  • アカウント一覧表示
    • データベースに登録されたIDを一覧で表示する
    • 有効フラグが立っていないIDは表示しない
  • アカウント追加
    • 入力された情報でデータベースへレコードを追加する

構成

  • Web/APサーバ

 EC2
 OS : CentOS7
 AP : Django

  • DBサーバ

 RDS
 DB : MySQL

前提

  • AWS契約済み
  • KeyPair作成済み、ローカルに証明書ファイルがあること

手順

  1. EC2インスタンス作成
     AMIはCentOS7を利用

  2. RDSインスタンス作成
     MySQLを選択
     EC2インスタンスと同じVPC、同じSubnetを選択
     EC2インスタンスと同じSecurityGroupを選択
     DB nameはtestsitedb

  3. SecurityGroup
     Sourceに選択したセキュリティグループ
     ポートにRDSのポート番号を入力(今回はMySQLのデフォル3306)

  4. OSログイン
     EC2はコンソール接続はない。
     個人的には衝撃の事実
     OSのNW系障害が発生したらどうするんだろ。。

    # ssh -i <証明書> centos@<PublicIP>
    $ sudo su -


  5. MySQLクライアントインストール
     パッケージインストール

    # yum install mysql mysql-dev gcc python-devel
    Loaded plugins: fastestmirror
    
    ・・・(略)・・・
    
    Installed:
      mariadb.x86_64 1:5.5.41-2.el7_0
    
    Dependency Installed:
      perl.x86_64 4:5.16.3-283.el7             perl-Carp.noarch 0:1.26-244.el7            perl-Encode.x86_64 0:2.51-7.el7
      perl-Exporter.noarch 0:5.68-3.el7        perl-File-Path.noarch 0:2.09-2.el7         perl-File-Temp.noarch 0:0.23.01-3.el7
      perl-Filter.x86_64 0:1.49-3.el7          perl-Getopt-Long.noarch 0:2.40-2.el7       perl-HTTP-Tiny.noarch 0:0.033-3.el7
      perl-PathTools.x86_64 0:3.40-5.el7       perl-Pod-Escapes.noarch 1:1.04-283.el7     perl-Pod-Perldoc.noarch 0:3.20-4.el7
      perl-Pod-Simple.noarch 1:3.28-4.el7      perl-Pod-Usage.noarch 0:1.63-3.el7         perl-Scalar-List-Utils.x86_64 0:1.27-248.el7
      perl-Socket.x86_64 0:2.010-3.el7         perl-Storable.x86_64 0:2.45-3.el7          perl-Text-ParseWords.noarch 0:3.29-4.el7
      perl-Time-Local.noarch 0:1.2300-2.el7    perl-constant.noarch 0:1.27-2.el7          perl-libs.x86_64 4:5.16.3-283.el7
      perl-macros.x86_64 4:5.16.3-283.el7      perl-parent.noarch 1:0.225-244.el7         perl-podlators.noarch 0:2.5.1-3.el7
      perl-threads.x86_64 0:1.87-4.el7         perl-threads-shared.x86_64 0:1.43-6.el7
    
    Dependency Updated:
      mariadb-libs.x86_64 1:5.5.41-2.el7_0
    
    Complete!


  6. 接続試験

    # mysql -h <RDS Endpoint> -u <db user> -p
    Enter password:
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 154
    Server version: 5.6.22-log MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2014, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.


  7. djangoインストール

    # easy_install pip
    Searching for pip
    Reading https://pypi.python.org/simple/pip/
    Best match: pip 6.0.8
    Downloading https://pypi.python.org/packages/source/p/pip/pip-6.0.8.tar.gz#md5=2332e6f97e75ded3bddde0ced01dbda3
    Processing pip-6.0.8.tar.gz
    Writing /tmp/easy_install-hvl4ts/pip-6.0.8/setup.cfg
    Running pip-6.0.8/setup.py -q bdist_egg --dist-dir /tmp/easy_install-hvl4ts/pip-6.0.8/egg-dist-tmp-UeBzQD
    warning: no previously-included files found matching '.coveragerc'
    warning: no previously-included files found matching '.mailmap'
    warning: no previously-included files found matching '.travis.yml'
    warning: no previously-included files found matching 'pip/_vendor/Makefile'
    warning: no previously-included files found matching 'tox.ini'
    warning: no previously-included files found matching 'dev-requirements.txt'
    no previously-included directories found matching '.travis'
    no previously-included directories found matching 'docs/_build'
    no previously-included directories found matching 'contrib'
    no previously-included directories found matching 'tasks'
    no previously-included directories found matching 'tests'
    Adding pip 6.0.8 to easy-install.pth file
    Installing pip script to /usr/bin
    Installing pip2.7 script to /usr/bin
    Installing pip2 script to /usr/bin
    
    Installed /usr/lib/python2.7/site-packages/pip-6.0.8-py2.7.egg
    Processing dependencies for pip
    Finished processing dependencies for pip
    
    # pip list
    backports.ssl-match-hostname (3.4.0.2)
    boto (2.25.0)
    chardet (2.0.1)
    Cheetah (2.4.4)
    cloud-init (0.7.5)
    configobj (4.7.2)
    decorator (3.4.0)
    iniparse (0.4)
    IPy (0.75)
    jsonpatch (1.2)
    jsonpointer (1.0)
    kitchen (1.1.1)
    Markdown (2.4.1)
    Pillow (2.0.0)
    pip (6.0.8)
    policycoreutils-default-encoding (0.1)
    prettytable (0.7.2)
    pycurl (7.19.0)
    Pygments (1.4)
    pygobject (3.8.2)
    pygpgme (0.3)
    pyliblzma (0.5.3)
    pyudev (0.15)
    pyxattr (0.5.1)
    PyYAML (3.10)
    requests (1.1.0)
    seobject (0.1)
    sepolicy (1.1)
    setuptools (0.9.8)
    six (1.3.0)
    urlgrabber (3.10)
    urllib3 (1.5)
    yum-metadata-parser (1.1.4)
    [root@ip-172-31-8-41 ~]# pip install django mysql-python
    Collecting django
      Downloading Django-1.7.7-py2.py3-none-any.whl (7.4MB)
        100% |################################| 7.4MB 74kB/s
    Installing collected packages: django
    
    Successfully installed django-1.7.7


  8. 動作確認

    # django-admin startproject testweb
    # cd testweb/
    # ./manage.py runserver 0.0.0.0:8888
    Performing system checks...
    
    System check identified no issues (0 silenced).
    
    You have unapplied migrations; your app may not work properly until they are applied.
    Run 'python manage.py migrate' to apply them.
    
    March 28, 2015 - 16:39:27
    Django version 1.7.7, using settings 'testweb.settings'
    Starting development server at http://0.0.0.0:8888/
    Quit the server with CONTROL-C.

    Webブラウザ起動してページへアクセス・・・繋がらない

    あ、SecurityGroupで8888ポート開放していない
    EC2のSecurityGroupに戻ってMyIPから8888へのアクセス開放

    もう一回アクセス・・・繋がった


  9. DB設定
     DjangoはデフォルトDB設定がsqlite3を利用する
     DBをRDSのDB情報に設定変更する

    # vi testweb/settings.py
    以下を変更
    ---
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    ---
     ↓
    ---
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'HOST': <RDS Endpoint>,
            'PORT': '3306',
            'NAME': 'testsitedb',
            'USER': 'test',
            'PASSWORD': <password>,
        }
    }
    ---
    # # ./manage.py runserver
    Traceback (most recent call last):
      File "./manage.py", line 10, in <module>
        execute_from_command_line(sys.argv)
      File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 385, in execute_from_command_line
        utility.execute()
      File "/usr/lib/python2.7/site-packages/django/core/management/__init__.py", line 354, in execute
        django.setup()
      File "/usr/lib/python2.7/site-packages/django/__init__.py", line 21, in setup
        apps.populate(settings.INSTALLED_APPS)
      File "/usr/lib/python2.7/site-packages/django/apps/registry.py", line 108, in populate
        app_config.import_models(all_models)
      File "/usr/lib/python2.7/site-packages/django/apps/config.py", line 202, in import_models
        self.models_module = import_module(models_module_name)
      File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
        __import__(name)
      File "/usr/lib/python2.7/site-packages/django/contrib/auth/models.py", line 40, in <module>
        class Permission(models.Model):
      File "/usr/lib/python2.7/site-packages/django/db/models/base.py", line 122, in __new__
        new_class.add_to_class('_meta', Options(meta, **kwargs))
      File "/usr/lib/python2.7/site-packages/django/db/models/base.py", line 297, in add_to_class
        value.contribute_to_class(cls, name)
      File "/usr/lib/python2.7/site-packages/django/db/models/options.py", line 166, in contribute_to_class
        self.db_table = truncate_name(self.db_table, connection.ops.max_name_length())
      File "/usr/lib/python2.7/site-packages/django/db/__init__.py", line 40, in __getattr__
        return getattr(connections[DEFAULT_DB_ALIAS], item)
      File "/usr/lib/python2.7/site-packages/django/db/utils.py", line 242, in __getitem__
        backend = load_backend(db['ENGINE'])
      File "/usr/lib/python2.7/site-packages/django/db/utils.py", line 108, in load_backend
        return import_module('%s.base' % backend_name)
      File "/usr/lib64/python2.7/importlib/__init__.py", line 37, in import_module
        __import__(name)
      File "/usr/lib/python2.7/site-packages/django/db/backends/mysql/base.py", line 18, in <module>
        raise ImproperlyConfigured("Error loading MySQLdb module: %s" % e)
    django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module: No module named MySQLdb

    MySQLdbモジュールがないらしい
    というか色々ないらしい。

    # yum install mysql-devel gcc python-devel
    # pip install mysql-python
    # ./manage.py migrate
    Operations to perform:
      Apply all migrations: admin, contenttypes, auth, sessions
    Running migrations:
      Applying contenttypes.0001_initial... OK
      Applying auth.0001_initial... OK
      Applying admin.0001_initial... OK
      Applying sessions.0001_initial... OK

    なんか色々作られた。

    # mysql -h <RDS Endpoint> -u test -p
    Enter password:
    Welcome to the MariaDB monitor.  Commands end with ; or \g.
    Your MySQL connection id is 167
    Server version: 5.6.22-log MySQL Community Server (GPL)
    
    Copyright (c) 2000, 2014, Oracle, MariaDB Corporation Ab and others.
    
    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
    
    MySQL [(none)]> use testsitedb
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    MySQL [testsitedb]> show tables
        -> ;
    +----------------------------+
    | Tables_in_testsitedb       |
    +----------------------------+
    | auth_group                 |
    | auth_group_permissions     |
    | auth_permission            |
    | auth_user                  |
    | auth_user_groups           |
    | auth_user_user_permissions |
    | django_admin_log           |
    | django_content_type        |
    | django_migrations          |
    | django_session             |
    +----------------------------+
    10 rows in set (0.00 sec)

    データベースにテーブルが作成されていた。


今日はここまで。。
全然出来なかった。

EC2とRDSが連携出来たので目的は達成かな。