AWS EC2の「Ubuntu Server(Ubuntu 22.04)」インスタンス上にFlaskを用いてREST APIを作成する

AWS EC2の「Ubuntu Server(Ubuntu 22.04)」インスタンス上にFlaskを用いてREST APIを作成してみます。

■PC環境

Windows10(Google Chrome)

AWS インスタンス作成済み(Ubuntu 22.04 LTS (GNU/Linux 5.15.0-1011-aws x86 64))

Python 3.10.4

■SSHクライアント「PuTTY」を用いてSSHで接続する

Flaskを用いてREST APIを作成してみますが、その前に「AWS マネジメントコンソール」にログインし、「EC2」サービスへ移動します。移動後、「EC2 Management Console」内の左メニューの「インスタンス」の「インスタンス」をクリックすると、作成した「インスタンス」が一覧で表示されます。

今回作成した「Ubuntu Server」インスタンスの「インスタンス状態」が「実行中」であることを確認します。確認後、SSHクライアント「PuTTY」を用いて、SSHで接続を行います。

Welcome to Ubuntu 22.04 LTS (GNU/Linux 5.15.0-1011-aws x86 64)
* Documentation: https://help.ub 
* Management: https://landscape.canonical.com 
* Support: https://ubuntu.com/advantage
System information as of Fri Jul 8 00:49:50 UTC 2022
System load: 0.0 Usage of 7: 22.6% of 7.58GB Memory usage: 234 Swap usage: 0%
Processes:
100 Users logged in: IPv4 address for etho: ***.**.**.**
* Ubuntu Pro delivers the most comprehensive open source security and,
compliance features.
Ubuntu Pro for AWS | Ubuntu
Ubuntu Pro for AWS, the Ubuntu image optimised for production and professional use on public cloud. Including broad security coverage, live kernel patching, cer...
42 updates can be applied immediately. 22 of these updates are standard security updates. To see these additional updates run: apt list --upgradable

SSHで接続すると、上記のようなメッセージが出力されます。

ubuntu@ip-**-**-**-**(ipアドレス):~$

出力後、上記のように出力されれば、接続は完了となります。

■Nginx(エンジンエックス)のインストール

$ sudo apt update

接続後、上記のコマンドを入力し、Enterキーを押します。パッケージ一覧を更新します。Enterキーを押すと更新が開始され、「Reading package lists… Done(パッケージリストを読んでいます…完了)」、「** packages can be upgraded. (パッケージはアップグレードできます。)」といったメッセージが出力されます。これが出力されれば更新が完了となります。

$ sudo apt install nginx

更新完了後、上記のコマンドを入力し、Enterキーを押します。Nginxパッケージと依存関係のインストールを行います。Enterキーを押すと、インストールが完了となり、その後、自動的にnginxが実行されます。

■仮想環境を作成する

$ mkdir flask_ap_project

次に、仮想環境の構築を行いますので、上記のコマンドを入力し、Enterキーを押します。「mkdir」コマンドで「flask_ap_project」ディレクトリを作成します。

$ cd flask_ap_project

作成後、上記のコマンドを入力し、Enterキーを押します。「cd」コマンドで「flask_ap_project」ディレクトリ内に移動します。

$ virtualenv myfirstflask

移動後、上記のコマンドを入力し、Enterキーを押します。「myfirstflask」タイプと呼ばれる新しい仮想環境を作成します。なお、Enterキーを押した場合に「Command ‘virtualenv’ not found, but can be installed with: sudo apt install python3-virtualenv」と出力されることがありますが、この場合は、python3-virtualenvをインストールする必要があります。

$ source myfirstflask/bin/activate

Enterキーを押すと、仮想環境が作成されます。その後、上記のコマンドを入力し、Enterキーを押します。仮想環境をアクティブ化し、仮想環境内に入ります。

(myfirstflask) ubuntu@ip-***-**-**-**:~/flask_ap_project$

Enterキーを押すと、先頭に仮想環境の名前が出力されます。このように出力されれば、仮想環境に入ったことになります。

■FlaskとGunicornをインストールする

$ sudo apt install gunicorn

仮想環境に入った後に、上記のコマンドを入力し、Enterキーを押します。UNIX用のPythonWSGIHTTPサーバーであるGunicornをインストールします。

$ pip install gunicorn flask

インストール後、さらに、pipを経由してflaskとgunicornをインストールしますので、上記のコマンドを入力し、Enterキーを押します。Enterキーを押すと、インストールが開始され、「Successfully installed」と出力されれば、正常にインストールは完了となります。

■サーバー構成とホスティングをテストするAPIのファイルを作成する

完了後、サーバー構成とホスティングをテストするAPIのファイルを作成します。

$ nano api_test.py

作成するために、上記のコマンドを入力し、Enterキーを押します。Ubuntuにプリインストールされているテキストエディタ「nano」を起動し、「api_test.py」というスクリプトファイルを作成します。

■コード

