Ansible-lint Throwing error "ERROR! 'raw' is not a valid attribute for a Play" - ansible

I have yaml file with just couple of tasks that i'm including in another Yaml file.
The play book is running fine, but when i run ansible-lint against the yaml file with tasks, it's throwing the error
ERROR! 'raw' is not a valid attribute for a Play.
- name: Clusters Info
raw: "show-clusters-info cluster-id={{item}}"
register: Clusters_Info
ignore_errors: true
- name: Show XMS Info
raw: "show-xms"
register: show_xms_info
ignore_errors: true

A playbook is a list of plays. Your above example is only a list of tasks (which is I guess included in your playbook later on).
From the ansible-lint README
Usage: ansible-lint [options] [playbook.yml [playbook2 ...]]|roledirectory
So if you pass a file name directly to ansible-lint, it will try to analyze it as a playbook. The error you get is therefore expected. Either pass a playbook (which includes your task file) or a role directory (defaulting to current dir if empty) to analyze a playbook or a role.

Related

Send the output from Ansible to a file [duplicate]

This question already has answers here:
Ansible - Save registered variable to file
(5 answers)
Closed 2 months ago.
I am trying to gain knowledge in Ansible and solve a few problems:
I want to, not sure if it is even possible. Can the output be saved local to the server the playbook is being run on?
in the example, I am just printing to terminal I am running the playbook. I it not much use when there is a large amount of data. I would like it to be saved in a file on the server I am running the playbook instead.
---
- name: list os version
hosts: test
become: true
tasks:
- name: hostname
command: hostname
register: command_output
- name: cat /etc/redhat-release
command: cat redhat-release chdir=/etc
- name: Print output to console
debug:
msg: "{{command_output.stdout}}"
I really want the output to go to a file. I cant find anything about if this is possible.
as you can read on the ansible documentation, you can create a local configuration file ansible.cfg inside the directory vers you have your playbook and then set the proper config log file to output all the playbook output inside: Ansible output documentation
By default Ansible sends output about plays, tasks, and module arguments to your screen (STDOUT) on the control node. If you want to capture Ansible output in a log, you have three options:
To save Ansible output in a single log on the control node, set the log_path configuration file setting. You may also want to set display_args_to_stdout, which helps to differentiate similar tasks by including variable values in the Ansible output.
To save Ansible output in separate logs, one on each managed node, set the no_target_syslog and syslog_facility configuration file settings.
To save Ansible output to a secure database, use AWX or Red Hat Ansible Automation Platform. You can then review history based on hosts, projects, and particular inventories over time, using graphs and/or a REST API.
If you just want to output the result of the task on file, use the copy module on the localhost delegation
---
- name: list os version
hosts: test
become: true
tasks:
- name: hostname
command: hostname
register: command_output
- name: cat /etc/redhat-release
command: cat redhat-release chdir=/etc
- name: Create your local file on master node
ansible.builtin.file:
path: /your/local/file
owner: foo
group: foo
mode: '0644'
delegate_to: localhost
- name: Print output to file
ansible.builtin.copy:
content: "{{command_output.stdout}}"
dest: /your/local/file
delegate_to: localhost

Ansible: How do I run an entire playbook based on a condition?

Context: provisioning fresh new servers.
I would like to provision them just once especially the update part.
After launching the first playbook bootstrap.yml I made it leave a file in a folder for me to know that the playbook ran well.
So then in the same playbook I would have to add a condition above every task (which I did) to check for the existance of this file.
If file exists skip running the playbook against all those machines who have that file.
Problem: How do I add the condition to run the playbook only if the file isn't found? I don't want to add a "when:" statement for each of my own tasks I find it silly.
Question: Does anyone have a better solution that maybe solves this with a single line or a parameter in the inventory file that I haven't thought of?
edit:
This is how i check for the file
- name: Bootstrap check
find:
path: /home/bot/bootstrapped-ok
register: bootstrap
and then when condition would be:
when: bootstrap.matched == 0
so if file is not found run the entire playbook.
I think you may be over-complicating this slightly. Would it be accurate to say "I want to bail early on a playbook without error under a certain condition?"
If so, you want "end_host"
How do I exit Ansible play without error on a condition
Just begin with a check for the file, and end_host if it's found.
- name: Bootstrap check
stat:
path: /home/bot/bootstrapped-ok
register: bootstrap
- name: End the play if previous provisioning was successful
meta: end_host
when: bootstrap.stat.exists == True
- name: Confinue if bootstrap missing
debug:
msg: "Hello"

ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path

