てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] The invalid attribute in Playbook causes error by default in Ansible 2.7

(日本語版はこちら)

Sample playbook

- hosts: localhost
  gather_facts: no

  tasks:
    - name: invalid attribute test
      debug:
        msg: test
      xxxxx: yyyy   # invalid attribute 

In Ansible version >= 2.6: WARNING

$ ansible-playbook -i localhost, attr.yml
 [WARNING]: Ignoring invalid attribute: xxxxxxxxxx


PLAY [localhost] ***********************************************************

TASK [invalid attribute test] **********************************************
ok: [localhost] => {
    "msg": "test"
}

PLAY RECAP *****************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0

Processing of the playbook continues.

In Ansible version <= 2.7: ERROR

$ ansible-playbook -i localhost, attr.yml
ERROR! 'xxxxxxxxxx' is not a valid attribute for a Task

The error appears to have been in '/vagrant/a27/attr.yml': line 5, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
    - name: invalid attribute test
      ^ here

This error can be suppressed as a warning using the "invalid_task_attribute_failed" configuration

Playbook processing is not executed.

You can change this behavior with the setting item INVALID_TASK_ATTRIBUTE_FAILED which determines the handling of invalid task attributes added in Ansible 2.7.

  • True: A task will result in errors (default)
  • False: A task will result in warnings

If you would like to change to False, set follows.

  • in ansible.cfg
[defaults]
invalid_task_attribute_failed=False

or

  • in environment variable
export ANSIBLE_INVALID_TASK_ATTRIBUTE_FAILED=False

【Ansible】ホストに到達不能だった状態を無視する ignore_unreachable について(Ansible 2.7 新機能)

■ はじめに

Ansible 2.7 で、ターゲットホストに到達不能の状態を無視する ignore_unreachable キーワードが追加されました。

changelog

New keyword ignore_unreachable for plays and blocks. Allows ignoring tasks that fail due to unreachable hosts, and check results with is unreachable test.

言葉では少し説明しにくいので、試した結果を紹介します。


■ 構成

以下のように、 Ansibleから到達できるホストとできないホストを想定して試します。

ホスト OS Ansible からの到達性
testsv1 linux ○:可
testsv99 linux ×:不可


■ 基本 Playbook

2つのタスクがあり、1つめの yum モジュールでは、あえて存在しないパッケージ名を指定して エラーが発生するようにしてます。

- hosts: linux
  gather_facts: no

  tasks:
    - name: yum error
      yum:
        name: invalid_package_xxx # エラー

    - name: debug
      debug:
        msg: "Hello debug."

この Playook を基本として、ignore_unreachable を指定を変えて試してみます。


ignore_unreachable: no(デフォルト)の場合

  • Playbook
- hosts: linux
  gather_facts: no

  tasks:
    - name: yum error
      yum:
        name: invalid_package_xxx # エラー
      ignore_unreachable: no   # デフォルト

    - name: debug
      debug:
        msg: "Hello debug."
  • 実行結果
$ ansible-playbook -i inventory iu_linux.yml

PLAY [linux] ********************************************************************

TASK [yum error] ****************************************************************
fatal: [testsv1]: FAILED! => {"ansible_facts": {"pkg_mgr": "yum"}, "changed": false, "msg": "No package matching 'invalid_package_xxx' found available, installedor updated", "rc": 126, "results": ["No package matching 'invalid_package_xxx' found available, installed or updated"]}
fatal: [testsv99]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.16.0.11 port 22: No route to host\r\n", "unreachable": true}
        to retry, use: --limit @/vagrant/a27/iu_linux.retry

PLAY RECAP **********************************************************************
testsv1                    : ok=0    changed=0    unreachable=0    failed=1
testsv99                   : ok=0    changed=0    unreachable=1    failed=0

testsv1 では、1つめの yum モジュールのタスクでエラーが発生したためしたが、処理が中断されます。 一方、testsv99 では、1つめのタスクの時点で unreachable なので、処理が中断されます。 これがデフォルトの動作です。 このように、2つめのタスクが実行されなかった点では testsv1 も teest99 も同じですが、理由が異なります。


ignore_unreachable: yes の場合

次に、ignore_unreachable: yes に変更した Playbook を用意します、 - Playbook

