ansible - 使用 Ansible 精细管理系统用户
问题描述
我正在使用Ansible剧本来管理用户(取自https://keksi.io/tutorials/2016/12/05/how-to-manage-remote-server-users-with-ansible/):
vars/users.yml文件(用户、用户到组分配、密码、SSH 密钥):
---
users:
- username: user1
comment: "User 1"
group: admin
password: "sha password"
keys:
active:
- "ssh-rsa etc"
admin: yes
- username: user2
comment: "User 2"
group: users
groups: deployer
keys:
active:
- "ssh-rsa etc"
- username: user3
[...]
这是剧本:
- hosts: all
become: true
tasks:
- include_vars: ../vars/users.yml
- name: Install sudo
apt: name=sudo state=present
- name: Add the group admin
group:
name: admin
state: present
- name: Create users
user:
name: "{{ item.username }}"
comment: "{{ item.comment | default('User {{item.username}}') }}"
password: "{{ item.password | default('!') }}"
state: "{{ item.state | default('present') }}"
shell: "{{ item.shell | default('/bin/bash') }}"
group: "{{ item.group | default('users') }}"
when: item.username is defined
with_items: '{{ users }}'
- name: Setup administrator users with complete sudo access
user: name={{ item.username }} groups=sudo append=yes
with_items: '{{ users }}'
when: item.admin is defined and item.admin == True
- name: Add SSH-keys to users
authorized_key:
user: "{{ item.0.username }}"
key: "{{ item.1 }}"
with_subelements:
- "{{ users }}"
- keys.active
- flags:
skip_missing: True
when: item.0.state is not defined or item.0.state != "absent"
- name: Remove old SSH-keys from users
authorized_key:
user: "{{ item.0.username }}"
key: "{{ item.1 }}"
state: absent
with_subelements:
- "{{ users }}"
- keys.disabled
- flags:
skip_missing: True
when: item.0.state is not defined or item.0.state != "absent"
我可以在所有服务器上正确执行此剧本,并在其上创建和管理管理员和普通用户。
现在我想添加一个新步骤。我有几台服务器,并不是每个用户都应该在每台服务器上配置,一些用户应该只在一些服务器上的附加组中(例如开发服务器上的开发人员)。
所以我希望为主机或主机组上的用户创建一些分配,例如:
- host: host1
admins:
- user1
- user2
deployers:
- user2
- user3
users:
- user4
- user5
- host: hostgroup1
admins:
- user2
users:
- user3
- user5
因此,我希望能够在所有服务器上执行剧本,以根据此声明创建或更新用户,而无需为每个主机编写剧本的副本。
我不知道如何实现这一点,你能帮我吗?
编辑:我试图在我的 users.yml 变量文件中添加一个新的“hosts”键,这样:
---
users:
- username: user1
comment: "User 1"
group: admin
password: "sha password"
keys:
active:
- "ssh-rsa etc"
admin: yes
- username: user2
comment: "User 2"
group: users
groups: deployer
keys:
active:
- "ssh-rsa etc"
hosts:
user:
- host1
- host2
deployer:
- host3
我这样修改了任务:
- name: Create users
user:
name: "{{ item.username }}"
comment: "{{ item.comment | default('User {{item.username}}') }}"
password: "{{ item.password | default('!') }}"
state: "{{ item.state | default('present') }}"
shell: "{{ item.shell | default('/bin/bash') }}"
group: "{{ item.group | default('users') }}"
with_items: '{{ users }}'
when: item.username is defined and ((item.admin is defined and item.admin == True) or (item.hosts is defined and item.hosts.user is defined and inventory_hostname in item.hosts.user)
我的解释:如果它是管理员,我需要创建用户(因此必须在每个主机上创建它,或者如果当前主机的 inventory_hostname 列在主机子键数组之一中(在第二步中,我希望扩展此检查,如果当前主机位于 item.hosts 子键之一中列出的主机组中。
问题是这样创建了 user1(因为 item.admin 为 True),但 user2 不是因为其他条件始终为 False。
解决方案
您可以使用 host_vars 或 group_vars 来存储用户数据,而不是 vars/users.yml
当您针对多个主机运行 playbook 时,将从相关的 group_vars 或 host_cars 文件中读取每个主机或组成员的适当值
有关更多信息,请参见此处:https ://docs.ansible.com/ansible/latest/user_guide/intro_inventory.html#splitting-out-host-and-group-specific-data
推荐阅读
- java - 使用 Jackson 解析 yaml 文件
- javascript - websocket.onerror = function(evt) {...}; 不能在 Chrome 中运行,但在 Firefox 中运行良好?
- ios - 同时过滤与搜索字符串中存在的前缀和字符对应的数组
- ruby-on-rails - Application#hhome 中的 ArgumentError 提供了 Nil 位置。无法构建 URI
- java - 使用 @RequestParam 的参数中的语言环境不起作用
- javascript - Chart JS - x 轴以天为单位的折线图
- python - 不要替换python中包含撇号或&的单词
- java - 使用jooq上下文将内存sqlite db备份到字节数组
- javascript - Actions Sdk 收到此错误 TypeError: Cannot read property 'output' of undefined
- python - 如何在python3中的EOF之前提前读取stdin缓冲区?