带循环的 Ansible 用户部署任务
Ansible user deployment task with loop
我已经启动了一个用于用户部署的 ansible 角色,并在 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
在 tasks/main.yml 中循环创建用户。
- 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 }}"
我想将一些文件复制到新创建的用户主目录,例如 .bashrc 或配置文件。
有没有办法创建一个内循环和外循环来将这些文件复制到任何新创建的用户
更新:
我创建了这样的任务:
- 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"
但是当我 运行 任务时我得到了这个错误:
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"}
您可以使用嵌套循环 [1],例如:
- 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 }}"
或者使用一个简单的循环 include_tasks
,而包含的任务文件有自己的循环 [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
我相信你想要一个嵌套循环。您可以使用 jinja2 expression to merge lists and iterate over them with product()
filter.
nested loop with with_nested
也有较旧的语法,但首选 product()
。例如,with_nested
看起来如下:
- name: "Testing, testing..."
debug:
msg: "echo MARK {{ item[0].name }} {{ item[1].file }}"
with_nested:
- "{{ bootstrap_users }}"
- "{{ filedest }}"
delegate_to: localhost
vars:
bootstrap_users:
- name: test1
- name: test2
filedest:
- file: a/b
- file: e/f
输出:
$ ansible .... | grep MARK
TASK [Testing, testing... msg=echo MARK {{ item[0].name }} {{ item[1].file }}] ***
echo MARK test1 a/b
echo MARK test1 e/f
echo MARK test2 a/b
echo MARK test2 e/f
echo MARK test1 a/b
echo MARK test1 e/f
echo MARK test2 a/b
echo MARK test2 e/f
我已经启动了一个用于用户部署的 ansible 角色,并在 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
在 tasks/main.yml 中循环创建用户。
- 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 }}"
我想将一些文件复制到新创建的用户主目录,例如 .bashrc 或配置文件。
有没有办法创建一个内循环和外循环来将这些文件复制到任何新创建的用户
更新: 我创建了这样的任务:
- 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"
但是当我 运行 任务时我得到了这个错误:
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"}
您可以使用嵌套循环 [1],例如:
- 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 }}"
或者使用一个简单的循环 include_tasks
,而包含的任务文件有自己的循环 [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
我相信你想要一个嵌套循环。您可以使用 jinja2 expression to merge lists and iterate over them with product()
filter.
nested loop with with_nested
也有较旧的语法,但首选 product()
。例如,with_nested
看起来如下:
- name: "Testing, testing..."
debug:
msg: "echo MARK {{ item[0].name }} {{ item[1].file }}"
with_nested:
- "{{ bootstrap_users }}"
- "{{ filedest }}"
delegate_to: localhost
vars:
bootstrap_users:
- name: test1
- name: test2
filedest:
- file: a/b
- file: e/f
输出:
$ ansible .... | grep MARK
TASK [Testing, testing... msg=echo MARK {{ item[0].name }} {{ item[1].file }}] ***
echo MARK test1 a/b
echo MARK test1 e/f
echo MARK test2 a/b
echo MARK test2 e/f
echo MARK test1 a/b
echo MARK test1 e/f
echo MARK test2 a/b
echo MARK test2 e/f