Actions from inventory variables
March 6, 2026 ยท View on GitHub
The role performs actions from inventory variables without creating a lot of tasks and copy-pasted roles
Role release to Ansible galaxy
-
clone me:
git clone --recursive \ git@github.com:raven428/ansible-mega-var.git \ ansible-mega-var -
make tag and send to release:
git checkout master && git pull git tag -fm $(git branch --sho) 1.0.7 && git push --force origin $(git describe)
Example site.yaml (TLDR)
For the whole role
In case you have most of the variables filled it's
- name: Perform some files, dirs, and templates upload
hosts: mega_var
become: true
handlers:
- import_tasks: handlers/main.yaml
roles:
- role: mega-var
vars:
meva_packages: "{{ meva_site_packages }}"
meva_groups2create: "{{ meva_site_groups2create }}"
meva_users2create: "{{ meva_site_users2create }}"
meva_dirs2create: "{{ meva_site_dirs2create }}"
meva_templates2upload: "{{ meva_site_templates2upload }}"
meva_files2upload: "{{ meva_site_files2upload }}"
meva_content2upload: "{{ meva_site_content2upload }}"
meva_tree2rsync: "{{ meva_site_tree2rsync }}"
meva_systemd4units: "{{ meva_site_systemd4units }}"
meva_key2user: "{{ meva_site_key2user }}"
meva_file2down: "{{ meva_site_file2down }}"
meva_partitions: "{{ meva_site_partitions }}"
meva_lvg: "{{ meva_site_lvg }}"
meva_lvol: "{{ meva_site_lvol }}"
meva_filesystems: "{{ meva_site_filesystems }}"
meva_mounts: "{{ meva_site_mounts }}"
meva_ghr2down: "{{ meva_site_ghr2down }}"
meva_file2down: "{{ meva_site_file2down }}"
tags: [mega-var]
By separate calls
In case you haven't filled most of the variables, a call of the role can be significantly speed up. Simple by using tasks_from: directive:
- name: Separate mega-var calls examples
hosts: mega_var
become: true
handlers:
- import_tasks: handlers/main.yaml
tasks:
- name: Install some packages outside of the whole role call
ansible.builtin.include_role:
role: mega-var
tasks_from: _apt.yaml
loop_control:
loop_var: i
loop: "{{ meva_site_packages }}"
- name: Ensure some groups outside of the whole role call
ansible.builtin.include_role:
role: mega-var
tasks_from: _group.yaml
loop_control:
loop_var: i
loop: "{{ meva_site_groups2create }}"
- name: Ensure some users outside of the whole role call
ansible.builtin.include_role:
role: mega-var
tasks_from: _user.yaml
loop_control:
loop_var: i
loop: "{{ meva_site_users2create }}"
- name: Ensure some dirs outside of the whole role call
ansible.builtin.include_role:
role: mega-var
tasks_from: _file.yaml
loop_control:
loop_var: i
loop: "{{ meva_site_dirs2create }}"
- name: Ensure some templates outside of the whole role call
ansible.builtin.include_role:
role: mega-var
tasks_from: _template.yaml
loop_control:
loop_var: i
loop: "{{ meva_site_templates2upload }}"
- name: Ensure some files outside of the whole role call
ansible.builtin.include_role:
role: mega-var
tasks_from: _copy.yaml
loop_control:
loop_var: i
loop: "{{ meva_site_files2upload }}"
- name: Download some files from GitHub releases example
hosts: download_github
become: true
handlers:
- import_tasks: handlers/main.yaml
tasks:
- name: Download some files from GitHub releases
ansible.builtin.include_role:
role: mega-var
tasks_from: _download.yaml
loop_control:
loop_var: i
loop: "{{ meva_site_ghr2down }}"
Role variables description
All the variables except meva_ghr2down and meva_file2down is just wrapper and refers to according Ansible module documentation. Most keys of meva_ghr2down and meva_file2down variables also refers to ansible.builtin.get_url documentation
Here will be only non-obvious options of usage
Simple HTTP download with meva_file2down variable
There are the molecule tests cases description. Most options are available from ansible.builtin.get_url, ansible.builtin.file and ansible.builtin.copy
Single raw download (remote and local)
Case 1.1.1
- url: "http://url.to/download.ext"
dest: "/dir/on/target/host/with/filename.ext"
delegate_to: localhost
Case 1.1.2
With delegate_to: localhost is set, file from url will be downloaded to Ansible controller first. Then ansible.builtin.copy will spread file to destination hosts. This can be useful when url source isn't able to handle a lot of requests from hosts in configuration
Single compressed download
Case 1.2.1
- url: "http://url.to/download.ext.gz"
dest: "/dir/on/target/host/with/"
creates: "filename.ext"
archive: true
This option will decompress downloaded file. Parameter dest should contain the destination directory name only, without a filename.
Filename part of the decompressed file should be in creates key. The archive: true indicates that downloaded file should be decompressed extension from uri. Extension gz, bz2, lz4, zst, lzma, xz supported by decompress module. It can recognize file format only by extension, no content scan will be performed
Sometimes uri couldn't contain extension or even reliable filename. In this case you may set it by hand in down_name key. Temporary download will be placed to file in temporary directory with this name. Thus, decompress module able to handle file by extension
Case 1.2.2
If delegate_to: localhost is set, then downloading will be performed on the Ansible controller, decompressed, then propagated to a remote host after decompress
Archive with a directory tree: complete unarchive
Case 1.3.1
- url: "http://url.to/download.tar.gz"
creates: "filename.ext"
dest: "/dir/on/target/host"
archive: true
delegate_to: localhost
files: []
This will download a file to a host, perform ansible.builtin.unarchive and then traverse result directory with chmod_tree module: directories to dir_mode, files with executive bit to exec_mode and non-executive files to file_mode
Case 1.3.2
If delegate_to: localhost is set, then downloading will be performed on the Ansible controller then downloaded result will be propagated to the remote host before unarchive
Archive with a directory tree: pick-me something
Case 1.4.1
- url: "http://url.to/download.tar.gz"
creates: "filename.ext"
dest: "/dir/on/target/host"
archive: true
files:
- name: "relative/dir/of/file-in-archive.ext"
dest: "sub-dir/from/parent/dest"
- name: "some/other/in-archive.dump"
dest: "/dir/for/other/"
- name: "one/more/file-in-archive.jpg"
dest: "/one/more/dir/picture.jpg"
This will download the file to a target host, perform ansible.builtin.unarchive, then pick elements from list of files: and propagate it to certain path
Case 1.4.2
If delegate_to: localhost is set, then downloading will be performed on the Ansible controller, perform ansible.builtin.unarchive also there, then pick elements from list of files: and propagate it to certain path
There are a lot of options in files: definitions (shown as f. below) the full list:
- Both
destandf.destare either relative or undefined or empty will raise error - If
destis defined, it should be absolute otherwise error will be raised. Other options are similar as above:- (
0.0.0) Heref.destcan be empty or undefined, soresult = i.dest ~ '/' ~ f.name | basename - (
0.0.1) Iff.destended by/,result = i.dest ~ '/' ~ f.dest ~ '/' ~ f.name | basename - (
0.0.2) Iff.destis not ended by/then treated as file name:result = i.dest ~ '/' ~ f.dest
- (
- Either
destis empty orf.deststarts with/the result defined byf.destandf.nameonly:- (
0.1.0) Iff.destfinished by/,result = f.dest ~ '/' ~ f.name | basename - (
0.1.1) Iff.destis not finished by/then treated as path with filename:result = f.dest
- (
Parameter f.name can be directory then will be propagated recursively. In this case two options of f.name are available to upload: w/ and w/o trailing /. Other rules are same as above multiplied on these options:
- (
0.2.0) Iff.nameended by/only content of directory will be uploaded to the result - (
0.2.1) Else the whole directory with content will be uploaded
This is the ansible.builtin.copy behavior. In both cases destination directory will be automatically created despite the result ended with / or not
Role development road-map
Add rsync ability to some cases of pick-me
For cases 1.4.1 and 1.4.2 when source is a directory and destination already contain some other files it will not be deleted. Just the new files will be placed near with existing ones. It will be nice to support sync state of source and destination directories
It can be achieved by using ansible.posix.synchronize module in _down2unp.yaml with the when condition near ansible.builtin.copy. The latter also should obtain when for avoiding simultaneous usage of both transfer modules
Add action plugin to decompress module
Unarchive module perform the upload of file to targets before unarchive, but decompress is not. This is inaccurate behavior, because upload of decompressed files may consume more traffic data than compressed. Also, this will consume more time to operate and this can be avoided
So, the better way is put compressed file to targets before decompress. This requires action plugin like done in unarchive. However, simple adding action plugin is not enough due to other role YAML-code expects decompressed file on the controller. So, these code also should be adapted
Replace docker to podman driver in molecule
Failed yet. I'm not able to start systemd inside a podman in podman container according to article. Grok and ChatGPT help also didn't work. However, docker in podman is tolerable here
Docker in docker also works. I choose the podman as first layer for the rootless approach which is impossible with the docker as a first layer. Probably, podman --remote with --url to host socket in podman should work. But there are no support for this in molecule_podman driver