午前三時の港町

理系院生(半導体)→コンサルティングファーム。IT基盤側。エクセルとパワーポイントしか使っていないため技術力はお察し。本やゲームの感想や学習記録など付ける予定。記載内容は個人の責任で、所属組織を代表するものではありません。

AWS Elastic Beanstalkを使用したDjangoアプリケーションのデプロイとジョブの自動実行

1. 概要

AWS Elastic Beanstalkを使用してDjangoで知人が作成したアプリケーションをデプロイした。
開発環境がUnix系なのにWindowsで作業してるなど素人感満載だが、一応出来たので手順を残しておく。

2. 環境・前提

2.1 端末環境

・以下の環境で作業を実施

  Windows 10 64bit
  Brackets 1.13
  Python 3.6.6
  Anaconda  1.6.13 (conda 4.5.4)
  Django 2.0.7
2.2 AWS

・EC2アクセス用のキーペアを作成済み
AWS Elastic Beanstalk用のIAMユーザーを作成済み

2.3 Django

・superユーザー作成済み
・collectstatic,migrateは実施済み
・DBとして用意したSQlite3をそのまま継続使用

3. 手順

3-1. ElasticBeanstalkコマンドラインツールの導入
$ pip install awsebcli --upgrade --user
3-2. Django projectにファイルを追加
::事前に構築済みの開発用環境を起動し、ElasticBeanstalk用にパッケージ情報を保存
$ conda activate (eb-virt)
(eb-virt)$ cd {アプリケーションのBASE_DIR}
(eb-virt)$ pip freeze > requirements.txt

::環境設定ファイル作成
(eb-virt)$ conda deactivate
$ mkdir .ebextensions
$ cd .ebextensions
$ type nul > django.config
$ Brackets django.config

django.configに以下を記載

option_settings:
  "aws:elasticbeanstalk:application:environment":
    DJANGO_SETTINGS_MODULE: "{アプリケーション名}.settings"
    "PYTHONPATH": "/opt/python/current/app/:$PYTHONPATH"
    "ALLOWED_HOSTS": ".elasticbeanstalk.com"
  "aws:elasticbeanstalk:container:python":
    WSGIPath: {アプリケーション名}/wsgi.py
    NumProcesses: 3
    NumThreads: 20
  "aws:elasticbeanstalk:container:python:staticfiles":
    "/static/": "static/"
3-3. デプロイまで

アプリケーションのBASE_DIR上で以下を実行

eb init -p python-3.6

いくつか設定項目(リージョンやアクセスキーなど)を聞かれるので回答する
リージョン

Select a default region
9) ap-northeast : Asia Pacific (Tokyo)

アクセスキーにはAWSElasticBeanstalkFullAccessのポリシーを割り当てたIAMを使用

You must provide your credentials.
(aws-access-id): 発行したアクセスキー
(aws-secret-key): シークレットキー

他、アプリ名やEC2に接続するキーペアを聞かれるので回答しておく。

Cannot setup CodeCommit because there is no Source Control setup, continuing with initialization
Do you want to set up SSH for your instances?
(Y/n): 

以下のコマンドを実行すると自動で環境構築を実施してくれる。

$ eb create {環境名}

設定値は以下のコマンドで確認可能
エラー出たときとかに見る

$ eb config

デプロイ実施 以下のコマンドでデプロイ実施

$ eb deploy
3-4. Cron設定まで

python manage.py {コマンド}を15分間隔で実施したい。
.ebextension内にcronjob.configを作成、下記のように設定する

container_commands:
  cron.exec_trade:
    command: "cat .ebextensions/{クーロン名}.cron > /etc/cron.d/{クーロン名} && chmod 644 /etc/cron.d/{クーロン名}"
    leader_only: true
  remove_old_cron:
    command: "rm -f /etc/cron.d/*.bak"

{クーロン名}.cronの中身は下記のように設定

SHELL=/bin/bash
PATH=/sbin:bin:/usr/sbin:/usr/bin
MAILTO=root
HOME=/
*/15 * * * * root source /opt/python/current/env && /opt/python/run/venv/bin/python3 /opt/python/current/app/manage.py {コマンド名} >> /var/log/cronjobs.log 2>> /var/log/cronjobs-err.log

※ここでWindows上でファイルを作ってしまったせいで改行コードが\r\nとなり、cronは\nじゃないと動かないので悲しみを背負う
 ちゃんと開発環境で作業すべき
 作業時はEC2上でodコマンド→trコマンドで原因の解明→解決となったが、最終的にSUSE上でファイルを1から作り直した
 /var/log/cronや自分で設定したログの出力先見る感じ動いてて僕満足

Appendix1. ディレクトリ構造抜粋
{アプリケーション名}
├── db.sqlite3
├── .ebextensions
│   ├──  cronjob.config
│   ├──  django.config
│   ├──  {クーロン名}.cron
├──.elasticbeanstalk
│   ├── config.yml 
│   └─saved_configs
├──  {アプリケーション名}
│   ├── settings.py
│   ├── wsgi.py
├── static
├── manage.py
└── requirements.txt


collectstaticやmigrateなどのコマンドも.ebextensions内のconfig内に設定することで勝手にやってくれるらしい。 今回はやらなかったが機会があればやる。

Appendix2. 参考にしたページなど

Elastic Beanstalk への Django アプリケーションのデプロイ - AWS Elastic Beanstalk

Elastic Beanstalk 環境で EC2インスタンスによる Cron ジョブの作成

Deploying a Django App to AWS Elastic Beanstalk – Real Python

Elastic Beanstalk + Python 3.6 + Django 2.0.5

[Elastic Beanstalk入門] Djangoアプリケーションのデプロイ その①|ハンズラボエンジニアブログ|ハンズラボ株式会社