Having some issues with my code and can't figure out the syntax error.
I'm trying to take output from a firewall and put it into an html file but i keep getting stuck. The command in its own separate file outputs a couple of lines of text. Note destination changed to protect it.
- hosts: firewall
gather_facts: no
tasks:
- name: Hardware Info
raw: show asset all
register: output
- local_action: lineinfile dest=dest destination regexp="{{item}}" insertafter="test" line={{item}}
with_items: output.stdout_lines
Error:
local_action: lineinfile dest=dest insertafter="test"
line='{{item}}'
^ here We could be wrong, but this one looks like it might be an issue with missing quotes. Always quote template expression brackets
when they start a value. For instance:
with_items:
{{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
Change this line:
- local_action: lineinfile dest=dest destination regexp="{{item}}" insertafter="test" line={{item}}
To this:
- local_action: lineinfile dest=dest destination regexp="{{item}}" insertafter="test" line="{{item}}"
The extra quotes should help.
Note lineinfile is terrible from a configuration management point of view, I predict you'll pull your hair out in the future.
Related
I would like to use the lineinfile module to automatically fill an inventory file (inventory/hosts) from another inventory file that I use to deploy VMs on vsphere.
When the file is empty, there is no problem but, when it is already filled, the module does not insert the lines when it sees that they exist elsewhere in the file. But I need it to build my inventory file.
How I can do this?
Here is my piece of code:
- name: Add parameters for connection of VMs Windows
ansible.builtin.lineinfile:
path: /home/ansible/inventory/hosts
line: "{{ item }}"
with_items:
- '[{{ group_names[0] }}:vars]'
- ansible_user=administrator
- ansible_password='{{ lookup('file', '/home/ansible/directory/file_'+group_names[0] ) }}'
- ansible_connection=winrm
- ansible_port=5986
- ansible_winrm_server_cert_validation=ignore
delegate_to: localhost
It only inserts the ansible_password line for me, since the others exist for other groups of VMs. I also tried with blockinfile
I have an ansible playbook that has created a file (/tmp/values.txt) in each server with the following content
1.1.1.1
2.2.2.2
3.3.3.3
4.4.4.4
5.5.5.5
And I have a conf file named etcd.conf in the /tmp/etcd.conf with the following content
and I need to substitute the value of each line from /tmp/values.txt, so /tmp/etcd.conf will look like this:
SELF_IP=1.1.1.1
NODE_1_IP=2.2.2.2
NODE_2_IP=3.3.3.3
NODE_3_IP=4.4.4.4
NODE_4_IP=5.5.5.5
Is there a way I can do this? I used the following lookup method but it only works in the controll server
- name: Create etcd.conf
template:
src: etcd.conf.j2
dest: /tmp/etcd.conf
vars:
my_values: "{{ lookup('file', '/tmp/values.txt').split('\n') }}"
my_vars: [SELF_IP, NODE_1_IP, NODE_2_IP, NODE_3_IP, NODE_4_IP]
my_dict: "{{ dict(my_vars|zip(my_values)) }}"
You can use the slurp: task to grab the content for each machine, or use command: cat /tmp/values.txt and then examine the stdout_lines of its register:-ed variable to achieve that same .split("\n") behavior (I believe you'll still need to use that .split call after | b64decode if you use the slurp approach)
What will likely require some massaging is that you'll need to identify the group (which may very well include all) of inventory hostnames for which that command will produce content, and then grab the hostvar out of them to get all values
Conceptually, similar to [ hostvars[hv].tmp_values.stdout_lines for hv in groups[the_group] ] | join("\n"), but it'll be tedious to write out, so I'd only want to do that if you aren't able to get it to work on your own
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 .
I have a task in an Ansible playbook that is supposed to iterate with a list of users and do a lineinfile to enable access to a postgress database:
- name: Postgres localhost access
lineinfile:
dest: "{{postgres_dest}}/data/pg_hba.conf"
line: "host all {{item.user}} 127.0.0.1/32 trust"
regexp: "^host[\s\t]*all[\s\t]*{{item.user}}[\s\t]*127.0.0.1/32[\s\t]*trust"
insertbefore: EOF
with_items: "{{postgres_users}}"
notify: postgres reload
tags:
- postgres
- postgres_hba
the problem I'm getting is that ansible thinks that the {{item.user}} is not being escaped with "", which actually is not true, since this will expand due to the "" of the whole line. The exact error I get:
Syntax Error while loading YAML script, jenkins.yml
Note: The error may actually appear before this position: line 156, column 9
line: "host all {{item.user}} 127.0.0.1/32 trust"
regexp: "^host[\s\t]*all[\s\t]*{{item.user}}[\s\t]*127.0.0.1/32[\s\t]*trust"
^
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:
with_items:
- {{ foo }}
Should be written as:
with_items:
- "{{ foo }}"
any ideas on how to do this?
first of all, thanks to the guys in IRC on the #ansible channel :)
seems that the issue wasn't with the vars itself but with the un-scaped backslashes
changed the line to:
regexp: "^host[\\s\\t]*all[\\s\\t]*{{item.user}}[\\s\\t]*127.0.0.1/32[\\s\\t]*trust"
and now it works great
I have a playbook that registers three variables. I want to produce a CSV report of those three variables on all hosts in my inventory.
This SO answer suggests to use:
- local_action: copy content={{ foo_result }} dest=/path/to/destination/file
But that does not append to the csv file.
Also, I have to manually compose by comma separators in this case.
Any ideas on how to log (append) variables to a local file?
If you are wanting to append a line to a file rather than replace it's contents then this is probably best suited to the lineinfile module and utilising the module's ability to insert a line at the end of the file.
The equivalent task to the copy one that you used would be something like:
- name: log foo_result to file
lineinfile:
line: "{{ foo_result }}"
insertafter: EOF
dest: /path/to/destination/file
delegate_to: 127.0.0.1
Note that I've used the long hand for delegating tasks locally rather than local_action. I personally feel that the syntax reads a lot clearer but you could easily use the following instead if you prefer the more compact syntax of local_action:
- local_action: lineinfile line={{ foo_result }} insertafter=EOF dest=/path/to/destination/file