これは、Ansible Advent Calendar 2020 (Qiita版)の19日目の記事です。
はじめに
Ansible には Cisco ACI の操作にも対応していて、モジュールが多数あります。
内部的には APIC の API を利用しますが、httpapi コネクションプラグインには対応していません。
そのため、基本的には各タスクごとに接続先や認証情報を指定する必要があり、Playbook が冗長になりがちになります。
YAML のアンカー、エイリアス、マージを利用すれば冗長さはある程度抑えられますが、YAML に慣れてないと初見で読み解けなかったり、マージ自体はタスクごとに指定が必要という点は残ります。
一方で、cisco.aci collection の version 1.1.0で、環境変数によって接続先や認証情報を指定できるようになりました。
この機能により、各タスクごとに接続先や認証情報を指定する必要がなくなりました。
この記事では、簡単なサンプルでご紹介します、
- 動作確認環境
- Ansible 2.10.3 / 2.9.15
cisco.acicollection 1.1.0- 2020/12/19 現在の最新は 2.0.0 です
- Ansible 2.9 系でも利用可能
- DevNet Sandox ACI Version 4.1(1k)
環境変数名とモジュールオプション名の対応
接続先や認証情報を指定する環境変数は、モジュールの各オプションに対応する形で用意されています。対応は以下のとおりです。
| 項目 | 環境変数名 | モジュールのオプション | 備考 |
|---|---|---|---|
| ホスト名 | ACI_HOST |
host |
|
| ポート | ACI_PORT |
port |
|
| ユーザー名 | ACI_USERNAME, ANSIBLE_NET_USERNAME |
username |
|
| パスワード | ACI_PASSWORD, ANSIBLE_NET_PASSWORD |
password |
|
| 証明書名 | ACI_CERTIFICATE_NAME |
certificate_name |
署名ベース認証でのみ利用 |
| 秘密鍵のファイル名 | ACI_PRIVATE_KEY |
private_key |
署名ベース認証でのみ利用 |
| 証明書検証の有無 | ACI_VALIDATE_CERTS |
validate_certs |
|
| SSL/TLSの利用 | ACI_USE_SSL |
use_ssl |
|
| プロキシ利用の有無 | ACI_USE_PROXY |
use_proxy |
|
| タイムアウト | ACI_TIMEOUT |
timeout |
各モジュールの説明ページ(例: aci_tenant モジュール)にも説明があります。
優先度はモジュールのオプションのほうが高く、モジュールのオプションが指定されていなければ環境変数を参照する仕様です。
(補足) 2種類の認証方式
aci_* モジュールは、パスワードベース、署名ベースの2種類の認証方式があります。
パスワードベース認証方式は環境面の手間が少ない反面、DDoS 攻撃と誤認されやすいデメリットがあります。
一方、署名ベース認証方式は証明書や鍵を用意して APIC に登録するといった準備が必要ですが、DDoS 攻撃と誤認されにくいメリットがあります。
- 参考
この記事でご紹介するサンプルは、準備が簡単なパスワードベース認証方式を利用した Playbook です。必要に応じて読み替えてください。
サンプル Playbook
テナント test_tenant01 と、 Application Profile test_ap01、EPG test_epg01 を作成する Playbook です。
環境変数で一括指定
環境変数を指定するenvironment キーワードは、Play レベルで指定します。Task レベルでも指定できますが、ここではなるべく冗長さを排除するために、 Play レベルで指定します。
また、各パラーメーターの実際の値は、別途変数定義ファイルで定義済みのものとします。
--- - hosts: apic gather_facts: no connection: local environment: # 環境変数による接続先や認証情報の指定 ACI_HOST: "{{ ansible_host }}" ACI_USERNAME: "{{ username }}" ACI_PASSWORD: "{{ password }}" ACI_VALIDATE_CERTS: false tasks: - name: create tenant cisco.aci.aci_tenant: tenant: test_tenant01 state: present - name: create ap cisco.aci.aci_ap: tenant: test_tenant01 ap: test_ap01 state: present - name: create epg cisco.aci.aci_epg: tenant: test_tenant01 ap: test_ap01 epg: test_epg01 state: present
(比較用)タスクごとに指定した場合
比較のために、普通にタスクごとに接続先や認証情報を指定した場合の Playbook も掲載します。
このように、基本的には各タスクに host や username などの接続先や認証情報の指定が必要です。
--- - hosts: apic gather_facts: no connection: local tasks: - name: create tenant cisco.aci.aci_tenant: host: "{{ ansible_host }}" # タスクごとに指定する場合 username: "{{ username }}" # タスクごとに指定する場合 password: "{{ password }}" # タスクごとに指定する場合 validate_certs: no # タスクごとに指定する場合 tenant: test_tenant01 state: present - name: create ap cisco.aci.aci_ap: host: "{{ ansible_host }}" # タスクごとに指定する場合 username: "{{ username }}" # タスクごとに指定する場合 password: "{{ password }}" # タスクごとに指定する場合 validate_certs: no # タスクごとに指定する場合 tenant: test_tenant01 ap: test_ap01 state: present - name: create epg cisco.aci.aci_epg: host: "{{ ansible_host }}" # タスクごとに指定する場合 username: "{{ username }}" # タスクごとに指定する場合 password: "{{ password }}" # タスクごとに指定する場合 validate_certs: no # タスクごとに指定する場合 tenant: test_tenant01 ap: test_ap01 epg: test_epg01 state: present
この場合、少し Playbook が長くなってしまいます。
実行結果
Play 単位の環境変数で接続先や認証情報を指定した Playbook を実行します。
$ ansible-playbook -i inventory.ini aci_test.yml PLAY [apic] ****************************************************************************************************** TASK [create tenant] ********************************************************************************************* changed: [apic01] TASK [create ap] ************************************************************************************************* changed: [apic01] TASK [create epg] ************************************************************************************************ changed: [apic01] PLAY RECAP ******************************************************************************************************* apic01 : ok=3 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 $
無事に接続、認証も成功し、処理が正常に完了しました。

まとめ
Play 単位の環境変数で、接続先や認証情報を指定することで、各タスクがスッキリする Playbook をご紹介しました。
タスクごとに接続先や認証情報を指定することを避けたい場合は、この方法を検討してみてはいかがでしょうか。