Reference a variable from another file - ansible

I have a play
---
- hosts: all
name: Full install with every component
gather_facts: no
roles:
- oracle_client
- another_role
- and_so_on
where each of the roles has a dependency on a single common role which is supposed to load all vairable I will require later:
- name: Include all default extension files in vars/all and all nested directories and save the output in test
include_vars:
dir: all
name: test
- debug:
msg: "{{test}}"
the common role folder structure has
common
vars
all
ansible.yml
common.yml
oracle_client.yml
where common.yml specifies a app_drive: "D:" and then oracle_client.yml tries to do oracle_base: "{{ app_drive }}\\app\\oracle"
At runtime I get
fatal: [10.188.27.27]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'app_drive' is undefined\n\nThe error appears to be in '<ansible-project-path>/roles/common/tasks/main.yml': line 18, column 5, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n - debug:\n ^ here\n"}
Per documentation "the files are sorted alphabetically before being loaded." so I was expecting to have access to a varible from another file? How should I do this instead?
TLDR;
I want to to load all my variables from one place but have them logically splits (I went for separate files) but cross reference the splits. How is that best done?

Looks like it works as I expect it to and in my example above it is the
- debug:
msg: "{{test}}
part that fails.

Related

Ansible how to run a role from other role

I have an ansible role named "role-a" and "role-b"
When running "role-a" i wish that "rule-b" will be executed as well.
in the main.yml of "role-a' i have added the following
include_role: role-b
But i'm ending with the following error
ERROR! 'name' is a required field for include_role.
The error appears to be in
'/home/ubuntu/mid-project/ansible/roles/role-a/tasks/main.yml': line
2, column 3, but may be elsewhere in the file depending on the exact
syntax problem.
The offending line appears to be:
include_role: role-b ^ here
The correct syntax for this would be
- include_role:
name: role-b

Ansible returning "no action detected in task"

I'm running ansible-playbook version 2.7.6+dfsg-1 on Debian Buster. I have a playbook that includes another, like so:
---
- hosts: "{{ target }}"
tasks:
- include_tasks: set-timezone.yaml
The contents of the included set-timezone.yaml is as follows:
---
- hosts: all
tasks:
- name: set timezone to MST
timezone:
name: America/Denver
When I run the playbook, I get an error telling me this:
no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to have been in '/etc/ansible/playbooks/set-timezone.yaml': line 2, column 3, but maybe elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
---
- hosts: all
^ here
I saw a similar question in which the asker mispelled the name of the module, but I'm quite sure "timezone" is spelled correctly and this module is in 2.7 as per the official docs. I tried removing hosts: all from set-timezone.yaml and got this error instead: "included task files must contain a list of tasks".
and got this error instead: "included task files must contain a list of tasks".
Correct, the "list of tasks" part means exactly that: a yaml list made up of items that are themselves ansible tasks:
# cat set-timezone.yaml
---
- name: this is a task
debug: msg="hello, world"
- name: set timezone to MST
timezone:
name: America/Denver

Is there a way to abort execution when vars file is missing?

I would like to wrap the following with something that stops execution when the file is missing:
vars_files:
- "{{ customer }}.yml"
Not sure if there is something like that in Ansible (2.4).
You don't need to do anything ― if the file is missing Ansible stops by default. Example:
ansible-playbook playbook.yml --extra-vars customer=non_existing_file
produces the following error and stops the execution:
ERROR! vars file {{ customer }}.yml was not found
I suspect your customer variable is not set in the scope to be used in vars_files declaration, so use include_vars module instead:
- hosts: all
pre_tasks:
- include_vars:
file: "{{ customer }}.yml"
By default it produces an error if customer is undefined:
fatal: [localhost]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'customer' is undefined\n\nThe error appears to have been in '/Users/techraf/so48065296-is-there-a-way-to-abort-execution-when-vars-file-is-missing/playbook.yml': line 8, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n tasks:\n - include_vars:\n ^ here\n\nexception type: \nexception: 'customer' is undefined"}
If you are unhappy with the error message itself, you can prepend it with a task using assert or fail.

Including playbook in a playbook and defining environment file

