てくなべ (tekunabe)

ansible / network automation / 学習メモ

[Ansible] ansible-galaxy collection install がオフライン環境で少し便利になった(ansible-core 2.13.5 以上)

この記事は、Ansible Advent Calendar 2022 (Adventar 版) の 23日目の記事です。

はじめに

コレクションをインストールするための ansible-galaxy collection install というコマンドがあります。

コレクション名(cisco.ios など)を指定して、オンラインでインストールするのがよくある使い方です。コレクション名の代わりに、予めコレクションを tar.gz でダウンロードしておき、そのファイル名を指定すると、オフライン環境でもコレクションをインストールできます。

ところが ansible-core 2.13.4 までは、依存コレクションがあるコレクションは扱いが不便な面がありました。具体的には、すでに依存コレクションがインストールされている状態でも、Ansible Galaxy に接続を試みてしまう点です (ansible.cfg などの設定による)。これを避けるには、インストール済みのコレクションの分まで tar.gz を用意する必要がありました。

ありがたいことに、ansible-core 2.13.5 でこの点が改善されました。

ansible-galaxy - remove extra server api call during dependency resolution for requirements and dependencies that are already satisfied (#77443).

この改善された挙動を、比較しながら確かめてみます。

前提環境

以下の3つのコレクションがすでにインストールされている状態から始めます。

% ansible-galaxy collection list

# /Users/sakana/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
ansible.netcommon 4.1.0  
ansible.utils     2.8.0  
cisco.ios         4.0.0  

cisco.iosansible.netcommon に依存していて、さらに ansible.netcommonansible.utils に依存しています。

ansible.cfg 上は、Galaxy 接続の設定はデフォルトのままなので、Ansible Galaxy に接続するようになっています。

オフラインでコレクションを追加インストールする

今回は、arista.eos コレクション 6.0.0 をオフラインで追加インストールすることにます。arista.eos コレクションも cisco.ios と同様に、ansible.netcommon コレクションに依存していて、さらに ansible.netcommonansible.utils に依存しています。

tar.gz をダウンロード

オフラインインストールなので、あらかじめ tar.gz ファイルをダウンロードして用意します。ダウンロードは、インターネット接続性がある環境で以下のいずれかの方法でしておきます。

ansible-core 2.13.4 の場合

まずは、少し不便だった ansible-core 2.13.4 での場合です。ansible-galaxy collection install arista-eos-6.0.0.tar.gz でインストールを試みます。

$ ansible-galaxy collection install arista-eos-6.0.0.tar.gz

Starting galaxy collection install process
Process install dependency map
[WARNING]: Skipping Galaxy server https://galaxy.ansible.com/api/. Got an unexpected error when getting
available versions of collection ansible.netcommon: Unknown error when attempting to call Galaxy at
'https://galaxy.ansible.com/api/v2/collections/ansible/netcommon/': <urlopen error [Errno 8] nodename nor
servname provided, or not known>
ERROR! Unknown error when attempting to call Galaxy at 'https://galaxy.ansible.com/api/v2/collections/ansible/netcommon/': <urlopen error [Errno 8] nodename nor servname provided, or not known>

接続性がないため、https://galaxy.ansible.com/api/v2/collections/ansible/netcommon/ への接続エラーが発生しました。

このように、ansible.netcommon はすでにインストールされいるにも関わらず、Ansible Galaxy への接続を試みてしまいます。オフライン環境では困ったことになります。

この現象を避けるには、依存コレクションもセットで ansible-galaxy collection install で指定する方法があります。

$ ansible-galaxy collection install arista-eos-6.0.0.tar.gz ansible-netcommon-4.1.0.tar.gz ansible-utils-2.8.0.tar.gz 
Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'arista.eos:6.0.0' to '/Users/sakana/.ansible/collections/ansible_collections/arista/eos'
arista.eos:6.0.0 was installed successfully
Installing 'ansible.netcommon:4.1.0' to '/Users/sakana/.ansible/collections/ansible_collections/ansible/netcommon'
ansible.netcommon:4.1.0 was installed successfully
Installing 'ansible.utils:2.8.0' to '/Users/sakana/.ansible/collections/ansible_collections/ansible/utils'
ansible.utils:2.8.0 was installed successfully

ただ、すでにインストールされている依存コレクション(今回は ansible.netcommonansible.utils)がすでにインストールされているにも関わらず、依存コレクション分の tar.gz を用意しておくという手間がありました。

ansible-core 2.13.5 の場合 (ansible-core 2.14.0 以上も)

先述の手間がなくなった、ansible-core 2.13.5 の場合をたしめします(ansible-core 2.14.0 以上でも同じです)。

まず、状態を戻すため、 arista.eos コレクションを削除します。

rm -fr ~/.ansible/collections/ansible_collections/arista/eos

続いて arista-eos-6.0.0.tar.gz だけ指定してインストールします。

$ ansible-galaxy collection install arista-eos-6.0.0.tar.gz

Starting galaxy collection install process
Process install dependency map
Starting collection install process
Installing 'arista.eos:6.0.0' to '/Users/sakana/.ansible/collections/ansible_collections/arista/eos'
arista.eos:6.0.0 was installed successfully
'ansible.netcommon:4.1.0' is already installed, skipping.
'ansible.utils:2.8.0' is already installed, skipping.

今度は、不要な Ansible Galaxy への接続がなくなり、依存コレクションがすでにインストールされていることも検出され、無事に arista.eos がインストールできました。

$ ansible-galaxy collection list

# /Users/sakana/.ansible/collections/ansible_collections
Collection        Version
----------------- -------
ansible.netcommon 4.1.0  
ansible.utils     2.8.0  
arista.eos        6.0.0  
cisco.ios         4.0.0  

changelog を見ると、この改善は Bug fix という扱いでした。

ansible-core 2.14.0 はよりオフラインを考慮した --offline オプションが追加

先程試した改善点でも、ある程度 Ansible Galaxy への接続は抑えられていましたが、例えば依存コレクションがまだインストールされていないときは、Ansible Galaxy への接続を試みます。オフライン環境では、このような接続試行も抑えたほうがより丁寧かと思います。

そんなときは、ansible-galaxy collection install に ansible-core 2.14.0 で追加された --offline オプションが便利です。

これも試してみます。

依存コレクション ansible.utils がまだインストールされていないときに --offline オプションなし(これまで通り)インストールを試みると、以下のエラーになります。接続エラーです。

$ ansible-galaxy collection install arista-eos-6.0.0.tar.gz
[WARNING]: Skipping Galaxy server https://galaxy.ansible.com/api/. Got an unexpected error when
getting available versions of collection ansible.utils: Unknown error when attempting to call
Galaxy at 'https://galaxy.ansible.com/api/v2/collections/ansible/utils/': <urlopen error [Errno
8] nodename nor servname provided, or not known>
ERROR! Unknown error when attempting to call Galaxy at 'https://galaxy.ansible.com/api/v2/collections/ansible/utils/': <urlopen error [Errno 8] nodename nor servname provided, or not known>

今度は、--offline オプションありでインストールします。

ansible-galaxy collection install  arista-eos-6.0.0.tar.gz --offline
Starting galaxy collection install process
Process install dependency map
ERROR! Failed to resolve the requested dependencies map. Could not satisfy the following requirements:
* ansible.utils:>=2.5.2 (dependency of ansible.netcommon:4.1.0)

オフラインなので、インストールできなかった事自体は同じですが、--offline オプションありのほうが以下の点で、オフライン環境にやさしい挙動になっていると感じました。

  • 接続エラーが表示されない
  • 依存コレクション名に加えて、どのコレクションが依存しているか、どのバージョンか、も表示される

なお、--offline オプションのヘルプは以下のように記載されています(ドキュメントはこちら)。

  --offline             Install collection artifacts (tarballs) without contacting any
                        distribution servers. This does not apply to collections in remote Git
                        repositories or URLs to remote tarballs.

おわりに

オフライン環境は何かと制約が大きく、できれば避けたいところですが、今回ためした改善点はいざというときに活用できそうです。

関連

2.13.5 changelog

  • ansible-galaxy - remove extra server api call during dependency resolution for requirements and dependencies that are already satisfied (#77443).

2.14.0 changelog

  • ansible-galaxy - remove extra server api call during dependency resolution for requirements and dependencies that are already satisfied (#77443).

  • ansible-galaxy collection install - add an --offline option to prevent querying distribution servers (#77443).