Add data from comand line in Ansible task - command-line

I have some task:
---
- name: Ansible multiple replace data in file {{ path_agentd_conf }}
replace:
path: "{{ item.path }}"
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"
with_items:
- {path: "{{ path_agentd_conf }}", regexp: "Server=127.0.0.1", replace: "Server={{ ip_zabbix_server }}"}
- {path: "{{ path_agentd_conf }}", regexp: "ServerActive=127.0.0.1", replace: "ServerActive={{ ip_zabbix_server }}"}
- {path: "{{ path_agentd_conf }}", regexp: "Hostname=Zabbix server", replace: "Hostname={{ ansible_hostname }}"}
- {path: "{{ path_agentd_conf }}", regexp: "# HostMetadata=", replace: "HostMetadata=73dc46da7abd1908951478965ca5b5be"}
And also i have variables in path /etc/ansible/roles/zabbix/zabbix-agent/agent/roles/agent/defaults/main.yml
---
# defaults file for agent
dir_download: /home/
path_agentd_conf: /etc/zabbix/zabbix_agentd.conf
url_zabbix: https://repo.zabbix.com/zabbix/6.0/ubuntu/pool/main/z/zabbix-release/zabbix-release_6.0-1+ubuntu20.04_all.deb
deb_zabbix: zabbix-release_6.0-1+ubuntu20.04_all.deb
ip_zabbix_server: 95.111.111.111
My first goal is, to use command line when I started playbook and change in line ip_zabbix_server: IP, for example ansible-playbook start.yaml -ip 55.55.55.55 and this IP should be replaced IP 95.111.111.111.
And second, is, to add also from command line in line - {path: "{{ path_agentd_conf }}", regexp: "# HostMetadata=", replace: "HostMetadata=73dc46da7abd1908951478965ca5b5be"} after numbers 73dc46da7abd1908951478965ca5b5be some worlds lxd mysq
- {path: "{{ path_agentd_conf }}", regexp: "# HostMetadata=", replace: "HostMetadata=73dc46da7abd1908951478965ca5b5be lxd mysq"}
I do not know is it passable in ansible or not ? I know that for example in bash it is possible, when we are using in bash scripts variables $1 $2 etc.
Could you please help? Thank you!

If I understood correctly, you want to modify this "default" value in the variables with one in command line:
Taking into consideration the order of the variables as you might know, Command Line prevails over what's already defined in roles, plays, tasks, defaults, etc.
So, for get that result you need to run your playbook like this:
ansible-playbook start.yaml -e "ip_zabbix_server=55.55.55.55"
basically it should be similar to bash but with the parameter -e | --extra-vars
For the second part I'm not sure but I would try if I can set that as variable and do in a similar way.

My first goal is, to use command line when I started playbook and change in line ip_zabbix_server
This a very common scenario of overriding a default role variable. You can have a look at where to put a variable for all possible solutions.
But in your specific case, to override from the command line, you would use an extra-vars:
ansible-playbook start.yaml --extra-vars ip_zabbix_server=55.55.55.55
And second, is, to add also from command line in line - {path: "{{ path_agentd_conf }}", regexp: "# HostMetadata=", replace: "HostMetadata=73dc46da7abd1908951478965ca5b5be"}
That one is trickier for 2 reasons:
you have hard-coded the list of dictionaries inside the task which makes it hard (not to say impossible) to overide
passing a long list of dictionaries directly on the command line is not really user friendly (but possible).
My below proposition is not the only solution and you can adapt depending on your exact requirement (see above link on variable precedence).
First add a new default variable in roles/agent/defaults/main.yml:
my_replace_list:
- {path: "{{ path_agentd_conf }}", regexp: "Server=127.0.0.1", replace: "Server={{ ip_zabbix_server }}"}
- {path: "{{ path_agentd_conf }}", regexp: "ServerActive=127.0.0.1", replace: "ServerActive={{ ip_zabbix_server }}"}
- {path: "{{ path_agentd_conf }}", regexp: "Hostname=Zabbix server", replace: "Hostname={{ ansible_hostname }}"}
- {path: "{{ path_agentd_conf }}", regexp: "# HostMetadata=", replace: "HostMetadata=73dc46da7abd1908951478965ca5b5be"}
Then modify your task to use that var:
- name: Ansible multiple replace data in file {{ path_agentd_conf }}
replace:
path: "{{ item.path }}"
regexp: "{{ item.regexp }}"
replace: "{{ item.replace }}"
with_items: "{{ my_replace_list }}"
We are then in the exact same situation as above for the zabbix server ip and the list can be overridden with an extra var in your command. The easiest way here is to declare the var in a separate file, e.g. my_list_override.yaml
my_replace_list:
- {path: "/toto", regexp: "from", replace: "to"}
- {path: "/titi", regexp: "a", replace: "b"}
You can then easily use that file to override your variable:
ansible-playbook start.yaml --extra-vars #/path/to/my_list_override.yml
Now, if you really want to pass that variable directly on the command line, it is possible but you will have to pass it as a correct json which is probably not the most user friendly method:
ansible-playbook start.yaml \
--extra-vars '{"my_replace_list":[{"path":"/toto","regexp":"from","replace":"to"},{"path":"/titi","regexp":"a","replace":"b"}]}'

Thank you all!
I just deleted line ip_zabbix_server: 95.217.188.202 from the file /etc/ansible/roles/zabbix/zabbix-agent/agent/roles/agent/defaults/main.yml, then add to lines variables {{ ip }}
- {path: "{{ path_agentd_conf }}", regexp: "Server=127.0.0.1", replace: "Server={{ ip }}"}
- {path: "{{ path_agentd_conf }}", regexp: "ServerActive=127.0.0.1", replace: "ServerActive={{ ip }}"}
and after I am using command ansible-playbook agent.yml --extra-vars ip=77.77.77.77 to add 77.77.77.77 to the line Server=127.0.0.1" and ServerActive=127.0.0.1.

Related

Ansible loop based on fact to Restart Kafka Connector Failed Tasks

Here I want to restart Kafka Connect tasks if they are in failed state using ansible-playbook, I have fetched connector tasks state using 'set_fact'
I want to create a loop over collected facts to restart Kafka Connector Tasks using connector name and task id.
tasks:
- name: Gethering Connector Names
uri:
url: "{{scheme }}://{{ server }}:{{ port_no }}/connectors"
user: "{{ username }}"
password: "{{ password }}"
method: GET
force_basic_auth: yes
status_code: 200
register: conn_stat
- name: Checking for Connector status
uri:
url: "{{scheme }}://{{ server }}:{{ port_no }}/connectors/{{ abc_conn_name }}/status"
user: "{{ username }}"
password: "{{ password }}"
method: GET
force_basic_auth: yes
loop: "{{ conn_name }}"
loop_control:
loop_var: abc_conn_name
vars:
conn_name: "{{ conn_stat.json }}"
register: conn_stat_1
- name: Gethering Failed task id
set_fact:
failed_connector_name_task_id: "{{ conn_stat_1 | json_query('results[].json[].{name: name ,id: [tasks[?state == `RUNNING`].id [] | [0] ]}') }}"
- name: Failed connector name with tasks id
ansible.builtin.debug:
var: failed_connector_name_task_id
Getting below values from fact, which I need to push into loop
"failed_connector_name_task_id": [
{
"id": [
0
1
],
"name": "test-connector-sample"
},
{
"id": [
0
1
],
"name": "confluent-connect"
},
{
"id": [
0
1
2
],
"name": "confluent-test-1"
}
]
},
"changed": false
}
value need to be posted
- name: Restart Connector Failed tasks
uri:
url: "{{scheme }}://{{ server }}:{{ port_no }}/connectors/**{{name of connector}}**/tasks/**{{task ID}}**/restart"
user: "{{ username }}"
password: "{{ password }}"
method: POST
force_basic_auth: yes
status_code: 200
register: conn_stat
name of connector,
task ID want to use in loop.
In above I need to setup loop for tasks.
As we can see above connector 'confluent-test-1' have three tasks in failed state, so it need to be iterate three times with task 'confluent-test-1'.
This is a typical case where you want to use subelements, either through the aforementioned filter or lookup. Here is an example using the filter
- name: Restart Connector Failed tasks
uri:
url: "{{scheme }}://{{ server }}:{{ port_no }}/connectors/{{ item.0.name }}/tasks/{{ item.1 }}/restart"
user: "{{ username }}"
password: "{{ password }}"
method: POST
force_basic_auth: yes
status_code: 200
loop: "{{ failed_connector_name_task_id | subelements('id', skip_missing=True) }}"
References worth to read:
ansible loops
subelements filter
You can actually remove your last unnecessary set_fact task with e.g. the following construct:
- name: Restart Connector Failed tasks
vars:
failed_connector_name_task_id: "{{ conn_stat_1 | json_query('results[].json[].{name: name ,id: [tasks[?state == `RUNNING`].id [] | [0] ]}') }}"
uri:
url: "{{scheme }}://{{ server }}:{{ port_no }}/connectors/{{ item.0.name }}/tasks/{{ item.1 }}/restart"
user: "{{ username }}"
password: "{{ password }}"
method: POST
force_basic_auth: yes
status_code: 200
loop: "{{ failed_connector_name_task_id | subelements('id', skip_missing=True) }}"

Juniper Ansible Json Formatting

