简体   繁体   中英

Ansible playbook loop with with_items

I have to update sudoers.d multiple user files with few lines/commands using ansible playbook

users.yml

user1:
   - Line1111
   - Line2222
   - Line3333

user2:
   - Line4444
   - Line5555
   - Line6666

main.yml

- hosts: "{{ host_group }}"
  vars_files:
    - ../users.yml

  tasks:

       - name: Add user "user1" to sudoers.d
      lineinfile:
        path: /etc/sudoers.d/user1
        line: '{{ item }}'
        state: present
        mode: 0440
        create: yes
        validate: 'visudo -cf %s'
      with_items:
          - "{{ user1 }}"

The above one is working only for user1 ..

If I want to also include user2 --> How to change the file name: path: /etc/sudoers.d/user1

I tried below and its not working :

Passing below users as variable to main.yml while running

users:
   - "user1"
   - "user2"



- name: Add user "{{users}}" to sudoers.d
  lineinfile:
    path: /etc/sudoers.d/{{users}}
    line: '{{ item }}'
    state: present
    mode: 0440
    create: yes
    validate: 'visudo -cf %s'
  with_items:
      - "{{ users }}"

So, basically I want to pass in users to a variable {{users}} as user1 and user2 and wanted to use the lines for each user from users.yml and add it to respective user files ( /etc/sudoers.d/user1 and /etc/sudoers.d/user2 ).

So /etc/sudoers.d/user1 should look like

Line1111
Line2222
Line3333

and /etc/sudoers.d/user2 should look like

Line4444
Line5555
Line6666

Try to add quotes:

users:
   - "user1"
   - "user2"

- name: "Add user {{users}} to sudoers.d"
  lineinfile:
    path: "/etc/sudoers.d/{{users}}"
    line: "{{ item }}"
    state: present
    mode: 0440
    create: yes
    validate: 'visudo -cf %s'
  with_items:
      - "{{ users }}"

As per Ansible Documentation on Using Variables:

YAML syntax requires that if you start a value with {{ foo }} you quote the whole line, since it wants to be sure you aren't trying to start a YAML dictionary. This is covered on the YAML Syntax documentation.

This won't work:

 - hosts: app_servers vars: app_path: {{ base_path }}/22

Do it like this and you'll be fine:

 - hosts: app_servers vars: app_path: "{{ base_path }}/22"
cat users.yml
---
users:
  - user1:
    filename: user1sudoers
    args:
      - Line1111
      - Line2222
      - Line3333
  - user2:
    filename: user2sudoers
    args:
      - Line4444
      - Line5555
      - Line6666

I use template here, instead of lineinfile

---
cat sudoers.j2
{% if item.args is defined and item.args %}
{%     for arg in item.args %}
{{ arg }}
{%     endfor %}
{% endif %}

the task content

---
- hosts: localhost
  vars_files: ./users.yml
  tasks:
    - name: sync sudoers.j2 to localhost
      template:
        src: sudoers.j2
        dest: "/tmp/{{ item.filename }}"
      loop: "{{ users_list }}"
      when: "users_list is defined and users_list"

after run the task.yml, generate two files under /tmp directory.

cat /tmp/user1sudoers
Line1111
Line2222
Line3333

cat /tmp/user2sudoers
Line4444
Line5555
Line6666

I tried the below for users.yml

users: 
    - user1: 
          - "Line1111" 
          - "Line2222" 
          - "Line3333" 
    - user2: 
          - "Line4444" 
          - "Line5555"

and also main.yml

- name: Add user "wasadmin" to sudo avsrelmgmt 
      lineinfile:  ```
        path: /etc/sudoers.d/"{{ users }}"  
        line: '{{ item}}'  
        state: present  
        mode: 0440  
        create: yes  
        validate: 'visudo -cf %s'  
      with_items:  
        - "{{ users }}"

The above line path: /etc/sudoers.d/"{{ users }}" specified is creating the folders with name ( "- user1: - "Line1111" )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM