使用 Ansible 管理用户和开放端口

使用 Ansible 管理用户和开放端口

我刚刚开始使用 Ansible。

我的 中有几个主机/etc/ansible/hosts。此文件和我的剧本都使用 git 进行版本控制。我的团队成员在 git 中进行了版本控制,例如

$cat users/john.json
{
   login: 'john.johnson',
   firstName: 'John',
   lastName : 'Johnson',
   sshPubKey: '....'
}

我想授予某些用户对某些机器的访问权限,例如:

server1 [john, alice, bob]
server2 [john, alice]
server3 [john, bob]
server4 [john]
server5 [john, kevin]
server6 [john, albert, alice]
server7 [john, bob, kevin]

我还希望对开放端口采用相同的方法,例如:

server1 [22, 80, 443]
server2 [22, 1234]
server3 [22, 1122]
server4 [22]
server5 [22, 1717]
server6 [22, 80, 443]
server7 [22]

我不需要帮助来编写剧本的任务(我知道如何使用用户/ufw 模块)但我找不到使用 ansible 干净地集中每个主机配置的方法。

我现在唯一的解决方案是拥有一个user.ymlport.yml剧本,每次我想为特定服务器运行它们时都编辑它们,然后使用运行剧本--limit server1。 它感觉不干净,并且阻止我在 git 上清晰地获取用户对每个服务器的访问和开放端口的快照。

在 ansible 中组织这个的干净方法是什么?

答案1

给定字典servers(参见下面剧本中的精简版)和目录中的 JSON 文件,users让我们在第一个剧本中创建字典users,并在下一个剧本中使用它。例如

- name: Collect data
  hosts: server1:server2:server3

  vars:
    servers:
      server1:
        access: [john, alice, bob]
        ports: [22, 80, 443]
      server2:
        access: [john, alice]
        ports: [22, 1234]
      server3:
        access: [john, bob]
        ports: [22, 1122]

  tasks:

    - block:
        - set_fact:
            servers: "{{ servers }}"
        - set_fact:
            users_list: "{{ servers|json_query('*.access')|flatten|unique }}"
        - set_fact:
            users: "{{ users|default({})|
                       combine({item: lookup('file', 'users/' ~ item ~ '.json')|from_yaml}) }}"
          loop: "{{ users_list }}"
        - debug:
            var: users
      run_once: true

- name: Configure users
  hosts: server1:server2:server3
  tasks:
    - debug:
        msg:
          - "{{ inventory_hostname }}"
          - "{{ item }}"
          - "{{ users[item].sshPubKey }}"
      loop: "{{ servers[inventory_hostname].access }}"

给出

PLAY [Collect data] ***
...
ok: [server1] => 
  users:
    alice:
      firstName: Alice
      lastName: Springs
      login: alice.springs
      sshPubKey: sshPubKey_alice
    bob:
      firstName: Bob
      lastName: Brown
      login: bob.brown
      sshPubKey: sshPubKey_bob
    john:
      firstName: John
      lastName: Johnson
      login: john.johnson
      sshPubKey: sshPubKey_john

PLAY [Configure users] ***
...
ok: [server1] => (item=john) => 
  msg:
  - server1
  - john
  - sshPubKey_john
ok: [server1] => (item=alice) => 
  msg:
  - server1
  - alice
  - sshPubKey_alice
ok: [server1] => (item=bob) => 
  msg:
  - server1
  - bob
  - sshPubKey_bob
ok: [server3] => (item=john) => 
  msg:
  - server3
  - john
  - sshPubKey_john
ok: [server2] => (item=john) => 
  msg:
  - server2
  - john
  - sshPubKey_john
ok: [server3] => (item=bob) => 
  msg:
  - server3
  - bob
  - sshPubKey_bob
ok: [server2] => (item=alice) => 
  msg:
  - server2
  - alice
  - sshPubKey_alice

根据需要更改剧本中的任务Configure users。以类似的方式,可以添加下一个剧本Configure ports

答案2

有多种方法可以实现这一点。

在库存中设置变量:

server1 users='["joe", "jane"]'
server2 users='["jane"]'

在目录中的文件中设置变量host_vars

使用include_vars. 示例文件内容:

"users": {
  "server1": [ "joe", "jane" ],
  "server2": [ "jane" ]
}

加载它include_vars。对于您的任务循环(with_itemsusers[ansible_hostname]

相关内容