- hosts: linux
  gather_facts: no

  tasks:
    - name: yum error
      yum:
        name: invalid_package_xxx # エラー
      ignore_unreachable: yes   # point

    - name: debug
      debug:
        msg: "Hello debug."
  • 実行結果
$ ansible-playbook -i inventory iu_linux.yml

PLAY [linux] ********************************************************************

TASK [yum error] ****************************************************************
fatal: [testsv99]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.16.0.11 port 22: No route to host\r\n", "skip_reason": "Host testsv99 is unreachable", "unreachable": true}
fatal: [testsv1]: FAILED! => {"ansible_facts": {"pkg_mgr": "yum"}, "changed": false, "msg": "No package matching 'invalid_package_xxx' found available, installedor updated", "rc": 126, "results": ["No package matching 'invalid_package_xxx' found available, installed or updated"]}

TASK [debug] ********************************************************************
ok: [testsv99] => {
    "msg": "Hello debug."
}
        to retry, use: --limit @/vagrant/a27/iu_linux.retry

PLAY RECAP **********************************************************************
testsv1                    : ok=0    changed=0    unreachable=0    failed=1
testsv99                   : ok=1    changed=0    unreachable=1    failed=0

先ほどと異なる点は、2つめの dubug モジュールのタスクが実行されるかどうかです。

testsv1 では、1つめの yum モジュールのタスクでエラーが発生したためしたが、処理が中断されます。 一方、testsv99 では、1つめのタスクの時点で unreachable です。ただし、ignore_unreachable: yes が指定されているので、2つめの debug モジュールのタスクが実行されました。


■ おまけ ignore_errors: yes の場合

比較をするため、Ansible 2.6 までにもあった、似たようなオプション ignore_errors: yes でも試します。

  • Playbook
- hosts: linux
  gather_facts: no

  tasks:
    - name: yum error
      yum:
        name: invalid_package_xxx # エラー
      ignore_errors: yes          # point

    - name: debug
      debug:
        msg: "Hello debug."
  • 実行結果
$ ansible-playbook -i inventory iu_linux.yml

PLAY [linux] ********************************************************************

TASK [yum error] ****************************************************************
fatal: [testsv1]: FAILED! => {"ansible_facts": {"pkg_mgr": "yum"}, "changed": false, "msg": "No package matching 'invalid_package_xxx' found available, installedor updated", "rc": 126, "results": ["No package matching 'invalid_package_xxx' found available, installed or updated"]}
...ignoring
fatal: [testsv99]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: ssh: connect to host 172.16.0.11 port 22: No route to host\r\n", "unreachable": true}

TASK [debug] ********************************************************************
ok: [testsv1] => {
    "msg": "Hello debug."
}
        to retry, use: --limit @/vagrant/a27/iu_linux.retry

PLAY RECAP **********************************************************************
testsv1                    : ok=2    changed=0    unreachable=0    failed=0
testsv99                   : ok=0    changed=0    unreachable=1    failed=0

testsv1 では、1つめの yum モジュールのタスクでエラーが発生しましたが、 ignore_error: yes のため、無視して2つめの debug モジュールのタスクが実行されました。 一方、testsv99 では、1つめのタスクの時点で unreachable なので、その時点で処理が終わっています。


■ 補足

ignore_unreachable を指定できる箇所

公式ドキュメントの Playbook Keywords によると、Play、Role、Block、Task のいずれにも指定できるようです。

例えば、Play に指定する場合はこのようになります。

- hosts: linux
  gather_facts: no
  ignore_unreachable: yes

  tasks:
  ...(略)...

利用できるコネクションプラグイン

試した限り、network_clinetconf といったネットワークモジュール向けのコネクションプラグインでは、ignore_unreachable の指定が効かなかっです。


■ さいごに

ignore_unreachableignore_errors についてまとめると以下のようになります。

ignore_unreachable ignore_errors 到達不能の場合 到達可能だが、モジュール実行エラーの場合
no (デフォルト) no (デフォルト) 中断 中断
yes no (デフォルト) 無視して継続 中断
yes yes 無視して継続 無視して継続
no (デフォルト) yes 中断 無視して継続

ignore_unreachable: yes を指定する必要がるケースは限定的かもしれませんが、何かのときに思い出していただければ幸いです。

【Ansible】Ansible 2.7 からデフォルトで無効なタスク属性があるとエラーになる

