0

After deploy new configuration of Nginx, I would like to verify configuration before Nginx handler for reload is applied. This is output of command line:

nginx -t && echo $?
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
0

Based on output above, I configured Ansible command task like this:

- name: Verify Nginx config
  become: yes
  command: nginx -t
  register: nginx_verify_config
  check_mode: no
  changed_when: "'syntax is ok' not in nginx_verify_config.stdout"

- debug:
    msg: "{{nginx_verify_config.stdout}}"

changed_when should show something changed only if output of command is mising syntax is ok. This does not work and I found out, the message in nginx_verify_config looks like this:

ok: [DevNgx] => {
    "msg": {
        "changed": true,
        "cmd": [
            "nginx",
            "-t"
        ],
        "delta": "0:00:00.018083",
        "end": "2023-04-14 14:44:16.656261",
        "failed": false,
        "msg": "",
        "rc": 0,
        "start": "2023-04-14 14:44:16.638178",
        "stderr": "nginx: the configuration file /etc/nginx/nginx.conf syntax is ok\nnginx: configuration file /etc/nginx/nginx.conf test is successful",
        "stderr_lines": [
            "nginx: the configuration file /etc/nginx/nginx.conf syntax is ok",
            "nginx: configuration file /etc/nginx/nginx.conf test is successful"
        ],
        "stdout": "",
        "stdout_lines": []
    }
}

Why is message stored under stderr sections msg and stdout are empty?

I tried to add 2>&1 at the end of the command, but it raised error nginx: invalid option: "2>&1".

U880D
  • 1,017
  • 2
  • 12
  • 18
dorinand
  • 319
  • 2
  • 5

2 Answers2

2

Instead of relying on string output you can check the return code itself (nginx will return non-zero rc if config is not valid):

- name: check nginx configuration
  become: yes
  command: "nginx -t"
  register: nginx_verify_config
  check_mode: no
  changed_when: "nginx_verify_config.rc != 0"

You should also consider checking a config file pre-deployment, that is run nginx -t -c /path/to/conf-file in your validator before you deploy the config, as otherwise your state change is inconsistent and you have to deal with rolling back the changes that may result in a whole lot of other problems..

Peter Zhabin
  • 2,696
  • 9
  • 10
  • I do not rely on string output. Task will fail if rc is not zero by default. Changed_when just does not show yellow task but green. So in ansible summary you do not see changes. This will be always as change, because command runs every time. I agree with your point about pre-deploymnet config check, I just past simple example of my issue here. – dorinand Apr 14 '23 at 13:33
  • 1
    Well, the thing is that the code I proposed differs from yours only in the way it evaluates `changed_when`, it does exactly the same thing otherwise. Maybe you chould clarify your question a bit to describe what problem you're trying to solve? – Peter Zhabin Apr 14 '23 at 17:50
  • In any case, `changed_when` should be false for the task since it does not change anything. It can be either ok with no change or failed because the configuration check failed. – Ginnungagap Apr 14 '23 at 21:42
  • @PeterZhabin my question is why the message of command is not in stdout section but in stderr? I know what I want to have in `change_when` it just does not work because of output of command task. If I change `"'syntax is ok' not in nginx_verify_config.stdout"` to `"'syntax is ok' not in nginx_verify_config.stderr"` it starts working. – dorinand Apr 16 '23 at 20:15
  • @Ginnungagap I do not think it should be set to `false` in any case. [Here](https://www.middlewareinventory.com/blog/ansible-changed_when-and-failed_when-examples/) is an example of when to set it to condition like I have. – dorinand Apr 16 '23 at 20:19
  • I don't see anything in what you link that remotely suggest having tasks that change nothing be marked as changed. The linked examples are about commands that actually may change something when run. In our current situation, the command never changes anything. So yes, it should be set to `false`. – Ginnungagap Apr 16 '23 at 20:26
1

Why is message stored under stderr sections msg and stdout are empty?

Because

This is how it works since introduction - nginx consistently uses stderr for all output

according Why write nginx version on stderr?

Other software packages like Java or Python are reporting his version to stderr too.

For validating the nginx.conf during a deployment with Ansible you may also have a look into


I tried to add 2>&1 at the end of the command, but it raised error nginx: invalid option: "2>&1".

That is also the expected behavior for command module – Execute commands on targets

The command(s) will not be processed through the shell, so variables like $HOSTNAME and operations like *, <, >, |, ; and & will not work. Use the ansible.builtin.shell module if you need these features.

U880D
  • 1,017
  • 2
  • 12
  • 18