Elastic BeanstalkでPython3.6/Flask1.0アプリを動かす

AWS Elastic Beanstalk ドキュメントの Python/Flask チュートリアル

  • Python 2.7
  • Flask 0.10

とプラットフォームのバージョンがかなり古いです。

から

  • Python 3.6
  • Flask 1.02

で Hello World アプリを Elastic Beanstalk 上で動かしてみました。

作業の流れ

  1. EB CLI のインストール
  2. Python 仮想環境を設定する
  3. Hello World Flask アプリケーションを作成する
  4. Elastic Beanstalk 用に Flask アプリケーションを設定する
  5. EB CLI でサイトをデプロイする
  6. クリーンアップ

1. EB CLI のインストール

Elastic Beanstalk の CLI である EB CLI を pip でインストールします。

$ python3 -m pip install -U awsebcli
...
$ eb --version
EB CLI 3.12.4 (Python 3.6.5)

-U はアップデートを意味します。

2. Python 仮想環境を設定する

Python 3.6 で仮想環境を構築する場合 virtualenv ではなく venv を利用します。

~$ python3 -m venv ~/eb-virt
~$ source ~/eb-virt/bin/activate
(eb-virt) ~$

次に Flask をインストールします

(eb-virt) ~$ python3 -m pip install flask==1.0.2
(eb-virt) ~$ python3 -m pip freeze
click==6.7
Flask==1.0.2
itsdangerous==0.24
Jinja2==2.10
MarkupSafe==1.0
Werkzeug==0.14.1

3. Hello World Flask アプリケーションを作成する

次に、Elastic Beanstalk を使用してデプロイするアプリケーションを作成します。 ここでは、"Hello World" という RESTful ウェブサービスを作成します。

オフィシャルドキュメントでは、動的にメッセージに変えられるようになっていますが、今回はレスポンスを "Hello world!" に決め打ちしてコードをシンプルにします。

プロジェクト用ディレクトリを作成

プロジェクト用ディレクトリ eb-flask を作成します。

(eb-virt) ~$ mkdir eb-flask
(eb-virt) ~$ cd eb-flask

Flask アプリケーションを作成

application.py という名前でアプリケーションを作成します。別の名前では作成しないようにして下さい。

デフォルトでは、Elastic Beanstalk は、アプリケーションを開始するために application.py というファイルを探します。作成した Python プロジェクトにこのファイルが存在しない場合は、アプリケーション環境の調整が必要になります。

https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/create-deploy-python-common-steps.html

from flask import Flask

application = Flask(__name__)

@application.route('/')
def hello_world():
    return 'Hello, World!'

if __name__ == "__main__":
    application.debug = True
    application.run()

トップページに対して "Hello, World!" を返すだけのシンプルなアプリケーションです。

Python を使用して application.py を実行

(eb-virt) ~/eb-flask$ python3 application.py
 * Serving Flask app "application" (lazy loading)
 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: on
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)
 * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 226-641-958
127.0.0.1 - - [03/May/2018 21:51:44] "GET / HTTP/1.1" 200 -

Flask にアクセス

別ターミナルから cURL でアクセスします。

$ curl localhost:5000
Hello, World!

4. Elastic Beanstalk 用に Flask アプリケーションを設定する

Elastic Beanstalk は requirements.txt を利用して、アプリケーションを実行する EC2 インスタンスにどのパッケージをインストールするかを判断します。

作成したアプリケーション向けの requirements.txt を出力します。

~/eb-flask$ source ~/eb-virt/bin/activate
(eb-virt) ~/eb-flask$ python3 -m pip freeze > requirements.txt
(eb-virt) ~/eb-flask$ deactivate

5. EB CLI でサイトをデプロイする

プロジェクトディレクトリは次のようになります。

$ tree ~/eb-flask
/home/foo/eb-flask
├── application.py
└── requirements.txt

0 directories, 2 files

eb init コマンドで EB CLI リポジトリを初期化します。

~/eb-flask$ eb init -p python-3.6 flask-tutorial

