I have started an ansible role for user deployment and created some variables in defaults/main.yml:
bootstrap_users:
- name: test1
comment: "test user 1"
shell: "/bin/bash"
password: "<hashed password>"
groups: []
sshpubkey: "<public ssh key"
home: "/home/test1"
create_home: yes
- name: test2
comment: "test user 2"
shell: "/bin/bash"
password: "<hashed password>"
groups: []
sshpubkey: "<public ssh key"
home: "/home/test2"
create_home: yes
in tasks/main.yml to create users in loop.
- name: "Create users"
user:
name: "{{ item.name }}"
comment: "{{ item.comment|default('test user') }}"
shell: "{{ item.shell|default('/bin/bash') }}"
password: "{{ item.password|default('1234') }}"
groups: "{{ ','.join(item.groups|default([])) }}"
state: present
update_password: on_create
create_home: "{{ item.create_home|default(yes) }}"
home: "{{ item.home|default('/home/{{ item.name }}') }}"
loop: "{{ bootstrap_users|default([]) }}"
loop_control:
label: "{{ item.name }}"
I want to copy some files to the newly created user homes like .bashrc or profile.
Is there a way to crate a inner and outer loop to copy those files to any newly created user
Update: I've created the task like this:
- name: "Copy user shell settings files"
copy:
src: "{{ item[1].src }}"
dest: "{{ item[0].home | default('/home/' ~ item[0].name) }}/{{ item[1].dest }}"
owner: "{{ item[0].name }}"
group: "{{ (item[0].name }}"
mode: "{{ item[1].mode | default('0600') }}"
loop: "{{ [ bootstrap_users|default([]), bash_files|default([]) ] }}"
loop_control:
label: "{{ item[0].name }}/{{ item[1].name }}"
vars:
bash_files:
- name: bashrc
src: "bash/bashrc"
dest: ".bashrc"
mode: "0600"
- name: profile
src: "bash/profile"
dest: ".profile"
mode: "0600"
- name: bash_aliases
src: "bash/bash_aliases"
dest: ".bash/bash_aliases"
mode: "0600"
- name: bash_functions
src: "bash/bash_functions"
dest: ".bash/bash_functions"
mode: "0600"
But when I run the task I got this error:
TASK [base_role : Copy user shell settings files] ****************************************************************
fatal: [172.20.2.4]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'dict object' has no attribute 'src'\n\nThe error appears to be in '/home/andre/Dokumente/Ansible Development/Ansible-BaseRole/roles/base_role/tasks/system_setup/os-settings-user_deployment.yml': line 96, 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: \"Copy user shell settings files\"\n ^ here\n"}
You could use a nested loop [1], something like:
- name: Install users configuration
copy:
dest: "{{ item[0].home | default('/home/' ~ item[0].name) }}/{{ item[1].path }}"
group: "{{ (item[0].groups|default([]))[0] | default(item[0].name) }}"
mode: "{{ item[1].mode | default('u=rw') }}"
owner: "{{ item[0].name }}"
src: "{{ item[1].name }}"
loop: "{{ (bootstrap_users|default([])) | product(bash_files|default([])) | list }}"
loop_control:
label: "{{ item[0].name }}/{{ item[1].name }}"
Or using a simple loop to include_tasks
, while the included task file has its own loop [2] :
#main.yaml
- include_tasks: install-config.yaml
loop: "{{ bootstrap_users|default([]) }}"
loop_control:
loop_var: "{{ userentry }}"
#install-config
- name: Install users configuration
copy:
dest: "{{ userentry.home | default('/home/' ~ userentry.name) }}/{{ item.path }}"
group: "{{ (userentry.groups|default([]))[0] | default(userentry.name) }}"
mode: "{{ item.mode | default('u=rw') }}"
owner: "{{ userentry.name }}"
src: "{{ item.name }}"
loop: "{{ files_to_install|default([]) }}"
loop_control:
label: "{{ item.name }}"
[1] https://docs.ansible.com/ansible/latest/user_guide/playbooks_loops.html#iterating-over-nested-lists