Ansible操作例 – BIG-IPの操作方法の説明

スポンサーリンク

AnsibleでBIG-IPを操作する方法を説明します。showコマンドの出力を得たい時はbigip_commandを使用し、複数の設定を投入したい時はbigip_configを使います。その他、冪等性を担保しつつ慎重な設定を行うbigip_device_dns, bigip_hostnameなどのモジュールもあります。

BIG-IPへの接続方法

BIG-IPへの接続方法が分からない方は「Ansible操作例 – BIG-IPへの接続方法の説明」を参照ください。

このシナリオは以下のようなインベントリファイルを使用する事を前提としています。

cat << EOF > inventory.ini 
[bigip:vars]
ansible_user = 'admin'
ansible_password = 'admin'
ansible_connection = 'local'

[bigip]
bigip161 ansible_host=192.168.1.161
bigip162 ansible_host=192.168.1.162
EOF

showコマンドの実行

プレイブック作成

以下のようなプレイブックを作成します。

着目して欲しいのはregister句です。Ansibleは実行結果を変数に格納する事ができ、その変数名を定義するのがregister句です。以下のプレイブックは、「show sys version」の実行結果を変数「result」に格納し、変数「result」をdebugで出力する例です。

cat << EOF > bigip_show_sys_version.yml
- hosts: bigip161
  gather_facts: no

  vars:
    provider:
      password: "{{ ansible_password }}"
      server: "{{ ansible_host }}"
      user: "{{ ansible_user }}"
      validate_certs: no

  tasks:
    - name: run show sys version
      bigip_command:
        commands: show sys version
        provider: "{{ provider }}"
      register: result

    - name: display show sys version
      debug:
        var: result['stdout']
EOF

戻り値の一覧

Ansibleは実行結果を変数に格納する事ができます。この実行結果をプログラミングの文脈では「戻り値」と呼ぶ事が多く、公式ドキュメントでは「Return Value」との表現を使っています。実行結果にどのような値が格納されているかは、公式ドキュメントをマニュアルを参照ください。この場合ならば、「eos command モジュール」に記載されています。

bigip commandのマニュアル

実行結果

実行結果は以下のようになります。

# ansible-playbook -i inventory.ini bigip_show_sys_version.yml 

PLAY [bigip161] ****************************************************************

TASK [run show sys version] ****************************************************
ok: [bigip161]

TASK [display show sys version] ************************************************
ok: [bigip161] => {
    "result['stdout']": [
        "Sys::Version\nMain Package\n  Product     BIG-IP\n  Version     16.0.0\n  Build       0.0.12\n  Edition     Final\n  Date        Tue Jun 23 18:31:26 PDT 2020"
    ]
}

PLAY RECAP *********************************************************************
bigip161                   : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

複数コマンドの実行

プレイブック作成

bigip_commandは複数コマンドを同時に流し込むこともできます。以下はvlanとip addressを設定する例です。

cat << EOF > bigip_create_ipv4_address01.yml
- hosts: bigip161
  gather_facts: no

  vars:
    provider:
      password: "{{ ansible_password }}"
      server: "{{ ansible_host }}"
      user: "{{ ansible_user }}"
      validate_certs: no

  tasks:
    - name: create ipv4 address
      bigip_command:
        commands:
          - create net vlan VLAN0020 tag 20
          - create net self SELF0020 vlan VLAN0020 address 10.0.20.1/24
        provider: "{{ provider }}"
EOF

プレイブック実行

プレイブックを実行すると以下のように出力されます。ただし、bigip_commadsを編集用途で使用するのは非推奨であり、idempotent(冪等)ではない旨の警告が出力されます。

# ansible-playbook -i inventory.ini bigip_create_ipv4_address01.yml 

PLAY [bigip161] ****************************************************************

TASK [create ipv4 address] *****************************************************
[WARNING]: Using "write" commands is not idempotent. You should use a module
that is specifically made for that. If such a module does not exist, then
please file a bug. The command in question is "create net vlan VLAN0020 tag
20..."
[WARNING]: Using "write" commands is not idempotent. You should use a module
that is specifically made for that. If such a module does not exist, then
please file a bug. The command in question is "create net self SELF0020 vlan
VLAN0020 a..."
ok: [bigip161]

PLAY RECAP *********************************************************************
bigip161                   : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

プレイブック確認

確かにプレイブックで記載された設定が投入されている事を確認します。

root@(bigip162)(cfg-sync Standalone)(Active)(/Common)(tmos)# list net vlan
net vlan VLAN0020 {
    if-index 144
    tag 20
}
root@(bigip162)(cfg-sync Standalone)(Active)(/Common)(tmos)# list net self
net self SELF0020 {
    address 10.0.20.1/24
    traffic-group traffic-group-local-only
    vlan VLAN0020
}

テンプレートの利用

テンプレートの作成

Ansibleはテンプレートを作成し、そのテンプレートに記載されたconfigを流し込む事ができます。