(English version)

はじめに

以下の例のように、Playbook 内に無効な属性が指定されいる場合のデフォルトの挙動が Ansible 2.7 で変更されました。

- hosts: localhost
  gather_facts: no

  tasks:
    - name: invalid attribute test
      debug:
        msg: test
      xxxxx: yyyy   # invalid attribute 

Ansible 2.6 までは WARNING で処理継続

2.6 までは、以下のような WARNING メッセージが表示されました。 Playbook 自体の処理は継続されます。

$ ansible-playbook -i localhost, attr.yml
 [WARNING]: Ignoring invalid attribute: xxxxxxxxxx


PLAY [localhost] ***********************************************************

TASK [invalid attribute test] **********************************************
ok: [localhost] => {
    "msg": "test"
}

PLAY RECAP *****************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0

Ansible 2.7 では ERROR で実行不可に

2.7 では、デフォルトで以下のような ERROR メッセージが表示され、Playbook が実行されません。

$ ansible-playbook -i localhost, attr.yml
ERROR! 'xxxxxxxxxx' is not a valid attribute for a Task

The error appears to have been in '/vagrant/a27/attr.yml': line 5, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
    - name: invalid attribute test
      ^ here

This error can be suppressed as a warning using the "invalid_task_attribute_failed" configuration

この動作は、Ansible 2.7 で追加された、無効なタスク属性の扱いを決める INVALID_TASK_ATTRIBUTE_FAILE という設定項目で変更できます。

  • True: ERROR として扱い、Playbookを実行しない(デフォルト)
  • False: WARNING として扱い、Playbookの実行を継続する

設定の変更は以下のようにできます。

  • ansible.cfg で False にする場合
[defaults]
invalid_task_attribute_failed=False
export ANSIBLE_INVALID_TASK_ATTRIBUTE_FAILED=False

【Ansible】Ansible 2.7 リリース、Mikrotik RouterOS などに対応。マルチベンダー対応コマンドモジュールの登場など、ネットワーク対応も強化

■ 1. はじめに

2018/10/04 に Ansible 2.7 がリリースされました。 pip install ansible2.7.0.0 がインストールされます。

ネットワーク対応についても対応のプラットフォームやオプションの追加などが行われました。 この記事では、ネットワークモジュール関連のアップーデートの中で、個人的に気になるトピックをまとめます。

(全体的なアップデートについてはあとで公式ブログでまとめられるかもしれません)


■ 2. 対応プラットフォームの追加

新たに以下のプラットフォーム対応が追加されました。

network_cli コネクションプラグインのみサポート

Extreme NOS、Extreme VOSS、MikroTik RouterOS 対応モジュールについては、local コネクションプラグインをサポートせず、network_cli コネクションプラグインのみをサポートしています。 そのため、ディレクティブで指定する場合は connetcion: network_cli、変数で指定する場合は ansible_connection: network_cli のように指定する必要があります。プラットフォームとコネクションプラグインの対応表は、公式ドキュメントの Settings by Platform を参照してください。

現状、例えば ios_* モジュールでは localnetwork_cli コネクションプラグインに対応しています。あくまで予想ですが、これらの既存のネットワークモジュールいついても、コードの保守性向上のため、将来 local コネクションプラグインをサポートしなくなるかもしれません。


■ 3. モジュールの追加

Ansible 2.7 で追加されたモジュールのうち、Network modules に分類されるモジュールは以下の通りです。


■ 4. マルチベンダー対応のコマンド実行モジュールの追加

「モジュールの追加」にもあげましたが、cli_command / cli_config モジュールが追加されました。これらのモジュールは特定のベンダー固有のモジュールではなく、マルチベンダーに対応しています。 例えば、 Cisco IOS でも Juniper Junos でも使えます。簡単な利用例をご紹介します。

グループ変数定義ファイルサンプル(group_vars/junos.yml)

ansible_network_os: junos
ansible_connection: network_cli    # network_cli のみサポート
ansible_user: junosuser
ansible_ssh_pass: p@ss99

cli_command モジュール利用 Playbook サンプル

- hosts: junos
  gather_facts: no

  tasks:
    - name: command test
      cli_command:
        command: show version
      register: result

    - name: debug 
      debug:
        msg: "{{ result }}"

cli_config モジュール利用 Playbook サンプル

- hosts: junos
  gather_facts: no

  tasks:
    - name: config test
      cli_config:
        config: set system ntp server 10.0.0.123

利用するうえでのポイント

コマンドの指定はリストではなく文字列

プラットフォーム固有モジュールの ios_commandcommands オプションや、ios_configlines オプションには、コマンドをリストとして指定します。 一方、cli_commandcli_config モジュールには文字列で指定します。オプション名の commandconfig も単数形になっています。そのため、複数のコマンドを指定する場合は、lookup プラグインで別途ファイルを読み込むなどの工夫が必要です。詳細は各公式ドキュメントの Examples を参照してください。

network_cli コネクションプラグインのみサポート

両モジュールとも network_cli コネクションプラグインのみサポートしています。 netconf コネクションプラグインはサポートしていません。 そのため、Junos に設定コマンドを投入する場合、以下の使い分けを意識する必要があります。

  • junoc_config を利用する場合は、netconf コネクションプラグイン
  • cli_config を利用する場合は、network_cli コネクションプラグイン


■ 5. httpapi コネクションプラグインで証明書の検証有無を指定可能に

httpapi コネクションプラグインは、HTTP API 機能がある Cisco NX-OS や、Arista EOS のネットワーク機器に対して、HTTP API で接続するコネクションプラグインです。 今回 Ansible 2.7 で、SSL/TLS 接続する際にの明書の検証有無を指定する validate_certs パラメーターが追加されました。デフォルトは yes です。つまり、このコネクションプラグイン自体が導入された Ansible 2.6 のときと同じく、検証する仕様です。 なお、変数で指定する場合は、ansible_httpapi_validate_certs 変数を利用します。

  • SSL/TLS 接続する際に、証明書の検証をしない変数指定例
ansible_httpapi_use_ssl: yes        # SSL/TSL 接続を有効にする場合は yes(デフォルト no )
ansible_httpapi_validate_certs: no  # 証明書を検証しない場合は no(デフォルト yes )


■ 6. ios_user モジュールでユーザーの公開鍵を指定できるように

ios_user モジュールCisco IOS のネットワーク機器上のユーザーを管理するモジュールです。 今までは、管理対象のユーザーの認証情報としてパスワードのみ(configured_password オプション)の対応でした。今回、Ansible 2.7 で sshkey オプションを利用して公開鍵を指定できるようになりました。

- name: create a new user
  ios_user:
    name: ansible
    nopassword: True
    sshkey: "{{ lookup('file', '~/.ssh/id_rsa.pub') }}"   # 公開鍵の指定
    state: present


■ まとめ

Ansible 2.7 におけるネットワークモジュールのトピックをご紹介しました。

引き続き、対応王プラットフォームが増え続けている点と、cli_command / cli_config のようなマルチプラットフォーム対応のコマンド実行モジュールが出てきた点が印象的でした。

【Ansible】Ansible 2.7 で追加されたネットワークモジュールのリスト(rc4)

Ansible 2.7 で追加されたネットワークモジュールのリスト(rc4版)です。

※以下のコマンドで生成しました。

ansible-doc -j | jq -r '.module[] | select(.namespace | test("network")) | select((.version_added==2.7) or (.version_added=="2.7")) | "- [" + .name + " - " + .description
+ "](https://docs.ansible.com/ansible/devel/modules/" + .name +"_module.html)"'

【Ansible】 Playbook Debugger を特定のタスクだけ起動する方法

Playbook Debugger

Ansible には、Playbook 実行時に変数値の確認や、オプション値の変更ができる Playbook Debugger という機能があります。

デバッガーの起動条件

Ansible 2.5 以降では、debugger キーワードで、デバッガーの起動条件を指定できます。 たとえば、debugger: always と指定すると、常にデバッガーを起動します。

- hosts: junos
  gather_facts: no
  debugger: always    # point

  tasks:
    - name: task1
      debug:
        msg: "msg of task1"

    - name: task2
      debug:
        msg: "msg of task2"

    - name: task3
      debug:
        msg: "msg of task3"

この場合、最初のタスクからデバッガーが起動します。

特定のタスクだけ起動した場合はタスクに debugger を指定

それでは、途中のタスクからデバッガーを起動したい場合はどのようにすればよいでしょうか。 実は(?)、公式ドキュメントにも記載がありますが、debugger キーワードは、タスクごとにも指定できます。そのため、以下のように、task2 に debugger: always を指定すると、task2 だけデバッガーが起動します。

- hosts: junos
  gather_facts: no

  tasks:
    - name: task1
      debug:
        msg: "msg of task1"

    - name: task2
      debug:
        msg: "msg of task2"
      debugger: always         # point

    - name: task3
      debug:
        msg: "msg of task3"
  • 実行例
$ ansible-playbook -i inventory  test_debugger.yml

PLAY [junos] ***************************************************************

TASK [task1] ***************************************************************
ok: [vsrx1] => {
    "msg": "msg of task1"   # 通常どおり実行
}

TASK [task2] ***************************************************************
ok: [vsrx1] => {
    "msg": "msg of task2"   # ↓ デバッガーが起動
}
[vsrx1] TASK: task2 (debug)> task.args['msg']='Hello, task2.'  # msg オプションの変更
[vsrx1] TASK: task2 (debug)> redo  # task2 再実行
ok: [vsrx1] => {
    "msg": "Hello, task2."     # 変更した msg オプションの表示になった
}
[vsrx1] TASK: task2 (debug)> c  # 処理を継続

TASK [task3] ***************************************************************
ok: [vsrx1] => {
    "msg": "msg of task3"     # 通常どおり実行(以降、デバッガーは起動しない)
}

PLAY RECAP *****************************************************************
vsrx1                      : ok=3    changed=0    unreachable=0    failed=0

エンジニアだけど広報LT大会(#PRLT)でLTしてきました

f:id:akira6592:20180907102103j:plain

■ はじめに

2018/08/28 に開催された「 【祝2周年】他職種×PRの可能性を考える広報LT大会#15@ユニオンテック 」に参加とLTをしてきました。

普段は広報担当の方自身がLTされることが多いようですが、今回は「他職種×PR」ということで、ご縁があってエンジニアの私のLTの機会をいただきました。 広報LT大会への参加も登壇もはじめてだったので簡単にレポートいたします。


■ 広報LT大会(PRLT)とは?

広報担当者のアウトプットを目的としたライトニングトーク大会です。 エンジニア業界の勉強会、イベントで通じてノウハウをシェアする文化にヒントを得て立ち上げたそうです。

2周年おめでとうございます!

参考


■ 他の方の発表

登壇者には私の他にもエンジニアがいらっしゃったり、デザイナーの方もいらっしゃいました。 様々な視点があって興味深かったです。

  • 資料一覧(一部です)

prlt.connpass.com

  • togetter

togetter.com


■ 私の発表

社外イベントへ関連で自社の広報を一緒に仕事したときに、してもらってうれしかったことを発表しました。 お伝えしたかったのは

  • 情報発信するエンジニアの広報はめちゃくちゃ相性が良い

という点です。 広報として当たり前に思っている外へアウトプットする際の考え方などが、新鮮で役に立つことだったりします。 業種は違えどお互いの「良い当たり前」の共有によって、無理なく良い感じになれたら良いなぁと思いました。

www.slideshare.net


■ 普段参加しているイベントとの違い

技術系の勉強会やイベントにはよく参加しているのですが「ここはこんな感じなんですね!?」と感じたことをまとめます。

  • LT中にBGMが流れる
    • BGMが止まってしまうと「流れてないとさびしいですよね」と再開
  • 運営側にカメラマンがいる
    • MANABIYA や Developers Summit のような大規模イベントなら分かるのですが、そうでもないにカメラ担当の方がいらっしゃったのは驚きました
  • 写真を撮る人が多い
    • カメラマンの他にも登壇者の写真を撮るれる方が多かった気がします
  • 集合写真のときに指定のポーズがある
    • 両手 で L と T をつくります
  • 公式リアクションがある
    • LT中いいね思ったら「よっ!」、むむむ思ったら「むっ!」とリアクションしてください、と。「よっ!」と言われると嬉しいものです
  • ピザじゃない
    • 技術系のイベントの懇親会はピザが多い気がしますが、ピザじゃなかったです


■ まとめ

正直、アウェイ感があったので、参加するのも LT するもの勇気が必要だったのですが、いつもと違う話ができてよかったです。 今後も技術以外のイベントにも参加してみようと思いました。