メモ > サーバ > 各論: Ansible > Playbookで構成管理
Playbookで構成管理
Playbookにサーバの状態を定義しておけば、それに沿ってサーバが構成される
内容はテキストファイルなので、このファイル自体をGitで管理することもできる
■Playbookを試す
$ mkdir ansible
$ mkdir ansible/group_vars
$ vi ansible/group_vars/webservers.yml … 変数を定義する
■色々な機能を試す
message: "Hello Ansible !"
fruits:
apples:
amount: 10
bananas:
amount: 20
oranges:
amount: 30
$ vi ansible/test.yml … 実行内容を定義する
- hosts: webservers
user: vagrant
tasks:
- name: output message.
debug: msg="{{ message }}"
- name: output fruits
debug: msg="We want {{ item.value.amount }} {{ item.key }} !"
with_dict: "{{ fruits }}"
$ ansible-playbook ansible/test.yml … Playbookを指定して実行
PLAY [webservers] **************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************
ok: [192.168.33.11]
TASK [output message.] *********************************************************************************************************************************
ok: [192.168.33.11] => {
"msg": "Hello Ansible !"
}
TASK [output fruits] ***********************************************************************************************************************************
ok: [192.168.33.11] => (item={'value': {u'amount': 10}, 'key': u'apples'}) => {
"msg": "We want 10 apples !"
}
ok: [192.168.33.11] => (item={'value': {u'amount': 30}, 'key': u'oranges'}) => {
"msg": "We want 30 oranges !"
}
ok: [192.168.33.11] => (item={'value': {u'amount': 20}, 'key': u'bananas'}) => {
"msg": "We want 20 bananas !"
}
PLAY RECAP *********************************************************************************************************************************************
192.168.33.11 : ok=3 changed=0 unreachable=0 failed=0
$ vi ansible/group_vars/webservers.yml … 変数を定義する
become と become_user により、rootになって作業ができる
Ansible1.9からはsudo/suの代わりにbecomeを使う - Qiita
https://qiita.com/imoyoukan/items/12832aecd956d14b03f5
message: "Hello Ansible !"
fruits:
apples:
amount: 10
bananas:
amount: 20
oranges:
amount: 30
$ mkdir ansible/files
$ vi ansible/files/hoge.txt … 静的ファイルを配置する
hoge
hoge
$ mkdir ansible/templates
$ vi ansible/templates/fuga.txt.j2 … 動的ファイルを配置する
This is a jinja template file.
{{ message }}
jinja template can extract variables. like, ...
{% for key,value in fruits.iteritems() %}
We want {{ value.amount }} {{ key }} !
{% endfor %}
$ vi ansible/site.yml … 実行内容を定義する
- hosts: webservers
user: vagrant
become: yes
become_user: root
tasks:
- name: install packages from yum
yum:
name:
- jq
- ruby
- httpd
- name: register cron job
cron: name="check ping" day="*/2" hour="12" minute="0" job="ping -c 3 192.168.33.10"
- name: create directories
file: path={{ item.path }} owner={{ item.owner }} group={{ item.group }} mode=0{{ item.mode }} state=directory
with_items:
- { "path":"/opt/ansible", "owner":"root", "group":"root", "mode":"755" }
- { "path":"/opt/vagrant", "owner":"vagrant", "group":"vagrant", "mode":"755" }
- name: copy files
copy: src=files/hoge.txt dest=/opt/ansible/hoge.txt owner=root group=root mode=0755
- name: copy template files
template: src=templates/fuga.txt.j2 dest=/opt/ansible/fuga.txt owner=root group=root mode=0755
$ cd ansible
$ ansible-playbook site.yml --check … Playbookを指定してチェックモードで実行
$ ansible-playbook site.yml --check -v … Playbookを指定してチェックモードで実行(詳細なメッセージを表示)
$ ansible-playbook site.yml --check -vv … Playbookを指定してチェックモードで実行(もっと詳細なメッセージを表示)
$ ansible-playbook site.yml --check -vvv … Playbookを指定してチェックモードで実行(もっともっと詳細なメッセージを表示)
$ ansible-playbook site.yml … Playbookを指定して実行
※「--check」を付けると、実際のサーバ設定を変更しない。処理内容のチェックのみ行う
ただし「httpdをインストールしてからhttpd.confを編集する」というPlaybookがあった場合、
チェックモードだと実際にhttpdはインストールされないため、「httpd.confを編集できません」というエラーになるので注意
このエラーは「こういうものだ」として妥協すべきなのか、なにか対応方法があるのかは要調査
PLAY [webservers] **************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************
ok: [192.168.33.11]
TASK [install packages from yum] ***********************************************************************************************************************
changed: [192.168.33.11]
TASK [register cron job] *******************************************************************************************************************************
changed: [192.168.33.11]
TASK [create directories] ******************************************************************************************************************************
changed: [192.168.33.11] => (item={u'owner': u'root', u'path': u'/opt/ansible', u'group': u'root', u'mode': u'755'})
changed: [192.168.33.11] => (item={u'owner': u'vagrant', u'path': u'/opt/vagrant', u'group': u'vagrant', u'mode': u'755'})
TASK [copy files] **************************************************************************************************************************************
changed: [192.168.33.11]
TASK [copy template files] *****************************************************************************************************************************
changed: [192.168.33.11]
PLAY RECAP *********************************************************************************************************************************************
192.168.33.11 : ok=6 changed=5 unreachable=0 failed=0
[vagrant@controller ansible]$ ansible-playbook site.yml
PLAY [webservers] **************************************************************************************************************************************
TASK [Gathering Facts] *********************************************************************************************************************************
ok: [192.168.33.11]
TASK [install packages from yum] ***********************************************************************************************************************
changed: [192.168.33.11]
TASK [register cron job] *******************************************************************************************************************************
changed: [192.168.33.11]
TASK [create directories] ******************************************************************************************************************************
changed: [192.168.33.11] => (item={u'owner': u'root', u'path': u'/opt/ansible', u'group': u'root', u'mode': u'755'})
changed: [192.168.33.11] => (item={u'owner': u'vagrant', u'path': u'/opt/vagrant', u'group': u'vagrant', u'mode': u'755'})
TASK [copy files] **************************************************************************************************************************************
changed: [192.168.33.11]
TASK [copy template files] *****************************************************************************************************************************
changed: [192.168.33.11]
PLAY RECAP *********************************************************************************************************************************************
192.168.33.11 : ok=6 changed=5 unreachable=0 failed=0
site.yml でCronの実行間隔を変更してから再度 ansible-playbook を実行すると、target サーバのCron設定も書き換わった
target サーバでCronの設定を編集してから再度 ansible-playbook を実行すると、編集内容を残して再度設定が追加された
なお上記の「register cron job」の方法でCronを登録した場合、target サーバの /var/spool/cron/root に登録された
■roleでファイル分割
「サーバの基本設定」「Webサーバに関する設定」「DBサーバに関する設定」
などで分割することにより、管理をしやすくなる
$ cd
$ vi ansible/site.yml … メイン処理を定義
HTTPDが起動したので、ブラウザから以下にアクセスできる
http://192.168.33.11/
■notifyでhandlersを呼び出す
「この処理が実行された場合にのみ、あの処理を実行する」ができる
例えば「my.cnfの設定を変更した場合のみ、MySQLを再起動する」など
- hosts: webservers
user: vagrant
become: yes
become_user: root
tasks:
- name: register cron job
cron: name="check ping" day="*/2" hour="12" minute="0" job="ping -c 3 192.168.33.10"
roles:
- role-common
- role-web
$ mkdir -p ansible/role-common/tasks
$ vi ansible/role-common/tasks/main.yml … rolesに指定した名前内の /tasks/main.yml が実行される
- name: install packages from yum
yum:
name:
- jq
- ruby
- name: create directories
file: path={{ item.path }} owner={{ item.owner }} group={{ item.group }} mode=0{{ item.mode }} state=directory
with_items:
- { "path":"/opt/ansible", "owner":"root", "group":"root", "mode":"755" }
- { "path":"/opt/vagrant", "owner":"vagrant", "group":"vagrant", "mode":"755" }
- name: copy files
copy: src=files/hoge.txt dest=/opt/ansible/hoge.txt owner=root group=root mode=0755
$ mkdir -p ansible/role-web/tasks
$ vi ansible/role-web/tasks/main.yml … rolesに指定した名前内の /tasks/main.yml が実行される
- name: install packages from yum
yum:
name:
- httpd
- name: copy template files
template: src=templates/fuga.txt.j2 dest=/opt/ansible/fuga.txt owner=root group=root mode=0755
$ cd ansible
$ ansible-playbook site.yml … Playbookを指定して実行
$ vi role-web/tasks/main.yml … 編集してみる
- name: install packages from yum
yum:
name:
- httpd
- name: http service state … 追加
service: name=httpd state=started enabled=yes … 追加
- name: copy template files
template: src=templates/fuga.txt.j2 dest=/opt/ansible/fuga.txt owner=root group=root mode=0755
$ ansible-playbook site.yml … Playbookを指定して実行(HTTPDが起動する)
$ cd ..
$ vi ansible/role-common/tasks/main.yml
Ansibleでhandlersとnotifyをつかってみる - かべぎわブログ
https://www.kabegiwablog.com/entry/2018/03/06/090000
■コメント
「#」から始まる行はコメントとして扱われる- name: copy files
copy: src=files/hoge.txt dest=/opt/ansible/hoge.txt owner=root group=root mode=0755
notify:
- copy files handler
$ mkdir -p ansible/role-web/handlers
$ vi ansible/role-web/handlers/main.yml … role-webのハンドラを指定する
- name: copy files handler
copy: src=files/hoge.txt dest=/opt/ansible/hoge_handler.txt owner=root group=root mode=0755
$ cd ansible
$ ansible-playbook site.yml … Playbookを指定して実行(files/hoge.txt を /opt/ansible/hoge.txt へ複製する際、ファイルに変化があると /opt/ansible/hoge_handler.txt にも複製される)