Whenever I run my playbook the following warning comes up:
[WARNING]: While constructing a mapping from /etc/ansible/roles/foo/tasks/main.yml, line 17, column 3, found
a duplicate dict key (file). Using last defined value only.
The relevant part of my main.yml in the tasks folder is like this:
(line 17 is the task to clean the files which seems a bit off so I guess the problem is with the previous "script" line)
- name: Run script to format output
script: foo.py {{ taskname }} /tmp/fcpout.log
- name: Clean temp files
file: path=/tmp/fcpout.log state=absent
And my vars file:
---
my_dict: {SLM: "114", Regular: "255", Production: "1"}
taskid: "{{my_dict[taskname]}}"
To run my playbook I do:
ansible-playbook playbooks/foo.yml --extra-vars "server=bar taskname=SLM"
What I'm trying to do is to take the command line arguments, set the hosts: with the "server" parameter, get the taskname and from that find out to which id refers to. This id is used as the first input to my python script which runs remotely.
The playbook works fine, but I don't understand why I get a warning. Could anyone explain what is wrong here?
Are you sure there is not more around the line 17? This warning is triggered when there are two identical keys in a task (or in general anywhere in a dict).
The warning claims there are two file keys, suggesting the task looks like this:
- name: Clean temp files
file: ...
file: ...
A common mistake is that people forget to start a new list item for the next task. The following would be valid, while the above is not:
- name: Clean temp files
file: ...
- file: ...
I noticed Ansible sometimes gets the lines or even files wrong in error messages. I have seen it complaining about tasks/main.yml while the problem actually was in handlers/main.yml. If no such task with duplicate file keys can be found near that line, search the whole file or even other files for it. If there is nothing like this anywhere to be found, then it would appear you found a bug in Ansible. In that case you should repot it on github.
I faced this warning because of using duplicate options in a module. For example, accidentally I used "host" option 2 times in the module definition like below:
name: Create NEW DB User
mysql_user:
name: NEW USER NAME
login_user: root
login_password: Root Passwd
password: NEW USER'S PASSWD
host: localhost
priv: 'DB NAME.*:ALL,GRANT'
state: present
host: localhost
The warning has been disappeared by omitting one of the host options.
Related
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"
Create a file named simplefile.txt - write a task in the main.yml file in present in fresco_when\tasks folder.- the task is to move the created simplefile.txt file to created directory i.e move the create file to /home/user/test folder.- move only if the file doesn't exist. using when in the playbook
I created a text file and then wrote this main.yml file:
hosts: localhost
tasks:
name: copy a file, but do not copy if the file already exists
command: cp challenge/fresco_when/defaults/simplefile.txt /home/usr/test/ creates=simplefile.txt
I got this error :
ERROR! unexpected parameter type in action: <class 'ansible.parsing.yaml.objects.AnsibleSequence'>
The error appears to be in '/projects/challenge/fresco_when/tasks/main.yml': line 1, column 3, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
hosts: localhost
^ here
SCORE:0%
Please let me know what is wrong with the code
Based solely on the path in your question, it appears you have used the playbook structure for a tasks file within that playbook
For clarity, playbooks need to specify the hosts to which they will apply, but tasks within a playbook are going to apply to all the hosts in that play (err, more or less)
The contents of tasks/*.yml inside a playbook directory should be a yaml list consisting only of tasks (- command:, - debug:, that kind of thing), and not - hosts:)
Separately, while this isn't what you asked, you are re-implementing - copy: as ansible is likely going to warn you about when you run that task
The ansible-y way of doing that is:
- name: copy a file, but do not copy if the file already exists
copy:
src: challenge/fresco_when/defaults/simplefile.txt
dest: /home/usr/test/simplefile.txt
I have installed ansible using following commands.
sudo apt-add-repository ppa:ansible/ansible
sudo apt update
sudo apt install ansible
After i followed this Link. By using that i created a yml file called test.yml ( the code is shown below)
- name: test my new module
hosts: 127.0.1
tasks:
- name: run the new module
my_test:
name: 'hello'
new: true
register: testout
- name: dump test output
debug:
msg: '{{ testout }}'
Then i run ansible-playbook ./test.yml . I get following error.
I have no idea where i missed. Any idea is appreciated. Thank you so much.
sato:~/play_around_with_ansible$ ansible-playbook ./test.yml
[WARNING]: provided hosts list is empty, only localhost is available. Note
that the implicit localhost does not match 'all'
ERROR! no action detected in task. This often indicates a misspelled module name, or incorrect module path.
The error appears to be in '/home/ven/play_around_with_ansible/test.yml': line 4, column 5, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
tasks:
- name: run the new module
^ here
You are missing the inventory file. Create inventory file in current folder or in the directory of your choice and provide the inventory file path to the ansible-playbook command as below or you can mention the default location of your host file in ansible.cfg
inventory file contents (sample)
[127.0.1]
localhost ansible_connection=local
command
ansible-playbook -i inventory ./test.yml
In the above command inventory is the file name with path.
seems your 'yaml' file was not able to recognize the path for custom module. Even I am new to custom module development. As per the standards you should keep the .py file in "library" directory and create the .ymal file outside of library directory.
This will help your yaml file to look into ./library directory for modules.
Hei guys,
After a few days of struggling, I've decided to write my issue here.
I have an ansible(2.7) task that that has a single variable, which points to a host var that uses the file lookup plugin.
Thing is that this works, for one host, but I have 6 hosts, where a value inside the lookup file should be different for each of the hosts.
Can you pass a variable inside the file that is looked up?
I'm new to ansible and don't master it fully.
Has someone encountered this before?
Task:
- name: Copy the file to its directory
template:
src: file.conf
dest: /path/to/file
vars:
file_contents: "{{file_configuration}}"
-----
hostvar file:
file_configuration:
- "{{lookup('file', './path/to/file') | from_yaml}}"
----
file that is looked up:
name: {{ value that should be different per host }}
driver:
long_name: unchanged value.
You should have 6 host_vars files, one for each host. In that host_var file, set your desired value.
Ansible documentation is here
E.g.
https://imgur.com/a/JCbnNBT
Content of host1.yml
---
my_value: something
Content of host2.yml
---
my_value: else
Ansible automagicly sees the host_var folder. It looks in that folder and searches for files which exactly match a host in the play.
So ensure your host_var/filename.yml matches the hostname in your play!
If there is a match, then it'll use that .yml file for that specific host.
I have a issue when i am trying to have a conditional statement based on the variable set in my inventory file. Below is the details. My inventory file looks like this.
[webserver]
server1
server2
[appserver]
server1
[webserver:vars]
TYPE=w
[appserver:vars]
TYPE=a
Now when i am trying to add a condition in my task like
name: abc
shell: run this task
when: TYPE == "w"
name: cde
shell: run this task
when: TYPE == "a"
Now when i run the Play 1 it picks up the first variable and stores it but when it tries to run the task second time (Play2) its still have the same variable and fails. I have two plays 1 for web and other for app. Please let me know what may be the issue.
You can't define the same variable twice in an inventory file, even if it belongs to another group.
After the parsing of your inventory file the only "TYPE" known to Ansible will be the last one defined in your inventory file. In your case that would be one within appserver.
If you switch the order of your variables you will face the exact opposite behavior I guess.
In my opinion you should change the way to determine which tasks to run.
Little example:
- name: some task for webservers
shell: run this webserver task
when: run_webserver_task
- name: some task for appservers
shell: run this appserver task
when: run_appserver_task
Please see this link as evidence for my bold statement:
https://github.com/ansible/ansible/issues/6538
OR
You could try to design your inventory file the yamlish way instead of using an ini file. Please see:
http://docs.ansible.com/ansible/latest/intro_inventory.html