Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

如何於 Ansible 操作一 Dict 的內容? #48

Open
brlin-tw opened this issue Oct 22, 2019 · 3 comments
Open

如何於 Ansible 操作一 Dict 的內容? #48

brlin-tw opened this issue Oct 22, 2019 · 3 comments

Comments

@brlin-tw
Copy link

情境說明

情境:我在變數中設定了一個使用者帳號列表與密碼的字典:

users:
  user_a:
    password: p@ssw0rd # 選填

我想要在一個迴圈中將沒有 password 值的使用者帳號建立一個隨機密碼並插入到該字典中應有的位置,之後再用 user 模組設定新的使用者帳號:

- name: Generate and set user password when unset
  loop: '{{ users | dict2items }}'
  loop_control:
    loop_var: user
  set_fact:
    users['{{ user.key }}'].password: "{{ user.value.password | default(lookup('password', '/dev/null length=30 chars=printable')) }}"

- name: Create user accounts
  loop: '{{ users | dict2items }}'
  loop_control:
    loop_var: user
  user:
    user: '{{ user.key }}'
    password: "{{ user.value.password | password_hash('sha256') }}"

但這個寫法會報以下錯誤(敏感訊息已替換佔位字):

failed: [{{inventory_hostname}}] (item={'key': 'user_a', 'value': {'anotherkey': 'anothervalue'}}) => {"ansible_loop_var": "user", "changed": false, "msg": "The variable name 'users['user_a].password' is not valid. Variables must start with a letter or underscore character, and contain only letters, numbers and underscores.", "user": {"key": "user_a", "value": {'anotherkey': 'anothervalue'}}}

求解?

@tsengeagle
Copy link

看不出來錯在哪一個task,錯誤訊息裡面像是單雙引號位置的問題

下面這是我的寫法,在centos7上面:

- hosts: all
  become: yes
  vars:
    users:
      - name: tsengeagle
        pub_key: ~/.ssh/id_rsa.pub
        sudoers: True
  tasks:
  - name: 新增使用者
    user:
      name: "{{ item.name }}"
      password: "{{ item.password | default('xxxxx') | password_hash('sha512') }}"
      generate_ssh_key: yes
      state: present
      update_password: on_create # 只有新開帳號的時候設定密碼
    with_items: "{{ users }}"

  - name: 設定公開金鑰
    authorized_key:
      user: "{{ item.name }}"
      key: "{{ lookup('file', item.pub_key) }}"
    with_items: "{{ users }}"
    when: item.pub_key is defined

  - name: 設定sudoer
    template:
      src: sudoers.d.user.j2
      dest: "/etc/sudoers.d/{{ item.name }}"
    vars:
      user_name: "{{ item.name }}"
    with_items: "{{ users }}"
    when: item.sudoers is defined and item.sudoers == True

@tsengeagle
Copy link

然後,這是您想要的效果嗎?
把原本normal_user的password換成 abcde

➜ cat lab.yml
- hosts: localhost
  vars:
    users:
      normal_user:
        password: '12345'
  tasks:
    - debug:
        msg: "{{ users }}"
    - set_fact:
        users:
          normal_user:
            password: 'abcde'
    - debug:
        msg: "{{ users }}"

執行:

➜ ansible-playbook lab.yml
 [WARNING]: No inventory was parsed, only implicit localhost is available

 [WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'

[DEPRECATION WARNING]: ansible.constants.BECOME_METHODS is deprecated, please use ansible.plugins.loader.become_loader. This list is statically defined and may not include all become
methods. This feature will be removed in version 2.10. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.

PLAY [localhost] ******************************************************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": {
        "normal_user": {
            "password": "12345"
        }
    }
}

TASK [set_fact] *******************************************************************************************************************************************************************************
ok: [localhost]

TASK [debug] **********************************************************************************************************************************************************************************
ok: [localhost] => {
    "msg": {
        "normal_user": {
            "password": "abcde"
        }
    }
}

PLAY RECAP ************************************************************************************************************************************************************************************
localhost                  : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

@brlin-tw
Copy link
Author

brlin-tw commented Oct 23, 2019

我希望 password 欄位可以在 vars 不設定,而在設定密碼前自動設定,所以大概是這樣:

- hosts: localhost
  vars:
    users:
      user_with_custom_password:
        password: '12345'
      user_without_custom_password:
        #password:
  tasks:
    - set_fact:
        users:
          '{{ item.key }}':
            password: '{{ item.value.password | default(lookup('password', '/dev/null length=12 chars=printable')) }}'
      with_dict: users

    - user:
        name: '{{ item.key }}'
        password: '{{ item.value.password }}'
      with_dict: users

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants