てくなべ (tekunabe)

ansible / network automation / 学習メモ

GitLab の WebIDE が開かないときの対処(external_url の修正)

はじめに

GitLab には、Web ブラウザ上でファイルの修正などができる WebIDE という機能があります。

先日、WebIDE を開くためのボタンを押してもガワだけ表示されて、中身が表示されないような現象で出くわしました。

この記事では、現象と対処を簡単にまとめます。

(セルフホスト版が前提です)

現象

こんな感じです。正常であれば、左側にファイル一覧が表示されます。

f:id:akira6592:20200628125618p:plain
ローディング中のような画面のまま

原因

Developer tool を開いたら、GitLab サーバーと異なる IPアドレスリポジトリの内容を取得しようとしてる様子が見えました。

f:id:akira6592:20200628125802p:plain
それらしい内容を別の IP アドレスにリクエス

ここで思い出したのですが、このサーバーは GitLab インストールの IP アドレスから変更されてたのでした。 そのため、/etc/gitlab/gitlab.rbexternal_url が GitLab インストール時の IP アドレスのままで、その IPアドレスにアクセスしようとしてる様子でした。

リポジトリ画面で、Clone 時のURLを表示するときに external_url のアドレスが利用されるのと同じ事情のようです。

f:id:akira6592:20200628125855p:plain
こうなる事情と同じ

対処

EIP をつけないままの場合の暫定対処ですが、external_url を現在の IP アドレスに修正することにしました。

/etc/gitlab/gitlab.rb

external_url 'http://y.y.y.151'

設定を反映するために reconfigure します。

$ sudo gitlab-ctl reconfigure

[Ansible] 通常時は実行せず、タグが指定されたときのみタスクを実行する

はじめに

Playbook には タグ機能があり、ansible-playbook コマンドから特定のタグを持ったタスクのみ実行できます。

タグの中には、いくつか特別なものがあります。

never タグをつけたタスクは、通常時は無視されます。他のタグをあわせて付けると、そのタグが指定されると実行されます。

この性質を利用すると「普段は実行したくないが、特定のタグをしていたときのみ実行する」といったこごができます。

この記事では簡単なサンプルをご紹介します。

  • 動作確認環境
    • Ansible 2.9.10

これの詳細です。

サンプル Playbook

---
- hosts: localhost
  gather_facts: false


  tasks:
    - name: special task 
      debug:
        msg: special task
      tags:
        - never    # このタグにより通常時はこのタスクは実行されない
        - special

    - name:
      debug:
        msg: normal task

タグ指定なしで実行

ansible-playbook コマンドで特にタグの指定をせずに実行する場合です。

$ ansible-playbook -i localhost, tagtest.yml 

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

TASK [normal task] *****************************************************************************
ok: [localhost] => {
    "msg": "normal task"
}

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

never タグが付いた special task が実行されなかったことが分かります。

タグ指定で実行

今度は -t special でタグを指定して実行します。

$ ansible-playbook -i localhost, tagtest.yml -t special

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

TASK [special task] **********************************************************************
ok: [localhost] => {
    "msg": "special task"
}

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

special タグがついたタスクが実行されました。

normarl taskspecial タグが指定されていないため実行されませんでした。

おわりに

never のような特別なタグの挙動が知られていない可能性もありますので、コメントで説明を書きておくと親切だと思います。

参考

[2021/03/24 追記]

zaki-hmkc.hatenablog.com

[Ansible] 「つまずき Ansible 【Part8】Collection を使う」ふりかえり

はじめに

2020/06/27 に、YouTube Live で「つまずき Ansible 【Part8】Collection を使う」という配信をしました。 実際に作業しながらエラーと戦って進めるシリーズです。

tekunabe.connpass.com

今回は、Collectionのインストールと、Collection のモジュールを利用した Plaubook の実行をためしました。 つまずいたエラーと原因、対処をふりかえります。

ただし今回は Collection とは直接関係ないものであり、かつ明確な原因もわかりませんでした。

動画

youtu.be


■ その前に: Collection とは? (一部 Part7 と重複)

Collection とは

  • モジュール、プラグイン、ロールなどを含む新しい配布形式
  • Ansible 本体とは別に開発が進められる
  • コミュニティとしては Ansible Galaxy 経由で配布される
  • Ansible 2.10 では、今まで標準で含まれていた多くのモジュールが Collection に移行
    • pip install ansible-base では、標準の68個のモジュールのみ
    • pip install ansible では、上記に加え、今までのモジュールが Collection 経由で一緒にインストール

名前空間

参考情報


やったこと

pip install ansible-base==2.10.0b0 でインストール済み

準備

  • cisco.ios をインストール
    • ansible-galaxy collection install コレクション名
  • どこにインストールされた?
    • ~/.ansible/collections/
      • 設定 COLLECTIONS_PATHS のデフォルト
  • インストールされた一覧の確認方法
    • ansible-galaxy collection list (Ansible 2.10)
  • いっぺんにいろいろインストールする
    • requirements.yml を利用
  • ansilbe-doc で確認

Playbook

cisco.ios.ios_acls を利用した ACL の設定 Playbook。

一応、FQCN で指定。

---
  - hosts: rt01
    gather_facts: false
  
    tasks:
      - name: set acl
        cisco.ios.ios_acls:
          config:
            - afi: ipv4
              acls:
                - name: test_acl
                  acl_type: extended
                  aces:
                    - grant: permit
                      sequence: 10
                      protocol: tcp
                      protocol_options:
                        tcp:
                          ack: true
                      source:
                        address: 10.0.0.0
                        wildcard_bits: 0.0.0.255
                      destination:
                        address: 172.16.1.0
                        wildcard_bits: 0.0.0.255
                        port_protocol:
                          eq: www
                    - grant: deny
                      sequence: 90
                      protocol: ip
                      source:
                        any: true
                      destination:
                        any: true
          state: merged
        register: res
  
      - name: debug
        debug:
          msg: "{{ res }}"


■ debug でのエラー

ios_acls モジュール実行結果の変数を debug モジュールで表示時に connection 系のエラー

debug タスクで、以下のエラー。

fatal: [rt01]: FAILED! => {"msg": "Traceback (most recent call last):\n File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 202, in send\n response = recv_data(sf)\n File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 76, in recv_data\n d = s.recv(header_len - len(data))\nConnectionResetError: [Errno 104] Connection reset by peer\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n File \"/home/vagrant/envs/a210/bin/ansible-connection\", line 342, in \n main()\n File \"/home/vagrant/envs/a210/bin/ansible-connection\", line 305, in main\n conn.set_options(var_options=variables)\n File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 186, in rpc\n response = self.exec_jsonrpc(name, *args, **kwargs)\n File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 152, in exec_jsonrpc\n out = self.send(data)\n File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 209, in send\n err=to_text(e, errors='surrogate_then_replace'), exception=traceback.format_exc()\nansible.module_utils.connection.ConnectionError: unable to connect to socket /home/vagrant/.ansible/pc/e0f315e513. See the socket path issue category in Network Debug and Troubleshooting Guide\n"}

原因

不明。 PCが重く、処理に時間がかかっていたが、debug モジュールはネットワーク機器に接続しにいかないはずなので、ConnectionResetError になるのは解せず。

対処

(なすすべ無し・・。再度実行したら正常となった。)


おまけ

閲覧したサイト

全実行ログ

クリックして開く(長いです)

(a210) [vagrant@stumble stumble]$ ansible-galaxy collection instal cisco.ios
usage: ansible-galaxy collection [-h] COLLECTION_ACTION ...
ansible-galaxy collection: error: argument COLLECTION_ACTION: invalid choice: 'instal' (choose from 'download', 'init', 'build', 'publish', 'install', 'list', 'verify')
 
usage: ansible-galaxy [-h] [--version] [-v] TYPE ...

Perform various Role and Collection related operations.

positional arguments:
  TYPE
    collection   Manage an Ansible Galaxy collection.
    role         Manage an Ansible Galaxy role.

optional arguments:
  --version      show program's version number, config file location,
                 configured module search path, module location, executable
                 location and exit
  -h, --help     show this help message and exit
  -v, --verbose  verbose mode (-vvv for more, -vvvv to enable connection
                 debugging)
 (a210) [vagrant@stumble stumble]$ ansible-galaxy collection install cisco.ios
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'cisco.ios:1.0.0' to '/home/vagrant/.ansible/collections/ansible_collections/cisco/ios'
Installing 'ansible.netcommon:1.0.0' to '/home/vagrant/.ansible/collections/ansible_collections/ansible/netcommon'
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ ansible-doc cisco.ios
^C [ERROR]: User interrupted execution
(a210) [vagrant@stumble stumble]$ ansible-doc ios_config
> IOS_CONFIG    (/home/vagrant/.ansible/collections/ansible_collections/cisco/ios/plugins/modules/ios_config.py)

        Cisco IOS configurations use a simple block indent file syntax for segmenting configuration into sections.  This module provides an implementation
        for working with IOS configuration sections in a deterministic way.

OPTIONS (= is mandatory):

- after
        The ordered set of commands to append to the end of the command stack if a change needs to be made.  Just like with `before' this allows the
        playbook designer to append a set of commands to be executed after the command set.
        [Default: (null)]

- backup
        This argument will cause the module to create a full backup of the current `running-config' from the remote device before any changes are made. If
        the `backup_options' value is not given, the backup file is written to the `backup' folder in the playbook root directory or role root directory,
        if playbook is part of an ansible role. If the directory does not exist, it is created.
        [Default: False]
        type: bool

- backup_options
        This is a dict object containing configurable options related to backup file path. The value of this option is read only when `backup' is set to
        `yes', if `backup' is set to `no' this option will be silently ignored.
        [Default: (null)]
        type: dict

(a210) [vagrant@stumble stumble]$ ansible-doc ios_acls
> IOS_ACLS    (/home/vagrant/.ansible/collections/ansible_collections/cisco/ios/plugins/modules/ios_acls.py)

        This module configures and manages the named or numbered ACLs on IOS platforms.

OPTIONS (= is mandatory):

- config
        A dictionary of ACL options.
        [Default: (null)]
        elements: dict
        type: list

        SUBOPTIONS:

        - acls
            A list of Access Control Lists (ACL).
            [Default: (null)]
            elements: dict
            type: list

            SUBOPTIONS:

            - aces
                The entries within the ACL.
                [Default: (null)]
                elements: dict
                type: list

                SUBOPTIONS:

                - destination
                    Specify the packet destination.
                    [Default: (null)]
                    type: dict

                    SUBOPTIONS:

                    - address
                        Host address to match, or any single host address.
                        [Default: (null)]
                        type: str

                    - any
                        Match any source address.
                        [Default: (null)]
                        type: bool

                    - host
                        A single destination host
                        [Default: (null)]
                        type: str

                    - port_protocol
                        Specify the destination port along with protocol.
                        Note, Valid with TCP/UDP protocol_options
                        [Default: (null)]
                        type: dict

                        SUBOPTIONS:

                        - eq
                            Match only packets on a given port number.
                            [Default: (null)]
                            type: str

                        - gt
                            Match only packets with a greater port number.
                            [Default: (null)]
                            type: str

                        - lt
                            Match only packets with a lower port number.
                            [Default: (null)]
                            type: str

                        - neq
                            Match only packets not on a given port number.
                            [Default: (null)]
                            type: str

                        - range
                            Port group.
                            [Default: (null)]
                            type: dict

                            SUBOPTIONS:

                            - end
                                Specify the end of the port range.
                                [Default: (null)]
                                type: int

                            - start
                                Specify the start of the port range.
                                [Default: (null)]
                                type: int

                    - wildcard_bits
                        Destination wildcard bits, valid with IPV4 address.
                        [Default: (null)]
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ deactivate 
[vagrant@stumble stumble]$ 
[vagrant@stumble stumble]$ 
(reverse-i-search)`sou': ^Curce ~/envs/a210/bin/activate
[vagrant@stumble stumble]$ 
[vagrant@stumble stumble]$ 
[vagrant@stumble stumble]$ python -m venv ~/a29
/usr/bin/python: No module named venv
[vagrant@stumble stumble]$ python3 -m venv ~/a29
[vagrant@stumble stumble]$ source ~/a29/bin/activate
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ pip install ansible
Collecting ansible
  Downloading https://files.pythonhosted.org/packages/03/4f/cccab1ec2e0ecb05120184088e00404b38854809cf35aa76889406fbcbad/ansible-2.9.10.tar.gz (14.2MB)
    100% |████████████████████████████████| 14.2MB 101kB/s 
Collecting jinja2 (from ansible)
  Using cached https://files.pythonhosted.org/packages/30/9e/f663a2aa66a09d838042ae1a2c5659828bb9b41ea3a6efa20a20fd92b121/Jinja2-2.11.2-py2.py3-none-any.whl
Collecting PyYAML (from ansible)
  Using cached https://files.pythonhosted.org/packages/64/c2/b80047c7ac2478f9501676c988a5411ed5572f35d1beff9cae07d321512c/PyYAML-5.3.1.tar.gz
Collecting cryptography (from ansible)
  Using cached https://files.pythonhosted.org/packages/58/95/f1282ca55649b60afcf617e1e2ca384a2a3e7a5cf91f724cf83c8fbe76a1/cryptography-2.9.2-cp35-abi3-manylinux1_x86_64.whl
Collecting MarkupSafe>=0.23 (from jinja2->ansible)
  Using cached https://files.pythonhosted.org/packages/b2/5f/23e0023be6bb885d00ffbefad2942bc51a620328ee910f64abe5a8d18dd1/MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl
Collecting six>=1.4.1 (from cryptography->ansible)
  Using cached https://files.pythonhosted.org/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.whl
Collecting cffi!=1.11.3,>=1.8 (from cryptography->ansible)
  Using cached https://files.pythonhosted.org/packages/f1/c7/72abda280893609e1ddfff90f8064568bd8bcb2c1770a9d5bb5edb2d1fea/cffi-1.14.0-cp36-cp36m-manylinux1_x86_64.whl
Collecting pycparser (from cffi!=1.11.3,>=1.8->cryptography->ansible)
  Using cached https://files.pythonhosted.org/packages/ae/e7/d9c3a176ca4b02024debf82342dab36efadfc5776f9c8db077e8f6e71821/pycparser-2.20-py2.py3-none-any.whl
Installing collected packages: MarkupSafe, jinja2, PyYAML, six, pycparser, cffi, cryptography, ansible
  Running setup.py install for PyYAML ... done
  Running setup.py install for ansible ... done
Successfully installed MarkupSafe-1.1.1 PyYAML-5.3.1 ansible-2.9.10 cffi-1.14.0 cryptography-2.9.2 jinja2-2.11.2 pycparser-2.20 six-1.15.0
You are using pip version 9.0.3, however version 20.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(a29) [vagrant@stumble stumble]$ pip install paramiko
Collecting paramiko
  Using cached https://files.pythonhosted.org/packages/06/1e/1e08baaaf6c3d3df1459fd85f0e7d2d6aa916f33958f151ee1ecc9800971/paramiko-2.7.1-py2.py3-none-any.whl
Collecting bcrypt>=3.1.3 (from paramiko)
  Using cached https://files.pythonhosted.org/packages/8b/1d/82826443777dd4a624e38a08957b975e75df859b381ae302cfd7a30783ed/bcrypt-3.1.7-cp34-abi3-manylinux1_x86_64.whl
Requirement already satisfied: cryptography>=2.5 in /home/vagrant/a29/lib/python3.6/site-packages (from paramiko)
Collecting pynacl>=1.0.1 (from paramiko)
  Using cached https://files.pythonhosted.org/packages/9d/57/2f5e6226a674b2bcb6db531e8b383079b678df5b10cdaa610d6cf20d77ba/PyNaCl-1.4.0-cp35-abi3-manylinux1_x86_64.whl
Requirement already satisfied: cffi>=1.1 in /home/vagrant/a29/lib/python3.6/site-packages (from bcrypt>=3.1.3->paramiko)
Requirement already satisfied: six>=1.4.1 in /home/vagrant/a29/lib/python3.6/site-packages (from bcrypt>=3.1.3->paramiko)
Requirement already satisfied: pycparser in /home/vagrant/a29/lib/python3.6/site-packages (from cffi>=1.1->bcrypt>=3.1.3->paramiko)
Installing collected packages: bcrypt, pynacl, paramiko
Successfully installed bcrypt-3.1.7 paramiko-2.7.1 pynacl-1.4.0
You are using pip version 9.0.3, however version 20.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ ansible-doc ios_config
> IOS_CONFIG    (/home/vagrant/a29/lib64/python3.6/site-packages/ansible/modules/network/ios/ios_config.py)

        Cisco IOS configurations use a simple block indent file syntax for segmenting configuration into sections.  This module provides an implementation
        for working with IOS configuration sections in a deterministic way.

  * This module is maintained by The Ansible Network Team
OPTIONS (= is mandatory):

- after
        The ordered set of commands to append to the end of the command stack if a change needs to be made.  Just like with `before' this allows the
        playbook designer to append a set of commands to be executed after the command set.
        [Default: (null)]

- auth_pass
        *Deprecated*
        Starting with Ansible 2.5 we recommend using `connection: network_cli' and `become: yes' with `become_pass'.
        For more information please see the L(IOS Platform Options guide, ../network/user_guide/platform_ios.html).
        HORIZONTALLINE
        Specifies the password to use if required to enter privileged mode on the remote device.  If `authorize' is false, then this argument does
        nothing. If the value is not specified in the task, the value of environment variable `ANSIBLE_NET_AUTH_PASS' will be used instead.
        [Default: (null)]
        type: str

- authorize
        *Deprecated*
(a29) [vagrant@stumble stumble]$ ansible-doc ios_acls
[WARNING]: module ios_acls not found in: /home/vagrant/.ansible/plugins/modules:/usr/share/ansible/plugins/modules:/home/vagrant/a29/lib64/python3.6/site-packages/ansible/modules
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ 
(a29) [vagrant@stumble stumble]$ ansible-playbook -i 
ansible.cfg     eos_set.yml     export/         inventory.ini   ios_set.yml     junos_set.yml   memo/           
collections/    eos_show.yml    group_vars/     ios_acls.yml    ios_show.yml    junos_show.yml  server.yml      
(a29) [vagrant@stumble stumble]$ ansible-playbook -i 
ansible.cfg     eos_set.yml     export/         inventory.ini   ios_set.yml     junos_set.yml   memo/           
collections/    eos_show.yml    group_vars/     ios_acls.yml    ios_show.yml    junos_show.yml  server.yml      
(a29) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_acls.yml 

PLAY [rt01] *************************************************************************************************************************************************************************************

TASK [merge acl] ********************************************************************************************************************************************************************************
changed: [rt01]

TASK [gather acl] *******************************************************************************************************************************************************************************
ok: [rt01]

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

(a29) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_acls
ERROR! the playbook: ios_acls could not be found
(a29) [vagrant@stumble stumble]$ ^C
(a29) [vagrant@stumble stumble]$ ansible-doc ios_acls
[WARNING]: module ios_acls not found in: /home/vagrant/.ansible/plugins/modules:/usr/share/ansible/plugins/modules:/home/vagrant/a29/lib64/python3.6/site-packages/ansible/modules
(reverse-i-search)`': ^C
(a29) [vagrant@stumble stumble]$ deactivate 
[vagrant@stumble stumble]$ 
[vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ ansible --version
ansible 2.10.0b1
  config file = /vagrant/stumble/ansible.cfg
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible
  executable location = /home/vagrant/envs/a210/bin/ansible
  python version = 3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
(a210) [vagrant@stumble stumble]$ ansible-doc -l | wc -l
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ ansible-galaxy collections list
usage: ansible-galaxy role [-h] ROLE_ACTION ...
ansible-galaxy role: error: argument ROLE_ACTION: invalid choice: 'collections' (choose from 'init', 'remove', 'delete', 'list', 'search', 'import', 'setup', 'login', 'info', 'install')
 
usage: ansible-galaxy [-h] [--version] [-v] TYPE ...

Perform various Role and Collection related operations.

positional arguments:
  TYPE
    collection   Manage an Ansible Galaxy collection.
    role         Manage an Ansible Galaxy role.

optional arguments:
  --version      show program's version number, config file location,
                 configured module search path, module location, executable
                 location and exit
  -h, --help     show this help message and exit
  -v, --verbose  verbose mode (-vvv for more, -vvvv to enable connection
                 debugging)
 (a210) [vagrant@stumble stumble]$ ansible-galaxy colleciton list
usage: ansible-galaxy role [-h] ROLE_ACTION ...
ansible-galaxy role: error: argument ROLE_ACTION: invalid choice: 'colleciton' (choose from 'init', 'remove', 'delete', 'list', 'search', 'import', 'setup', 'login', 'info', 'install')
 
usage: ansible-galaxy [-h] [--version] [-v] TYPE ...

Perform various Role and Collection related operations.

positional arguments:
  TYPE
    collection   Manage an Ansible Galaxy collection.
    role         Manage an Ansible Galaxy role.

optional arguments:
  --version      show program's version number, config file location,
                 configured module search path, module location, executable
                 location and exit
  -h, --help     show this help message and exit
  -v, --verbose  verbose mode (-vvv for more, -vvvv to enable connection
                 debugging)
 (a210) [vagrant@stumble stumble]$ ansible-galaxy collection list

# /home/vagrant/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
ansible.netcommon 1.0.0  
cisco.ios         1.0.0  
(a210) [vagrant@stumble stumble]$ vi requirements.yml
(a210) [vagrant@stumble stumble]$ ansible-galaxy collection -r requirements.yml 
usage: ansible-galaxy collection [-h] COLLECTION_ACTION ...
ansible-galaxy collection: error: argument COLLECTION_ACTION: invalid choice: 'requirements.yml' (choose from 'download', 'init', 'build', 'publish', 'install', 'list', 'verify')
 
usage: ansible-galaxy [-h] [--version] [-v] TYPE ...

Perform various Role and Collection related operations.

positional arguments:
  TYPE
    collection   Manage an Ansible Galaxy collection.
    role         Manage an Ansible Galaxy role.
(a210) [vagrant@stumble stumble]$ ansible-galaxy collection list

# /home/vagrant/.ansible/collections/ansible_collections
Collection            Version
--------------------- -------
ansible.netcommon     1.0.0  
arista.eos            1.0.0  
cisco.ios             1.0.0  
junipernetworks.junos 1.0.0  
(a210) [vagrant@stumble stumble]$ ansible-doc ios_acls
> IOS_ACLS    (/home/vagrant/.ansible/collections/ansible_collections/cisco/ios/plugins/modules/ios_acls.py)

        This module configures and manages the named or numbered ACLs on IOS
        platforms.

OPTIONS (= is mandatory):

- config
        A dictionary of ACL options.
        [Default: (null)]
        elements: dict
        type: list

        SUBOPTIONS:

        - acls
            A list of Access Control Lists (ACL).
            [Default: (null)]
            elements: dict
            type: list

            SUBOPTIONS:

            - aces
                The entries within the ACL.
                [Default: (null)]
                elements: dict
                type: list

                SUBOPTIONS:

                - destination
                    Specify the packet destination.
                    [Default: (null)]
                    type: dict

                    SUBOPTIONS:

                    - address
                        Host address to match, or any single host address.
                        [Default: (null)]
                        type: str

                    - any
                        Match any source address.
                        [Default: (null)]
                        type: bool

                    - host
                        A single destination host
                        [Default: (null)]
                        type: str

                    - port_protocol
                        Specify the destination port along with protocol.
                        Note, Valid with TCP/UDP protocol_options
                        [Default: (null)]
                        type: dict

                        SUBOPTIONS:

                        - eq
                            Match only packets on a given port number.
                            [Default: (null)]
                            type: str

                        - gt
                            Match only packets with a greater port number.
                            [Default: (null)]
                            type: str

                        - lt
                            Match only packets with a lower port number.
                            [Default: (null)]
                            type: str

                        - neq
                            Match only packets not on a given port number.
                            [Default: (null)]
                            type: str

                        - range
                            Port group.
                            [Default: (null)]
                            type: dict

                            SUBOPTIONS:

                            - end
                                Specify the end of the port range.
                                [Default: (null)]
                                type: int

                            - start
                                Specify the start of the port range.
                                [Default: (null)]
                                type: int

                    - wildcard_bits
                        Destination wildcard bits, valid with IPV4 address.
                        [Default: (null)]
                        type: str

                - dscp
                    Match packets with given dscp value.
                    [Default: (null)]
                    type: str

                - fragments
                    Check non-initial fragments.
                    [Default: (null)]
                    type: str

                - grant
                    Specify the action.
                    (Choices: permit, deny)[Default: (null)]
                    type: str

                - log
                    Log matches against this entry.
                    [Default: (null)]
                    type: str

                - log_input
                    Log matches against this entry, including input interface.
                    [Default: (null)]
                    type: str

                - option
                    Match packets with given IP Options value.
                    Valid only for named acls.
                    [Default: (null)]
                    type: dict

                    SUBOPTIONS:

                    - add_ext
                        Match packets with Address Extension Option (147).
                        [Default: (null)]
                        type: bool

                    - any_options
                        Match packets with ANY Option.
                        [Default: (null)]
                        type: bool

                    - com_security
                        Match packets with Commercial Security Option (134).
                        [Default: (null)]
                        type: bool

                    - dps
                        Match packets with Dynamic Packet State Option (151).
                        [Default: (null)]
                        type: bool

                    - encode
                        Match packets with Encode Option (15).
                        [Default: (null)]
                        type: bool

                    - eool
                        Match packets with End of Options (0).
                        [Default: (null)]
                        type: bool

                    - ext_ip
                        Match packets with Extended IP Option (145).
                        [Default: (null)]
                        type: bool

                    - ext_security
                        Match packets with Extended Security Option (133).
                        [Default: (null)]
                        type: bool

                    - finn
                        Match packets with Experimental Flow Control Option
                        (205).
                        [Default: (null)]
                        type: bool

                    - imitd
                        Match packets with IMI Traffic Desriptor Option (144).
                        [Default: (null)]
                        type: bool

                    - lsr
                        Match packets with Loose Source Route Option (131).
                        [Default: (null)]
                        type: bool

                    - mtup
                        Match packets with MTU Probe Option (11).
                        [Default: (null)]
                        type: bool

                    - mtur
                        Match packets with MTU Reply Option (12).
                        [Default: (null)]
                        type: bool

                    - no_op
                        Match packets with No Operation Option (1).
                        [Default: (null)]
                        type: bool

                    - nsapa
                        Match packets with NSAP Addresses Option (150).
                        [Default: (null)]
                        type: bool

                    - record_route
                        Match packets with Record Route Option (7).
                        [Default: (null)]
                        type: bool

                    - router_alert
                        Match packets with Router Alert Option (148).
                        [Default: (null)]
                        type: bool

                    - sdb
                        Match packets with Selective Directed Broadcast Option
                        (149).
                        [Default: (null)]
                        type: bool

                    - security
                        Match packets with Basic Security Option (130).
                        [Default: (null)]
                        type: bool

                    - ssr
                        Match packets with Strict Source Routing Option (137).
                        [Default: (null)]
                        type: bool

                    - stream_id
                        Match packets with Stream ID Option (136).
                        [Default: (null)]
                        type: bool

                    - timestamp
                        Match packets with Time Stamp Option (68).
                        [Default: (null)]
                        type: bool

                    - traceroute
                        Match packets with Trace Route Option (82).
                        [Default: (null)]
                        type: bool

                    - ump
                        Match packets with Upstream Multicast Packet Option
                        (152).
                        [Default: (null)]
                        type: bool

                    - visa
                        Match packets with Experimental Access Control Option
                        (142).
                        [Default: (null)]
                        type: bool

                    - zsu
                        Match packets with Experimental Measurement Option (10).
                        [Default: (null)]
                        type: bool

                - precedence
                    Match packets with given precedence value.
                    [Default: (null)]
                    type: int

                - protocol
                    Specify the protocol to match.
                    Refer to vendor documentation for valid values.
                    [Default: (null)]
                    type: str

                - protocol_options
                    protocol type.
                    [Default: (null)]
                    type: dict

                    SUBOPTIONS:

                    - ahp
                        Authentication Header Protocol.
                        [Default: (null)]
                        type: bool

                    - eigrp
                        Cisco's EIGRP routing protocol.
                        [Default: (null)]
                        type: bool

                    - esp
                        Encapsulation Security Payload.
                        [Default: (null)]
                        type: bool

                    - gre
                        Cisco's GRE tunneling.
                        [Default: (null)]
                        type: bool

                    - hbh
                        Hop by Hop options header. Valid for IPV6
                        [Default: (null)]
                        type: bool

                    - icmp
                        Internet Control Message Protocol.
                        [Default: (null)]
                        type: dict

                        SUBOPTIONS:

                        - administratively_prohibited
                            Administratively prohibited
                            [Default: (null)]
                            type: bool

                        - alternate_address
                            Alternate address
                            [Default: (null)]
                            type: bool

                        - conversion_error
                            Datagram conversion
                            [Default: (null)]
                            type: bool

                        - dod_host_prohibited
                            Host prohibited
                            [Default: (null)]
                            type: bool

                        - dod_net_prohibited
                            Net prohibited
                            [Default: (null)]
                            type: bool

                        - echo
                            Echo (ping)
                            [Default: (null)]
                            type: bool

                        - echo_reply
                            Echo reply
                            [Default: (null)]
                            type: bool

                        - general_parameter_problem
                            Parameter problem
                            [Default: (null)]
                            type: bool

                        - host_isolated
                            Host isolated
                            [Default: (null)]
                            type: bool

                        - host_precedence_unreachable
                            Host unreachable for precedence
                            [Default: (null)]
                            type: bool

                        - host_redirect
                            Host redirect
                            [Default: (null)]
                            type: bool

                        - host_tos_redirect
                            Host redirect for TOS
                            [Default: (null)]
                            type: bool

                        - host_tos_unreachable
                            Host unreachable for TOS
                            [Default: (null)]
                            type: bool

                        - host_unknown
                            Host unknown
                            [Default: (null)]
                            type: bool

                        - host_unreachable
                            Host unreachable
                            [Default: (null)]
                            type: bool

                        - information_reply
                            Information replies
                            [Default: (null)]
                            type: bool

                        - information_request
                            Information requests
                            [Default: (null)]
                            type: bool

                        - mask_reply
                            Mask replies
                            [Default: (null)]
                            type: bool

                        - mask_request
                            mask_request
                            [Default: (null)]
                            type: bool

                        - mobile_redirect
                            Mobile host redirect
                            [Default: (null)]
                            type: bool

                        - net_redirect
                            Network redirect
                            [Default: (null)]
                            type: bool

                        - net_tos_redirect
                            Net redirect for TOS
                            [Default: (null)]
                            type: bool

                        - net_tos_unreachable
                            Network unreachable for TOS
                            [Default: (null)]
                            type: bool

                        - net_unreachable
                            Net unreachable
                            [Default: (null)]
                            type: bool

                        - network_unknown
                            Network unknown
                            [Default: (null)]
                            type: bool

                        - no_room_for_option
                            Parameter required but no room
                            [Default: (null)]
                            type: bool

                        - option_missing
                            Parameter required but not present
                            [Default: (null)]
                            type: bool

                        - packet_too_big
                            Fragmentation needed and DF set
                            [Default: (null)]
                            type: bool

                        - parameter_problem
                            All parameter problems
                            [Default: (null)]
                            type: bool

                        - port_unreachable
                            Port unreachable
                            [Default: (null)]
                            type: bool

                        - precedence_unreachable
                            Precedence cutoff
                            [Default: (null)]
                            type: bool

                        - protocol_unreachable
                            Protocol unreachable
                            [Default: (null)]
                            type: bool

                        - reassembly_timeout
                            Reassembly timeout
                            [Default: (null)]
                            type: bool

                        - redirect
                            All redirects
                            [Default: (null)]
                            type: bool

                        - router_advertisement
                            Router discovery advertisements
                            [Default: (null)]
                            type: bool

                        - router_solicitation
                            Router discovery solicitations
                            [Default: (null)]
                            type: bool

                        - source_quench
                            Source quenches
                            [Default: (null)]
                            type: bool

                        - source_route_failed
                            Source route failed
                            [Default: (null)]
                            type: bool

                        - time_exceeded
                            All time exceededs
                            [Default: (null)]
                            type: bool

                        - timestamp_reply
                            Timestamp replies
                            [Default: (null)]
                            type: bool

                        - timestamp_request
                            Timestamp requests
                            [Default: (null)]
                            type: bool

                        - traceroute
                            Traceroute
                            [Default: (null)]
                            type: bool

                        - ttl_exceeded
                            TTL exceeded
                            [Default: (null)]
                            type: bool

                        - unreachable
                            All unreachables
                            [Default: (null)]
                            type: bool

                    - igmp
                        Internet Gateway Message Protocol.
                        [Default: (null)]
                        type: dict

                        SUBOPTIONS:

                        - dvmrp
                            Distance Vector Multicast Routing Protocol(2)
                            [Default: (null)]
                            type: bool

                        - host_query
                            IGMP Membership Query(0)
                            [Default: (null)]
                            type: bool

                        - mtrace_resp
                            Multicast Traceroute Response(7)
                            [Default: (null)]
                            type: bool

                        - mtrace_route
                            Multicast Traceroute(8)
                            [Default: (null)]
                            type: bool

                        - pim
                            Protocol Independent Multicast(3)
                            [Default: (null)]
                            type: bool

                        - trace
                            Multicast trace(4)
                            [Default: (null)]
                            type: bool

                        - v1host_report
                            IGMPv1 Membership Report(1)
                            [Default: (null)]
                            type: bool

                        - v2host_report
                            IGMPv2 Membership Report(5)
                            [Default: (null)]
                            type: bool

                        - v2leave_group
                            IGMPv2 Leave Group(6)
                            [Default: (null)]
                            type: bool

                        - v3host_report
                            IGMPv3 Membership Report(9)
                            [Default: (null)]
                            type: bool

                    - ip
                        Any Internet Protocol.
                        [Default: (null)]
                        type: bool

                    - ipinip
                        IP in IP tunneling.
                        [Default: (null)]
                        type: bool

                    - ipv6
                        Any IPv6.
                        [Default: (null)]
                        type: bool

                    - nos
                        KA9Q NOS compatible IP over IP tunneling.
                        [Default: (null)]
                        type: bool

                    - ospf
                        OSPF routing protocol.
                        [Default: (null)]
                        type: bool

                    - pcp
                        Payload Compression Protocol.
                        [Default: (null)]
                        type: bool

                    - pim
                        Protocol Independent Multicast.
                        [Default: (null)]
                        type: bool

                    - protocol_number
                        An IP protocol number
                        [Default: (null)]
                        type: int

                    - sctp
                        Stream Control Transmission Protocol.
                        [Default: (null)]
                        type: bool

                    - tcp
                        Match TCP packet flags
                        [Default: (null)]
                        type: dict

                        SUBOPTIONS:

                        - ack
                            Match on the ACK bit
                            [Default: (null)]
                            type: bool

                        - established
                            Match established connections
                            [Default: (null)]
                            type: bool

                        - fin
                            Match on the FIN bit
                            [Default: (null)]
                            type: bool

                        - psh
                            Match on the PSH bit
                            [Default: (null)]
                            type: bool

                        - rst
                            Match on the RST bit
                            [Default: (null)]
                            type: bool

                        - syn
                            Match on the SYN bit
                            [Default: (null)]
                            type: bool

                        - urg
                            Match on the URG bit
                            [Default: (null)]
                            type: bool

                    - udp
                        User Datagram Protocol.
                        [Default: (null)]
                        type: bool

                - sequence
                    Sequence Number for the Access Control Entry(ACE).
                    Refer to vendor documentation for valid values.
                    [Default: (null)]
                    type: int

                - source
                    Specify the packet source.
                    [Default: (null)]
                    type: dict

                    SUBOPTIONS:

                    - address
                        Source network address.
                        [Default: (null)]
                        type: str

                    - any
                        Match any source address.
                        [Default: (null)]
                        type: bool

                    - host
                        A single source host
                        [Default: (null)]
                        type: str

                    - port_protocol
                        Specify the destination port along with protocol.
                        Note, Valid with TCP/UDP protocol_options
                        [Default: (null)]
                        type: dict

                        SUBOPTIONS:

                        - eq
                            Match only packets on a given port number.
                            [Default: (null)]
                            type: str

                        - gt
                            Match only packets with a greater port number.
                            [Default: (null)]
                            type: str

                        - lt
                            Match only packets with a lower port number.
                            [Default: (null)]
                            type: str

                        - neq
                            Match only packets not on a given port number.
                            [Default: (null)]
                            type: str

                        - range
                            Port group.
                            [Default: (null)]
                            type: dict

                            SUBOPTIONS:

                            - end
                                Specify the end of the port range.
                                [Default: (null)]
                                type: int

                            - start
                                Specify the start of the port range.
                                [Default: (null)]
                                type: int

                    - wildcard_bits
                        Destination wildcard bits, valid with IPV4 address.
                        [Default: (null)]
                        type: str

                - time_range
                    Specify a time-range.
                    [Default: (null)]
                    type: str

                - tos
                    Match packets with given TOS value.
                    Note, DSCP and TOS are mutually exclusive
                    [Default: (null)]
                    type: dict

                    SUBOPTIONS:

                    - max_reliability
                        Match packets with max reliable TOS (2).
                        [Default: (null)]
                        type: bool

                    - max_throughput
                        Match packets with max throughput TOS (4).
                        [Default: (null)]
                        type: bool

                    - min_delay
                        Match packets with min delay TOS (8).
                        [Default: (null)]
                        type: bool

                    - min_monetary_cost
                        Match packets with min monetary cost TOS (1).
                        [Default: (null)]
                        type: bool

                    - normal
                        Match packets with normal TOS (0).
                        [Default: (null)]
                        type: bool

                    - service_value
                        Type of service value
                        [Default: (null)]
                        type: int

                - ttl
                    Match packets with given TTL value.
                    [Default: (null)]
                    type: dict

                    SUBOPTIONS:

                    - eq
                        Match only packets on a given TTL number.
                        [Default: (null)]
                        type: int

                    - gt
                        Match only packets with a greater TTL number.
                        [Default: (null)]
                        type: int

                    - lt
                        Match only packets with a lower TTL number.
                        [Default: (null)]
                        type: int

                    - neq
                        Match only packets not on a given TTL number.
                        [Default: (null)]
                        type: int

                    - range
                        Match only packets in the range of TTLs.
                        [Default: (null)]
                        type: dict

                        SUBOPTIONS:

                        - end
                            Specify the end of the port range.
                            [Default: (null)]
                            type: int

                        - start
                            Specify the start of the port range.
                            [Default: (null)]
                            type: int

            - acl_type
                ACL type
                Note, it's mandatory and required for Named ACL, but for
                Numbered ACL it's not mandatory.
                (Choices: extended, standard)[Default: (null)]
                type: str

            = name
                The name or the number of the ACL.

                type: str

        = afi
            The Address Family Indicator (AFI) for the Access Control Lists
            (ACL).
            (Choices: ipv4, ipv6)
            type: str

- running_config
        The module, by default, will connect to the remote device and retrieve
        the current running-config to use as a base for comparing against the
        contents of source. There are times when it is not desirable to have the
        task get the current running-config for every task in a playbook.  The
        `running_config' argument allows the implementer to pass in the
        configuration to use as the base config for comparison.
        [Default: (null)]
        type: str

- state
        The state the configuration should be left in
        The states `rendered', `gathered' and `parsed' does not perform any
        change on the device.
        The state `rendered' will transform the configuration in `config' option
        to platform specific CLI commands which will be returned in the
        `rendered' key within the result. For state `rendered' active connection
        to remote host is not required.
        The state `gathered' will fetch the running configuration from device
        and transform it into structured data in the format as per the resource
        module argspec and the value is returned in the `gathered' key within
        the result.
        The state `parsed' reads the configuration from `running_config' option
        and transforms it into JSON format as per the resource module parameters
        and the value is returned in the `parsed' key within the result. The
        value of `running_config' option should be the same format as the output
        of command `show running-config | include ip route|ipv6 route' executed
        on device. For state `parsed' active connection to remote host is not
        required.
        (Choices: merged, replaced, overridden, deleted, gathered, rendered,
        parsed)[Default: merged]
        type: str


NOTES:
      * Tested against Cisco IOSv Version 15.2 on VIRL


AUTHOR: Sumit Jaiswal (@justjais)

VERSION_ADDED_COLLECTION: cisco.ios

EXAMPLES:

# Using merged

# Before state:
# -------------
#
# vios#sh access-lists
# Extended IP access list 110
#    10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 echo dscp ef ttl eq 10

- name: Merge provided configuration with device configuration
  cisco.ios.ios_acls:
    config:
    - afi: ipv4
      acls:
      - name: std_acl
        acl_type: standard
        aces:
        - grant: deny
          source:
            address: 192.168.1.200
        - grant: deny
          source:
            address: 192.168.2.0
            wildcard_bits: 0.0.0.255
      - name: 110
        aces:
        - sequence: 10
          protocol_options:
            icmp:
              traceroute: true
        - grant: deny
          protocol_options:
            tcp:
              ack: true
          source:
            host: 198.51.100.0
          destination:
            host: 198.51.110.0
            port_protocol:
              eq: telnet
      - name: test
        acl_type: extended
        aces:
        - grant: deny
          protocol_options:
            tcp:
              fin: true
          source:
            address: 192.0.2.0
            wildcard_bits: 0.0.0.255
          destination:
            address: 192.0.3.0
            wildcard_bits: 0.0.0.255
            port_protocol:
              eq: www
          option:
            traceroute: true
          ttl:
            eq: 10
      - name: 123
        aces:
        - grant: deny
          protocol_options:
            tcp:
              ack: true
          source:
            address: 198.51.100.0
            wildcard_bits: 0.0.0.255
          destination:
            address: 198.51.101.0
            wildcard_bits: 0.0.0.255
            port_protocol:
              eq: telnet
          tos:
            service_value: 12
        - grant: deny
          protocol_options:
            tcp:
              ack: true
          source:
            address: 192.0.3.0
            wildcard_bits: 0.0.0.255
          destination:
            address: 192.0.4.0
            wildcard_bits: 0.0.0.255
            port_protocol:
              eq: www
          dscp: ef
          ttl:
            lt: 20
    - afi: ipv6
      acls:
      - name: R1_TRAFFIC
        aces:
        - grant: deny
          protocol_options:
            tcp:
              ack: true
          source:
            any: true
            port_protocol:
              eq: www
          destination:
            any: true
            port_protocol:
              eq: telnet
          dscp: af11
    state: merged

# Commands fired:
# ---------------
#
# - ip access-list standard std_acl
# - deny 192.168.1.200
# - deny 192.168.2.0 0.0.0.255
# - ip access-list extended 110
# - no 10
# - 10 deny icmp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 traceroute dscp ef ttl eq 10
# - deny tcp host 198.51.100.0 host 198.51.110.0 eq telnet ack
# - ip access-list extended test
# - deny tcp 192.0.2.0 0.0.0.255 192.0.3.0 0.0.0.255 eq www fin option traceroute ttl eq 10
# - ip access-list extended 123
# - deny tcp 198.51.100.0 0.0.0.255 198.51.101.0 0.0.0.255 eq telnet ack tos 12
# - deny tcp 192.0.3.0 0.0.0.255 192.0.4.0 0.0.0.255 eq www ack dscp ef ttl lt 20
# - ipv6 access-list R1_TRAFFIC
# - deny tcp any eq www any eq telnet ack dscp af11

# After state:
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_acls.yml 

PLAY [rt01] ********************************************************************

TASK [set acl] *****************************************************************
fatal: [rt01]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "value of state must be one of: merged, replaced, overridden, deleted, gathered, rendered, parsed, got: merge"}

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

(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_acls.yml 

PLAY [rt01] ********************************************************************

TASK [set acl] *****************************************************************
changed: [rt01]

TASK [debug] *******************************************************************
fatal: [rt01]: FAILED! => {"msg": "Traceback (most recent call last):\n  File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 202, in send\n    response = recv_data(sf)\n  File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 76, in recv_data\n    d = s.recv(header_len - len(data))\nConnectionResetError: [Errno 104] Connection reset by peer\n\nDuring handling of the above exception, another exception occurred:\n\nTraceback (most recent call last):\n  File \"/home/vagrant/envs/a210/bin/ansible-connection\", line 342, in <module>\n    main()\n  File \"/home/vagrant/envs/a210/bin/ansible-connection\", line 305, in main\n    conn.set_options(var_options=variables)\n  File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 186, in __rpc__\n    response = self._exec_jsonrpc(name, *args, **kwargs)\n  File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 152, in _exec_jsonrpc\n    out = self.send(data)\n  File \"/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/module_utils/connection.py\", line 209, in send\n    err=to_text(e, errors='surrogate_then_replace'), exception=traceback.format_exc()\nansible.module_utils.connection.ConnectionError: unable to connect to socket /home/vagrant/.ansible/pc/e0f315e513. See the socket path issue category in Network Debug and Troubleshooting Guide\n"}

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

(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_acls.yml 

PLAY [rt01] ******************************************************************************

TASK [set acl] ***************************************************************************
ok: [rt01]

TASK [debug] *****************************************************************************
ok: [rt01] => {
    "msg": {
        "ansible_facts": {
            "discovered_interpreter_python": "/usr/bin/python"
        },
        "before": [
            {
                "acls": [
                    {
                        "aces": [
                            {
                                "destination": {
                                    "address": "172.16.1.0",
                                    "port_protocol": {
                                        "eq": "www"
                                    },
                                    "wildcard_bits": "0.0.0.255"
                                },
                                "grant": "permit",
                                "protocol": "tcp",
                                "protocol_options": {
                                    "tcp": {
                                        "ack": true
                                    }
                                },
                                "sequence": 10,
                                "source": {
                                    "address": "10.0.0.0",
                                    "wildcard_bits": "0.0.0.255"
                                }
                            },
                            {
                                "destination": {
                                    "any": true
                                },
                                "grant": "deny",
                                "protocol": "ip",
                                "protocol_options": {
                                    "ip": true
                                },
                                "sequence": 90,
                                "source": {
                                    "any": true
                                }
                            }
                        ],
                        "acl_type": "extended",
                        "name": "test_acl"
                    }
                ],
                "afi": "ipv4"
            }
        ],
        "changed": false,
        "commands": [],
        "failed": false
    }
}

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

Part9 にむけて

企画中です。ちょっと気分転換に Ansible Tower や AWX も良いかもしれません。

[Ansible] 「つまずき Ansible 【Part7】Ansible 2.10.0b1 でずっこける」ふりかえり

はじめに

2020/06/21 に、YouTube Live で「つまずき Ansible 【Part7】Ansible 2.10.0b1 でずっこける」という配信をしました。 実際に作業しながらエラーと戦って進めるシリーズです。

tekunabe.connpass.com

今回は、前日リリースされた Ansible 2.10.0b1 をインストールして、既存の Playbook が動くかどうか試しました。

※ 現時点で私が分かっている範囲での情報です。特に Collection に関しては Ansible Collections Overviewをウォッチされることをお勧めします。

つまずいたエラーと原因、対処をふりかえります。

動画

www.youtube.com


■ その前に: Ansible 2.10 とは?

次の Ansible のリリースバージョン

多くのモジュールが Collection へ移行

Collection とは

[2020/06/22 追記] pip install ansible==2.10.0a1 でインストールしたら、ansible 2.10.0b1 とともに、今までのモジュールたちが collection 経由でインストールされました。対象のコレクションのバージョンはこちらで定義されているようです。 正式リリース時は、単に pip install ansible で ansible 2.10.0 と今までのモジュールがインストールされるかもしれません。 今回配信の内容は、あくまでこの時点にこの手順でやったらこうなった、という程度に留めていただければと思います。


■ インストール

pip install ansible==2.10.0b0 でインストールできない

以下のエラー。

(a210) [vagrant@stumble ~]$ pip install ansible==2.10.0b1
Collecting ansible==2.10.0b1
  Could not find a version that satisfies the requirement ansible==2.10.0b1 (from versions: 1.0, 1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 1.3.0, 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.4, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.6, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.7, 1.7.1, 1.7.2, 1.8, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.9.0.1, 1.9.1, 1.9.2, 1.9.3, 1.9.4, 1.9.5, 1.9.6, 2.0.0.0, 2.0.0.1, 2.0.0.2, 2.0.1.0, 2.0.2.0, 2.1.0.0, 2.1.1.0, 2.1.2.0, 2.1.3.0, 2.1.4.0, 2.1.5.0, 2.1.6.0, 2.2.0.0, 2.2.1.0, 2.2.2.0, 2.2.3.0, 2.3.0.0, 2.3.1.0, 2.3.2.0, 2.3.3.0, 2.4.0.0, 2.4.1.0, 2.4.2.0, 2.4.3.0, 2.4.4.0, 2.4.5.0, 2.4.6.0, 2.5.0a1, 2.5.0b1, 2.5.0b2, 2.5.0rc1, 2.5.0rc2, 2.5.0rc3, 2.5.0, 2.5.1, 2.5.2, 2.5.3, 2.5.4, 2.5.5, 2.5.6, 2.5.7, 2.5.8, 2.5.9, 2.5.10, 2.5.11, 2.5.12, 2.5.13, 2.5.14, 2.5.15, 2.6.0a1, 2.6.0a2, 2.6.0rc1, 2.6.0rc2, 2.6.0rc3, 2.6.0rc4, 2.6.0rc5, 2.6.0, 2.6.1, 2.6.2, 2.6.3, 2.6.4, 2.6.5, 2.6.6, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.7.0.dev0, 2.7.0a1, 2.7.0b1, 2.7.0rc1, 2.7.0rc2, 2.7.0rc3, 2.7.0rc4, 2.7.0, 2.7.1, 2.7.2, 2.7.3, 2.7.4, 2.7.5, 2.7.6, 2.7.7, 2.7.8, 2.7.9, 2.7.10, 2.7.11, 2.7.12, 2.7.13, 2.7.14, 2.7.15, 2.7.16, 2.7.17, 2.7.18, 2.8.0a1, 2.8.0b1, 2.8.0rc1, 2.8.0rc2, 2.8.0rc3, 2.8.0, 2.8.1, 2.8.2, 2.8.3, 2.8.4, 2.8.5, 2.8.6, 2.8.7, 2.8.8, 2.8.9, 2.8.10, 2.8.11, 2.8.12, 2.9.0b1, 2.9.0rc1, 2.9.0rc2, 2.9.0rc3, 2.9.0rc4, 2.9.0rc5, 2.9.0, 2.9.1, 2.9.2, 2.9.3, 2.9.4, 2.9.5, 2.9.6, 2.9.7, 2.9.8, 2.9.9, 2.9.10, 2.10.0a1)
No matching distribution found for ansible==2.10.0b1
You are using pip version 9.0.3, however version 20.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.

原因

(少なくとも現状は)ansible ではなく ansible-base をパッケージ名で指定する必要がある。

対処

以下のコマンドで ansible-base をインストール。

(a210) [vagrant@stumble ~]$ pip install ansible-base==2.10.0b1
Collecting ansible-base==2.10.0b1
  Downloading https://files.pythonhosted.org/packages/14/40/8c71ee17f6568b831463fd0de02c8ff87227776bda688def4de4da30747e/ansible-base-2.10.0b1.tar.gz (5.7MB)
    100% |████████████████████████████████| 5.7MB 76kB/s 
...(略)...
(a210) [vagrant@stumble ~]$ ansible --version
ansible 2.10.0b1
  config file = None
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible
  executable location = /home/vagrant/envs/a210/bin/ansible
  python version = 3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]


ios_command モジュールの使用

ios_command が見つからないエラーが発生

以下のエラー。

(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_show.yml
ERROR! couldn't resolve module/action 'ios_command'. This often indicates a misspelling, missing collection, or incorrect module path.

The error appears to be in '/vagrant/stumble/ios_show.yml': line 7, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
    - name: show version
      ^ here                    : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

原因

ios_command モジュールは、標準では入らなくなり、cisco.ios collection に移行したため。

対処

cisco.ios collection をインストールする。

(a210) [vagrant@stumble stumble]$ ansible-galaxy collection install cisco.ios
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'cisco.ios:0.0.3' to '/home/vagrant/.ansible/collections/ansible_collections/cisco/ios'
Installing 'ansible.netcommon:0.0.3' to '/home/vagrant/.ansible/collections/ansible_collections/ansible/netcommon'

yaml コールバックプラグインがないエラーが発生

ansible-doc yaml -t plugin

でヘルプが表示されない。

原因

yaml コールバックプラグインは、標準では入らなくなり community.genal collection へ移行したため。

対処

community.genal collection をインストールする。

(a210) [vagrant@stumble stumble]$ ansible-galaxy collection install community.general
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'community.general:0.2.0' to '/home/vagrant/.ansible/collections/ansible_collections/community/general'
Installing 'google.cloud:0.0.9' to '/home/vagrant/.ansible/collections/ansible_collections/google/cloud'
Installing 'ansible.posix:0.1.3' to '/home/vagrant/.ansible/collections/ansible_collections/ansible/posix'
Skipping 'ansible.netcommon' as it is already installed
Installing 'community.kubernetes:0.11.0' to '/home/vagrant/.ansible/collections/ansible_collections/community/kubernetes'

インストールした collection 一覧の確認

(a210) [vagrant@stumble stumble]$ ansible-galaxy collection list

# /home/vagrant/.ansible/collections/ansible_collections
Collection           Version
-------------------- -------
ansible.netcommon    0.0.3  
ansible.posix        0.1.3  
cisco.ios            0.0.3  
community.general    0.2.0  
community.kubernetes 0.11.0 
google.cloud         0.0.9  


yum モジュールの使用

You need to be root to perform this command.というエラーが発生。(Ansiible 2.10 とは無関係)

以下のエラー。

TASK [yum] ******************************************************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  changes:
    installed:
    - httpd
  msg: |-
    You need to be root to perform this command.
  rc: 1
  results:
  - |-
    Loaded plugins: fastestmirror

原因

特権が必要なタスクに対して、become: true の指定がない。

対処

become: true を追加


おまけ

閲覧したサイト

全実行ログ

クリックして開く

bash: ansible: command not found
(a210) [vagrant@stumble ~]$ 
(a210) [vagrant@stumble ~]$ pip instal ansible==2.10.0b1
ERROR: unknown command "instal" - maybe you meant "install"
(a210) [vagrant@stumble ~]$ pip install ansible==2.10.0b1
Collecting ansible==2.10.0b1
  Could not find a version that satisfies the requirement ansible==2.10.0b1 (from versions: 1.0, 1.1, 1.2, 1.2.1, 1.2.2, 1.2.3, 1.3.0, 1.3.1, 1.3.2, 1.3.3, 1.3.4, 1.4, 1.4.1, 1.4.2, 1.4.3, 1.4.4, 1.4.5, 1.5, 1.5.1, 1.5.2, 1.5.3, 1.5.4, 1.5.5, 1.6, 1.6.1, 1.6.2, 1.6.3, 1.6.4, 1.6.5, 1.6.6, 1.6.7, 1.6.8, 1.6.9, 1.6.10, 1.7, 1.7.1, 1.7.2, 1.8, 1.8.1, 1.8.2, 1.8.3, 1.8.4, 1.9.0.1, 1.9.1, 1.9.2, 1.9.3, 1.9.4, 1.9.5, 1.9.6, 2.0.0.0, 2.0.0.1, 2.0.0.2, 2.0.1.0, 2.0.2.0, 2.1.0.0, 2.1.1.0, 2.1.2.0, 2.1.3.0, 2.1.4.0, 2.1.5.0, 2.1.6.0, 2.2.0.0, 2.2.1.0, 2.2.2.0, 2.2.3.0, 2.3.0.0, 2.3.1.0, 2.3.2.0, 2.3.3.0, 2.4.0.0, 2.4.1.0, 2.4.2.0, 2.4.3.0, 2.4.4.0, 2.4.5.0, 2.4.6.0, 2.5.0a1, 2.5.0b1, 2.5.0b2, 2.5.0rc1, 2.5.0rc2, 2.5.0rc3, 2.5.0, 2.5.1, 2.5.2, 2.5.3, 2.5.4, 2.5.5, 2.5.6, 2.5.7, 2.5.8, 2.5.9, 2.5.10, 2.5.11, 2.5.12, 2.5.13, 2.5.14, 2.5.15, 2.6.0a1, 2.6.0a2, 2.6.0rc1, 2.6.0rc2, 2.6.0rc3, 2.6.0rc4, 2.6.0rc5, 2.6.0, 2.6.1, 2.6.2, 2.6.3, 2.6.4, 2.6.5, 2.6.6, 2.6.7, 2.6.8, 2.6.9, 2.6.10, 2.6.11, 2.6.12, 2.6.13, 2.6.14, 2.6.15, 2.6.16, 2.6.17, 2.6.18, 2.6.19, 2.6.20, 2.7.0.dev0, 2.7.0a1, 2.7.0b1, 2.7.0rc1, 2.7.0rc2, 2.7.0rc3, 2.7.0rc4, 2.7.0, 2.7.1, 2.7.2, 2.7.3, 2.7.4, 2.7.5, 2.7.6, 2.7.7, 2.7.8, 2.7.9, 2.7.10, 2.7.11, 2.7.12, 2.7.13, 2.7.14, 2.7.15, 2.7.16, 2.7.17, 2.7.18, 2.8.0a1, 2.8.0b1, 2.8.0rc1, 2.8.0rc2, 2.8.0rc3, 2.8.0, 2.8.1, 2.8.2, 2.8.3, 2.8.4, 2.8.5, 2.8.6, 2.8.7, 2.8.8, 2.8.9, 2.8.10, 2.8.11, 2.8.12, 2.9.0b1, 2.9.0rc1, 2.9.0rc2, 2.9.0rc3, 2.9.0rc4, 2.9.0rc5, 2.9.0, 2.9.1, 2.9.2, 2.9.3, 2.9.4, 2.9.5, 2.9.6, 2.9.7, 2.9.8, 2.9.9, 2.9.10, 2.10.0a1)
No matching distribution found for ansible==2.10.0b1
You are using pip version 9.0.3, however version 20.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(a210) [vagrant@stumble ~]$ pip install ansible-base==2.10.0b1
Collecting ansible-base==2.10.0b1
  Downloading https://files.pythonhosted.org/packages/14/40/8c71ee17f6568b831463fd0de02c8ff87227776bda688def4de4da30747e/ansible-base-2.10.0b1.tar.gz (5.7MB)
    100% |████████████████████████████████| 5.7MB 76kB/s 
Collecting jinja2 (from ansible-base==2.10.0b1)
  Using cached https://files.pythonhosted.org/packages/30/9e/f663a2aa66a09d838042ae1a2c5659828bb9b41ea3a6efa20a20fd92b121/Jinja2-2.11.2-py2.py3-none-any.whl
Collecting PyYAML (from ansible-base==2.10.0b1)
  Using cached https://files.pythonhosted.org/packages/64/c2/b80047c7ac2478f9501676c988a5411ed5572f35d1beff9cae07d321512c/PyYAML-5.3.1.tar.gz
Collecting cryptography (from ansible-base==2.10.0b1)
  Using cached https://files.pythonhosted.org/packages/58/95/f1282ca55649b60afcf617e1e2ca384a2a3e7a5cf91f724cf83c8fbe76a1/cryptography-2.9.2-cp35-abi3-manylinux1_x86_64.whl
Collecting packaging (from ansible-base==2.10.0b1)
  Downloading https://files.pythonhosted.org/packages/46/19/c5ab91b1b05cfe63cccd5cfc971db9214c6dd6ced54e33c30d5af1d2bc43/packaging-20.4-py2.py3-none-any.whl
Collecting MarkupSafe>=0.23 (from jinja2->ansible-base==2.10.0b1)
  Using cached https://files.pythonhosted.org/packages/b2/5f/23e0023be6bb885d00ffbefad2942bc51a620328ee910f64abe5a8d18dd1/MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl
Collecting six>=1.4.1 (from cryptography->ansible-base==2.10.0b1)
  Using cached https://files.pythonhosted.org/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.whl
Collecting cffi!=1.11.3,>=1.8 (from cryptography->ansible-base==2.10.0b1)
(a210) [vagrant@stumble ~]$ ansible --version
ansible 2.10.0b1
  config file = None
  configured module search path = ['/home/vagrant/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible
  executable location = /home/vagrant/envs/a210/bin/ansible
  python version = 3.6.8 (default, Apr  2 2020, 13:34:55) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
(a210) [vagrant@stumble ~]$ ansible-doc junos_config
[WARNING]: module junos_config not found in:
/home/vagrant/.ansible/plugins/modules:/usr/share/ansible/plugins/modules:/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/modules
(a210) [vagrant@stumble ~]$ 
(a210) [vagrant@stumble ~]$ 
(a210) [vagrant@stumble ~]$ pwd
/home/vagrant
(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_show.yml ^C
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ rm -fr ~/.ansible/
pc/  tmp/ 
(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_show.yml
ERROR! couldn't resolve module/action 'ios_command'. This often indicates a misspelling, missing collection, or incorrect module path.

The error appears to be in '/vagrant/stumble/ios_show.yml': line 7, column 7, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

  tasks:
    - name: show version
      ^ here
(a210) [vagrant@stumble stumble]$ ansible-galaxy collection install cisco.ios
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'cisco.ios:0.0.3' to '/home/vagrant/.ansible/collections/ansible_collections/cisco/ios'
Installing 'ansible.netcommon:0.0.3' to '/home/vagrant/.ansible/collections/ansible_collections/ansible/netcommon'
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ ansible-doc ios_command
> IOS_COMMAND    (/home/vagrant/.ansible/collections/ansible_collections/cisco/ios/plugins/modules/ios_command.py)

        Sends arbitrary commands to an ios node and returns the results read from the device. This module includes an
        argument that will cause the module to wait for a specific condition before returning or timing out if the
        condition is not met. This module does not support running commands in configuration mode. Please use
        [ios_config] to configure IOS devices.

OPTIONS (= is mandatory):

= commands
        List of commands to send to the remote ios device over the configured provider. The resulting output from the
        command is returned. If the `wait_for' argument is provided, the module is not returned until the condition
        is satisfied or the number of retries has expired. If a command sent to the device requires answering a
        prompt, it is possible to pass a dict containing `command', `answer' and `prompt'. Common answers are 'y' or
        "\r" (carriage return, must be double quotes). See examples.


- interval
        Configures the interval in seconds to wait between retries of the command. If the command does not pass the
        specified conditions, the interval indicates how long to wait before trying the command again.
        [Default: 1]

- match
        The `match' argument is used in conjunction with the `wait_for' argument to specify the match policy.  Valid
        values are `all' or `any'.  If the value is set to `all' then all conditionals in the wait_for must be
        satisfied.  If the value is set to `any' then only one of the values must be satisfied.
        (Choices: any, all)[Default: all]

- provider
        *Deprecated*
        Starting with Ansible 2.5 we recommend using `connection: network_cli'.
        For more information please see the L(IOS Platform Options guide, ../network/user_guide/platform_ios.html).
        HORIZONTALLINE
        A dict object containing connection details.
        [Default: (null)]
        type: dict

        SUBOPTIONS:

        - auth_pass
            Specifies the password to use if required to enter privileged mode on the remote device.  If `authorize'
            is false, then this argument does nothing. If the value is not specified in the task, the value of
            environment variable `ANSIBLE_NET_AUTH_PASS' will be used instead.
            [Default: (null)]
            type: str

        - authorize
            Instructs the module to enter privileged mode on the remote device before sending any commands.  If not
            specified, the device will attempt to execute all commands in non-privileged mode. If the value is not
            specified in the task, the value of environment variable `ANSIBLE_NET_AUTHORIZE' will be used instead.
            [Default: False]
            type: bool

        = host
            Specifies the DNS host name or address for connecting to the remote device over the specified transport.
            The value of host is used as the destination address for the transport.

            type: str

        - password
(a210) [vagrant@stumble stumble]$ ansible-doc debug
> DEBUG    (/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/modules/debug.py)

        This module prints statements during execution and can be useful for debugging variables or expressions
        without necessarily halting the playbook. Useful for debugging together with the 'when:' directive. This
        module is also supported for Windows targets.

  * note: This module has a corresponding action plugin.

OPTIONS (= is mandatory):

- msg
        The customized message that is printed. If omitted, prints a generic message.
        [Default: Hello world!]
        type: str

(a210) [vagrant@stumble stumble]$ ansible-doc cisco.ios.ios_command
(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_show.yml

PLAY [rt01] ***************************************************************************************************************************************

TASK [show version] *******************************************************************************************************************************
fatal: [rt01]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "paramiko is not installed: No module named 'paramiko'"}

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

(a210) [vagrant@stumble stumble]$ pip install paramiko
Collecting paramiko
  Using cached https://files.pythonhosted.org/packages/06/1e/1e08baaaf6c3d3df1459fd85f0e7d2d6aa916f33958f151ee1ecc9800971/paramiko-2.7.1-py2.py3-none-any.whl
Collecting pynacl>=1.0.1 (from paramiko)
  Using cached https://files.pythonhosted.org/packages/9d/57/2f5e6226a674b2bcb6db531e8b383079b678df5b10cdaa610d6cf20d77ba/PyNaCl-1.4.0-cp35-abi3-manylinux1_x86_64.whl
Collecting bcrypt>=3.1.3 (from paramiko)
  Using cached https://files.pythonhosted.org/packages/8b/1d/82826443777dd4a624e38a08957b975e75df859b381ae302cfd7a30783ed/bcrypt-3.1.7-cp34-abi3-manylinux1_x86_64.whl
Requirement already satisfied: cryptography>=2.5 in /home/vagrant/envs/a210/lib/python3.6/site-packages (from paramiko)
Requirement already satisfied: six in /home/vagrant/envs/a210/lib/python3.6/site-packages (from pynacl>=1.0.1->paramiko)
Requirement already satisfied: cffi>=1.4.1 in /home/vagrant/envs/a210/lib/python3.6/site-packages (from pynacl>=1.0.1->paramiko)
Requirement already satisfied: pycparser in /home/vagrant/envs/a210/lib/python3.6/site-packages (from cffi>=1.4.1->pynacl>=1.0.1->paramiko)
Installing collected packages: pynacl, bcrypt, paramiko
Successfully installed bcrypt-3.1.7 paramiko-2.7.1 pynacl-1.4.0
You are using pip version 9.0.3, however version 20.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_show.yml

PLAY [rt01] ***************************************************************************************************************************************

TASK [show version] *******************************************************************************************************************************
ok: [rt01]

TASK [debug] **************************************************************************************************************************************
ok: [rt01] => {
    "msg": [
        [
            "Cisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.8(3)M2, RELEASE SOFTWARE (fc2)",
            "Technical Support: http://www.cisco.com/techsupport",
            "Copyright (c) 1986-2019 by Cisco Systems, Inc.",
            "Compiled Thu 28-Mar-19 14:06 by prod_rel_team",
            "",
            "",
            "ROM: Bootstrap program is IOSv",
            "",
            "rt01 uptime is 44 minutes",
            "System returned to ROM by reload",
            "System image file is \"flash0:/vios-adventerprisek9-m\"",
            "Last reload reason: Unknown reason",
            "",
            "",
            "",
            "This product contains cryptographic features and is subject to United",
            "States and local country laws governing import, export, transfer and",
            "use. Delivery of Cisco cryptographic products does not imply",
            "third-party authority to import, export, distribute or use encryption.",
            "Importers, exporters, distributors and users are responsible for",
            "compliance with U.S. and local country laws. By using this product you",
            "agree to comply with applicable laws and regulations. If you are unable",
            "to comply with U.S. and local laws, return this product immediately.",
            "",
            "A summary of U.S. laws governing Cisco cryptographic products may be found at:",
            "http://www.cisco.com/wwl/export/crypto/tool/stqrg.html",
            "",
            "If you require further assistance please contact us by sending email to",
            "export@cisco.com.",
            "",
            "Cisco IOSv (revision 1.0) with  with 460137K/62464K bytes of memory.",
            "Processor board ID 9K3FGTY3R8XN9BUUOQPMP",
            "4 Gigabit Ethernet interfaces",
            "DRAM configuration is 72 bits wide with parity disabled.",
            "256K bytes of non-volatile configuration memory.",
            "2097152K bytes of ATA System CompactFlash 0 (Read/Write)",
            "0K bytes of ATA CompactFlash 1 (Read/Write)",
            "11217K bytes of ATA CompactFlash 2 (Read/Write)",
            "0K bytes of ATA CompactFlash 3 (Read/Write)",
            "",
            "",
            "",
            "Configuration register is 0x0"
        ]
    ]
}

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

(a210) [vagrant@stumble stumble]$ ansible-doc yaml
[WARNING]: module yaml not found in:
/home/vagrant/.ansible/plugins/modules:/usr/share/ansible/plugins/modules:/home/vagrant/envs/a210/lib64/python3.6/site-packages/ansible/modules
(a210) [vagrant@stumble stumble]$ ansible-doc yaml -t plugin
usage: ansible-doc [-h] [--version] [-v] [-M MODULE_PATH]
                   [--playbook-dir BASEDIR]
                   [-t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,vars,module,strategy}]
                   [-j] [-F | -l | -s | --metadata-dump]
                   [plugin [plugin ...]]
ansible-doc: error: argument -t/--type: invalid choice: 'plugin' (choose from 'become', 'cache', 'callback', 'cliconf', 'connection', 'httpapi', 'inventory', 'lookup', 'netconf', 'shell', 'vars', 'module', 'strategy')
 
usage: ansible-doc [-h] [--version] [-v] [-M MODULE_PATH]
                   [--playbook-dir BASEDIR]
                   [-t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,vars,module,strategy}]
                   [-j] [-F | -l | -s | --metadata-dump]
                   [plugin [plugin ...]]

plugin documentation tool

positional arguments:
  plugin                Plugin

optional arguments:
  --metadata-dump       **For internal testing only** Dump json metadata for
                        all plugins.
  --playbook-dir BASEDIR
                        Since this tool does not use playbooks, use this as a
                        substitute playbook directory.This sets the relative
                        path for many features including roles/ group_vars/
                        etc.
  --version             show program's version number, config file location,
                        configured module search path, module location,
                        executable location and exit
  -F, --list_files      Show plugin names and their source files without
                        summaries (implies --list). A supplied argument will
                        be used for filtering, can be a namespace or full
                        collection name.
  -M MODULE_PATH, --module-path MODULE_PATH
                        prepend colon-separated path(s) to module library (def
                        ault=~/.ansible/plugins/modules:/usr/share/ansible/plu
                        gins/modules)
  -h, --help            show this help message and exit
  -j, --json            Change output into json format.
  -l, --list            List available plugins. A supplied argument will be
                        used for filtering, can be a namespace or full
                        collection name.
  -s, --snippet         Show playbook snippet for specified plugin(s)
  -t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,vars,module
(a210) [vagrant@stumble stumble]$ ansible-galaxy collection install community.general
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'community.general:0.2.0' to '/home/vagrant/.ansible/collections/ansible_collections/community/general'
Installing 'google.cloud:0.0.9' to '/home/vagrant/.ansible/collections/ansible_collections/google/cloud'
Installing 'ansible.posix:0.1.3' to '/home/vagrant/.ansible/collections/ansible_collections/ansible/posix'
Skipping 'ansible.netcommon' as it is already installed
Installing 'community.kubernetes:0.11.0' to '/home/vagrant/.ansible/collections/ansible_collections/community/kubernetes'
(a210) [vagrant@stumble stumble]$ pip install paramiko^C
(reverse-i-search)`c': ansible-galaxy collection install ^Cmmunity.general
(reverse-i-search)`c': ansible-galaxy collection install ^Cmmunity.general
(a210) [vagrant@stumble stumble]$ ansible-doc yaml -t callback                                                               > YAML    (/home/vagrant/.ansible/collections/ansible_collections/community/general/plugins/callback/yaml.py)

(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_show.yml
[DEPRECATION WARNING]: 'ansible_collections.community.general.plugins.callback.yaml' is subclassing DefaultCallback without 
the corresponding doc_fragment. This feature will be removed from ansible-base in version 2.14. Deprecation warnings can be 
disabled by setting deprecation_warnings=False in ansible.cfg.

PLAY [rt01] *****************************************************************************************************************

TASK [show version] *********************************************************************************************************
ok: [rt01]

TASK [debug] ****************************************************************************************************************
ok: [rt01] => 
  msg:
  - - Cisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.8(3)M2, RELEASE SOFTWARE (fc2)
    - 'Technical Support: http://www.cisco.com/techsupport'
    - Copyright (c) 1986-2019 by Cisco Systems, Inc.
    - Compiled Thu 28-Mar-19 14:06 by prod_rel_team
    - ''
    - ''
    - 'ROM: Bootstrap program is IOSv'
    - ''
    - rt01 uptime is 55 minutes
    - System returned to ROM by reload
    - System image file is "flash0:/vios-adventerprisek9-m"
    - 'Last reload reason: Unknown reason'
    - ''
    - ''
    - ''
    - This product contains cryptographic features and is subject to United
    - States and local country laws governing import, export, transfer and
    - use. Delivery of Cisco cryptographic products does not imply
    - third-party authority to import, export, distribute or use encryption.
    - Importers, exporters, distributors and users are responsible for
    - compliance with U.S. and local country laws. By using this product you
    - agree to comply with applicable laws and regulations. If you are unable
    - to comply with U.S. and local laws, return this product immediately.
    - ''
    - 'A summary of U.S. laws governing Cisco cryptographic products may be found at:'
    - http://www.cisco.com/wwl/export/crypto/tool/stqrg.html
    - ''
    - If you require further assistance please contact us by sending email to
(a210) [vagrant@stumble stumble]$ cat /etc/redhat-release 
CentOS Linux release 7.8.2003 (Core)
(a210) [vagrant@stumble stumble]$ ansible-playbook -i localhost, server.yml 
[DEPRECATION WARNING]: 'ansible_collections.community.general.plugins.callback.yaml' is subclassing DefaultCallback without 
the corresponding doc_fragment. This feature will be removed from ansible-base in version 2.14. Deprecation warnings can be 
disabled by setting deprecation_warnings=False in ansible.cfg.

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

TASK [yum] ******************************************************************************************************************
fatal: [localhost]: FAILED! => changed=false 
  ansible_facts:
    discovered_interpreter_python: /usr/bin/python
  changes:
    installed:
    - httpd
  msg: |-
    You need to be root to perform this command.
  rc: 1
  results:
  - |-
    Loaded plugins: fastestmirror

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

(a210) [vagrant@stumble stumble]$ ansible-playbook -i localhost, server.yml 
[DEPRECATION WARNING]: 'ansible_collections.community.general.plugins.callback.yaml' is subclassing DefaultCallback without 
the corresponding doc_fragment. This feature will be removed from ansible-base in version 2.14. Deprecation warnings can be 
disabled by setting deprecation_warnings=False in ansible.cfg.

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

TASK [yum] ******************************************************************************************************************
changed: [localhost]

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

(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ ansible-playbook -i localhost, server.yml  -t service
[DEPRECATION WARNING]: 'ansible_collections.community.general.plugins.callback.yaml' is subclassing DefaultCallback without 
the corresponding doc_fragment. This feature will be removed from ansible-base in version 2.14. Deprecation warnings can be 
disabled by setting deprecation_warnings=False in ansible.cfg.

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

TASK [service] **************************************************************************************************************
changed: [localhost]

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

(a210) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini ios_show.yml
[DEPRECATION WARNING]: 'ansible_collections.community.general.plugins.callback.yaml' is subclassing 
DefaultCallback without the corresponding doc_fragment. This feature will be removed from ansible-
base in version 2.14. Deprecation warnings can be disabled by setting deprecation_warnings=False in 
ansible.cfg.

PLAY [rt01] ******************************************************************************************

TASK [show version] **********************************************************************************
ok: [rt01]

TASK [debug] *****************************************************************************************
ok: [rt01] => 
  msg:
  - - Cisco IOS Software, IOSv Software (VIOS-ADVENTERPRISEK9-M), Version 15.8(3)M2, RELEASE SOFTWARE (fc2)
    - 'Technical Support: http://www.cisco.com/techsupport'
    - Copyright (c) 1986-2019 by Cisco Systems, Inc.
    - Compiled Thu 28-Mar-19 14:06 by prod_rel_team
    - ''
    - ''
    - 'ROM: Bootstrap program is IOSv'
    - ''
    - rt01 uptime is 1 hour, 1 minute
    - System returned to ROM by reload
    - System image file is "flash0:/vios-adventerprisek9-m"
    - 'Last reload reason: Unknown reason'
    - ''
    - ''
    - ''
    - This product contains cryptographic features and is subject to United
    - States and local country laws governing import, export, transfer and
    - use. Delivery of Cisco cryptographic products does not imply
    - third-party authority to import, export, distribute or use encryption.
    - Importers, exporters, distributors and users are responsible for
    - compliance with U.S. and local country laws. By using this product you
    - agree to comply with applicable laws and regulations. If you are unable
    - to comply with U.S. and local laws, return this product immediately.
    - ''
    - 'A summary of U.S. laws governing Cisco cryptographic products may be found at:'
    - http://www.cisco.com/wwl/export/crypto/tool/stqrg.html
    - ''
    - If you require further assistance please contact us by sending email to
(a210) [vagrant@stumble stumble]$ 
(a210) [vagrant@stumble stumble]$ ansible-galaxy collection list

# /home/vagrant/.ansible/collections/ansible_collections
Collection           Version
-------------------- -------
ansible.netcommon    0.0.3  
ansible.posix        0.1.3  
cisco.ios            0.0.3  
community.general    0.2.0  
community.kubernetes 0.11.0 
google.cloud         0.0.9  
(a210) [vagrant@stumble stumble]$ 

耳寄り情報: オフライン環境へ適用するには

Part8 にむけて

企画中です。もう少しネットワークモジュール?

[Ansible] cisco.ios collection 0.0.3 リリース、ACL や OSPF などのモジュールなどが追加

はじめに

Ansible は、Ansible 本体の標準モジュールの他に、Collection という形式でも配布されています。

例えば、ios_* モジュールは cisco.ios collection 経由で配布されてます。

先日 cisco.ios collection 0.0.3 がリリースされ、4つモジュールが追加されました。

この記事では追加されたモジュールについて、ごく簡単ではありますがご紹介します。


追加モジュール

いずれも、Netwrok Resource Module です。

cisco.ios.ios_acl_interfaces

cisco.ios/ios_acl_interfaces.py at 0.0.3 · ansible-collections/cisco.ios · GitHub

ACL をインターフェースに適用するモジュールです。

  • Example (
- name: Merge module attributes of given access-groups
  cisco.ios.ios_acl_interfaces:
    config:
    - name: GigabitEthernet0/1
      access_groups:
      - afi: ipv4
        acls:
        - name: 110
          direction: in
        - name: 123
          direction: out
      - afi: ipv6
        acls:
        - name: test_v6
          direction: out
        - name: temp_v6
          direction: in
    - name: GigabitEthernet0/2
      access_groups:
      - afi: ipv4
        acls:
        - name: 100
          direction: in
    state: merged

cisco.ios.ios_acls

cisco.ios/ios_acls.py at 0.0.3 · ansible-collections/cisco.ios · GitHub

ACL を定義するモジュールです。コマンドのオプションが多いのでモジュールのオプションも多いですね。

標準 ACL、拡張ACL に対応しているようです。

  • Example (
- name: Merge provided configuration with device configuration
  cisco.ios.ios_acls:
    config:
    - afi: ipv4
      acls:
      - name: std_acl
        acl_type: standard
        aces:
        - grant: deny
          source:
            address: 192.168.1.200
        - grant: deny
          source:
            address: 192.168.2.0
            wildcard_bits: 0.0.0.255
      - name: 110
        aces:
        - sequence: 10
          protocol_options:
            icmp:
              traceroute: true
        - grant: deny
          protocol_options:
            tcp:
              ack: true
          source:
            host: 198.51.100.0
          destination:
            host: 198.51.110.0
            port_protocol:
              eq: telnet
      - name: test
        acl_type: extended
        aces:
        - grant: deny
          protocol_options:
            tcp:
              fin: true
          source:
            address: 192.0.2.0
            wildcard_bits: 0.0.0.255
          destination:
            address: 192.0.3.0
            wildcard_bits: 0.0.0.255
            port_protocol:
              eq: www
          option:
            traceroute: true
          ttl:
            eq: 10
      - name: 123
        aces:
        - grant: deny
          protocol_options:
            tcp:
              ack: true
          source:
            address: 198.51.100.0
            wildcard_bits: 0.0.0.255
          destination:
            address: 198.51.101.0
            wildcard_bits: 0.0.0.255
            port_protocol:
              eq: telnet
          tos:
            service_value: 12
        - grant: deny
          protocol_options:
            tcp:
              ack: true
          source:
            address: 192.0.3.0
            wildcard_bits: 0.0.0.255
          destination:
            address: 192.0.4.0
            wildcard_bits: 0.0.0.255
            port_protocol:
              eq: www
          dscp: ef
          ttl:
            lt: 20
    - afi: ipv6
      acls:
      - name: R1_TRAFFIC
        aces:
        - grant: deny
          protocol_options:
            tcp:
              ack: true
          source:
            any: true
            port_protocol:
              eq: www
          destination:
            any: true
            port_protocol:
              eq: telnet
          dscp: af11
    state: merged

cisco.ios.ios_ospfv2

cisco.ios/ios_ospfv2.py at 0.0.3 · ansible-collections/cisco.ios · GitHub

OSPFv4 を設定するモジュールです。細かいオプションも指定できるようです。

  • Example (
- name: Merge provided OSPF V2 configuration
  cisco.ios.ios_ospfv2:
    config:
      processes:
      - process_id: 1
        max_metric:
          router_lsa: true
          on_startup:
            time: 110
        areas:
        - area_id: '5'
          capability: true
          authentication:
            enable: true
        - area_id: '10'
          authentication:
            message_digest: true
          nssa:
            default_information_originate:
              metric: 10
            translate: suppress-fa
          default_cost: 10
          filter_list:
          - name: test_prefix_in
            direction: in
          - name: test_prefix_out
            direction: out
        network:
          address: 198.51.100.0
          wildcard_bits: 0.0.0.255
          area: 5
        default_information:
          originate: true
      - process_id: 200
        vrf: blue
        domain_id:
          ip_address:
            address: 192.0.3.1
        max_metric:
          router_lsa: true
          on_startup:
            time: 100
        auto_cost:
          reference_bandwidth: 4
        areas:
        - area_id: '10'
          capability: true
        distribute_list:
          acls:
          - name: 10
            direction: out
          - name: 123
            direction: in
    state: merged

cisco.ios.ios_static_routes

cisco.ios/ios_static_routes.py at 0.0.3 · ansible-collections/cisco.ios · GitHub

スタティックルートを設定するモジュールです。

ios_static_route モジュール(末尾 s なし)の後継版です。

  • Example (
- name: Merge provided configuration with device configuration
  cisco.ios.ios_static_routes:
    config:
    - vrf: blue
      address_families:
      - afi: ipv4
        routes:
        - dest: 192.0.2.0/24
          next_hops:
          - forward_router_address: 192.0.2.1
            name: merged_blue
            tag: 50
            track: 150
    - address_families:
      - afi: ipv4
        routes:
        - dest: 198.51.100.0/24
          next_hops:
          - forward_router_address: 198.51.101.1
            name: merged_route_1
            distance_metric: 110
            tag: 40
            multicast: true
          - forward_router_address: 198.51.101.2
            name: merged_route_2
            distance_metric: 30
          - forward_router_address: 198.51.101.3
            name: merged_route_3
      - afi: ipv6
        routes:
        - dest: 2001:DB8:0:3::/64
          next_hops:
          - forward_router_address: 2001:DB8:0:3::2
            name: merged_v6
            tag: 105
    state: merged


これらモジュールを利用するには?

cisco.ios collection はAnsible 2.9.10 以上 2.11 未満で利用できるようです。

Ansible versions: >=2.9.10,<2.11

まず、 ansible-galaxy collection install cisco.ios でインストールします。

モジュール名を cisco.ios_acls のように指定して呼び出します。詳細は、公式ドキュメントをご参照ください。

Using collections — Ansible Documentation


おわりに

これまでは Ansible 本体のバージョンアップの際の changelog を見れば、この手の情報は追えたのですが、今は collection の情報をウォッチする必要があります。

気になる方は Collection もチェックすることをおすすめします。

Ansible Galaxy にログインし、対象の Collection のFollow Author ボタンを押してフォローすると、更新をメールや右上のアイコンで通知してくれます。

f:id:akira6592:20200621103006p:plain
Follow Author

[2020/06/23 追記] 1.0.0 がリリースされました。0.0.3 からモジュールは追加されていませんが、ドキュメントが整備されました。

[Ansible] 「つまずき Ansible 【Part6】Juniper Junos に何かしてみる」ふりかえり

はじめに

2020/06/20 に、YouTube Live で「[つまずき Ansible 【Part6】Juniper Junos に何かしてみる(https://www.youtube.com/watch?v=jJedVzaGDRU)」という配信をしました。 実際に作業しながらエラーと戦って進めるシリーズです。

tekunabe.connpass.com

今回は、Juniper Junos の機器への接続確認、show コマンド実行、インターフェース設定する Playbook を作りました。

環境は vLabs を利用しました。

つまずいたエラーと原因、対処をふりかえります。

動画

www.youtube.com


■ 疎通確認

ncclient が見つからないエラーが発生

以下のエラー。

(ansible) [vagrant@stumble stumble]$ ansible -i inventory.ini junos -m junos_facts
[WARNING]: Platform linux on host vsrx1 is using the discovered Python interpreter at /usr/bin/python, but future installation
of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
vsrx1 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "msg": "Failed to import the required Python library (ncclient) on stumble's Python /home/vagrant/envs/ansible/bin/python3. Please read module documentation and install in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter: No module named 'ncclient'"
}

原因

NETCONF 接続に必要な ncclient がインストールされていないため。

対処

以下のコマンドで nccliant をインストール。

$ pip install ncclient


■ インターフェースの description 設定スタティックルートの追加

lxml が見つからないエラーが発生

以下のエラー。

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml 

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

TASK [set int] ******************************************************************************************************
[WARNING]: Platform linux on host vsrx1 is using the discovered Python interpreter at /usr/bin/python, but future
installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
fatal: [vsrx1]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "lxml is not installed."}

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

原因

Ansible をインストールした venv には lxml は入っているが、Playbook 実行に利用する Python 環境(今回の場合、デフォルト /usr/bin/python)には入っていなかった。

対処

PlyaPython インタープリタの指定を追加。

---
- hosts: junos
  gather_facts: false

  vars:    
    ansible_python_interpreter: ~/envs/ansible/bin/python    # 追加

network_cli が使えないエラーが発生

junos_interfaces モジュールnetwork の組み合わせで、以下のエラー。

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

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

TASK [set int] ******************************************************************************************************
fatal: [vsrx1]: FAILED! => {"changed": false, "msg": "Connection type 'network_cli' is not valid for 'junos_interfaces' module. Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"}

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

原因

junos_interafaces モジュールは network_cli には対応しておらず、netconf のみ対応しているため。

参考: https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html:

対処

netconf を利用する。

もし、タスク個別にコネクションプラグインを指定する場合は、以下のようにタスク変数で指定する。

    - name: set int
      junos_interfaces:
        config:
          - name: ge-0/0/0
            description: funa
      vars:
        ansible_connection: netconf     # ここ
        ansible_port: 33001             # ここ

Configuration database is not open というエラーが発生

※ 配信時は放置しして終わりましたが、配信終了後に対処しました

以下のエラー。

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

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

TASK [set int] ******************************************************************************************************
fatal: [vsrx1]: FAILED! => {"changed": false, "module_stderr": "", "module_stdout": "\n{\"msg\": \"b'\\\\nconfiguration database modified\\\\n'\", \"failed\": true, \"invocation\": {\"module_args\": {\"config\": [{\"name\": \"ge-0/0/0\", \"description\": \"funa\", \"enabled\": true, \"duplex\": null, \"hold_time\": null, \"mtu\": null, \"speed\": null}], \"state\": \"merged\"}}}\n\n{\"msg\": \"b'\\\\nConfiguration database is not open\\\\n'\", \"failed\": true, \"invocation\": {\"module_args\": {\"config\": [{\"name\": \"ge-0/0/0\", \"description\": \"funa\", \"enabled\": true, \"duplex\": null, \"hold_time\": null, \"mtu\": null, \"speed\": null}], \"state\": \"merged\"}}}\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

PLAY RECAP **********************************************************************************************************

原因

手作業で設定変更を試みた時に、未コミットの変更を残してしまったため。

[edit]
ansible@vSRX-addr-0# show | compare 
[edit interfaces ge-0/0/0]
-   description funa;
+   description funa2;

[edit]
ansible@vSRX-addr-0# exit 
The configuration has been changed but not committed
Exit with uncommitted changes? [yes,no] (yes) 

Exiting configuration mode

ansible@vSRX-addr-0>    # 未コミットの変更が残っている。

Ansible としては、安全のために設定変更を控えた。

(配信時はコンフィグ不整合を起こしたといってしまいましたが、正しくは不整合を起こさないために安全側に倒したものです)

対処

手作業で設定変更を試みたた未コミットの変更を破棄。

ansible@vSRX-addr-0> configure 
Entering configuration mode
The configuration has been changed but not committed

[edit]
ansible@vSRX-addr-0# 

[edit]
ansible@vSRX-addr-0# rollback 
load complete

[edit]
ansible@vSRX-addr-0# exit 
Exiting configuration mode

ansible@vSRX-addr-0> 


おまけ

閲覧したサイト

作った各種ファイル

インベントリ: inventory.ini

[ios]
rt01 ansible_host=192.168.1.11
rt02 ansible_host=192.168.1.12

[eos]
eos1 ansible_host=192.168.1.133

; 以下追加
[junos]
vsrx1 ansible_port=33001

変数定義ファイル: group_vars/junos.yml




Playbook: juos_show.yml

show version の実行と表示。

---
- hosts: junos
  gather_facts: false
  
  tasks:
    - name: show version
      junos_command:
        commands:
          - show version
      register: resgister_show_version
  
    - name: debug
      debug:
        msg: "{{ resgister_show_version.stdout_lines }}"

Playbook: juos_set.yml

インターフェースの description 設定。

---
- hosts: junos
  gather_facts: false

  vars:
    ansible_python_interpreter: ~/envs/ansible/bin/python   # 追加
  
  tasks:
    - name: set int
      junos_interfaces:
        config:
          - name: ge-0/0/0
            description: kingyo

全実行ログ

クリックして開く(長いです)

(ansible) [vagrant@stumble stumble]$ ansible -i inventory.ini junos -m junos_facts
[WARNING]: Platform linux on host vsrx1 is using the discovered Python interpreter at /usr/bin/python, but future installation
of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
vsrx1 | FAILED! => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false,
    "msg": "Failed to import the required Python library (ncclient) on stumble's Python /home/vagrant/envs/ansible/bin/python3. Please read module documentation and install in the appropriate location. If the required library is installed, but Ansible is using the wrong Python interpreter, please consult the documentation on ansible_python_interpreter: No module named 'ncclient'"
}
(ansible) [vagrant@stumble stumble]$ pip install ncclient
Collecting ncclient
  Downloading https://files.pythonhosted.org/packages/dd/7f/700ffea36c4c1c72d7581ef3dc3f40ec9756fd161816cd258cd303cd9f39/ncclient-0.6.7.tar.gz (605kB)
    100% |████████████████████████████████| 614kB 214kB/s 
Requirement already satisfied: setuptools>0.6 in /home/vagrant/envs/ansible/lib/python3.6/site-packages (from ncclient)
Requirement already satisfied: paramiko>=1.15.0 in /home/vagrant/envs/ansible/lib/python3.6/site-packages (from ncclient)
Collecting lxml>=3.3.0 (from ncclient)
(ansible) [vagrant@stumble stumble]$ ansible -i inventory.ini junos -m junos_facts
[WARNING]: default value for `gather_subset` will be changed to `min` from `!config` v2.11 onwards
[WARNING]: Platform linux on host vsrx1 is using the discovered Python interpreter at /usr/bin/python, but future installation
of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
vsrx1 | SUCCESS => {
    "ansible_facts": {
        "ansible_net_api": "netconf",
        "ansible_net_filesystems": [
            "/dev/gpt/junos",
            "tmpfs",
            "tmpfs",
            "host_corefiles",
            "host_volatile",
            "host_log",
            "host_traffic_log",
            "host_local",
            "host_aamwd",
            "host_geoip",
            "host_secinteld",
            "host_app_disk"
        ],
        "ansible_net_gather_network_resources": [],
        "ansible_net_gather_subset": [
            "hardware",
            "default",
            "interfaces"
        ],
        "ansible_net_has_2RE": false,
        "ansible_net_hostname": "vSRX-addr-0",
        "ansible_net_interfaces": {
            ".local.": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Loopback"
            },
            "dsc": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "Software-Pseudo"
            },
            "em0": {
                "admin-status": "up",
                "macaddress": "02:00:00:00:00:04",
                "mtu": "1514",
                "oper-status": "up",
                "speed": "1000mbps",
                "type": "Ethernet"
            },
            "em1": {
                "admin-status": "up",
                "macaddress": "52:54:00:21:26:49",
                "mtu": "1514",
                "oper-status": "up",
                "speed": "1000mbps",
                "type": "Ethernet"
            },
            "em2": {
                "admin-status": "up",
                "macaddress": "52:54:00:d9:7c:01",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "Unspecified",
                "type": "Ethernet"
            },
            "fti0": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "FTI"
            },
            "fxp0": {
                "admin-status": "up",
                "macaddress": "00:50:56:01:0c:00",
                "mtu": "1514",
                "oper-status": "up",
                "speed": "1000mbps",
                "type": "Ethernet"
            },
            "ge-0/0/0": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:d8:85",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/1": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:c6:23",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/2": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:f9:11",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/3": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:6f:db",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/4": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:04:91",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/5": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:d0:57",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/6": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:41:9d",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "ge-0/0/7": {
                "admin-status": "up",
                "macaddress": "00:50:56:a2:da:ed",
                "mtu": "1514",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": null
            },
            "gr-0/0/0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "GRE"
            },
            "gre": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "GRE"
            },
            "ip-0/0/0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "IPIP"
            },
            "ipip": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "IPIP"
            },
            "irb": {
                "admin-status": "up",
                "macaddress": "4c:96:14:c4:b1:70",
                "mtu": "1514",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "Ethernet"
            },
            "lo0": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "Loopback"
            },
            "lsi": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Software-Pseudo"
            },
            "lsq-0/0/0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "1504",
                "oper-status": "up",
                "speed": null,
                "type": null
            },
            "lt-0/0/0": {
                "admin-status": "up",
                "macaddress": "02:96:14:c4:b1:73",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "Logical-tunnel"
            },
            "mt-0/0/0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "Multicast-GRE"
            },
            "mtun": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Multicast-GRE"
            },
            "pimd": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "PIMD"
            },
            "pime": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "PIME"
            },
            "pp0": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "1532",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "PPPoE"
            },
            "ppd0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "PIMD"
            },
            "ppe0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "PIME"
            },
            "sp-0/0/0": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "9192",
                "oper-status": "up",
                "speed": "800mbps",
                "type": "Adaptive-Services"
            },
            "st0": {
                "admin-status": "up",
                "macaddress": null,
                "mtu": "9192",
                "oper-status": "up",
                "speed": "Unspecified",
                "type": "Secure-Tunnel"
            },
            "tap": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Software-Pseudo"
            },
            "vlan": {
                "admin-status": "up",
                "macaddress": "00:00:00:00:00:00",
                "mtu": "1518",
                "oper-status": "down",
                "speed": "1000mbps",
                "type": "VLAN"
            },
            "vtep": {
                "admin-status": "up",
                "macaddress": "Unspecified",
                "mtu": "Unlimited",
                "oper-status": "up",
                "speed": "Unlimited",
                "type": "Software-Pseudo"
            }
        },
        "ansible_net_memfree_mb": 27784,
        "ansible_net_memtotal_mb": 955320,
        "ansible_net_model": "vsrx",
        "ansible_net_modules": [
            {
                "description": "VSRX",
                "name": "Midplane",
                "part_number": "750-058562",
                "serial_number": "42227D10",
                "version": "REV 08"
            },
            {
                "name": "Pseudo CB 0"
            },
            {
                "description": "VSRX-S",
                "name": "Routing Engine 0",
                "part_number": "BUILTIN",
                "serial_number": "BUILTIN"
            },
            {
                "chassis_sub_module": null,
                "description": "FPC",
                "name": "FPC 0",
                "part_number": "611-049549",
                "serial_number": "RL3714040884",
                "version": "REV 07"
            }
        ],
        "ansible_net_python_version": "2.7.5",
        "ansible_net_routing_engines": {
            "null": {
                "cpu_background": "0",
                "cpu_background1": "0",
                "cpu_background2": "0",
                "cpu_background3": "0",
                "cpu_idle": "84",
                "cpu_idle1": "95",
                "cpu_idle2": "98",
                "cpu_idle3": "98",
                "cpu_interrupt": "2",
                "cpu_interrupt1": "0",
                "cpu_interrupt2": "0",
                "cpu_interrupt3": "0",
                "cpu_system": "14",
                "cpu_system1": "4",
                "cpu_system2": "1",
                "cpu_system3": "1",
                "cpu_temperature": "0 degrees C / 32 degrees F",
                "cpu_user": "1",
                "cpu_user1": "1",
                "cpu_user2": "1",
                "cpu_user3": "1",
                "last_reboot_reason": "0x4000:VJUNOS reboot",
                "load_average_fifteen": "0.47",
                "load_average_five": "0.57",
                "load_average_one": "0.74",
                "memory_buffer_utilization": "82",
                "memory_system_total": "933",
                "memory_system_total_used": "774",
                "memory_system_total_util": "83",
                "model": "VSRX-S",
                "serial_number": "BUILTIN",
                "slot": null,
                "start_time": "2020-06-20 09:54:25 UTC",
                "status": "OK",
                "temperature": "0 degrees C / 32 degrees F",
                "up_time": "1 hour, 15 minutes, 11 seconds"
            }
        },
        "ansible_net_serialnum": "XXX",
        "ansible_net_system": "junos",
        "ansible_net_version": "18.3R1.9",
        "ansible_network_resources": {},
        "discovered_interpreter_python": "/usr/bin/python"
    },
    "changed": false
}
(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_show.yml 

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

TASK [show version] **************************************************************************
[WARNING]: Platform linux on host vsrx1 is using the discovered Python interpreter at
/usr/bin/python, but future installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more
information.
ok: [vsrx1]

TASK [debug] *********************************************************************************
ok: [vsrx1] => {
    "msg": [
        [
            "Hostname: vSRX-addr-0",
            "Model: vsrx",
            "Junos: 18.3R1.9",
            "JUNOS OS Kernel 64-bit  [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS libs [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS runtime [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS time zone information [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS libs compat32 [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS 32-bit compatibility [20180816.8630ec5_builder_stable_11]",
            "JUNOS py extensions [20180920.185504_builder_junos_183_r1]",
            "JUNOS py base [20180920.185504_builder_junos_183_r1]",
            "JUNOS OS vmguest [20180816.8630ec5_builder_stable_11]",
            "JUNOS OS crypto [20180816.8630ec5_builder_stable_11]",
            "JUNOS network stack and utilities [20180920.185504_builder_junos_183_r1]",
            "JUNOS libs [20180920.185504_builder_junos_183_r1]",
            "JUNOS libs compat32 [20180920.185504_builder_junos_183_r1]",
            "JUNOS runtime [20180920.185504_builder_junos_183_r1]",
            "JUNOS Web Management Platform Package [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx libs compat32 [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx runtime [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx platform support [20180920.185504_builder_junos_183_r1]",
            "JUNOS common platform support [20180920.185504_builder_junos_183_r1]",
            "JUNOS srxtvp runtime [20180920.185504_builder_junos_183_r1]",
            "JUNOS pppoe [20180920.185504_builder_junos_183_r1]",
            "JUNOS mtx network modules [20180920.185504_builder_junos_183_r1]",
            "JUNOS modules [20180920.185504_builder_junos_183_r1]",
            "JUNOS srxtvp modules [20180920.185504_builder_junos_183_r1]",
            "JUNOS srxtvp libs [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx libs [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx Data Plane Crypto Support [20180920.185504_builder_junos_183_r1]",
            "JUNOS daemons [20180920.185504_builder_junos_183_r1]",
            "JUNOS srx daemons [20180920.185504_builder_junos_183_r1]",
            "JUNOS SRX TVP AppQos Daemon [20180920.185504_builder_junos_183_r1]",
            "JUNOS High End AppQos Daemon [20180920.185504_builder_junos_183_r1]",
            "JUNOS Extension Toolkit [20180920.185504_builder_junos_183_r1]",
            "JUNOS Phone-home [20180920.185504_builder_junos_183_r1]",
            "JUNOS J-Insight [20180920.185504_builder_junos_183_r1]",
            "JUNOS Online Documentation [20180920.185504_builder_junos_183_r1]",
            "JUNOS jail runtime [20180816.8630ec5_builder_stable_11]",
            "JUNOS FIPS mode utilities [20180920.185504_builder_junos_183_r1]"
        ]
    ]
}

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

(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ ansible-doc junos_interfaces
> JUNOS_INTERFACES    (/home/vagrant/envs/ansible/lib64/python3.6/site-packages/ansible/modules/network/junos/junos_i

        This module manages the interfaces on Juniper Junos OS network devices.

  * This module is maintained by The Ansible Network Team
OPTIONS (= is mandatory):

- config
        The provided configuration
        [Default: (null)]
        suboptions:
          description:
            description:
            - Interface description.
            type: str
          duplex:
            choices:
            - automatic
            - full-duplex
            - half-duplex
            description:
            - Interface link status. Applicable for Ethernet interfaces only, either in half
              duplex, full duplex or in automatic state which negotiates the duplex automatically.
            type: str
          enabled:
            default: true
            description:
            - Administrative state of the interface.
            - Set the value to `true' to administratively enabled the interface or `false'
              to disable it.
            type: bool
          hold_time:
            description:
            - The hold time for given interface name.
            suboptions:
              down:
                description:
                - The link down hold time in milliseconds.
                type: int
              up:
                description:
                - The link up hold time in milliseconds.
                type: int
            type: dict
          mtu:
            description:
            - MTU for a specific interface.
            - Applicable for Ethernet interfaces only.
            type: int
          name:
            description:
            - Full name of interface, e.g. ge-0/0/0.
            required: true
            type: str
          speed:
            description:
            - Interface link speed. Applicable for Ethernet interfaces only.
            type: int
        
        type: list

- state
        The state of the configuration after module completion
        (Choices: merged, replaced, overridden, deleted)[Default: merged]
        type: str


NOTES:
      * This module requires the netconf system service be enabled on the remote device
        being managed.
      * Tested against vSRX JUNOS version 18.4R1.
      * This module works with connection `netconf'. See L(the Junos OS Platform
        Options,../network/user_guide/platform_junos.html).


REQUIREMENTS:  ncclient (>=v0.6.4)

AUTHOR: Ganesh Nalawade (@ganeshrn)
        METADATA:
          status:
          - preview
          supported_by: network
        

EXAMPLES:

# Using deleted

# Before state:
# -------------
# user@junos01# show interfaces
# ge-0/0/1 {
#    description "Configured by Ansible-1";
#    speed 1g;
#    mtu 1800
# }
# ge-0/0/2 {
#    description "Configured by Ansible-2";
#    ether-options {
#        auto-negotiation;
#    }
# }

- name: "Delete given options for the interface (Note: This won't delete the interface itself if any other values are
  junos_interfaces:
    config:
      - name: ge-0/0/1
        description: 'Configured by Ansible-1'
        speed: 1g
        mtu: 1800
      - name: ge-0/0/2
        description: 'Configured by Ansible -2'
    state: deleted

# After state:
# ------------
# user@junos01# show interfaces
# ge-0/0/2 {
#    ether-options {
#        auto-negotiation;
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml 

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

TASK [set int] ******************************************************************************************************
[WARNING]: Platform linux on host vsrx1 is using the discovered Python interpreter at /usr/bin/python, but future
installation of another Python interpreter could change this. See
https://docs.ansible.com/ansible/2.9/reference_appendices/interpreter_discovery.html for more information.
fatal: [vsrx1]: FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "msg": "lxml is not installed."}

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

(ansible) [vagrant@stumble stumble]$ pip install lxml
Requirement already satisfied: lxml in /home/vagrant/envs/ansible/lib/python3.6/site-packages
You are using pip version 9.0.3, however version 20.1.1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ python 
Python 3.6.8 (default, Apr  2 2020, 13:34:55) 
[GCC 4.8.5 20150623 (Red Hat 4.8.5-39)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import lxml
>>> 
>>> 
>>> exit
Use exit() or Ctrl-D (i.e. EOF) to exit
>>> 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ 
(ansible) [vagrant@stumble stumble]$ python python
python: can't open file 'python': [Errno 2] No such file or directory
(ansible) [vagrant@stumble stumble]$ which python
~/envs/ansible/bin/python
(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml 

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

TASK [set int] ***************************************************************************************************
changed: [vsrx1]

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

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --check --diff

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

TASK [set int] ******************************************************************************************************
[edit interfaces ge-0/0/0]
-   description kingyo;
+   description funa;
changed: [vsrx1]

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

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

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

TASK [set int] ******************************************************************************************************
[edit interfaces ge-0/0/0]
-   description kingyo;
+   description funa;
changed: [vsrx1]

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

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

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

TASK [set int] ******************************************************************************************************
fatal: [vsrx1]: FAILED! => {"changed": false, "msg": "Connection type 'network_cli' is not valid for 'junos_interfaces' module. Please see https://docs.ansible.com/ansible/latest/network/user_guide/platform_junos.html"}

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

(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff
^CTraceback (most recent call last):
  File "/home/vagrant/envs/ansible/bin/ansible-playbook", line 62, in <module>
    import ansible.constants as C
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/ansible/constants.py", line 174, in <module>
    config = ConfigManager()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/ansible/config/manager.py", line 279, in __init__
    self._base_defs = self._read_config_yaml_file(defs_file or ('%s/base.yml' % os.path.dirname(__file__)))
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/ansible/config/manager.py", line 305, in _read_config_yaml_file
    return yaml_load(config_def, Loader=SafeLoader) or {}
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/__init__.py", line 114, in load
    return loader.get_single_data()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/constructor.py", line 49, in get_single_data
    node = self.get_single_node()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 36, in get_single_node
    document = self.compose_document()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 55, in compose_document
    node = self.compose_node(None, None)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
    node = self.compose_mapping_node(anchor)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
    item_value = self.compose_node(node, item_key)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 84, in compose_node
    node = self.compose_mapping_node(anchor)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 133, in compose_mapping_node
    item_value = self.compose_node(node, item_key)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 82, in compose_node
    node = self.compose_sequence_node(anchor)
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/composer.py", line 110, in compose_sequence_node
    while not self.check_event(SequenceEndEvent):
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/parser.py", line 98, in check_event
    self.current_event = self.state()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/parser.py", line 379, in parse_block_sequence_first_entry
    return self.parse_block_sequence_entry()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/parser.py", line 382, in parse_block_sequence_entry
    if self.check_token(BlockEntryToken):
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/scanner.py", line 115, in check_token
    while self.need_more_tokens():
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/scanner.py", line 152, in need_more_tokens
    self.stale_possible_simple_keys()
  File "/home/vagrant/envs/ansible/lib64/python3.6/site-packages/yaml/scanner.py", line 286, in stale_possible_simple_keys
    for level in list(self.possible_simple_keys):
KeyboardInterrupt
(ansible) [vagrant@stumble stumble]$ ansible-playbook -i inventory.ini junos_set.yml  --diff

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

TASK [set int] ******************************************************************************************************
fatal: [vsrx1]: FAILED! => {"changed": false, "module_stderr": "", "module_stdout": "\n{\"msg\": \"b'\\\\nconfiguration database modified\\\\n'\", \"failed\": true, \"invocation\": {\"module_args\": {\"config\": [{\"name\": \"ge-0/0/0\", \"description\": \"funa\", \"enabled\": true, \"duplex\": null, \"hold_time\": null, \"mtu\": null, \"speed\": null}], \"state\": \"merged\"}}}\n\n{\"msg\": \"b'\\\\nConfiguration database is not open\\\\n'\", \"failed\": true, \"invocation\": {\"module_args\": {\"config\": [{\"name\": \"ge-0/0/0\", \"description\": \"funa\", \"enabled\": true, \"duplex\": null, \"hold_time\": null, \"mtu\": null, \"speed\": null}], \"state\": \"merged\"}}}\n", "msg": "MODULE FAILURE\nSee stdout/stderr for the exact error", "rc": 1}

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

(ansible) [vagrant@stumble stumble]$ 

Part7 にむけて

リリースされたばかりの Ansible 2.10.0b1 で遊びます。

https://tekunabe.connpass.com/event/180268/

参加ブログ

参加ブログありがとうございます!

note.com

[Ansible] user01、user02・・のように数値を任意の桁数にゼロパディングする

はじめに

なにか連番を生成する際に、user1、user2・・user10 ではなく、user01、user02・・のように 特定の桁数でゼロパディングしたいことはないでしょうか。

Jinja2 の filter でフォーマットするのが便利です。

  • 動作確認環境
    • Ansible 2.9.9
    • Jinja2 2.11.2

サンプル1: 簡単な例(単一の値)

10進数を2桁で揃えたいときは %02d です。

- hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - debug:
        msg: "{{ 'user%02d' | format(1) }}"

実行結果

TASK [debug] **********************************************************************************
ok: [localhost] => {
    "msg": "user01"
}

サンプル2: 連番

- hosts: localhost
  connection: local
  gather_facts: false

  tasks:
    - debug:
        msg: "{{ 'user%02d' | format(item) }}"
      loop: "{{ range(1, 10 + 1 , 1)| list }}"

実行結果

TASK [debug] **********************************************************************************
ok: [localhost] => (item=1) => {
    "msg": "user01"
}
ok: [localhost] => (item=2) => {
    "msg": "user02"
}
ok: [localhost] => (item=3) => {
    "msg": "user03"
}
ok: [localhost] => (item=4) => {
    "msg": "user04"
}
ok: [localhost] => (item=5) => {
    "msg": "user05"
}
ok: [localhost] => (item=6) => {
    "msg": "user06"
}
ok: [localhost] => (item=7) => {
    "msg": "user07"
}
ok: [localhost] => (item=8) => {
    "msg": "user08"
}
ok: [localhost] => (item=9) => {
    "msg": "user09"
}
ok: [localhost] => (item=10) => {
    "msg": "user10"
}