SEワンタンの独学備忘録

IT関連の独学した内容や資格試験に対する取り組みの備忘録

【Ansible】入門④ Playbookの基本的な記述方法


今回は前回に引き続きPlaybookの基本的な記述方法について確認していきます。

Playbookの基本要素

ここではPlaybookで使用される主要な要素について確認していきます。
恐らく全てを網羅するのは大変すぎるので、本当に基本的なものだけ。

hosts ホストの指定

hostsはInventoryに記述したホストを指定するものになります。
一般に記述できるのは以下のものにです。

指定値 内容
all Inventoryに記述されているすべてのホスト
localhost ローカルホスト、自分自身
ホスト名 指定したホストが対象(またはIPアドレス)
ホストグループ 指定したホストが対象

以下のInventoryファイルを扱って、Playbookの記述をいじってみます。

・Inventoryの例

#Inventory hosts-file
[web]
web-server1
web-server2

[db]
db-server1

・ホスト名で指定する
以下の例ではweb-server1db-server1に対して処理を実行する。

---
- hosts: web-server1 db-server1
  tasks:
   - name: test-playbook
     file:
        path: /tmp/server1.txt
        state: touch

・ホストグループ名で指定する
以下の例ではwebホストグループに属するweb-server1web-server2に対して処理が実行されます。

---
- hosts: web
  tasks:
   - name: test-playbook
     file:
        path: /tmp/web.txt
        state: touch

・all指定
Inventoryに記述した全てのホストに対して実行する。
以下は抜粋。

---
- hosts: all

・hostsで複数指定する
指定したホストに応じて別の処理を実行したい場合には次のように記述できます。
YAML記法を軽くでも押さえておけばなんとなくでも記述方法が分かると思います。

---
- hosts: web
  tasks:
   - name: test-playbook
     file:
        path: /tmp/web.txt
        state: touch

- hosts: web-server1
  tasks:
   - name: web1
     copy:
        dest: /tmp/web.txt
        content: web-server1
vars 変数

Inventoryファイルの中でもホストに対する変数を定義することができましたが、Playbook内でも変数を定義することができます。

・vars定義の例

以下ではPlaybook内で定義した変数をテキストファイルに書き出します。
変数の取り出し方法はInventoryでホスト変数を定義した場合と同様です。

---
- hosts: web
  vars:
   text: "hello Ansible"
  tasks:
   - name: hello
     copy:
        dest: /tmp/web.txt
        content: "{{ text }}"
task 実行タスク

tasks:はこれまでも記述してきましたが、対象のホストに実際に実行する処理(タスク)を記述していきます。
タスクの記述自体は多くはcopyモジュールやfileモジュールなどのmoduleが占めるので実現したいことを考える場合はmoduleの使い方を把握する必要があります。

---
- hosts: web
  tasks:
   - name: test-playbook
     file:
        path: /tmp/web.txt
        state: touch

- name: 部分にはタスクの名称を記述し、Playbookの実行を行った際にタスク名として表示されます。

・タスク名の出力例

TASK [test-playbook] ***********************************************************
changed: [web-server1]
changed: [web-server2]

基本構文

ここでは、Ansibleにおける基本構文を確認します。
プログラミング言語などでも一般的な条件分岐とループを確認します。

条件分岐

参考:条件 (Conditional) — Ansible Documentation

Ansibleにおける条件分岐はwhenで行います。
判定の結果で処理を実行したりしなかったりするわけですが、OSのバージョンやディストリビューションなどに応じて処理を変える場合などに使用されるようです。

・変数定義の判定

変数の定義を判定するにはis definedを使用します。定義されていない場合の判定を行いたい場合には同様にis undefinedを使用します。

以下の例ではtext変数が定義されている場合にはdebug:を実行します。

---
- hosts: web
  vars:
   text: "hello Ansible"
  tasks:
   - name: debug
     debug:
        msg: "true"
     when: text is defined

■変数の内容で判定

