Ansible fact is undefined error in conditional - mongodb

Below is the playbook
---
- name: stop agent process
shell: "ps -ef | grep -v grep | grep -w {{ MONGODB_AGENT_PROCESS }} | awk '{print $2}'"
register: running_agent_processes
- name: stop mongod process
shell: "ps -ef | grep -v grep | grep -w {{ MONGODB_SERVER_PROCESS }} | awk '{print $2}'"
register: running_mongod_processes
- name: combine processes
set_fact:
all_processes: "{{ running_agent_processes.stdout_lines + running_mongod_processes.stdout_lines }}"
- name: Kill all processes
shell: "kill {{ item }}"
with_items: "{{ all_processes }}"
when: ansible_facts[ansible_hostname] != primary
- wait_for:
path: "/proc/{{ item }}/status"
state: absent
with_items: "{{ all_processes }}"
ignore_errors: yes
register: killed_processes
when: ansible_facts[ansible_hostname] != primary
- name: Force kill stuck processes
shell: "kill -9 {{ item }}"
with_items: "{{ killed_processes.results | select('failed') | map(attribute='item') | list }}"
when: ansible_facts[ansible_hostname] != primary
I have stored a fact called "primary" which stores the primary of a mongodb replica set in a previous step in the playbook.
I just want to compare the ansible_facts[ansible_hostname] with my primary fact. If they are not equal, I would like to kill processes.
The error I am getting is below:
fatal: [lpdkubpoc01d.phx.aexp.com]: FAILED! => {"msg": "The
conditional check 'ansible_facts[ansible_hostname] != primary' failed.
The error was: error while evaluating conditional
(ansible_facts[ansible_hostname] != primary): 'ansible_facts' is
undefined\n\nThe error appears to have been in
'/idn/home/sanupin/stop-enterprise-mongodb/tasks/stopAutomationAgent.yml':
line 11, column 3, but may\nbe elsewhere in the file depending on the
exact syntax problem.\n\nThe offending line appears to be:\n\n
all_processes: "{{ running_agent_processes.stdout_lines +
running_mongod_processes.stdout_lines }}"\n- name: Kill all
processes\n ^ here\n"} fatal: [lpdkubpoc01c.phx.aexp.com]: FAILED! =>
{"msg": "The conditional check 'ansible_facts[ansible_hostname] !=
primary' failed. The error was: error while evaluating conditional
(ansible_facts[ansible_hostname] != primary): 'ansible_facts' is
undefined\n\nThe error appears to have been in
'/idn/home/sanupin/stop-enterprise-mongodb/tasks/stopAutomationAgent.yml':
line 11, column 3, but may\nbe elsewhere in the file depending on the
exact syntax problem.\n\nThe offending line appears to be:\n\n
all_processes: "{{ running_agent_processes.stdout_lines +
running_mongod_processes.stdout_lines }}"\n- name: Kill all
processes\n ^ here\n"} fatal: [lpdkubpoc01e.phx.aexp.com]: FAILED! =>
{"msg": "The conditional check 'ansible_facts[ansible_hostname] !=
primary' failed. The error was: error while evaluating conditional
(ansible_facts[ansible_hostname] != primary): 'ansible_facts' is
undefined\n\nThe error appears to have been in
'/idn/home/sanupin/stop-enterprise-mongodb/tasks/stopAutomationAgent.yml':
line 11, column 3, but may\nbe elsewhere in the file depending on the
exact syntax problem.\n\nThe offending line appears to be:\n\n
all_processes: "{{ running_agent_processes.stdout_lines +
running_mongod_processes.stdout_lines }}"\n- name: Kill all
processes\n ^ here\n"}
Can someone help me with comparing an ansible_fact with a set_fact fact?

You can comparing use directly ansible facts without write ansible_facts before. Just use as when: ansible_hostname != primary

Related

In RunDeck from the bash script file manual error trigger adds multiple rows under the activities tab