I'm trying to output a retrieved Juniper json config file using to_nice_json. I can't use a post playbook tool such as "json.tool" but I'd rather pull the config and save it in nice_json format.
Below is my task that creates a serialized json file.
- name: Save device "json" config
juniper_junos_config:
provider: "{{ netconf }}"
retrieve: "committed"
format: "json"
dest: "{{ temp_config_file }}"
- name: Copy temp json file to timestamped file
copy:
src: "{{ temp_config_file }}"
dest: "{{ conf_file_json }}.json"
Add the filter "to_nice_json" to the destination and that should do the trick:
- name: Copy temp json file to timestamped file
copy:
src: "{{ temp_config_file }}"
dest: "{{ conf_file_json | to_nice_json }}.json"

How to write below condition in Helm chart syntax in a job.yaml file?

I have to write this condition in helm chart syntax in job.yaml file so that imagePullSecrets get's executed only when the condition is satisfied.
Condition is
when: (network.docker.username | default('', true) | trim != '') and (network.docker.password | default('', true) | trim != '')
To write above condition below this code:
imagePullSecrets:
- name: "{{ $.Values.image.pullSecret }}"
Ideally, Docker username & password should come from Secrets. Here's the Sample helm code to use if in yaml file:
imagePullSecrets:
{{ if and (ne $.Values.network.docker.password '') (ne $.Values.network.docker.username '') }}
- name: "{{ $.Values.image.pullSecret }}"
{{ end }}
And values.yaml should have:
network:
docker:
username: your-uname
password: your-pwd

Helm lint error but everything looks ok to me

I'm getting this error when linting my helm project
$ helm lint --debug
==> Linting .
[INFO] Chart.yaml: icon is recommended
[ERROR] templates/: render error in "myProject/templates/configmap.yaml": template: myProject/templates/configmap.yaml:26:27: executing "myProject/templates/configmap.yaml" at <.Values.fileServiceH...>: can't evaluate field fileHost in type interface {}
Error: 1 chart(s) linted, 1 chart(s) failed
This is my configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myProject-configmap
data:
tkn.yaml: |
iss: "{{ .Values.iss }}"
aud: "{{ .Values.aud }}"
db.yaml: |
database: "{{ .Values.database }}"
user: "{{ .Values.user }}"
host: "{{ .Values.host }}"
dialect: "{{ .Values.dialect }}"
pool:
min: "{{ .Values.pool.min }}"
max: "{{ .Values.pool.max }}"
acquire: "{{ .Values.pool.acquire }}"
idle: "{{ .Values.pool.idle }}"
fileservice.yaml: |
fileServiceHost:
fileHost: "{{ .Values.fileServiceHost.fileHost }}"
notificationservice.yaml: |
notificationServiceHost:
notificationHost: "{{ .Values.notificationservice.notificationHost }}"
organizationservice.yaml: |
organizationServiceHost:
organizationHost: "{{ .Values.organizationservice.organizationHost }}"
organizations.yaml: |
organizations: {{ .Values.organizations | toJson | indent 4 }}
epic.yaml: |
redirectUri: "{{ .Values.redirectUri }}"
This is my /vars/dev/fileservice.yaml file
fileServiceHost:
fileHost: 'https://example.com'
What is wrong that i'm getting this lint error?
You want to either use .Files.Get to load the yaml files or take the yaml content that you have in the yaml files and capture it in the values.yaml so that you can insert it directly in your configmap with toYaml.
If the values are just static and you don't need the user to override them then .Files.Get is better for you. If you want to be able to override the content in the yaml files easily at install time then just represent them in the values.yaml file.

Ansible - 'unicode object' has no attribute 'file_input'

I'm working with Ansible 2.2.1.0 and I work on a old project made by someone else with errors.
I have the following variables in my code:
software_output:
- { file_input: 'Download_me.zip', file_output: 'download.zip' }
software_version:"0.5,0.6"
And I have this shell module instruction to download on a FTP:
- name: "MySoftware | get package on FTP"
shell: >
curl --ftp-ssl -k {{ ' --ssl-allow-beast ' if os == 'aix' else "" }} -# -f -u {{ ftp_user }}:{{ ftp_password }} -f "{{ ftp_url | replace('##software_version##',item[1]) }}{{ item[0].file_input }}"
-o {{ require_inst_dir }}/{{ item[0].file_output }} 2>/dev/null
with_nested:
- software_output
- "{{ software_version.split(',') }}"
when: software_version is defined
But it doesn't work at all, I have the following error:
'unicode object' has no attribute 'file_input'
It looks like with_nested is not used as it has to be used, did I missed something?
In:
with_nested:
- software_output
software_output is a string software_output.
To refer to the variable value, change to:
with_nested:
- "{{ software_output }}"
Long time ago the first syntax was valid, but it was long time ago.