Can I include multiple tasks in include_tasks from tasks/main.yml? - ansible

I would like to include multiple variables and tasks from my main task file, however I receive the following error when I attempt to do so:
ERROR! unexpected parameter type in action: <class 'ansible.parsing.yaml.objects.AnsibleSequence'>
...
The offending line appears to be:
- name: install and configure [application]
^ here
Here's my tasks/main.yml file in the role:
---
- name: install and configure [application]
include_vars:
- dependencies.yml
- directories.yml
- installations.yml
include_tasks:
- pre-setup.yml
- [application-23].yml
- database.yml
- [application-4].yml
- update.yml
- additional-components.yml
- ldap.yml
- test.yml
I suspect my formatting or syntax is invalid but I'm not precisely sure how to fix it.
I'd prefer to make my variables available globally at this time.

An ansible task can only do a single action, i.e. contain only one module call
The include_tasks module does not accept a list in the file/free-form parameter, only one single file name
The include_vars module can eventually read several files if you load a full directory with the dir option.
There are filenames that look a little weird in your included tasks and might cause errors. Do your file names really contain square brackets ([]) ? They are markers for lists and might be interpreted as such.
From the info I have so far, this is all I can propose to fix your current failing task:
- name: Include variables
include_vars: "{{ item }}"
loop:
- dependencies.yml
- directories.yml
- installations.yml
- name: Play needed tasks in order
include_tasks: "{{ item }}"
loop:
- pre-setup.yml
- application-23.yml
- database.yml
- application-4.yml
- update.yml
- additional-components.yml
- ldap.yml
- test.yml
Meanwhile, I suggest you take some time to read the doc a little more and maybe get familiar with the concept of roles as the above does not look like a good design at first glance.

Related

Invoking multiple playbooks with include inside a block of Ansible

I am trying to have a block in Ansible which will invoke multiple playbooks using include if a specific flag is set. I am trying to achieve something similar to below:
- hosts: localhost
tasks:
- block:
- include: script1.yml
- include: script2.yml
- include: script3.yml
when: flag|bool
This snippet throws an error stating ERROR! unexpected parameter type in action: <type 'bool'>
Thanks in advance!
The plays can't be included in a block. Quoting from ansible.builtin.include Synopsis
Files with a list of plays can only be included at the top level.
As a result, only Play keywords can be applied. The condition when is not among them.

Ansible - using include_role from within an include_tasks action

I have a file containing some tasks. One of the tasks in this file uses include_role to execute a bunch of tasks from a role.
# tasks.yml
- name: task-1
include_role:
name: my-role
- name: task-2
...
I have my main playbook which calls the tasks in tasks.yaml from a with_items loop:
# main.yml
tasks:
- name: main-task
include_tasks: tasks.yaml
with_items: "{{ items.values()|list }}"
When this playbook is run I get the following errors:
ERROR! 'include_role' is not a valid attribute for a Play.
The error appears to have been in '.../tasks.yml': line 1, column 3, but may be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: task-1
^ here
Ansible appears to not like the way include_role is being used in the tasks file. I am not sure if the syntax is wrong somewhere or if doing it this way is not supported. Any ideas?
Test it with anither role first. I would remove the with_items for include as second option, may not work.

ansible write variable to local file

I have the following ansible playbook that writes the content of the variable "hello" as a message (I got this code from an example online). I tried modifying it so it would write this to a local file however I got an error. The modified code and error message are below:
original code (successful):
- hosts: all
vars:
hello: world
tasks:
- name: Ansible Basic Variable Example
debug:
msg: "{{ hello }}"
modified code (unsuccessful):
- hosts: all
vars:
hello: world
tasks:
- name: Ansible Basic Variable Example
- local_action: copy content={{hello}} dest=~/ansible_logfile
debug:
msg: "{{ hello }}"
error message:
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to have been in '/space/mathewLewis/towerCodeDeploy/playBooks/test.yml': line 5, column 5, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: Ansible Basic Variable Example
^ here
I would like to know how to write a variable to a file correctly
It's a simple syntax error.
A Task is an entry in the list of tasks, which in YAML is designated by a - (dash).
Task names are optional in Ansible.
Both copy and debug are modules, which are supposed to be a task's "action".
What the error message is telling you is that the task with name: Ansible Basic Variable Example does not have an action, which is because your local_action is a separate task, indicated by a -.
Fixing your example with appropriate names for the tasks:
- name: Write variable to file
local_action: copy content="{{hello}}" dest=~/ansible_logfile
- name: Output the variable
debug:
msg: "{{ hello }}"
Thomas Hirsh's answer is correct. However, I found this representation less confusing (I'm a newbie to ansible):
- name: "Controller"
hosts: "controller.jeff.ddns.net"
tasks:
- name: "Register a variable to be shared with the clients"
set_fact: shared_fact="Brother"
- name: "Client"
hosts: "client.jeff.ddns.net"
tasks:
- name: "writing to hostvars.json"
local_action: copy content="{{hostvars | to_json(indent=4) }}" dest="hostvars.json"
This example has two plays. The controller play only sets a variable. The client is what actually writes to the file. In this case, hostvars has a complicated structure, so I used the to_json(indent=4) filter to convert to a good .json file, suitable for use with jq .

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

Ansible use task return varible in variable templates

I am trying to craft a list of environment variables to use in tasks that may have slightly different path on each host due to version differences.
For example, /some/common/path/v_123/rest/of/path
I created a list of these variables in variables.yml file that gets imported via roles.
roles/somerole/varables/main.yml contains the following
somename:
somevar: 'coolvar'
env:
SOME_LIB_PATH: /some/common/path/{{ unique_part.stdout }}/rest/of/path
I then have a task that runs something like this
- name: Get unique path part
shell: 'ls /some/common/path/'
register: unique_part
tags: workflow
- name: Perform some actions that need some paths
shell: 'binary argument argument'
environment: somename.env
But I get some Ansible errors about variables not being defined.
Alternatively I tried to predefine the unique_part.stdout in hopes of register overwriting predefined variable, but then I got other ansible errors - failure to template.
Is there another way to craft these variables based on command returns?
You can also use facts:
http://docs.ansible.com/set_fact_module.html
# Prepare unique variables
- hosts: myservers
tasks:
- name: Get unique path part
shell: 'ls /some/common/path/'
register: unique_part
tags: workflow
- name: Add as Fact per for each hosts
set_fact:
library_path: "{{ unique_part.stdout }}"
# launch roles that use those unique variables
- hosts: myservers
roles:
- somerole
This way you can dynamicaly add variable to your hosts before using them.
The vars files gets evaluated when it is read by Ansible. Your only chance would be to include a placeholder which you then later have to replace yourself, like this:
somename:
somevar: 'coolvar'
env:
SOME_LIB_PATH: '/some/common/path/[[ unique_part.stdout ]]/rest/of/path'
And then later in your playbook you can replace that placeholder:
- name: Perform some actions that need some paths
shell: 'binary argument argument'
environment: '{{ somename.env | replace("[[ unique_part.stdout ]]", unique_part.stdout) }}'

Resources