Hi
I’m setting out to upgrade ansible in some places here.
We exclusively use ansible in dedicated venvs, using python3.9.
Most of the installs are 3.4.0.
Looking back over the last years I had the impression that doing ‘pip install ansible’ was increasingly slower.
This makes sense as there is increasingly more to it. I just a quick test and indeed it’s been growing a lot:
153M 2.9.27
368M 2.10.7
402M 3.4.0
488M 4.10.0
508M 5.3.0
Half a gig seems like a lot for what we do - we use the same modules as when we ran 2.9.
Since we’ll move to 5.x, I looked at how much is in there, and apparently the bulk of the space is taken up by collections. For example in 5.3.0 the bundled collections are 457M in total (in lib/python3.9/site-packages/ansible_collections):
142M community
78M fortinet
65M cisco
19M dellemc
14M netapp
14M f5networks
14M ansible
10M google
9.5M junipernetworks
9.4M azure
9.4M arista
7.7M vyos
7.5M amazon
6.0M netbox
5.9M purestorage
4.6M inspur
4.0M netapp_eseries
3.7M ngine_io
3.4M ovirt
2.8M check_point
2.6M openstack
2.6M kubernetes
2.5M sensu
2.5M awx
2.3M containers
2.0M mellanox
1.6M hetzner
1.4M theforeman
1.2M infoblox
1.1M t_systems_mms
972K wti
944K cyberark
804K hpe
652K cloudscale_ch
576K frr
548K openvswitch
436K splunk
428K infinidat
416K ibm
336K chocolatey
260K cloud
256K servicenow
152K gluster
Since we only use a fraction of these, I would like to have only those installed.
I couldn’t find any clean way of uninstalling collections from lib/python3.9/site-packages/ansible_collections.
But rather than fetching content and then removing almost all of it again, I thought it’d be cleaner to start with ansible-core and then add collections to that.
Ideally just the collections that we need, with the same versions that are installed using a ‘full’ ansible install.
I couldn’t find any information on where that is defined. The next best thing was to do a temporary full install, and then check what versions are installed there.
To automate this a little bit I came up with (please don’t laugh):
ansible-galaxy collection list --format yaml |
yq -y -r ’
. | with_entries( select( .key | test(
“^(amazon.aws|ansible.(posix|utils)|community.(aws|crypto|docker|general|postgresql))”
)))|
to_entries |
{
collections: map(
{ name: .key,
version: .value.version
}
)
}’ > requirements.yml
FYI this file reads:
collections:
- name: amazon.aws
version: 2.1.0 - name: ansible.posix
version: 1.3.0 - name: ansible.utils
version: 2.4.3 - name: community.aws
version: 2.2.0 - name: community.crypto
version: 2.2.0 - name: community.docker
version: 2.1.1 - name: community.general
version: 4.4.0 - name: community.postgresql
version: 1.6.1
This file is then used in a venv that has just ansible-core==2.12.2 (and yq) installed.
I force installation into the same location as where the collections end up if the ansible package was installed:
ANSIBLE_COLLECTIONS_PATH=$(python -c “import site; print(site.getsitepackages()[0])”) ansible-galaxy collection install -r requirements.yml
It appears I now have a fully functioning ansible install, with just the collections that I need:
$ ansible-galaxy collection list
/Users/dick.visser/tmp/ansible/5.3.0-slim/lib/python3.9/site-packages/ansible_collections
Collection Version
amazon.aws 2.1.0
ansible.netcommon 2.5.0
ansible.posix 1.3.0
ansible.utils 2.4.3
community.aws 2.2.0
community.crypto 2.2.0
community.docker 2.1.1
community.general 4.4.0
community.network 3.0.0
community.postgresql 1.6.1
I’ve repeated this for ansible 3.4.0 (which uses ansible-base 2.10.7) and 4.10.0 (which uses ansible-core 2.11.8).
Those seem to work fine as well. The resulting installed code base is indeed much smaller.
I’ve labeled the venvs that have a limited collection set as ‘slim’:
403M 3.4.0
109M 3.4.0-slim
489M 4.10.0
96M 4.10.0-slim
509M 5.3.0
114M 5.3.0-slim
Now, while all of this seems to work - I’m not sure if it is supposed to work…
Are there any gotchas with this approach?
thx