whenでは他の言語などと同様に==などを使用して変数の中身を判定に用いることができます。

以下の例では、ホスト変数として用意したhostname変数がweb1だった場合にはdebug:を実行します。

---
- hosts: web
  tasks:
   - name: debug
     debug:
        msg: "{{ hostname }}"
     when: hostname == "web1"

実行結果は以下のように表示され、条件に合致しなかった場合にはskippingとして表示されるようです。

TASK [debug] *******************************************************************
ok: [web-server1] => {
    "msg": "web1"
}
skipping: [web-server2]

PLAY RECAP *********************************************************************
web-server1                : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
web-server2                : ok=1    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

・ディストリビューションの判定

     when: ansible_distribution == 'CentOS'

メジャーバージョンの判定

     when: ansible_distribution_major_version == '7'
ループ(with_items)

参考:ループ — Ansible Documentation

Ansibleではwith_loopループを使用することで一つのタスクでリスト様な変数を定義することができます。
旧来からあるループ手法のようです。

---
- hosts: web
  tasks:
   - name: debug
     debug:
        msg: "{{ item }} "
     with_items:
        - test1
        - test2

・出力結果

TASK [debug] *******************************************************************
ok: [web-server1] => (item=test1) => {
    "msg": "test1 "
}
ok: [web-server1] => (item=test2) => {
    "msg": "test2 "
}
ok: [web-server2] => (item=test1) => {
    "msg": "test1 "
}
ok: [web-server2] => (item=test2) => {
    "msg": "test2 "
}
ループ(loops)

with_itemsと同様のことをloop:を使用することでも実現できます。
こちらは比較的新しいループ手法のようです。

---
- hosts: web
  tasks:
   - name: debug
     debug:
        msg: "{{ item }} "
     loop:
        - test1
        - test2

・出力例

TASK [debug] *******************************************************************
ok: [web-server2] => (item=test1) => {
    "msg": "test1 "
}
ok: [web-server2] => (item=test2) => {
    "msg": "test2 "
}
ok: [web-server1] => (item=test1) => {
    "msg": "test1 "
}
ok: [web-server1] => (item=test2) => {
    "msg": "test2 "
}

・複数の要素を格納して、特定の要素だけ取り出す。

---
- hosts: web
  tasks:
   - name: debug
     debug:
        msg: "{{ item.network.nic01 }} "
     loop:
      - name: server1
        disks: 3gb
        ram: 15Gb
        network:
          nic01: 100Gb
          nic02: 10Gb

・出力例

TASK [debug] *******************************************************************
ok: [web-server1] => (item={u'disks': u'3gb', u'ram': u'15Gb', u'name': u'server1', u'network': {u'nic02': u'10Gb', u'nic01': u'100Gb'}}) => {
    "msg": "100Gb "
ループ制御(loop_control)

上記のループ構文はloop_control:により制御を加えることができます。

■loop_var:

ループ別名を付けネストループを可能にする。

loop_var: machine

■label:

ループの出力内容を抑制する。

label: "{{ machine.network }}"

■index_var:

ループの場所を追跡する。

index_var: my_idx

■pause:

タスクループの中でアイテムの実行間隔を秒単位で指定する。

pause: 3


・使用例

---
- hosts: web
  tasks:
   - name: debug
     debug:
        msg: "{{ machine.network.nic01 }} "
     loop:
      - name: server1
        disks: 3gb
        ram: 15Gb
        network:
          nic01: 100Gb
          nic02: 10Gb
     loop_control:
        loop_var: machine
        label: "{{ machine.network }}"

ループアイテムに別名をつけ、machine.network以外の出力を抑制する。

TASK [debug] *******************************************************************
ok: [web-server1] => (item={u'nic02': u'10Gb', u'nic01': u'100Gb'}) => {
    "msg": "100Gb "
}
ok: [web-server2] => (item={u'nic02': u'10Gb', u'nic01': u'100Gb'}) => {
    "msg": "100Gb "
}


・前回
www.wantanblog.com


■参考書籍