簡體   English   中英

Ansible:更改嵌套變量的默認值

[英]Ansible: Change default values of nested vars

我寫了一個角色來創建用戶。 現在我想修改角色以提供刪除用戶的選項。 一開始看起來很簡單的事情現在讓我一直頭疼。

這是我的角色:

---
- name: Dictionary playbook example
  hosts: localhost
  vars:
    my_default_values:
        users: &def
            state: 'present'
            force: 'yes'
            remove: 'no'
    my_values:
        users:
            - username: bla
              <<: *def
              state: absent
            - username: bla2
              <<: *def

  tasks:
    - debug: var=my_default_values
    - debug: var=my_values

這是輸出:

PLAY [Dictionary playbook example] ********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
        
        TASK [Gathering Facts] ********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
        ok: [localhost]
        
        TASK [debug] ******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
        ok: [localhost] => {
            "my_default_values": {
                "users": {
                    "force": "yes",
                    "remove": "no",
                    "state": "present"
                }
            }
        }
        
        TASK [debug] ******************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
        ok: [localhost] => {
            "my_values": {
                "users": [
                    {
                        "force": "yes",
                        "remove": "no",
                        "state": "absent",
                        "username": "bla"
                    },
                    {
                        "force": "yes",
                        "remove": "no",
                        "state": "present",
                        "username": "bla2"
                    }
                ]
            }
        }
        
PLAY RECAP ********************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
localhost                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0
rescued=0    ignored=0

只要我總是在我的角色中的每個- username名下定義<<: *def ,這就可以正常工作。 但是,如果假設我想在外部文件users.yml中定義users變量,這是有問題的。 我想我需要某種循環?

最后,我想將角色與 Katello 一起使用,因此用戶是在 Katello 內部定義的。 這就是為什么我需要讓它以更動態的方式工作。

我可以看到兩種方法:

如果您計划循環訪問這些用戶並使用字典的值,那么只需使用有目的的default過濾器定義適當的默認值:

角色/演示/任務/main.yml

- debug:
    msg:
      user:
        username: "{{ item.username }}"
        state: "{{ item.state | default('present') }}"
        force: "{{ item.force | default('yes') }}"
        remove: "{{ item.remove | default('no') }}"
  loop: "{{ users }}"
  loop_control:
    label: "{{ item.username }}"

劇本:

- hosts: localhost
  gather_facts: no

  roles:
    - name: demo
      users:
        - username: bla
          state: absent
        - username: bla2

這將產生:

ok: [localhost] => (item=bla) => 
  msg:
    user:
      force: 'yes'
      remove: 'no'
      state: absent
      username: bla
ok: [localhost] => (item=bla2) => 
  msg:
    user:
      force: 'yes'
      remove: 'no'
      state: present
      username: bla2

如果您確實需要角色中的列表,請重新創建一個新列表,將默認值與給定角色的輸入相結合,利用以下事實:當組合包含相同鍵的兩個字典時,第二個的值字典將覆蓋第一個的值:

角色/演示/任務/main.yml

- set_fact:
    users_with_default: >-
      {{
        users_with_default | default([])
        + [user_defaults | combine(item)]
      }}
  loop: "{{ users }}"
  vars:
    user_defaults:
      state: 'present'
      force: 'yes'
      remove: 'no'

- debug:
    var: users_with_default

劇本:

- hosts: localhost
  gather_facts: no

  roles:
    - name: demo
      users:
        - username: bla
          state: absent
        - username: bla2

這將產生:

ok: [localhost] => 
  users_with_default:
  - force: 'yes'
    remove: 'no'
    state: absent
    username: bla
  - force: 'yes'
    remove: 'no'
    state: present
    username: bla2

使用module_defaults 沒有必要包括state: presentremove: no因為這些是默認值。 在列表中my_users僅包括必需的參數名稱和具有非默認值的參數

- hosts: localhost
  module_defaults:
    ansible.builtin.user:
      force: yes
  vars:
    my_users:
      - name: foo
        state: absent
      - name: bar

在任務中,默認省略您要使用的可選參數

  tasks:
    - ansible.builtin.user:
        name: "{{ item.name }}"
        state: "{{ item.state|default(omit) }}"
        force: "{{ item.force|default(omit) }}"
        remove: "{{ item.remove|default(omit) }}"
      loop: "{{ my_users }}"

我的角色終於奏效了。 也許這不是最好的解決方案,但它確實可以很好地實現我想要實現的目標:

---
# tasks file for securehost

- set_fact:
    users_with_default: >-
      {{
        users_with_default | default([])
        + [user_defaults | combine(item)]
      }}
  loop: "{{ users }}"
  vars:
    user_defaults:
      state: 'present'
      force: 'yes'
      remove: 'no'

- name: Allow 'wheel' group to have passwordless sudo
  lineinfile:
    dest: /etc/sudoers
    state: present
    regexp: '^%wheel'
    line: '%wheel ALL=(ALL) NOPASSWD: ALL'
    validate: 'visudo -cf %s'

- name: create base homedir /lhome with mode 775
  file:
    path: /lhome
    state: directory
    mode: "u=rwx,g=rx,o=rx"

- name: Add / Remove users
  environment: umask=077
  user: name={{ item.username }} uid={{ item.uid }} home="/lhome/{{ item.username }}" groups={{ item.groups }} state={{ item.state }} remove={{ item.remove }} force={{ item.force }}
  with_items: "{{ users_with_default }}"

- name: change mode of all homedirs under /lhome to mode 0700
  file:
    path: "/lhome/{{ item.username }}"
    state: directory
    mode: 0700
  with_items: "{{ users_with_default }}"
  when:
    - item.state != 'absent'

- name: Add authorized keys for users
  authorized_key: user={{ item.username }} key="{{ item.key }}" exclusive={{ pubkey_exclusive }}
  with_items: "{{ users_with_default }}"
  when:
    - item.state != 'absent'

- name: Change root password
  user:
   name: root
   password: "{{ root_password_hash }}"
  when: change_root_pw | bool

再次感謝您對此的快速幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM