I have a file which has the following data
!
multiply 4 and 5
multiply 5 and 6
!
add 3 to 4
add 8 to 4
!
sub 3 from 6
sub 9 from 5
!
!
div 6 by 2
div 8 by 1
I want to read only add commands from the file.
Using lookup plugin I was able to read the data of the entire file.
But I don't know how to read only the specific add commands from the file
Here's the code that I've written.
---
- name: Extracting the Add commands from the File
hosts: 127.0.0.1
connection: local
vars:
contents: "{{lookup('file', 'file1.txt')}}"
tasks:
- name: Printing the Add commands of the File
debug:
var: contents
I am stuck at this point.Could anyone help me out of how to read the specific part of a file in ansible.
Use with_lines. The play below
- hosts: localhost
vars:
my_data_file: "{{ playbook_dir }}/data.txt"
my_commands: []
tasks:
- set_fact:
my_commands: "{{ my_commands + [ item ] }}"
with_lines: "cat {{ my_data_file }}"
when: item is search('^add')
- debug:
var: my_commands
gives
"my_commands": [
"add 3 to 4",
"add 8 to 4"
]
Related
i'am trying to start application with a ansible playbook.
the variable inst got all the required software id's:
WEB
TS3
SQL
....
how can i create a loop for all the software id's and run the same command on all of them?
---
- name: "start sw"
become: yes
command: "swstart {{ inst }}"
retries: 3
failed_when: ( instance_start.rc not in [ 0 ] )
You should first of all define your list as a variable on your playbook .
After that you can use
with_items
Like that:
---
- hosts: all
remote_user: root
vars:
softwares:
- WEB
- TS3
- SQL
vars_files:
- /softwares.yml # if you need to import data from file
tasks:
- name: display your softwares using debug module
debug:
msg: "An item: {{ item }}"
with_items: "{{ softwares }}"
I hope that this can help you to fix your issue.
Use with_items as below
---
- name: "start sw"
become: yes
command: "swstart {{ item }}"
with_items: "{{ inst }}"
Documentation:
https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#with-items
The documentation for import_tasks mentions
Any loops, conditionals and most other keywords will be applied to the included tasks, not to this statement itself.
This is exactly what I want. Unfortunately, when I attempt to make import_tasks work with a loop
- import_tasks: msg.yml
with_items:
- 1
- 2
- 3
I get the message
ERROR! You cannot use loops on 'import_tasks' statements. You should use 'include_tasks' instead.
I don't want the include_tasks behaviour, as this applies the loop to the included file, and duplicates the tasks. I specifically want to run the first task for each loop variable (as one task with the standard with_items output), then the second, and so on. How can I get this behaviour?
Specifically, consider the following:
Suppose I have the following files:
playbook.yml
---
- hosts: 192.168.33.100
gather_facts: no
tasks:
- include_tasks: msg.yml
with_items:
- 1
- 2
msg.yml
---
- name: Message 1
debug:
msg: "Message 1: {{ item }}"
- name: Message 2
debug:
msg: "Message 2: {{ item }}"
I would like the printed messages to be
Message 1: 1
Message 1: 2
Message 2: 1
Message 2: 2
However, with import_tasks I get an error, and with include_tasks I get
Message 1: 1
Message 2: 1
Message 1: 2
Message 2: 2
You can add a with_items loop taking a list to every task in the imported file, and call import_tasks with a variable which you pass to the inner with_items loop. This moves the handling of the loops to the imported file, and requires duplication of the loop on all tasks.
Given your example, this would change the files to:
playbook.yml
---
- hosts: 192.168.33.100
gather_facts: no
tasks:
- import_tasks: msg.yml
vars:
messages:
- 1
- 2
msg.yml
---
- name: Message 1
debug:
msg: "Message 1: {{ item }}"
with_items:
- "{{ messages }}"
- name: Message 2
debug:
msg: "Message 2: {{ item }}"
with_items:
- "{{ messages }}"
It is not possible. include/import statements operate with task files as a whole.
So with loops you'll have:
Task 1 with Item 1
Task 2 with Item 1
Task 3 with Item 1
Task 1 with Item 2
Task 2 with Item 2
Task 3 with Item 2
Task 1 with Item 3
Task 2 with Item 3
Task 3 with Item 3
I'm trying to store content of the certificate.pem file to a variable using the following task:
- name: Get the contents of the root certificate
shell: cat {{ ca_certificate_file }}
- name: Decode data and store as fact
set_fact:
root_certificate_content: "{{ ca_certificate_data.stdout }}"
The variable root_certificate_content has the entire content of the file but instead of a new line it is replacing it with a space. I there a way I can get the certificate content as it is in the variable.
Try lookup plugins
- set_fact:
root_certificate_content: "{{ lookup('file', ca_certificate_file) }}"
For example "the variable "root_certificate_content" should have the contents of the file as it is. If the file has a new line then it should come as the new line". The play below
- hosts: localhost
tasks:
- set_fact:
root_certificate_content: "{{ lookup('file', 'cert1') }}"
- debug:
msg: "{{ root_certificate_content.split('\n') }}"
with the file (3 lines with newline each)
$ cat cert1
line 1
line 2
line 3
gives the content of the variable root_certificate_content (3 lines with newline each)
"msg": [
"line 1",
"line 2",
"line 3"
]
"if you just show the value of root_certificate_content without using .split('\n') in the debug msg"
- debug:
var: root_certificate_content
then the newlines can be seen in the string
"root_certificate_content": "line 1\nline 2\nline 3"
I have a dynamic inventory which returns me my hosts addresses.
But sometimes, I would like to apply some configuration to a limited number of hosts.
A sample with N hosts but only 5 are echoed:
- name: "Run silly shell script"
shell: |
echo {{ item }}
exit 0
with_items: "{{ hosts | only(5) }}"
to get the first X elements from a list, use: list_var[:X].
full example as PB below:
---
- hosts: localhost
gather_facts: false
vars:
list_var:
- 1
- 2
- 3
- 4
- 5
- 6
tasks:
- name: print full list
debug:
var: list_var
- name: print list of first 3 elements
debug:
var: list_var[:3]
hope it helps.
As a follow up to this question How to read a particular part of file in ansible. I am trying to do the same but by using roles. The variables are stored in vars files
Here is the vars/main.yml file in the role
add:
commands: []
sub:
commands: []
multiply:
commands: []
div:
commands: []
Here's the code in tasks/main.yml file
- name: Getting the Add Commands
set_fact:
add.commands: "{{add.commands + [ item ]}}"
with_lines: "cat {{ {{playbook_dir}}/testing/files/data.txt }}"
when: item is search('^add')
- debug:
var: add.commands
- name: Getting the Sub Commands
set_fact:
sub.commands: "{{sub.commands + [ item ]}}"
with_lines: "cat {{ {{playbook_dir}}/testing/files/data.txt }}"
when: item is search('^sub')
- debug:
var: sub.commands
- name: Getting the Multiply Commands
set_fact:
multiply.commands: "{{multiply.commands + [ item ]}}"
with_lines: "cat {{ {{playbook_dir}}/testing/files/data.txt }}"
when: item is search('^multiply')
- debug:
var: multiply.commands
- name: Getting the Div Commands
set_fact:
div.commands: "{{div.commands + [ item ]}}"
with_lines: "cat {{ {{playbook_dir}}/testing/files/data.txt }}"
when: item is search('^div')
- debug:
var: div.commands
Code to execute the role
testing.yml
- name: Main Program
hosts: localhost
roles:
- testing
I thought that I would get the add commands for add.commands and similarly for others but I am getting the following error
"msg": "The variable name 'add.commands' is not valid. Variables must start with a letter or underscore character, and contain only letters, numbers and underscores."
Can anyone tell me how to troubleshoot this error and why it happened in the first place.
This is as expected and the error clearly states that.
Also as per ansible,
Variable names should be letters, numbers, and underscores. Variables
should always start with a letter.
So . can't be part of the variable name.