In RunDeck in the bash script I am triggering a Linux error to cause job execution failure
CODE=`echo $RESULT | head -n1 | cut -c2`
if [ $CODE != '0' ];
then
exit 1
fi
Strange thing is that I am getting four records(failed) instead of one under the activity tab
Next I tried to add sleep 20 right above exit 1 and it logged one record only. As I see some processes still running in RunDeck after exit 1 command and it continues adding rows in activities. Any Idea how to wait until everything is finished to add only one row under the activity tab?
EDIT
Here is full definition
#!/bin/bash
set –e
URL="https://my_url"
MY_COMMAND="command_name"
RAW_DATA="[null,\"${MY_COMMAND}\",{}]"
echo "Raw Data ${RAW_DATA}"
RESULT=$(curl "$URL/${MY_COMMAND}" \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H 'User-Agent: my_user_agent' \
--data-raw $RAW_DATA)
echo $RESULT
CODE=`echo $RESULT | head -n1 | cut -c2`
if [ $CODE != '0' ];
then
exit 1
fi
EDIT 2 - Added Job Definition(YAML)
- defaultTab: output
description: JOB_DESCRIPTION
executionEnabled: true
id: 125cb755-3eaa-49f8-a8b8-dc1004238a44
loglevel: INFO
loglimit: 10MB
loglimitAction: truncate
loglimitStatus: failed
name: JOB_NAME
nodeFilterEditable: false
notification:
onfailure:
email:
attachLog: true
attachLogInFile: true
recipients: someone#mail.com
notifyAvgDurationThreshold: null
plugins:
ExecutionLifecycle: {}
retry: '3'
schedule:
dayofmonth:
day: '*'
month: '*'
time:
hour: '04'
minute: '05'
seconds: '0'
year: '*'
scheduleEnabled: true
schedules: []
sequence:
commands:
- script: "#!/bin/bash\n\n"
keepgoing: false
strategy: node-first
timeout: 1h
uuid: 125cb755-3eaa-49f8-a8b8-dc1004238a44
Your job is configured to retry 3 times in case of error (the original failed execution + 3 retries = 4 failed executions), you can change this behavior by editing your job > Go to the "Other" tab > Retry textbox. More info here.

Helm upgrade - preserve value of an environment variable when if condition is not met

I am doing helm upgrade --install with the --reuse-values option. I want to conditionally update the value of an environment variable if a certain condition is met and if the condition is not met preserve the already existing value. I've tried to achieve that this way:
env:
- name: RELEASE_DATE
value: "{{ if eq .Values.config.myCondition "testValue" }}{{ date "2006-01-02T15:04:05" .Release.Time }}{{ end }}"
or
env:
- name: RELEASE_DATE
value: "{{ if eq .Values.config.myCondition "testValue" }}{{ date "2006-01-02T15:04:05" .Release.Time }}{{ else }}{{ .Values.someOtherValue }}{{ end }}"
where .Values.someOtherValue is never really existing, or even doing it this way
env:
{{- if eq .Values.config.deployedService "ftmFrontend" }}
- name: RELEASE_DATE
value: "{{ if eq .Values.config.myCondition "testValue" }}{{ date "2006-01-02T15:04:05" .Release.Time }}{{ end }}"
{{- end }}
I was expecting that if I use a --reuse-values option that the values are going to be kept/preserved if the condition is not met, but instead it always deletes it and leaves it empty.
The option does work however, when there is no condition clause and only the value from the chart is referenced. It's only not working if the if statement is used.
How can I use if statement and still preserve the value if the condition is not met?

Extracting specific value from stderr_lines

