Python Ansible webserver

Python学習【365日チャレンジ!】259日目のマスターU(@Udemy11)です。

人は自分が見たいものしか見ない

というカエサルの有名な言葉がありますが、最近のアメリカ大統領選を見ていると、ほんとそのとおりだなと思います。

ある種の宗教的な様相を表している感じがしないこともないですが、大半のアメリカ人が自分が見たいと思うものをそれぞれの候補に見いだしているのかもしれません。

とはいっても、トランプ大統領以外だったらだれでもいいと思っている人がかなり多いのは間違いないでしょう。

どうなるんでしょうね。

それでは今日もPython学習を始めましょう。

昨日の復習

昨日は、Ansibleの自動化で共通の処理を行うcommonサーバーを設定する際にハマったポイントを整理しました。

学習しているPython講座の中でバージョンが最新ではなく、うまく動かなかったりするため、Q&Aやネットで調べて解決する必要がありました。

詳しくは昨日の記事をごらんください。

今日は、昨日の続きでserver2のwebserverの初期設定を行うコードを書いていきます。

ファイル構造

webserverの設定ファイルはcommonより少し多くなります。

Python Ansible webserver

ansible_project > roles > webserverの中に上記のようなフォルダ階層にして、ファイルを作成します。

設定するファイルを順番にみていきましょう

hello.py

filesフォルダの中に作成するhello.pyはFlaskのアプリケーションとなるので、Fabricのときに作成したファイルをそのまま使います。

from flask import Flask

app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello world'

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

tasks/main.yml

taskフォルダの中に作るのは、main.ymlinstall-app.ymlです。

install-app.ymlは、main.ymlから読み込まれるファイルになりますので、まずはmain.ymlの中身をみていきましょう

---

- include_tasks: install-app.yml

...

install_app.ymlを読み込むだけの内容ですね。

順番では、次にinstall_app.ymlですが、先にvarsフォルダの中のmain.ymlを書いていきます。

vars/main.yml

このmain.ymlは、次に書くapp.conf.j2install-app.ymlから読み込まれる変数を指定します。

---

server_ip: 0.0.0.0
server_port: 5000
app_name: hello
app_dir: /root/work

...

サーバーIPとポート、アプリケーションの名前と保存先のディレクトリを定義しています。

次に、templates/app.conf.j2を作成します。

app.conf.j2

j2は、jinja2のファイルで、jinja2はpythonのweb開発使われているテンプレートエンジンライブラリです。

設定ファイル(vars/main.yml)に記述した変数を、{{}}で囲んで読み込んで活用することができます。

[program:{{ app_name }}]
command = gunicorn --bind {{ server_ip}}:{{ server_port }} {{ app_name }}:app
directory = {{ app_dir }}

programの名前にapp_name、実行するコマンドにserver_ipserver_portapp_dirをそれぞれ読み込んでいます。

install-app.yml

実際にインストールの作業を実行するのがinstall-app.ymlになります。

---

- name: Install WSGI HTTP server
  apt:
    name: gunicorn

- name: Python Framework
  pip:
    name: flask

- name: Create new directory
  file:
    path: "{{ app_dir }}"
    state: directory
    mode: 0755

- name: Drop app src
  copy:
    src: hello.py
    dest: "{{ app_dir }}/hello.py"

- name: Install supervisor
  apt:
    name: supervisor

- name: Drop supervisord conf
  template:
    src: app.conf.j2
    dest: /etc/supervisor/conf.d/app.conf

- name: Start supervisor
  service:
    name: supervisor
    enabled: yes
    state: restarted

...

7つの実行コードを記述しています。

3行目から5行目がgunicornのインストール、7行目から9行目がflaskのインストールです。

11行目から15行目でvars/main.ymlで指定したapp_dirを指定してディレクトリを作成し、誰でも読込みと実行ができて、書込みは自分だけができるパーミッション(755)に指定しています。

17行目から20行目でhello.py/root/work/にコピーします。

22行目から24行目でsupervisorをインストールして、26行目から29行目で、jinja2ファイルを指定したディレクトリ(/etc/supervisor/conf.d/app.conf)にコピーしています。

最後に31行目から35行目でsupervisorをリスタートして使用できるようにしています。

次に最後のsite.ymlです。

site.yml

こちらのファイルには、commonで書いたコードに1行付け加えるだけです。

---

- hosts: webservers

  roles:
    - common
    - webserver

...

7行目の- webserverを付け加えて完成です。

実行結果

ここまでできれば、commonで実行したときと同じように、ansible-playbook -i inventories site.ymlを実行します。

Python Ansible webserver

問題なくプログラムが終了して、failedが0になっています。

本来なら、これでブラウザーからlocalhost:8002にアクセスすれば、hello.pyで定義されたHello worldと表示されるはずなのですが、どうにも後にもうまくいきませんでした。

同じような状況の方が質問されていたので、同じように対処して見るのですが、どうにも後にもうまくいかず、最終的にインストールしているOSのubuntuのバグで表示されないような感じでした。

まとめ

今回も問題を解決しようと、あれをやったりこれをやったりしたのですが、最終的に解決には至りませんでした。

ただ、前回easy_installpipのインストールに失敗していたので、今回はすでにインストールしているpipを使って、flaskをインストールしてみたらうまくいったので、少しは成長したな〜と勝手に自己満足してしまいました。

とはいっても、自動化で立ち上げたサーバーに表示されないという問題が残っているので、解決方法を探りたいと思いますが、今日はすでにオーバーヒート状態なので、ここまでにしておきます。

ということで、明日もGood Python!