Ansible - 具有相同变量的多个语句

Ansible - 具有相同变量的多个语句

我是 Ansible 的新手,所以我可能会遗漏一些显而易见的东西。我有一个剧本执行以下操作:

- name: Create real users
  user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
  with_items:
    - { user_name: "user1", user_description: "user 1", user_id: "2000" }
    - { user_name: "user2", user_description: "user 2",  user_id: "2001" }

- name: Copy SSH keys
  copy:
    src: "keys/{{ item.user_name }}.key"
    dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
    owner: "{{ item.user_name }}"
    group: "{{ item.user_name }}"
    mode: 0600
  with_items:
     - { user_name: "user1", user_description: "user 1", user_id: "2000" }
     - { user_name: "user2", user_description: "user 2",  user_id: "2001" }

基本上就是with_items一遍又一遍地重复使用。理想情况下,我希望将其与我可能使用的所有字段一起存储在外部文件中。

这可能吗?我应该从哪里开始寻找?

哇....汤姆

答案1

我是 ansible 新手

我在这里列出了一些不同的选项,这样你就可以学到更多,而不仅仅是理想的解决方案(选项 5)

选项 1:使用 YAML 锚点和引用

这与 Ansible 完全无关,但由于文件采用 YAML 格式,因此您可以执行以下操作:

- name: Create real users
  user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
  with_items: &my_items
    - user_name: user1
      user_description: user 1
      user_id: 2000
    - user_name: user2
      user_description: user 2
      user_id: 2001

- name: Copy SSH keys
  copy:
    src: "keys/{{ item.user_name }}.key"
    dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
    owner: "{{ item.user_name }}"
    group: "{{ item.user_name }}"
    mode: 0600
  with_items: *my_items

选项 2:块中的变量

块是 Ansible 2 中引入的功能。你可以为块定义变量并在所包含的任务中使用它们

- vars:
    userlist:
      - user_name: user1
        user_description: user 1
        user_id: 2000
      - user_name: user2
        user_description: user 2
        user_id: 2001
  block:
    - name: Create real users
      user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
      with_items: "{{ userlist }}"

    - name: Copy SSH keys
      copy:
        src: "keys/{{ item.user_name }}.key"
        dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
        owner: "{{ item.user_name }}"
        group: "{{ item.user_name }}"
        mode: 0600
      with_items: "{{ userlist }}"

选项 3:将循环应用于include任务并将任务放在包含的文件中

- include: other_file.yml
  with_items:
    - user_name: user1
      user_description: user 1
      user_id: 2000
    - user_name: user2
      user_description: user 2
      user_id: 2001

在包含的文件中,您将能够访问该项目及其属性,例如item.user_name,就像您已经拥有它一样:

- name: Create real users
  user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"

- name: Copy SSH keys
  copy:
    src: "keys/{{ item.user_name }}.key"
    dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
    owner: "{{ item.user_name }}"
    group: "{{ item.user_name }}"
    mode: 0600

选项 4:在单独的任务中设置包含用户列表的事实

- set_fact:
    userlist:
      - user_name: user1
        user_description: user 1
        user_id: 2000
      - user_name: user2
        user_description: user 2
        user_id: 2001

- name: Create real users
  user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
  with_items: "{{ userlist }}"

- name: Copy SSH keys
  copy:
    src: "keys/{{ item.user_name }}.key"
    dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
    owner: "{{ item.user_name }}"
    group: "{{ item.user_name }}"
    mode: 0600
  with_items: "{{ userlist }}"

选项 5:使用 group_vars

组变量可能在这里最有意义。我猜你的主机在你的清单文件中属于某个组,我们姑且称之为foo

创建一个与你的剧本相关的文件group_vars/foo,内容如下:

userlist:
  - user_name: user1
    user_description: user 1
    user_id: 2000
  - user_name: user2
    user_description: user 2
    user_id: 2001

现在,属于该组的所有主机foo将自动有权访问该userlist变量。您可以在任务中使用它:

- name: Create real users
  user: name="{{item.user_name}}" comment="{{item.user_description}}" home="/home/{{item.user_name}}" shell="/bin/bash" uid="{{item.user_id}}"
  with_items: "{{ userlist }}"

- name: Copy SSH keys
  copy:
    src: "keys/{{ item.user_name }}.key"
    dest: "/home/{{ item.user_name }}/.ssh/authorized_keys"
    owner: "{{ item.user_name }}"
    group: "{{ item.user_name }}"
    mode: 0600
  with_items: "{{ userlist }}"

如果您没有群组或者不想将其限制到某些群组,您可以将 vars 文件存储为group_vars/all所有主机都可以访问的位置。

答案2

感谢您如此完整的回答。最后我发现我可以像这样使用 with_dict:

1)创建vars.yml文件(在同一目录中)

---
usersxxx:
    user1:
      description: User1
      user_id: 2001
      shell: /bin/bash
      ...other options here
    user2:
      description: User2        
      user_id: 2002
      shell: /bin/bash
      ...other options here

2)创建新的剧本:

---
- hosts: home
  vars_files:
    - vars.yml

  become: yes

  tasks: 
    - name: Create real users
      user: name="{{item.key}}" comment="{{item.value.description}}" home="/home/{{item.key}}" uid="{{item.value.user_id}}"
      with_dict: "{{usersxxx}}"

看起来它运行完美。

我只是将其更改为 usersxxx 以确保我没有碰到任何 python/ansible 原语。

希望这对其他人有帮助!

相关内容