How to use when condition in Ansible? - variables

I cannot figure out this Ansible task
i run my playbook ansible-playbook play.yml -e proxyHost=$proxyHost -e proxyPort=$proxyPort
- name: Set proxy when provided
set_fact: proxyproperty=" -Dhttp.proxyHost={{ proxyHost }} -Dhttp.proxyPort={{ proxyPort }} -Dhttps.proxyHost={{ proxyHost }} -Dhttps.proxyPort={{ proxyPort }} -Dhttp.nonProxyHosts=localhost|127.0.0.1|{{ ip }}|{{ fqdn }}|{{ hostName }}"
when: proxyHost is defined
So why is it when i have not set $ProxyHost this ansible task is still being triggered? What am i missing?

Python (hence Ansible) differentiates between an undefined variable and a variable with an empty value.
You define the proxyHost variable in Ansible, but in case when $proxyHost is undefined in shell/environment, you assign proxyHost an empty value.
You need, for example, to compare it to an empty string:
when: proxyHost != ''

Related

Ansible uri module loop on files

I'm using the Ansible uri module to make a PUT API call and using all files in a directory as parameters.
I have a list of files in a directory, and I want to use the name and the content of each file in the API call
First of all i tried to list all files.
- name: "Find pipeline files in folder"
find:
paths: "/app/pipelines"
patterns: "pipeline-*.json"
file_type: "file"
register: pipe_files
- debug:
var: pipe_files
Then I want to make a loop on each file in the directory and call the API
- name: PUT PIPE
uri:
method: PUT
headers:
Content-Type: "application/json"
url: "https://api_url/**FILE_NAME**"
user: "user"
password: "user_pass"
body_format: json
body: "{{ lookup('file','/app/pipelines/**FILE_NAME.json**') }}"
validate_certs: no
force_basic_auth: yes
validate_certs: no
return_content: yes
register: pipeline_created
until: pipeline_created.status == 200
When I deploy the content, I don't have the exact filename, how can I make the loop on each file to call the API?
Best regards,
Thanks in advance.
pipe_files is a register from a find task. You can have a look at returned values in the find module documentation. You can also examine your debug task output to better get accustomed with the content of the variable.
Anyway. The list of file objects returned will be in pipe_files.files. Each element is a dict where the information you need is in the path key.
You may test with
- name: PUT pipeline
uri:
method: PUT
headers:
Content-Type: "application/json"
url: "https://api_url/{{ item.path | basename }}" # depends on input list content
user: "user"
password: "user_pass"
body_format: json
body: "{{ lookup('file', item.path) }}" # content
validate_certs: no
force_basic_auth: yes
validate_certs: no
return_content: yes
until: pipeline_created.status == 200
loop: "{{ pipe_files.files }}"
register: pipeline_created # result will become a list

Add Single Quotes around a list in Ansible

I have a list of items services and each needs to be wrapped in single quotes to configure some parameters.
The simplest solution I saw posted was:
"{{services | match('quote') | join(' OR ')}}"
This only wrapped the first element in the list in a single quote but not the remaining.
I also tried some variations of match regex.
Finally I tried adding the single quote manually in the data source, then joining. The first element retained the single quotes but subsequent were stripped off? What is going on here?
Right now they are static from the inventory
i.e.:
---
inventory:
hosts:
host1:
procs:
- splunkd.*
services:
- 'some service name'
- 'another service name'
- 'SplunkForwarder'
I need the end result to be
"Name='some service name' OR Name='another service name'"
Currently with the services single quoted in variable the quotes are stripped or ignored.
Result
Name=some service or Name=another service
you could cut your problem by using loop:
tasks:
- name: set var
set_fact:
result: "{{ result | d('') + _i + _o }}"
loop: "{{ services }}"
loop_control:
extended: yes
vars:
_i: "Name='{{ item }}'"
_o: "{{ '' if ansible_loop.last else ' OR ' }}"
- name: display result
debug:
var: result
result:
ok: [localhost] => {
"result": "Name='some service name' OR Name='another service name' OR Name='SplunkForwarder'"
}
with your vars:
- name: Join services
set_fact:
joined_services: "{{ joined_services | d('') + service + serviceAppend }}"
loop: "{{ services }}"
loop_control:
extended: yes
vars:
service: "'{{ item }}'"
serviceAppend: "{{ '' if ansible_loop.last else ' OR ' }}"

rundeck - api - ansible - uri - Add Key passwd - Value not good

