yet another question about loops

82 views
Skip to first unread message

Александр Костырев

unread,
Mar 19, 2015, 4:27:24 PM3/19/15
to ansible...@googlegroups.com
yet another question about loops

I want to be able to merge users across servers.
For example,
I want user1 to be on all of my hosts
and I want user_special_at_office to be only at my office's servers

So I made inventory file, where I specified all of the groups.
I made group_vars for all and for office

As I've read I can merge only dictionaries.

file group_vars/all
---
users:
  user1:
    comment: 'user1'
    authorized:
     - 'ssh-rsa 123'
     - 'ssh-rsa 999'
     - 'ssh-rsa 345'

file group_vars/office
---
users:
  user_special_at_office:
    comment: 'user_special_at_office'
    authorized:
     - 'ssh-rsa 555'
     - 'ssh-rsa 444'

with this play
---
- hosts: all
  tasks:
    - name: add users
      user: name={{ item.key }} comment="{{ item.value.comment }}"
      with_dict: users
      tags: user

    - name: add sshkey for users
      authorized_key: user={{ item.0.key }} key="{{ item.1 }}"
      with_subelements:
       - users
       - authorized
      tags: user_key

When I run this play with  --tags user I get two users - so the merging is working.
But I'm completely hopeless to get the task "add sshkey for users" working.
One or more undefined variables: 'dict object' has no attribute 'key'

Please advise me how can I accoplish what I want

Dan Vaida

unread,
Mar 21, 2015, 12:21:30 PM3/21/15
to ansible...@googlegroups.com
There are various ways you could go about doing this. Here's one of them.
users.yml
---
- hosts: all
  sudo: yes
  tasks:
    - name: add users
      user: name="{{ item.key }}" comment="{{ item.value.comment }}"
      when: inventory_hostname in groups.{{ item.value.hosts|join(',') }}
      with_dict: users
      tags: user

    - name: add sshkey for users
      authorized_key: user="{{ item.key }}" key="{{ item.value.authorized|join() }}"
      when: inventory_hostname in groups.{{ item.value.hosts|join(',') }}
      with_dict: users
      tags: user


vars.yml
users:
  user1:
    comment: "user2"
    authorized:
      - "ssh-rsa aaa"
      - "ssh-rsa bbb"
    hosts: [ "all", "office" ]
  user2:
    comment: "user3"
    authorized:
      - "ssh-rsa ccc"
    hosts: [ "office" ]

hosts:
[something]
hostX

[office]
hostY

[all:children]
something
office

$ ansible-playbook -i hosts users.yml --tags user --extra-vars @vars.yml

I accept this is not the most elegant way to do it, but it's just something I came up with on the spot.
Hope it helps,

Dan.

Александр Костырев

unread,
Mar 26, 2015, 10:14:38 AM3/26/15
to ansible...@googlegroups.com
Thanks, Dan!
I've managed to do what I wanted with you help.
I ended up with:
setting hash_behaviour = merge in ansible.cfg

group_vars/all
users:
  user1:
    comment: "user1"
    state: "present"
    groups:
      - "wheel"
      - "dvp"
    authorized:
      - "ssh-rsa 111"
      - "ssh-rsa 222"
  user2:
    comment: "user2"
    state: 'absent'
    groups:
      - "wheel"
      - "dvp"
    authorized:
      - "ssh-rsa 333"
  user3:
    comment: "user3"
    state: 'absent'
    groups:
      - "wheel"
      - "dvp"
    authorized:
      - "ssh-rsa 123"
  user4:
    comment: "user4"
    state: 'absent'
    groups:
      - "dvp"
    authorized:
      - "ssh-rsa 555"

group_vars/office
---
users:
  user2:
    state: 'present'

host_vars/office-host1
---
users:
  user4:
    state: 'present'

Now I can have all my users enumerated in one file, and then can enable them on group of hosts- or host-based level
Reply all
Reply to author
Forward
0 new messages