remove files from host that are not in a dictionary

I’m trying to remove config files from a host if they are no longer managed by ansible.

The ansible managed files are in a dictionary similar to the following :

config_files:
vhost01:
servername: vhost01
domain: company.com
vhost02:
servername: vhost02
domain: company.com

And get added to the host as follows :

  • name: Add ansible managed vhost config files.
    template:
    src: vhost.j2
    dest: “{{ vhost_path }}/{{ item.key }}.conf”
    mode: 0644
    with_dict: “{{ config_files }}”

But when attempting to remove them with the following it does not work :

  • name: Build list of ansible managed files.
    shell: echo “{{ item.key }}.conf”
    with_dict: “{{ config_files }}”
    register: managed_files

  • name: Build list of config files on host.
    shell: ls -1 “{{ vhost_path }}”
    register: vhost_config_files

  • name: Remove unmanaged vhost config files.
    file:
    path: “{{ vhost_path }}/{{ item }}”
    state: absent
    with_items: vhost_config_files.stdout_lines
    when: item not in managed_files.stdout_lines

The error is as follows :

Unable to look up a name or access an attribute in template string ({% if item not in managed_files.stdout_lines %} True {% else %} False {% endif %})

Here is the output of managed_files :

{“msg”: “All items completed”, “changed”: true, “results”: [{“_ansible_parsed”: true, “changed”: true, “stdout”: “vhost02.conf”, “_ansible_item_result”: true, “warnings”: , “delta”: “0:00:00.002037”, “stdout_lines”: [“vhost02.conf”], “end”: “2017-01-10 12:14:06.090689”, “_ansible_no_log”: false, “start”: “2017-01-10 12:14:06.088652”, “cmd”: “echo "vhost02.conf"”, “item”: {“key”: “vhost02”, “value”: {“servername”: “vhost02”, “domain”: “company.com”}}, “stderr”: “”, “rc”: 0, “invocation”: {“module_name”: “command”, “module_args”: {“warn”: true, “executable”: null, “_uses_shell”: true, “_raw_params”: “echo "vhost02.conf"”, “removes”: null, “creates”: null, “chdir”: null}}}, {“_ansible_parsed”: true, “changed”: true, “stdout”: “vhost01.conf”, “_ansible_item_result”: true, “warnings”: , “delta”: “0:00:00.002117”, “stdout_lines”: [“vhost01.conf”], “end”: “2017-01-10 12:14:06.253953”, “_ansible_no_log”: false, “start”: “2017-01-10 12:14:06.251836”, “cmd”: “echo "vhost01.conf"”, “item”: {“key”: “vhost01”, “value”: {“servername”: “vhost01”, “domain”: “company.com”}}, “stderr”: “”, “rc”: 0, “invocation”: {“module_name”: “command”, “module_args”: {“warn”: true, “executable”: null, “_uses_shell”: true, “_raw_params”: “echo "vhost01.conf"”, “removes”: null, “creates”: null, “chdir”: null}}}]}

Here is the output of vhost_config_files :

{“start”: “2017-01-10 12:14:06.895256”, “delta”: “0:00:00.002718”, “cmd”: “ls -1 "/etc/nginx/conf.d"”, “end”: “2017-01-10 12:14:06.897974”, “stderr”: “”, “stdout”: “dummy.conf\nvhost01.conf\nvhost02.conf\nvhost03.conf”, “stdout_lines”: [“dummy.conf”, “vhost01.conf”, “vhost02.conf”, “vhost03.conf”], “changed”: true, “rc”: 0, “warnings”: }

I would expect it to remove dummy.conf and vhost03.conf from the host.

Any help on how to do this would be greatly appreciated.

I am running Ansible version 2.2.0.0

I'm trying to remove config files from a host if they are no longer managed
by ansible.

The ansible managed files are in a dictionary similar to the following :

config_files:
  vhost01:
    servername: vhost01
    domain: company.com
  vhost02:
    servername: vhost02
    domain: company.com

And get added to the host as follows :

- name: Add ansible managed vhost config files.
  template:
    src: vhost.j2
    dest: "{{ vhost_path }}/{{ item.key }}.conf"
    mode: 0644
  with_dict: "{{ config_files }}"

But when attempting to remove them with the following it does not work :

- name: Build list of ansible managed files.
  shell: echo "{{ item.key }}.conf"
  with_dict: "{{ config_files }}"
  register: managed_files

- name: Build list of config files on host.
  shell: ls -1 "{{ vhost_path }}"
  register: vhost_config_files

- name: Remove unmanaged vhost config files.
  file:
    path: "{{ vhost_path }}/{{ item }}"
    state: absent
  with_items: vhost_config_files.stdout_lines
  when: item not in managed_files.stdout_lines

When you are using register and with_dict together, all the result will be a list in managed_files.results, one item in the list for every iteration.
So the managed_files.stdout_lines doesn't exist.

The error is as follows :

Unable to look up a name or access an attribute in template string ({% if
item not in managed_files.stdout_lines %} True {% else %} False {% endif %})

Here is the output of managed_files :

{"msg": "All items completed", "changed": true, "results":
[{"_ansible_parsed": true, "changed": true, "stdout": "vhost02.conf",
"_ansible_item_result": true, "warnings": , "delta": "0:00:00.002037",
"stdout_lines": ["vhost02.conf"], "end": "2017-01-10 12:14:06.090689",
"_ansible_no_log": false, "start": "2017-01-10 12:14:06.088652", "cmd":
"echo \"vhost02.conf\"", "item": {"key": "vhost02", "value": {"servername":
"vhost02", "domain": "company.com"}}, "stderr": "", "rc": 0, "invocation":
{"module_name": "command", "module_args": {"warn": true, "executable":
null, "_uses_shell": true, "_raw_params": "echo \"vhost02.conf\"",
"removes": null, "creates": null, "chdir": null}}}, {"_ansible_parsed":
true, "changed": true, "stdout": "vhost01.conf", "_ansible_item_result":
true, "warnings": , "delta": "0:00:00.002117", "stdout_lines":
["vhost01.conf"], "end": "2017-01-10 12:14:06.253953", "_ansible_no_log":
false, "start": "2017-01-10 12:14:06.251836", "cmd": "echo
\"vhost01.conf\"", "item": {"key": "vhost01", "value": {"servername":
"vhost01", "domain": "company.com"}}, "stderr": "", "rc": 0, "invocation":
{"module_name": "command", "module_args": {"warn": true, "executable":
null, "_uses_shell": true, "_raw_params": "echo \"vhost01.conf\"",
"removes": null, "creates": null, "chdir": null}}}]}

Here is the output of vhost_config_files :

{"start": "2017-01-10 12:14:06.895256", "delta": "0:00:00.002718", "cmd":
"ls -1 \"/etc/nginx/conf.d\"", "end": "2017-01-10 12:14:06.897974",
"stderr": "", "stdout":
"dummy.conf\nvhost01.conf\nvhost02.conf\nvhost03.conf", "stdout_lines":
["dummy.conf", "vhost01.conf", "vhost02.conf", "vhost03.conf"], "changed":
true, "rc": 0, "warnings": }

I recommend using
- debug: var=managed_files
and
- debug: var=vhost_config_files

Then you get it in more human readable format, and you can easily the structure of the variable.