I am fairly new to Ansible, and I have been googling about this particular issue described below:
name: GETTING OUTPUT AND STORING IT INTO A VARIABLE
connection: network_cli
cli_command:
command: show configuration interface ge-0/0/0 | display set | match unit
register: A
Above, the task will run the command show configuration interface ge-0/0/0 on Juniper router, the out put will contain a bunch of key words unit. This output is then stored in a variable A.
I want to count the number of occurence key word unit appear in the output and store it in a variable COUNT. How can I do that? Ijust need an example.
Thanks and have a good weekend!!
If you have this task:
- name: get output and store
connection: network_cli
cli_command:
command: show configuration interface ge-0/0/0 | display set | match unit
register: show_config_result
Then you use a subsequent set_fact task to store the value you want in a variable:
- name: store unit count in unit_count variable
set_fact:
unit_count: "{{ (show_config_result.stdout_lines|length)-1 }}"
Related
I am trying to create a script which is only selecting an item within a list, with a regex.
In my case, based on a certain condition which should be triggered wheter a specific character set is present of not within the name, then just select that item.
So far, I have produced the following code within an ansible Role:
- name: "Set_initial_regex"
set_fact:
name_regex: ".*((-a)+(\\d)?)\\..*\\.company\\..+"
# This regex should select any FQDN with "-a" followed by an optional number within its name (e.g. fqdn-test-a1.test.company.local)
- name: "Debug"
debug:
msg: "{{ name | split(',') | regex_search(name_regex) }}"
The name variable is provided with --extra-vars and could be multiple, but usually there are only two of them. They are separated by a comma - hence the split.
The code above works fine with | first and | last instead of regex_search, but I am looking for something more custom.
At the moment, the returned output is (for example):
"msg": [
"fqdn-test-a1.test.company.local",
"fqdn-test-b1.test.company.local"
]
And the desired output should -in this case- be just
"msg": [
"fqdn-test-a1.test.company.local"
]
Thanks in advance for any help or insights you might provide.
I found out the way to do this; the following code works fine for this purpose:
- name: "Debug"
debug:
msg: "{{ name | split(',') | select('search', name_regex) }}"
vars:
name_regex: ".*((-a)+(\\d)?)\\..*\\.company\\..+"
This returns the desired output mentioned above.
With select(), this works fine, as it should create a subset of a list, which is what I needed in this case.
How can I put the discovered values into loop variables so that they are on one line using Ansible task? I have now task like this
- name: Updating test.conf
lineinfile:
path: "/root/test.conf"
regexp: "test="
line: "test={{ hostvars[item]['ansible_env'].SSH_CONNECTION.split(' ')[2] }}"
state: present
with_nested:
- "{{groups['app']}}"
It needs that when invoking the job, it takes the IP addresses from the servers that are in the app group and puts them on a single line. Currently, it performs such a substitution twice with which they are replaced and finally there is only one address in the test parameter.
I need format after task like this:
test=1.1.1.1, 2.2.2.2
While jinja2 is heavily inspired from python, its does not allow you to do all the same operations. To join a list your would have to do something like:
- debug:
msg: "{{ myvar | join(',') }}"
vars:
myvar:
- foo
- bar
When in doubt, always use a simple playwook with a debug task to validate your jinja code.
My hosts have 3 network IP addresses and one of them is needed later in my playbook.
In my playbook I have ran the following setup module:
- name: Gather Networks Facts into Variable
setup:
register: setup
- name: Debug Set Facts
debug:
var: setup.ansible_facts.ansible_ip_addresses
The provides the following output:
{
"setup.ansible_facts.ansible_ip_addresses": [
"10.0.2.15",
"fe80::85ae:2178:df12:8da0",
"192.168.99.63",
"fe80::3871:2201:c0ab:6e39",
"192.168.0.63",
"fe80::79c5:aa03:47ff:bf65",
"fd89:8d5f:2227:0:79c5:aa03:47ff:bf65",
"2a02:c7f:9420:7100:79c5:aa03:47ff:bf65"
]
}
I am trying to find a way to find the 192.168.0.63 by searching using the first three octets or 192.168.0. I also then want to get that value into a fact so I can use this later in my playbook.
What would be the best way to search and find that value with Ansible or Jinja2?
Will this do?
- set_fact:
my_fact: "{{ (setup.ansible_facts.ansible_ip_addresses | select('match','192.168.0.') | list)[0] }}"
If there are multiple values matching the pattern, it will get the first one in order.
I write this:
- name: test for seed
debug:
var: hostvars|json_query("*.ansible_host")
And it prints every host. But this does not filter hosts:
- name: test for seed
debug:
var: hostvars|json_query("*[?ansible_host=='192.168.56.101']")
It just prints an empty list, while I'm sure this host exists. This is the relevant inventory line:
[build-servers]
build-server ansible_host=192.168.56.101
Am I doing something wrong?
You should filter resulting list, not original hash: * | [?ansible_host=='192.168.168.21']
P.S. you usually don't want to use var option of debug module to print Jinja statements, use msg instead.
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) }}'