user.state

Is it currently possible to have a conditional like:

when: “{{ item }}.user.state == present”

Thanks.

not really, you probably want this:

when: hostvars[inventory_hostname][item][‘user’][‘state’] == ‘present’

in yours you are conflating ‘present’ which is a string with variables and then trying to ‘double interpolate’ neither of which will work.

Hmm… Just dropping it in didn’t quite do the trick. Maybe I’d be better off iterating through the users present on my hosts, and building the conditional off the files that exist. Right now, this currently works with ignore_errors instead of the conditional, but I’m hoping to get rid of it, so I can actually monitor it for correct runs. Here’s the full task:

  • name: deploy the ssh keys
    authorized_key:
    user: “{{ item | basename }}”
    key: “{{ lookup(‘file’, item) }}”
    when: “{{ item | basename }}.user.state == present”
    with_fileglob:
  • files/*

don’t use {{ }} in when, its already implied, you’ll get weird results, also if present is not a var, it should be quoted, again, double interpolation does not work.

when: hostvars[inventory_hostname][item|basename][‘user’][‘state’] == “present”

When I try:

  • name: deploy the ssh keys
    authorized_key:
    user: “{{ item | basename }}”
    key: “{{ lookup(‘file’, item) }}”
    when: hostvars[inventory_hostname][item|basename][‘user’][‘state’] == “present”
    with_fileglob:
  • files/*

I get:

fatal: [vmtest01]: FAILED! => {“failed”: true, “msg”: “The conditional check ‘hostvars[inventory_hostname][item|basename][‘user’][‘state’] == "present"’ failed. The error was: error while evaluating conditional (hostvars[inventory_hostname][item|basename][‘user’][‘state’] == "present"): ‘dict object’ has no attribute u’imntreal’\n\nThe error appears to have been in ‘/etc/ansible/roles/deploy_ssh_keys/tasks/main.yml’: line 14, column 3, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n\n- name: deploy the ssh keys\n ^ here\n”}

Thanks.

so the var you are looking for does not exist in the first place, where are you setting them?

Thanks for helping with this. I would up rewriting the whole thing:

  • name: list users
    shell: ls /home | grep -v domain & ls /home/domain
    register: userlist

  • name: set users fact
    set_fact: users={{ userlist.stdout_lines }}

  • name: set files fact
    set_fact: files={{ item }}
    with_fileglob:

  • files/*
    register: files_result

  • name: set keys fact
    set_fact: keys={{ files_result.results | map(attribute=‘ansible_facts.files’) | list }}

  • name: deploy ssh keys
    authorized_key:
    user: “{{ item[0] }}”
    key: “{{ lookup(‘file’,item[1]) }}”
    when: item[0] == item[1]|basename
    with_nested:

  • “{{ users }}”

  • “{{ keys }}”

or you can use the ‘getent’ module to list the users on the machine.

The issue with going that route is these machines are members of an AD domain with over 10000 users, but only users who have actually logged in will have a home directory to deploy the SSH key to. Thanks.

Why deploy the key to a home directory at all?
https://social.technet.microsoft.com/Forums/en-US/8aa28e34-2007-49fe-a689-e28e19b2757b/is-there-a-way-to-link-ssh-key-in-ad?forum=winserverDS

(For better or worse I am thinking of distributing public keys via
OpenLDAP to clean up my bastion host. So I guessed AD should be able to
accomplish that somehow too)

Benjamin

Aren't you missing a second ampersand here?

Johannes

I also have some local accounts that need to have keys deployed.

Now, that you mention it, I’m kind of surprised it doesn’t wind up leaving out one list or another every time it’s run, but it seems to work. The reason there’s only one is because I originally copied it from a fish shell, not bash. I think I’ll add it to be safe, though.

Thanks.