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?
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..)
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