This is my ansible script
- name: show1
debug:
msg: "{{response.stderr_lines}}"
Here is the output
msg:
- Using endpoint [https://us-central1-aiplatform.googleapis.com/]
- CustomJob [projects/123456/locations/us-central1/customJobs/112233445566] is submitted successfully.
- ''
- Your job is still active. You may view the status of your job with the command
- ''
- ' $ gcloud ai custom-jobs describe projects/123456/locations/us-central1/customJobs/112233445566'
- ''
- or continue streaming the logs with the command
- ''
- ' $ gcloud ai custom-jobs stream-logs projects/123456/locations/us-central1/customJobs/112233445566'
Here I want to extract custom Job ID which is 112233445566
I used the select module like below
- name: show
debug:
msg: "{{train_custom_image_unmanaged_response.stderr_lines | select('search', 'describe') | list }}"
and it gives me this output
msg:
- ' $ gcloud ai custom-jobs describe projects/123456/locations/us-central1/customJobs/112233445566'
But I just want the job id as specified above. Any idea about that ?
Thanks.
You selected the line you are interested in. From that now you want to isolate the job id number in the end. You can do that using a regular expression like so:
- set_fact:
line: "{{train_custom_image_unmanaged_response.stderr_lines | select('search', 'describe') | list }}"
- debug:
msg: "{{ line | regex_search('.*/customJobs/(\\d+)', '\\1') }}"
This will give you all the digits in the end of the line after /customJobs/. See https://docs.ansible.com/ansible/latest/user_guide/playbooks_filters.html#searching-strings-with-regular-expressions

Sorting ansible output

Below is my ansible task output.
TASK [debug] **************************************************************************************************** **************************************
ok: [server01] => {
"my_updates.stdout_lines": [
"",
"",
"Title : Definition Update for Windows Defender Antivirus - KB2267602 (Definition 1.297.486.0)",
"",
"",
""
]
}
ok: [server02] => {
"my_updates.stdout_lines": [
"",
"",
"Title : 2020-08 Cumulative Update for Windows Server 2016 for x64-based Systems",
"",
"",
""
]
}
I only want entries
Definition Update for Windows Defender Antivirus - KB2267602 (Definition 1.297.486.0)
2020-08 Cumulative Update for Windows Server 2016 for x64-based Systems
So i tried below method,
- name: Fetch Update List
shell: echo {{ my_updates.stdout_lines }} | tr -s ' ' | sed 's/[][]//g' | sed 's/u,//g' | sed 's/u //g' | sed 's/ u//g' | sed 's/),/)/g'
delegate_to: 127.0.0.1
register: my_sec_result
when: ansible_os_family == "Windows" and my_updates.stdout_lines | length |int > 0
- debug:
var: my_sec_result.stdout_lines
but this wont help, it gives me below output
TASK [debug] ******************************************************************************************************************************************
ok: [server01] => {
"my_sec_result.stdout_lines": [
"Title : Definition Update for Windows Defender Antivirus - KB2267602 (Definition 1.297.486.0) "
]
}
ok: [server02] => {
"my_sec_result.stdout_lines": [
"Title : 2020-08 Cumulative Update for Windows Server 2016 for x64-based Systems "
]
}
How to get only these Entries, At present only one entry each found on each server. There can be multiple entries.
Definition Update for Windows Defender Antivirus - KB2267602 (Definition 1.297.486.0)
2020-08 Cumulative Update for Windows Server 2016 for x64-based Systems
In your initial list, reject lines which are empty strings then remove the prepending "Title : " with the regexp_replace filter. The following task does it all in one:
- name: Display updates
debug:
msg: "{{ my_updates.stdout_lines | reject('eq', '') | map('regex_replace', 'Title : (.*)', '\\g<1>') | list }}"
Update: As pointed out by #Vladimir, in this case your can replace reject with select for a cleaner template string:
- name: Display updates
debug:
msg: "{{ my_updates.stdout_lines | select() | map('regex_replace', 'Title : (.*)', '\\g<1>') | list }}"

How to grab last two lines from ansible (register stdout) initialization of kubernetes cluster

This is the piece of my playbook file for the question:
- name: Initialize the Kubernetes cluster using kubeadm
command: kubeadm init --config /etc/kubernetes/kubeadminit.yaml
register: init_output
- name: Copy join command to local file
local_action: copy content={{ init_output.stdout }} dest="./join-command"
Currently join-command contains the entire stdout (30+ lines of text) for content. What I want to grab is just the last two lines of init_output.stdout instead of the entire output. I've looked into using index reference (ie. init_output.stdout[#]) but I don't know that the output will always be the same length and I don't know how to use indexes to grab more than one line, but i'm fairly certain that the last two lines will always be the join command. Any suggestions?
Select last 2 lines from the list stdout_lines
- local_action: copy content={{ init_output.stdout_lines[-2:] }} dest="./join-command"
It's possible to format the lines in a block. For example
- local_action:
module: copy
content: |
{{ init_output.stdout_lines[-2] }}
{{ init_output.stdout_lines[-1] }}
dest: "./join-command"
To append the lines in a loop try
- local_action:
module: lineinfile
path: "./join-command"
line: "{{ item }}"
insertafter: EOF
create: true
loop: "{{ init_output.stdout_lines[-2:] }}"
I encountered this kind of issue and did not want to copy the join command to a local file so I did a set_fact instead this way:
- set_fact:
join_cmd: '{{ init_output.stdout_lines[-2][:-2] }}{{ init_output.stdout_lines[-1] }}'
I did this...
- name: kubeadm init
shell: |
kubeadm init --control-plane-endpoint \
localhost \
--control-plane-endpoint kube-api.local >> /tmp/run_kube_init.sh
when: master == "yes"
- name: Get join from master
fetch:
src: "/tmp/run_kube_init.sh"
dest: "/tmp/run_kube_init.sh"
flat: yes
when: ansible_hostname == 'k-master'
- name: Add join file to nodes
copy:
src: "/tmp/run_kube_init.sh"
dest: "/tmp/run_kube_init.sh"
when: master == "no"
- name: Extract join token for nodes
shell: tail -n +2 /tmp/run_kube_init.sh | head -n -1 | awk '{print $5}' | tail -n 1
register: JOIN_TOKEN
- set_fact:
join_token: "{{ JOIN_TOKEN.stdout }}"
- name: join nodes
shell: |
kubeadm join kube-api.local:6443 \
--token {{ JOIN_TOKEN.stdout }} \
--discovery-token-unsafe-skip-ca-verification
when: master == "no"
- name: rm /tmp/run_kube_init.sh
ansible.builtin.file:
path: /tmp/run_kube_init.sh
state: absent