I have an ansible playbook. When I run the playbook I specify which environment file to use.
ansible-playbook playbooks/release-deploy.yaml -i env/LAB3
Within the ansible-playbook I am calling another playbook and I want the same environment file to be used.
My current config is:
- include: tasks/replace_configs.yaml
So when I run the playbook, I get the error:
TASK [include] *****************************************************************
fatal: [10.169.99.70]: FAILED! => {"failed": true, "reason": "no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to have been in '/home/ansible/playbooks/tasks/replace_configs.yaml': line 2, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
---
- hosts: cac
^ here
The error appears to have been in '/home/ansible/playbooks/tasks/replace_configs.yaml': line 2, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
---
- hosts: cac
^ here
"}
tasks/replace_configs.yaml also needs to use env/LAB3
Looks like it doesn't know what cac is. Do I need to do another config ?
My current config is:
- include: tasks/replace_configs.yaml
This is not any "config", this is a line which includes a file containing tasks.
Let's look at the following "task":
The offending line appears to be:
---
- hosts: cac
^ here
It does not look like a task, it looks like a play. It most likely does not contain any module directive, so Ansible rightfully complains that there is no module name provided in the task it expected: no action detected in task.
When you use include directive in Ansible it puts the included content at the indentation level of the include, so when you include tasks, you should include only tasks
Your included file should look like:
---
- name: This is a task
debug: msg="One task"
- name: This is another task
debug: msg="Another task"
and should not contain any other definitions, particularly those belonging to a higher level.

ansible rsync or copy a randomly named file to a remote machine

I am using ansible 2.1 to either rsync or copy a file from the host machine to a remote one. The file is in a directory but has a random string as part of its name. I have tried using ls -d to get the name via the shell command and tried to register this value but apparently, the syntax I am using is causing the role to fail. Any thoughts on what I might be doing wrong?
---
- name: copying file to server
- local_action: shell cd /tmp/directory/my-server/target/
- local_action: shell ls -d myfile*.jar
register: test_build
- debug: msg={{ test_build.stdout }}
- copy: src=/tmp/directory/my-server/target/{{ test_build.stdout }} dest=/home/ubuntu/ owner=ubuntu group=ubuntu mode=644 backup=yes
become: true
become_user: ubuntu
become_method: sudo
exception
fatal: [testserver]: FAILED! => {"failed": true, "reason": "no action detected in task. This often indicates a misspelled module name, or incorrect module path.\n\nThe error appears to have been in '/home/user/test/roles/test-server/tasks/move.yml': line 2, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n---\n- name: transferring file to server\n ^ here\n\n\nThe error appears to have been in '/home/user/test/roles/test-server/tasks/synchronize.yml': line 2, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n---\n- name: transferring artifact to server\n ^ here\n"}
You should avoid shell commands if possible, it is Ansible anti-pattern.
In your case you can use fileglob lookup like follows:
- name: Copy file
copy:
src: "{{ lookup('fileglob','/tmp/directory/my-server/target/myfile*.jar', wantlist=true) | first }}"
dest: /home/ubuntu/
owner: ubuntu
group: ubuntu
mode: 644
backup: yes
If you 100% sure that there is only one such file, you can omit wantlist=true and | first – I used it as a safe net to filter only first entry, if there are many.
You need to simplify your commands. You also do not want to put a hyphen before a module name. This will cause a syntax error as it won't be able to identify that module as an action. You can only invoke one module per task. For example, this will not work;
- name: task one
copy: src=somefile dest=somefolder/
copy: src=somefile2 dest=somefolder2/
The two would need to be split into two separate tasks. The same for your playbook. Do the following:
- name: copying file to server
local_action: "shell ls -d /tmp/directory/my-server/target/myfile*.jar"
register: test_build
- debug: msg={{ test_build.stdout }}
- name: copy the file
copy: src={{ test_build.stdout }} dest=/home/ubuntu/ owner=ubuntu group=ubuntu mode=644 backup=yes
If possible, insert "become" in your playbook not in your tasks/main.yml file, unless you only want to use become for these two tasks and will be adding more tasks to the same playbook later on.
Note: The debug msg line is completely optional. It doesn't affect the results of the playbook in any way, all it will do is show you the folder/file name that was found as a result of the shell "ls" command.

Resources