Select a default region
1) us-east-1 : US East (N. Virginia)
2) us-west-1 : US West (N. California)
3) us-west-2 : US West (Oregon)
4) eu-west-1 : EU (Ireland)
5) eu-central-1 : EU (Frankfurt)
6) ap-south-1 : Asia Pacific (Mumbai)
7) ap-southeast-1 : Asia Pacific (Singapore)
8) ap-southeast-2 : Asia Pacific (Sydney)
9) ap-northeast-1 : Asia Pacific (Tokyo)
10) ap-northeast-2 : Asia Pacific (Seoul)
11) sa-east-1 : South America (Sao Paulo)
12) cn-north-1 : China (Beijing)
13) cn-northwest-1 : China (Ningxia)
14) us-east-2 : US East (Ohio)
15) ca-central-1 : Canada (Central)
16) eu-west-2 : EU (London)
17) eu-west-3 : EU (Paris)
(default is 3): 5
Application flask-tutorial has been created.

設定ファイルを確認します。

~/eb-flask$ cat .elasticbeanstalk/config.yml
branch-defaults:
  default:
    environment: null
    group_suffix: null
global:
  application_name: flask-tutorial
  branch: null
  default_ec2_keyname: null
  default_platform: python-3.6
  default_region: eu-central-1
  include_git_submodules: true
  instance_profile: null
  platform_name: null
  platform_version: null
  profile: null
  repository: null
  sc: null
  workspace_type: Application

環境を作成し、eb create を使用してそこにアプリケーションをデプロイします。

完了には何分もかかります。 ゆっくりお待ち下さい。

~/eb-flask$ eb create flask-env
Creating application version archive "app-180503_215458".
Uploading flask-tutorial/app-180503_215458.zip to S3. This may take a while.
Upload Complete.
Environment details for: flask-env
  Application name: flask-tutorial
  Region: eu-central-1
  Deployed Version: app-180503_215458
  Environment ID: e-vkesqhxxxf
  Platform: arn:aws:elasticbeanstalk:eu-central-1::platform/Python 3.6 running on 64bit Amazon Linux/2.6.6
  Tier: WebServer-Standard-1.0
  CNAME: UNKNOWN
  Updated: 2018-05-03 21:55:01.209000+00:00
Printing Status:
INFO: createEnvironment is starting.
...
INFO: Successfully launched environment: flask-env

しばらくすると、 CNAME(アプリケーション用に作成されたドメイン名) も登録されます。 eb status コマンドで確認します。

~/eb-flask$ eb status
Environment details for: flask-env
  Application name: flask-tutorial
  Region: eu-central-1
  Deployed Version: app-180503_215458
  Environment ID: e-vkesqhxxxf
  Platform: arn:aws:elasticbeanstalk:eu-central-1::platform/Python 3.6 running on 64bit Amazon Linux/2.6.6
  Tier: WebServer-Standard-1.0
  CNAME: flask-env.XXX.eu-central-1.elasticbeanstalk.com
  Updated: 2018-05-03 21:58:16.882000+00:00
  Status: Ready
  Health: Green

cURL でアクセスします

$ curl flask-env.XXX.eu-central-1.elasticbeanstalk.com
Hello, World!

無事「Hello, World!」とかえってきました。

6. クリーンアップ

Elastic Beanstalk は実際には EC2 など関連リソースが動作しています。

管理コンソール

Elastic Beanstalk で起動された EC2

利用が終わったら、速やかにリソースを削除しましょう。

~/eb-flask$ eb terminate flask-env

ローカルサーバーの仮想環境とプロジェクトフォルダーも削除します。

~$ rm -rf ~/eb-virt  # 仮想環境
~$ rm -rf ~/eb-flask # プロジェクトディレクトリ

まとめ

Elastic Beanstalk の Python 3.6 対応と Flask 1.0 リリースを記念して、これらの組み合わせで、ミニマムなアプリケーションをデプロイしてみました。

Elastic Beanstalk Python は WSGI 上でアプリを動作させるため、Python2系/3系での開発フローの違いは仮想環境の構築・パッケージ管理程度です。雑に言えば、$ python application.py で動作する Web アプリを用意すれば良いのです。

EB CLI(eb)と Elastic Beanstalk 用 Python アプリともに pip でインストールしますが、それぞれの環境は異なることに注意して下さい。

  • EB CLI のインストール/CLI 操作はグローバル環境で実行
  • アプリケーションの作成、実行、requirements.txt の生成などは専用の仮想環境で実行

以上です。

参考