from flask import Flask, jsonify, request
app = Flask(__name__)
@app.route('/', methods=['GET'])
def hi_test():
   if request.method == 'GET':
      return jsonify({"text": "Hi, there!"})
if __name__ == "__main__":
   app.run(host='0.0.0.0')

「from import」でflaskでFlask, jsonify, requestを呼び出します。

その後、「app = Flask(__name__)」でFlaskインスタンスを作成します。作成後、「@app.route(‘/’, methods=[‘GET’])」とし、URLとfuncitonを紐付けます。「methods=[‘GET’]」とすることで、要素を取得できるようになります。

紐付けするhi_test()関数は、ifを用いて、もし’/’にアクセスした場合にreturnとしてjsonify()で引数,パラメータとして渡したdict型のデータをjsonに変換し返します。

最後に「if __name__ == ‘__main__’:」と、run()を用いて、ローカル開発サーバーでアプリケーションを実行します。

このコードを「api_test.py」に記述し、「Ctrl + S」で上書き保存し、「Ctrl + X」でnanoを閉じます。

■ポート開放の設定

閉じた後に、ポート開放の設定を行います。Flaskはポート番号”5000”を使用するため、ポートを開く必要があります。

$ sudo ufw allow 5000

ポートを開くために、上記のコマンドを入力し、Enterキーを押します。ufw(Uncomplicated FireWall)というファイアウォールを管理して操作するプログラムで、ポート番号”5000”をallow(許可)します。Enterキーを押すと、ポート番号”5000”が許可されます。

$ python api_test.py

■実行と検証

許可後、上記のコマンドを入力し、Enterキーを押します。先程作成したスクリプトファイルを実行します。

 * Serving Flask app 'api_test' (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on all addresses (0.0.0.0)
   WARNING: This is a development server. Do not use it in a production deployment.
 * Running on http://127.0.0.1:5000
 * Running on http://172.31.27.46:5000 (Press CTRL+C to quit)

実行すると、上記のメッセージが出力されます。出力されたURLの「http://127.0.0.1:5000」をコピーし、Webブラウザを起動し、アドレスバーに入力しアクセスしてみます。

このサイトにアクセスできません127.0.0.1 で接続が拒否されました。
次をお試しください

接続を確認する
プロキシとファイアウォールを確認する
ERR_CONNECTION_REFUSED

アクセスすると、「127.0.0.1 で接続が拒否されました。」とページ上に表示されました。

このサイトにアクセスできません***.**.**.**(IPアドレス) からの応答時間が長すぎます。
次をお試しください

接続を確認する
プロキシとファイアウォールを確認する
Windows ネットワーク診断ツールを実行する
ERR_CONNECTION_TIMED_OUT

表示後、もう1つの出力されたURLを確認してみます。確認してみましたが、こちらも応答時間が長過ぎるということで、REST APIが表示されませんでした。このような現象が発生する原因を探してみると、AWSのファイアウォールまたはセキュリティグループを設定する必要があることが判明しました。そこで、「AWS マネジメント コンソール」にログインし、「EC2 Management Console」へ移動します。移動後、左メニューから「インスタンス」をクリックします。

クリックすると、現在使用しているインスタンスの「セキュリティグループ」を確認します。今回は「launch-wizard-1」となっています。

確認後、左メニューから「セキュリティグループ」をクリックします。 クリックすると、セキュリティグループの一覧が表示されますので、この中から現在使用しているインスタンスのセキュリティグループの「セキュリティグループ ID」をクリックします。

クリックすると、選択したセキュリティグループの詳細ページが表示されます。ページ内の「インバウンドルール」タブをクリックします。タブが表示され、現在のセキュリティグループが選択されている状態で「インバウンドのルールを編集」ボタンをクリックします。

クリックすると、「インバウンドのルールを編集」が表示されます。ページ内の「ルールを追加」ボタンをクリックし、新しいルールを追加します。

今回追加するルールは「タイプ」を「カスタム TCP」とし、「ポート範囲」を「5000」とします。さらに「ソース」を「0.0.0.0/0」とします。最後に「ルールを保存」ボタンをクリックします。

クリックすると、「インバウンドセキュリティグループのルールが、セキュリティグループで正常に変更されました 」という緑のポップアップが表示されます。これでセキュリティグループの設定は完了となります。

■再度、実行と検証

完了後、先程出力されたURLの「http://127.0.0.1:5000」ともう1つのURLにアクセスしてみますが、アクセスしても、REST APIが表示されませんでした。なぜ表示されないのかの原因を調べて解決策として、「EC2 Management Console」の「インスタンス」から現在使用しているインスタンスをクリックし、「インスタンス概要」ページを表示させます。

表示後、「パブリック IPv4 アドレス」が表示されていますが、このアドレスの後ろに「5000」を付けて「http://***.**.**.***:5000/」という形で、Webブラウザで開いてみることにしました。

開いてみると、REST APIが表示されることが確認できました。

コメント

タイトルとURLをコピーしました