前回の続きです。
AnsibleWorks AWX User Guide では projects/helloworld/helloworld.yml
というテスト用の Playbook が載っているのですが、この内容が次のようになっており user: root
が指定してあるため Credentials の SSH Username が helloworld.yml で上書きされて Authentication failed となるという現象で少しハマりました。
--- - name: Hello World! hosts: all user: root tasks: - name: Hello World! shell: echo "Hi! AWX is working"
AWX の良い所は実行のログがずっと残って簡単に参照や再実行ができるところですね。Playbook の作成自体は手動です。ユーザーや権限管理ができるので権限分離の上でぽちぽちボタンをクリックするだけでアプリのデプロイができたりするのは便利なのかもしれない。
さて、前回 AWX のインストーラーが Playbook でできているから参考になりそうなので読んでみようと書きました。さっそく確認してみます。
まずはインベントリファイルの myhosts
と、メインの site.yml
です。
[all] 127.0.0.1
--- # This playbook deploys the AWX application (database, web and worker) to a # single server. - hosts: all tasks: - name: group hosts by distribution group_by: key="{{ ansible_distribution }}-{{ ansible_distribution_version }}" - hosts: RedHat-6*:CentOS-6*:SL-6* user: root roles: - { role: packages_el6 } - { role: postgres, pg_hba_location: "/var/lib/pgsql/data/pg_hba.conf" } - { role: awx_install } - { role: supervisor, sup_init_name: "supervisord", sup_conf_location: "/etc/supervisord.conf" } - { role: httpd, httpd_init_name: "httpd" } - { role: iptables } - { role: misc } - hosts: Fedora-* user: root roles: - { role: packages_fedora } - { role: postgres, pg_hba_location: "/var/lib/pgsql/data/pg_hba.conf" } - { role: awx_install } - { role: supervisor, sup_init_name: "supervisord", sup_conf_location: "/etc/supervisord.conf" } - { role: httpd, httpd_init_name: "httpd" } - { role: iptables } - { role: misc } - hosts: Ubuntu-12*:Ubuntu-13* user: root roles: - { role: packages_ubuntu } - { role: postgres, pg_hba_location: "/etc/postgresql/9.1/main/pg_hba.conf" } - { role: awx_install } - { role: supervisor, sup_init_name: "supervisor", sup_conf_location: "/etc/supervisor/conf.d/awx.conf" } - { role: httpd, httpd_init_name: "apache2" } - { role: misc }
なるほどぉ。group_by
でダイナミックにグルーピングを行い、Linux の distribution 毎の role へと振り分けることが可能なわけですね。
そして、roles
を使って role を割り付ける際に変数を設定できるようです。Distribution 間での差がファイルの path だけとか、簡単なものについてはこうやって変数を使うことで role (task) をまとめられるんですね。
今回は CentOS 6 へインストールしたので以降は CentOS 用の role を見ていきます。
packages_el6
- name: install EL6 awx yum repository template: src=yum_repo.j2 dest=/etc/yum.repos.d/awx.repo when: tarball is not defined register: yum_repo - name: yum clean cached awx repository information command: yum clean all --disablerepo=* --enablerepo=ansibleworks-awx when: tarball is not defined and yum_repo.changed - name: install required packages for EL6 yum: name=$item state=installed with_items: - Django14 - httpd - mod_wsgi - libselinux-python - policycoreutils-python - postgresql-server - python-psycopg2 - python-setuptools - setools-libs-python - supervisor tags: packages
注目すべき点を含む task を抜粋しました。
"install EL6 awx yum repository"
では when: tarball is not defined
と register: yum_repo
がポイントです。when
では ansible-playbook
の -e, --extra-vars
で指定する EXTRA_VARS (key=value) で tarball
という変数が指定されているかどうかでこの task を実行するかどうか判断しています。AWX のインストールでは setup.sh
に -e
オプションで渡した引数が ansible-playbook
コマンドに渡されます。
register: yum_repo
はこの task の結果情報を yum_repo という変数(Object?)に登録します。以降の task でこの情報を参照することができます。この機能の詳細は Advanced Playbooks (register variables) が参考になります。
次の "yum clean cached awx repository information"
task の when
で yum_repo の情報が参照されています。when: tarball is not defined and yum_repo.changed
先ほどの tarball 変数が未定義という条件に and
で yum_repo.changed
とあります。あの task で変更があった場合ということになります。yum_repo の task で変更の必要がなかった場合にはこの task も実行されないということになります。
そして、次の task には with_items
と $item
があります。with_items
のリストの要素をループで $item
変数に入れて処理します。
postgres
- name: init postgresql command: service postgresql initdb creates=/var/lib/pgsql/data/PG_VERSION when: ansible_distribution != "Ubuntu" tags: postgresql - name: update postgresql authentication settings template: src=pg_hba.conf.j2 dest={{pg_hba_location}} owner=postgres notify: restart postgresql tags: postgresql - name: restart postgresql and configure to startup automatically service: name=postgresql state=restarted enabled=yes tags: postgresql - name: wait for postgresql restart command: sleep 10 tags: postgresql
PostgreSQL 関連 task の抜粋です(次以降も抜粋です)。1つ目の task では when: ansible_distribution != "Ubuntu"
という条件が指定されています。Ubuntu ではインストーラーが initdb を実行してくれるんでしょう(locale ってどう指定されてるんだろう?)。command
で creates=/var/lib/pgsql/PG_VERSION
が指定されているのでこのファイルが存在していればこの task (initdb) は実行されません。
次の task では template
モジュールを使って pg_hba.conf
を書き換えています。notify: restart postgresql
により、pg_hba.conf
が書き換えられたら PostgreSQL をリスタートします。この "restart postgresql"
処理は roles/postgres/handlers/main.yml
で定義されています。でも pg_hba.conf の更新で restart って良くないな、reload で十分なのに。
最後の task は sleep です。PostgreSQL の起動には時間がかかるので 10 秒待っています。でもこれは pause
モジュールを使う方が良いのかな?
それとも中断の選択肢を与えないための command
モジュールでの sleep なのかな?
awx_install
- name: configure awx user user: name={{aw_user}} system=yes home={{aw_home}} shell=/bin/bash comment="AWX" when: tarball is defined tags: awx,user - name: create django super user shell: echo "from django.contrib.auth.models import User; User.objects.filter(username='{{admin_username}}').count() or User.objects.create_superuser('{{admin_username}}', '{{admin_email}}', '{{admin_password}}')" | awx-manage shell sudo_user: awx tags: awx
ここは特に特殊な使い方は無いですね。tags
ってカンマ区切りで複数指定できるんですね。まあ tags って s がついてるくらいだから。
2つ目のは「Python ってワンライナー書けるんだ!?」と…
supervisor
- name: update supervisor config ini_file: dest={{sup_conf_location}} section="program:awx-celeryd" option="{{item.option}}" value="{{item.value}}" with_items: - option: command value: "/usr/bin/awx-manage celeryd -B -l info --autoscale=20,2" - option: directory value: "{{ aw_home }}" - option: user value: "{{ aw_user }}" - option: autostart value: "true" - option: autorestart value: "true" - option: stopwaitsecs value: 600 - option: log_stdout value: "true" - option: log_stderr value: "true" - option: logfile value: "/var/log/supervisor/awx-celeryd.log" - option: logfile_maxbytes value: 50MB - option: logfile_backups value: 999 notify: restart supervisor tags: supervisor
へー、with_items
って list の要素が hash っていうのもありなんですね。
httpd
- name: determine if selinux is installed shell: which getenforce || exit 0 register: selinux_installed - name: determine if selinux is enabled shell: getenforce | grep -q Disabled || echo yes && echo no register: selinux_enabled when: selinux_installed.stdout != "" ignore_errors: true - name: allow Apache network connections seboolean: name=httpd_can_network_connect state=true persistent=yes when: selinux_installed.stdout != "" and selinux_enabled.stdout == "yes" tags: httpd
SELinux の有効・無効をチェックして必要な場合に seboolean モジュールで SELinux の設定を行なっています。register
, when
, ignore_errors
が活用されています。
iptables
- name: determine if iptables is installed command: iptables --version register: iptables_installed ignore_errors: True - name: insert iptables rule for httpd lineinfile: dest=/etc/sysconfig/iptables state=present regexp="^.*INPUT.*tcp.*$httpd_port.*ACCEPT" insertafter="^:OUTPUT " line="-A INPUT -p tcp --dport {{httpd_port}} -j ACCEPT" when: iptables_installed.rc == 0 notify: restart iptables tags: iptables httpd
iptables の設定はできれば restart なしで行えれば良いのですが、やっぱりちょっと難しいですかね。
misc
- name: deploy config file for rsyslogd copy: src=51-awx.conf dest=/etc/rsyslog.d/51-awx.conf notify: restart rsyslogd tags: - misc - rsyslog
おや?tags
が今度はカンマ区切りじゃなくて list になってますね。こうも書けるようです。
以上、インストーラーの Playbook を調査してみました。Ansible を使ったインストーラーも悪くないですね。
Ansible については Ansible Tutorial, Ansible in detail もよろしく〜。
Comments