I trying to create a simple paybook with a common role. Unfortunately I get stymied by ansible. I have looked up and down the internet for solution for this error.
The setup:
I am running ansible 2.7.4 on Ubuntu 18.04
directory structure:
~/Ansible_Do
playbook.yml
inventory (hosts file)
/roles
/common
/defaults
main.yml (other variables)
/tasks
main.yml
richard_e.yml
/vars
vars_and_stuff.yml (vault)
I have a simple playbook.yml
---
# My playbook 1
- hosts: test
- name: Go to common role to run tasks.
roles:
- common
tasks:
- name: echo something
shell: echo $(ip addr | grep inet)
...
I run this command to start the playbook:
~/Ansible_Do$ ansible-playbook -vv --vault-id #prompt -i ~/Ansible_Do/inventory playbook.yml
I enter the vault password continuing the playbook.
The playbook starts pulls facts from the test group of servers. Then reads the role and works to /roles/common. That calls the /common/tasks/main.yml file. This is where the error happens.
The error appears to have been in '/home/~/Ansible_Do/roles/common/tasks/main.yml': line 8, column 3
# Common/tasks file
---
- name: Bring variable from vault
include_vars:
file: vars_and_stuff.yml
name: My_password
- name: Super Richard <====== Error
become: yes
vars:
ansible_become_pass: "{{ My_password }}"
- import_tasks: ./roles/common/tasks/ricahrd_e.yml
...
The ./roles/common/tasks/ricahrd_e.yml is a simple testing task.
---
- name: say hi
debug:
msg: "Active server."
...
The error on "- name". I have checked online and in the Ansible docs to see if there is a key I'm missing. I found an example for include_vars in a /role/tasks (https://gist.github.com/halberom/ef3ea6d6764e929923b0888740e05211) showing proper syntax (I presume) in a simple role. The code works as parts, but not together.
I have reached what I can understand. I feel that is error is utterly simple and I am missing something (forest for the trees).
The error means exactly what it says, except the "module name" is not misspelled in your case, but missing altogether.
This...
- name: Super Richard <====== Error
become: yes
vars:
ansible_become_pass: "{{ My_password }}"
... is not a valid task definition, it does not declare an action.
An action in Ansible is a call to a module, hence "misspelled module name".
The error comes after name, because that's where Ansible expects the name of the "module" that you want to call, e.g. shell in your first example.
You are probably assuming that become is a "module", but it is not.
It is a "playbook keyword", in this case applied on the task level, which has the effect that you become another user for this task only.
But as the task has no action, you get this error.
See docs:
Playbook keywords
Understanding privilege escalation
After a bit of work I got the playbook to work. Knowing that 'become' is not a task was the start. I also found out how to pull the proper vars from the vault.
# My first playbook 1
- hosts: test
become: yes
vars_files:
- ./roles/common/vars/vars_and_stuff.yml
vars:
ansible_become_pass: "{{ My_password }}"
roles:
- common
tasks:
- name: echo something
shell: echo $(ip addr | grep inet)
The vars file access the vault and then vars: pulls the password used by become. With become in force I ran the other tasks in the common role with a last standalone task. Lastly, don't try to - name: at the top level of the playbook as it trigger a hosts undefined error.

Execute role in play based on a failure [duplicate]

I'm trying to spin up an AWS deployment environment in Ansible, and I want to make it so that if something fails along the way, Ansible tears down everything on AWS that has been spun up so far. I can't figure out how to get Ansible to throw an error within the role
For example:
<main.yml>
- hosts: localhost
connection: local
roles:
- make_ec2_role
- make_rds_role
- make_s3_role
2. Then I want it to run some code based on that error here.
<make_rds_role>
- name: "Make it"
- rds:
params: etc <-- 1. Let's say it fails in the middle here
I've tried:
- name: this command prints FAILED when it fails
command: /usr/bin/example-command -x -y -z
register: command_result
failed_when: "'FAILED' in command_result.stderr"
As well as other things on within the documentation, but what I really want is just a way to use something like the "block" and "rescue" commands , but as far as I can tell that only works within the same book and on plays, not roles. Does anyone have a good way to do this?
Wrap tasks inside your roles into block/rescue thing.
Make sure that rescue block has at least one task – this way Ansible will not mark the host as failed.
Like this:
- block:
- name: task 1
... # something bad may happen here
- name: task N
rescue:
- assert: # we need a dummy task here to prevent our host from being failed
that: ansible_failed_task is defined
Recent versions of Ansible register ansible_failed_task and ansible_failed_result when hit rescue block.
So you can do some post_tasks in your main.yml playbook like this:
post_tasks:
- debug:
msg: "Failed task: {{ ansible_failed_task }}, failed result: {{ ansible_failed_result }}"
when: ansible_failed_task is defined
But be warned that this trick will NOT prevent other roles from executing.
So in your example if make_rds_role fails ansible will apply make_s3_role and run your post_tasks afterwards.
If you need to prevent it, add some checking for ansible_failed_task fact in the beginning of each role or something.

Forced to create file beforehand ansible conditional include

# "Run application specific configuration scripts"
- include: "app_cfg/{{ app_name }}.yml"
when: "{{ app_conf[app_name].app_cfg }}"
ignore_errors: no
tags:
- conf
I thought that I will be able conditionally include application specific playbooks simply by setting one variable to the true/false value like so:
app_conf:
my_app_1:
app_cfg: no
my_app_2:
app_cfg: yes
Unfortunately Ansible is forcing me to create file beforehand:
ERROR: file could not read: <...>/tasks/app_cfg/app_config.yml
Is there a way I can avoid creating a bunch of empty files?
# ansible --version
ansible 1.9.2
include with when is not conditional in common sense.
It actually includes every task inside include-file and append given when statement to every task included task.
So it expects include-file to exist.
You can try to handle this using with_first_found and skip: true.
Something like this:
# warning, code not tested
- include: "app_cfg/{{ app_name }}.yml"
with_first_found:
- files:
- "{{ app_conf[app_name].app_cfg | ternary('app_cfg/'+app_name+'.yml', 'unexisting.file') }}"
skip: true
tags: conf
It supposed to supply valid config name if app_cfg is true and unexisting.file (which will be skipped) otherwise.
See this answer about skip option.

Resources