以下にテンプレートの例を紹介します。ここで記載したテンプレートは静的なものですが、Ansibleが内部的に使うJinja2と呼ばれるテンプレートエンジンは変数読み込みや繰り返し処理も実装する事ができます。説明は省略しますが、JavaやRubyの実装経験がある人ならばJSP, ERBなどとほぼ同等機能と思って差支えございません。

cat << EOF > bigip_template.j2
net vlan VLAN0030 {
    tag 30
}
net self SELF0030 {
    address 10.0.30.1/24
    vlan VLAN0030
}
EOF

プレイブックの作成

テンプレートを流し込むプレイブックの例を紹介します。

なお、この時に流し込む構文はtmshで指定する構文ではなく、”load sys config from-terminal merge”で指定する構文です。bigip.confやbigip_base.confで記述される構文と同じです。

cat << EOF > bigip_create_ipv4_address02.yml
- hosts: bigip161
  gather_facts: no

  vars:
    provider:
      password: "{{ ansible_password }}"
      server: "{{ ansible_host }}"
      user: "{{ ansible_user }}"
      validate_certs: no

  tasks:
    - name: create ipv4 address
      bigip_config:
        merge_content: "{{ lookup('file', 'bigip_template.j2') }}"
        provider: "{{ provider }}"
EOF

テンプレート実行

プレイブックを実行すると以下のように出力されます。

# ansible-playbook -i inventory.ini bigip_create_ipv4_address02.yml 

PLAY [bigip161] ****************************************************************

TASK [create ipv4 address] *****************************************************
changed: [bigip161]

PLAY RECAP *********************************************************************
bigip161                   : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

プレイブック確認

確かにプレイブックで記載された設定が投入されている事を確認します。

root@(bigip162)(cfg-sync Standalone)(Active)(/Common)(tmos)# list net vlan
net vlan VLAN0020 {
    if-index 144
    tag 20
}
net vlan VLAN0030 {
    if-index 160
    tag 30
}
root@(bigip162)(cfg-sync Standalone)(Active)(/Common)(tmos)# list net self
net self SELF0030 {
    address 10.0.30.1/24
    traffic-group traffic-group-local-only
    vlan VLAN0030
}
net self SELF0020 {
    address 10.0.20.1/24
    traffic-group traffic-group-local-only
    vlan VLAN0020
}

手堅い設定投入

概要

Ansibleは、前述のbigip_command, bigip_config以外のモジュールを使用する事を推奨しています。bigip_hostname, bigip_device_dnsなどのモジュールが該当し、これらは「冪等性」が担保されたモジュールです。

「冪等性」とは「再実行しても得られる結果が同じ」という意味ですが、私個人の見解としては、「一般的な意味の冪等性」と「Ansibleの文脈での冪等性」はニュアンスが異なると理解しています。前述のbigip_configは何度実行しても「changed」と表示されますが、bigip_hostname, bigip_device_dnsなどのモジュールは設定変更が発生してない場合は「ok」のみが表示されます。Ansibleの文脈での「冪等性」とは、プレイブックを何度も実行するような運用において、changeなのかokなのかが目視チェックしやすい仕組みと理解した方が良いでしょう。

例えば、以下スクリーンショットならば、DNSは設定変更されたもののホスト名はそのままである事が一目瞭然です。

冪等性のあるAnsibleモジュールの実行例

プレイブック作成

ホスト名とDNSサーバを設定する例を紹介します。

cat << EOF > bigip_modify_services.yml 
---
- hosts: bigip161
  gather_facts: no

  vars:
    provider:
      password: "{{ ansible_password }}"
      server: "{{ ansible_host }}"
      user: "{{ ansible_user }}"
      validate_certs: no

  tasks:
    - name: Set the hostname of the BIG-IP
      bigip_hostname:
        hostname: bigip162.localhost.localdomain
        provider: "{{ provider }}"
    - name: Set the DNS settings on the BIG-IP
      bigip_device_dns:
        name_servers:
          - 208.67.222.222
          - 208.67.220.220
        search:
          - localdomain
          - lab.local
        provider: "{{ provider }}"
EOF

プレイブック実行

プレイブックを実行すると以下のように出力されます。

# ansible-playbook -i inventory.ini bigip_modify_services.yml 

PLAY [bigip161] ****************************************************************

TASK [Set the hostname of the BIG-IP] ******************************************
ok: [bigip161]

TASK [Set the DNS settings on the BIG-IP] **************************************
ok: [bigip161]

PLAY RECAP *********************************************************************
bigip161                   : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

プレイブック確認

確かにプレイブックで記載された設定が投入されている事を確認します。

root@(bigip162)(cfg-sync Standalone)(Active)(/Common)(tmos)# list sys global-settings hostname 
sys global-settings {
    hostname bigip162.localhost.localdomain
}
root@(bigip162)(cfg-sync Standalone)(Active)(/Common)(tmos)# list sys dns
sys dns {
    name-servers { 208.67.222.222 208.67.220.220 }
    search { localdomain lab.local }
}
タイトルとURLをコピーしました