I try to add a new key password, facing the issue with the API. The key is successfully created. But, when is used is not good value.
I try to generate the key with Postman, and the key is created but the value is not correct. When I use the same value manually on the interface then it works fine.
I deleted before the key (manually)
postman:
curl --location --request POST 'https://rundeck.dev.xxxxxx.com/api/11/storage/keys/project_name/gitlab?authtoken=FdMORu02flT2R5zI' \
--header 'Content-type: application/x-rundeck-data-password' \
--header 'Cookie: AWSALB=D6Kpid4U/o7uHy9G0Pg40uvILs1toq367tPzPiCskEha7YGM3eCJldNnKyMFYBrkwOXIyvVmKAsIe9yIRm/8xOX/0mj4LIRy2wMl3qYpOvXKw3x9e+rXnjd8gEjX; AWSALBCORS=D6Kpid4U/o7uHy9G0Pg40uvILs1toq367tPzPiCskEha7YGM3eCJldNnKyMFYBrkwOXIyvVmKAsIe9yIRm/8xOX/0mj4LIRy2wMl3qYpOvXKw3x9e+rXnjd8gEjX' \
--data-raw 'XKmB1wkjsdfikjkHkKwCEW'
I try to add SCM with the key generated but still is not working. However, when I create manually the key with the same name and value the SCM import is working.
I have the same error with ansible with URI.
I deleted before the key (manually)
I create a playbook to access rundeck API
- name: "Create Keys {{ project_name }} - gitlab"
uri:
url: "{{ RD_URL }}{{ API_11 }}/storage/keys/{{ project_name }}/gitlab?authtoken={{ RD_TOKEN }}"
method: POST
body_format: raw
validate_certs: no
status_code: [201, 409]
return_content: true
headers:
Content-Type: application/x-rundeck-data-password
X-Rundeck-Auth-Token: "{{ RD_TOKEN }}"
body: '{{ GITLAB_TOKEN }}'
You can create the password via API 40 and Rundeck 3.4.9 with the following call:
#!/bin/sh
# protocol
protocol="http"
# basic rundeck info
rdeck_host="localhost"
rdeck_port="4440"
rdeck_api="40"
rdeck_token="hcFPFbJHFIqerwaRsWtuhPnPAIUoY4Kt"
# api call
curl --location --request POST "$protocol://$rdeck_host:$rdeck_port/api/$rdeck_api/storage/keys/mypass" \
--header "X-Rundeck-Auth-Token: $rdeck_token" \
--header "Content-Type: application/x-rundeck-data-password" \
--data-raw "12345"
Also, I created a Job example to test the password content:
- defaultTab: nodes
description: ''
executionEnabled: true
id: 5658bb13-f9e9-494b-839c-d18f25057a4e
loglevel: INFO
name: HelloWorld
nodeFilterEditable: false
options:
- name: opt1
secure: true
storagePath: keys/mypass
valueExposed: true
plugins:
ExecutionLifecycle: null
scheduleEnabled: true
sequence:
commands:
- exec: echo ${option.opt1}
keepgoing: false
strategy: node-first
uuid: 5658bb13-f9e9-494b-839c-d18f25057a4e
Running the job, you can see the password value.
Also tested using the SCM config.
So, make sure that you're pointing to the right key in your SCM config and ensure to use the latest API version (40 at this moment) in your API Call.

Create Ansible variables for username and password with special characters

I have my vcenter username "Administrator#vsphere.local" and password as "Test#2100$1", if I create variable as below:
vars:
- username: 'vsphere.local\Administrator'
vars_prompt:
- name: password
prompt: Enter Vcenter password to authenticate fence user
It authenticates with wrong username and password, when checked in the configuration it shows:
username = vsphere.localAdministrator {without the slash}
password = Test#2100 {without the $1 characters in the password text}.
Kindly suggest me how to key in the AD domain username "vsphere.local\Administrator" and password with special character as ansible variable.
so a simple test to check the value off user/password:
i have added private: no to see the password typed
- name: test
hosts: localhost
vars:
username: vsphere.local\Administrator
vars_prompt:
- name: password
prompt: Enter Vcenter password to authenticate fence user
private: no
tasks:
- debug:
msg: password for {{ username }} is {{ password}}
result:
ok: [localhost] =>
msg: password for vsphere.local\Administrator is Test#2100$1

how to reference variable variable in jinja2 template

In one of my ansible roles I would like to set up a basic network/interfaces stanza, like this:
auto eth1
ifaces eth1 inet dhcp
dns-nameserver {{ ansible_eth1.ipv4.address }}
dns-search maas
I have variables, and I create the stanza with the jinja2 template:
auto {{ iface }}
ifaces {{ iface}} inet dhcp
dns-nameserver {{ ansible_{{ iface }}.ipv4.address }}
dns-search maas
Can I reference a variable variable in a template? I also tried creating a variable in the ansible yaml, like nserver: ansible_{{iface}}.ipv4.address, that didn't work either!
You can use built-in hostvars dict variable to reference variables of host.
auto {{ iface }}
iface {{ iface }} inet dhcp
dns-nameserver {{ hostvars[inventory_hostname]['ansible_'+ iface]['ipv4']['address'] }}
dns-search maas
inventory_hostname is name of current host as known by Ansible.