I am trying to invoke a command on provisioning via Saltstack. If command fails then I get state failing and I don't want that (retcode of command doesn't matter).
Currently I have the following workaround:
Run something:
cmd.run:
- name: command_which_can_fail || true
is there any way to make such state ignore retcode using salt features? or maybe I can exclude this state from logs?
Use check_cmd :
fails:
cmd.run:
- name: /bin/false
succeeds:
cmd.run:
- name: /bin/false
- check_cmd:
- /bin/true
Output:
local:
----------
ID: fails
Function: cmd.run
Name: /bin/false
Result: False
Comment: Command "/bin/false" run
Started: 16:04:40.189840
Duration: 7.347 ms
Changes:
----------
pid:
4021
retcode:
1
stderr:
stdout:
----------
ID: succeeds
Function: cmd.run
Name: /bin/false
Result: True
Comment: check_cmd determined the state succeeded
Started: 16:04:40.197672
Duration: 13.293 ms
Changes:
----------
pid:
4022
retcode:
1
stderr:
stdout:
Summary
------------
Succeeded: 1 (changed=2)
Failed: 1
------------
Total states run: 2
If you don't care what the result of the command is, you can use:
Run something:
cmd.run:
- name: command_which_can_fail; exit 0
This was tested in Salt 2017.7.0 but would probably work in earlier versions.
Related
So, my problem is that I want to check if nginx is installed on two different OS with different package managers.
- name: Veryfying nginx installation # RedHat
command: "rpm -q nginx"
when: ansible_facts.pkg_mgr in ["yum","dnf","rpm"] #or (ansible_os_family == "RedHat")
- name: Veryfying nginx installation # Debian
command: "dpkg -l nginx"
when: ansible_facts.pkg_mgr in ["dpkg", "apt"] #or (ansible_os_family == "Debian")
Can I combine it in one task and how if it is possible? Because I need to register the output result and then use it onwards. Can't figure it out.
An alternative solution is to use the package_facts module, like this:
- hosts: localhost
tasks:
- package_facts:
- debug:
msg: "Nginx is installed!"
when: "'nginx' in packages"
But you could also register individual variables for your two tasks, and then combine the result:
- hosts: localhost
tasks:
- name: Veryfying nginx installation # RedHat
command: "rpm -q nginx"
when: ansible_facts.pkg_mgr in ["yum","dnf","rpm"] #or (ansible_os_family == "RedHat")
failed_when: false
register: rpm_check
- name: Veryfying nginx installation # Debian
command: "dpkg -l nginx"
when: ansible_facts.pkg_mgr in ["dpkg", "apt"] #or (ansible_os_family == "Debian")
failed_when: false
register: dpkg_check
- set_fact:
nginx_result: >-
{{
(rpm_check is not skipped and rpm_check.rc == 0) or
(dpkg_check is not skipped and dpkg_check.rc == 0)
}}
- debug:
msg: "nginx is installed"
when: nginx_result
my output now
I'm learning salt stack right now and I was wondering if there was a way to get the stdout of a salt state and put it into a document and then send it to the master. Or is there a better way to do this?
To achieve this, we'll have to save the execution of the script in a variable. It will contain a hash containing keys that are showing up under changes:. Then the contents of this variable (stdout) can be written to a file.
{% set script_res = salt['cmd.script']('salt://test.sh') %}
create-stdout-file:
file.managed:
- name: /tmp/script-stdout.txt
- contents: {{ script_res.stdout }}
The output is already going to the master. It would be better to actually output in json and query down to the data you want in your document on the master.
such as the following
Normal output
$ sudo salt salt00\* state.apply tests.test3
salt00.wolfnet.bad4.us:
----------
ID: test_run
Function: cmd.run
Name: echo test
Result: True
Comment: Command "echo test" run
Started: 10:39:51.103057
Duration: 18.281 ms
Changes:
----------
pid:
8661
retcode:
0
stderr:
stdout:
test
Summary for salt00.wolfnet.bad4.us
------------
Succeeded: 1 (changed=1)
Failed: 0
------------
Total states run: 1
Total run time: 18.281 ms
json output
$ sudo salt salt00\* state.apply tests.test3 --out json
{
"salt00.wolfnet.bad4.us": {
"cmd_|-test_run_|-echo test_|-run": {
"name": "echo test",
"changes": {
"pid": 9057,
"retcode": 0,
"stdout": "test",
"stderr": ""
},
"result": true,
"comment": "Command \"echo test\" run",
"__sls__": "tests.test3",
"__run_num__": 0,
"start_time": "10:40:55.582273",
"duration": 19.374,
"__id__": "test_run"
}
}
}
json parsed down with jq to just the stdout
$ sudo salt salt00\* state.apply tests.test3 --out=json | jq '.|.[]|."cmd_|-test_run_|-echo test_|-run"|.changes.stdout'
"test"
Also, for the record it is considered bad practice to put code that changes the system into jinja. Jinja always runs when a template is rendered and there is no way to control if it happens so just running test=true tests will still run the jinja code that makes changes which could be very harmful to your systems.
I'd like to disable the built-in windows local administrator account if it is enabled.
As salt.state.user.present doesn't support disabling accounts, I'm using salt.modules.win_useradd.update. However, it disables the account even if it is already disabled.
I can't use unless or onlyif because they only use results parsed from shell commands.
Is there a way to use the boolean value for [user.info][account_disabled] in salt.module.win_useradd.info's return data 'changes' dictionary as a requirement?
I'd like to do something like the following:
builtin_administrator:
module.run:
- user.info:
- name: Administrator
disable_builtin_administrator:
module.run:
- user.update:
- name: Administrator
- account_disabled: true
- require:
- module: builtin_administrator
- require:
- module: builtin_administrator['changes']['user.info']['account_disabled']['false']
You can see the results data changes dictionary from win_useradd.info in the output:
local:
----------
ID: builtin_administrator
Function: module.run
Result: True
Comment: user.info: Built-in account for administering the computer/domain
Started: 15:59:56.440000
Duration: 15.0 ms
Changes:
----------
user.info:
----------
account_disabled:
True
account_locked:
False
active:
False
comment:
Built-in account for administering the computer/domain
description:
Built-in account for administering the computer/domain
disallow_change_password:
False
expiration_date:
2106-02-07 01:28:15
expired:
False
failed_logon_attempts:
0L
fullname:
gid:
groups:
- Administrators
home:
None
homedrive:
last_logon:
Never
logonscript:
name:
Administrator
passwd:
None
password_changed:
2019-10-09 09:22:00
password_never_expires:
True
profile:
None
successful_logon_attempts:
0L
uid:
S-1-5-21-3258603230-662395079-3947342588-500
----------
ID: disable_builtin_administrator
Function: module.run
Result: False
Comment: The following requisites were not found:
require:
module: builtin_administrator['changes']['user.info']['account_disabled']['false']
Started: 15:59:56.455000
Duration: 0.0 ms
Changes:
Summary for local
------------
Succeeded: 1 (changed=1)
Failed: 1
------------
Total states run: 2
Total run time: 15.000 ms
I'm testing with a Windows 10 1903 masterless salt-minion 2019.2.1 (Fluorine) where I set use_superseded for module.run in the minion config file.
Thanks in advance!
I settled for this:
localuser.disable.administrator:
cmd.run:
- name: "Get-LocalUser Administrator | Disable-LocalUser"
- shell: powershell
- onlyif: powershell -command "if ((Get-LocalUser | Where-Object {($_.Name -eq 'Administrator') -and ($_.Enabled -eq $true)}) -eq $null) {exit 1}"
When I am trying to run a task asynchronously as another user using become in ansible plabook, I am getting "Job not found error". Can some one suggest me how can I successfully check the async job status.
I am using ansible version 2.7
I read in some articles suggesting use the async_status task with same become user as async task, to read the job status.
I tried that solution but still I am getting the same "job not found error"
- hosts: localhost
tasks:
- shell: startInstance.sh
register: start_task
async: 180
poll: 0
become: yes
become_user: venu
- async_status:
jid: "{{start_task.ansible_job_id}}"
register: start_status
until: start_status.finished
retries: 30
become: yes
become_user: venu
Expected Result:
I should be able to Fire and forget the job
Actual_Result:
{"ansible_job_id": "386361757265.15925428", "changed": false, "finished": 1, "msg": "could not find job", "started": 1}
I am trying to generate the lets-encrypt certificate and here are the steps that I followed:
Under /srv/salt/pillars/minion I added the file init.sls
letsencrypt:
config: |
email = email
auth:
method: standalone
type: http-01
port: 8080
agree-tos = True
renew-by-default = True
domainsets:
mydomain:
- mydomain.com
After that I updated the salt_pillar:
# . update_salt.sh
# salt 'minion' state.sls letsencrypt
I got this result:
ID: letsencrypt-crontab-mydomain.com
Function: cron.present
Name: /usr/local/bin/renew_letsencrypt_cert.sh mydomain.com
Result: False
Comment: One or more requisite failed: letsencrypt.domains.create-initial-
cert-mydomain.com
Started:
Duration:
Changes:
------------
ID: create-fullchain-privkey-pem-for-mydomain.com
Function: cmd.run
Name: cat /etc/letsencrypt/live/mydomain.com/fullchain.pem \
/etc/letsencrypt/live/mydomain.com/privkey.pem \
> /etc/letsencrypt/live/mydomain.com/fullchain-privkey.pem && \
chmod 600 /etc/letsencrypt/live/mydomain.com/fullchain-privkey.pem
Result: False
Comment: One or more requisite failed: letsencrypt.domains.create-initial-cert-mydomain.com
Started:
Duration:
Changes:
What should I modify in my configuration to get the certificate?