I have multiple hosts and my playbook has apt, pip modules to download necessary packages from repositories. When any (apt,pip) download module attempt to download packages, it does it for each host one by one. So I have to wait too long. Can ansible download these deb or pip packages to its local (or anywhere) and install to each host to decrease time. What is the best practice when there are lots of hosts and lots of packages?
3 Answers
You can set up a proxy. A reverse proxy can be a good choice for this kind of setup. You would configure each machine to use the proxy as its apt/pip repository. The first time a package is requested the proxy downloads it from the internet and stores it, the next machine that requires it will get it from the proxy directly.
One popular choice is Squid. Another one is Nginx, set up in a reverse proxy configuration.
The advantage over mirroring entire repositories is that you'll only get the packages you need. The advantage over having Ansible copy the files is that it acts like the real proxy, dependencies and upgrades and all. But you'll have to change apt and pip repository configurations. Or "hijack" those repository names through your local DNS.
If your local network is faster than your internet connexion you can do the following:
- Download the tarball in your ansible host using run_once option.
- Copy it to each target.
- Install it locally from a file ; most of package managers support local install.
Yum rpm example
- name: Download RPM locally
get_url:
url: http://example.com/path/file.rpm
dest: /local_path/file.rpm
delegate_to: localhost
run_once: yes
- name: Copying file.rpm
copy:
src: /local_path/file.rpm
dest: /remote_path/file.rpm
- name: Install rpm from a local file
yum:
name: /remote_path/file.rpm
state: present
Local install example with pip
- pip:
name: file:///remote_path/file.gz
Local install example with apt
- name: Install a .deb package
apt:
deb: /remote_path/file.deb
The problem with this method, is when you have many dependencies ; you have to download and install them all before your package (Optionally with a requirements.txt or so depending on the package manager you use..)
-
Thanks. Yes dependencies is a problem with this method. Another problem is to find out all rpm and pip packages' link manually, right?– CanCommented Jan 23, 2019 at 13:28
-
1@Can: It depends .. if you use a local repository or a nexus server which is a common practice, finding packages is not a hard task. Also consider using variables for all links to make your code maintainable– stormCommented Jan 24, 2019 at 8:44
Can Ansible use a local repository?
I just take the title because the answer lies in it.
What is the best practice when there are lots of hosts and lots of packages?
You have a many hosts, hopefully from the same distribution. So it would make sense to create a local mirror (repository), which can be on your Ansible machine by the way, and to configure, for either pip or apt.
This takes space, but will save you a lot of time downloading updates and packages.
You have to calculate if it is worth it, as it takes a fair amount of storage, but setting this up isn't very complicated.
Then just update the apt
configuration of each hosts to point to your local mirror with Ansible.
Can ansible download these deb or pip packages to its local (or anywhere) and install to each host to decrease time.
For that part, I believe @storm gave a very good answer:
delegate_to: localhost
run_once: yes