I want to include a task from a different role.
I would not want to hardcode it like
- name : Set topology based on Jenkins job name
include: ../../pre-req/tasks/set-topo.yml
tags: core
Is there a way to do this with dependency? I tried creating a meta directory with files and tasks, somehow it' s not getting triggered.
something like this
vim roles/pre-req/meta/main.yml
---
allow_duplicates: yes
dependencies:
- { role: topo, tags: ['core'] }
I would not want to hardcode it like
Why not? You want to include a task, and that's how you include a task.
If what you want to do is include the entire other role, Ansible 2.2 (released yesterday) added include_role.
Related
I have a playbook which should retrieve atrifacts from maven repo, extract them to temp dir and copy some file to destinatiom folder. Currently it works pretty fine - artifacts are downloaded using maven_artifact task. But some requirements have changed and I need to use get_url task now. After changing to get_url the whole rest of the playbook is broken because object returned from maven_artifact and get_url are of different types. How to determine what type with what fields is getting returned from a task?
Best regards
No matter which ansible module you use there is the option to create variables from the output of the task by using register.
The ansible documentation states which return values are available to you when doing so. Here for example are the return values for the get_url module: https://docs.ansible.com/ansible/latest/reference_appendices/common_return_values.html
In that case you may do something like the following to retrieve the status code of the get_url module:
- name: Download foo.conf
get_url:
url: http://example.com/path/file.conf
dest: /etc/foo.conf
mode: '0440'
register: my_result
- name: Print status code of get_url
debug:
var: my_result.status_code
Each module returns an object of a different type.
There Is no way within Ansible to identify the type of a registered variable (i.e. what attributes you can read from it) however, a module will always return an object of the same type.
The return values of a module are listed at the bottom of that modules documentation page.
I'm getting an error with Ansible, "ERROR! No action detected in task." According to Why does Ansible show "ERROR! no action detected in task" error? , it looks like my error should be that I tried to write a role, and put a playbook in my role/tasks/main.yml. And the solution is to specify only a list of tasks in the tasks/main.yml file. Like this:
---
- name: My first task
my_module:
parameter1: value1
So my file looks like this:
---
- name: using a module
ansible.builtin.command: echo hello there
So I am using a module, just like in the example shown elsewhere on StackOverflow, but still I get the error message. What am I missing?
This is for Ansible 2.9 on RHEL 7.7. Thanks.
You are using ansible v2.9.
The (optional) full <namespace>.<collection>.<module_name> you are using in your task is only valid starting from ansible v2.10.
Use the short name: ansible.builtin.command => command.
You can also switch to the ansible v2.9 version on the documentation on the site to prevent this kind of problem when copy/pasting. See the dropdown on the top left
From the information you provided here it doesn't appear that you're using an actual module, but instead you've placed a task list file in a module search path. Modules are implemented as programming language code that gets bundled and piped over the connection plugin to be executed in order to carry out task work on the managed host in the inventory.
I have the following Ansible role which simply does the following:
Create a temporary directory.
Download Goss, a server testing tool, into that temporary directory.
Upload a main Goss YAML file for the tests.
Upload additional directories for additional included tests.
Here are a couple places where I'm using it:
naftulikay.python-dev
naftulikay.ruby-dev
Specifically, these playbooks upload a local file adjacent to the playbook named goss.yml and a directory goss.d again adjacent to the playbook.
Unfortunately, it seems that Ansible logic has changed recently, causing my tests to not work as expected. My role ships with a default goss.yml, and it appears that when I set goss_file: goss.yml within my playbook, it uploads degoss/files/goss.yml instead of the Goss file adjacent to my playbook.
If I'm passing the name of a file to a role, is there a way to specify that Ansible should look up the file in the context of the playbook or the current working directory?
The actual role logic that is no longer working is this:
# deploy test files including the main and additional test files
- name: deploy test files
copy: src={{ item }} dest={{ degoss_test_root }} mode=0644 directory_mode=0755 setype=user_tmp_t
with_items: "{{ [goss_file] + goss_addtl_files + goss_addtl_dirs }}"
changed_when: degoss_changed_when
I am on Ansible 2.3.2.0 and I can reproduce this across distributions (namely CentOS 7, Ubuntu 14.04, and Ubuntu 16.04).
Ansible searches for relative paths in role's scope first, then in playbook's scope.
For example if you want to copy file test.txt in role r1, search order is this:
/path/to/playbook/roles/r1/files/test.txt
/path/to/playbook/roles/r1/test.txt
/path/to/playbook/roles/r1/tasks/files/test.txt
/path/to/playbook/roles/r1/tasks/test.txt
/path/to/playbook/files/test.txt
/path/to/playbook/test.txt
You can inspect your search_path order by calling ansible with ANSIBLE_DEBUG=1.
To answer your question, you have to options:
Use filename that doesn't exist within role's scope. Like:
goss_file: local_goss.yml
Supply absolute path. For example, you can use:
goss_file: '{{ playbook_dir }}/goss.yml'
Ansible doesn't apply search logic if the path is absolute.
I am using the zzet.rbenv role on my playbook. It has a files/default-gems file that it copies to the provisioned system.
I need my playbook to check for a myplaybook/files/default-gems and use it if it exists, using the zzet.rbenv/files/default-gems if otherwise.
How can I do that?
After some research and trial/error. I found out that Ansible is not capable of checking if files exist between roles. This is due to the way role dependencies (which roles themselves) will get expanded into the one requiring it, making it part of the playbook. There are no tasks that will let you differentiate my_role/files/my_file.txt from required_role/files/my_file.txt.
One approach to the problem (the one I found the easiest and cleanest) was to:
Add a variable to the my_role with the path to the file I want to use (overriding the default one)
Add a task (identical to the one that uses the default file) that checks if the above variable is defined and run the task using it
Example
required_role
# Existing task
- name: some task
copy: src=roles_file.txt dest=some/directory/file.txt
when: my_file_path is not defined
# My custom task
- name: my custom task (an alteration of the above task)
copy: src={{ my_file_path }} dest=/some/directory/file.txt
when: my_file_path is defined
my_role
#... existing code
my_file_path: "path/to/my/file"
As mentioned by Ramon de la Fuente: this solution was accepted into the zzet.rbenv repo :)
I have packages of Ansible roles that I would like to import into a project.
If I organise them by subdirectory I run into problems relating to dependency relative paths
i.e the shared role needs to know its relative location of where it would be installed if it uses meta dependencies
I would like to be able to just reference everything to the directory the playbook is being run from though this doesn't work
roles/roleA/meta
---
dependencies:
- { role: "{{ playbook_dir }}/roles/shared_roles/roleB"}
roles/shared_roles/roleB
...
I've tried multiple options and running out of ideas.
I looked into roles-path http://docs.ansible.com/intro_configuration.html#roles-path
Though I don't really want to have to uniquely name all roles as they ought to be namespaced / grouped.
Thanks
You could basically use ansible-galaxy to install the roles within ~/.ansible/roles/ path.
The path of .ansible in my macOS machine is in: ~/.ansible/roles/
All you need to do is just create a requirements.yml file which looks something like this:
- src: git+https://<githubURL-Master-role>.git
scm: git
name: Master-role
- src: git+https://<githubURL-dependent1-role>.git
scm: git
name: dependent1-role
- src: git+https://<githubURL-dependent2-role>.git
scm: git
name: dependent2-role
Run this command to install your roles in ~/.ansible/roles/ path:
sudo ansible-galaxy -vvv -r install requirements.yml
This will basically set your roles in the ~/.ansible/roles/ path. To understand it better please follow this documentation https://docs.ansible.com/ansible/latest/reference_appendices/galaxy.html.
and then, like you have already mentioned, you should add all the dependent roles in your ##path/master-role/meta/main.yml file even before executing the anisble-galaxy command, in-order to execute the dependent roles before the master-role, when you run your master-role playbook.
The ##path/master-role/meta/main.yml file looks something like this:
galaxy_info:
author: Jithendra
description: blah...blah...blah
min_ansible_version: 1.2
galaxy_tags:'[]'
dependencies:
- { role: 'Master-role, when: blah == "true"'} #when condition is optional
- { role: 'dependent1-role, when blah == "false"'}
- { role: 'dependent2-role, when blah == "false"'}
Solved it by enforcing that all shared modules reference the name of the shared directory in all dependencies.
I wanted to leave this up to the calling project and hoped that dependencies would be relative to the role directory.
The solution works though and provides namespacing so I can include multiple roles with the same name as long as they are in separate directories.
I now have a project that includes 3 separate packages of roles
PLAY RECAP ********************************************************************
staging : ok=214 changed=5 unreachable=0 failed=0
Its all built using Maven, each shared group being a maven dependency. If anybody reads this and it helps i'll share the structure / poms etc.