如何循环遍历在Ansible清单文件中设置的变量列表?

huangapple go评论77阅读模式
英文:

How to loop through a list of variables set-up in an Ansible inventory file?

问题

以下是翻译后的内容:

拥有这样的 Ansible 主机清单文件:

hostname1 users=user1,user2,user3
hostname2 users=user1,user2

我需要一个 Ansible playbook,它将循环遍历每个用户变量列表,并针对每个主机/用户变量运行 grep username /etc/passwd 命令。

到目前为止,我有以下内容:

---
- name: Grep shadow entries for users
  hosts: all
  tasks:
    - name: Get shadow entry for each user
      shell: "grep {{ item }} /etc/shadow"
      register: shadow_entry
      with_items: "{{ hostvars[inventory_hostname].users }}"

    - name: Print shadow entry
      debug:
        msg: "{{ shadow_entry.results }}"

但这不会循环遍历每个用户列表,而是运行 grep [user1,user2,user3] /etc/passwd

我还尝试了不同的设置清单文件的变化,如:

hostname1 users=["user1","user2","user3"]
hostname1 users='["user1","user2","user3"]'
hostname1 users="user1","user2","user3"

似乎什么都不起作用。

英文:

Having an ansible inventory file like this:

hostname1 users=user1,user2,user3
hostname2 users=user1,user2

I need an Ansible playbook that will loop through each of the user variable list and run the grep username /etc/passwd command for each hostname/user variable

What I have so far is:

---
- name: Grep shadow entries for users
  hosts: all
  tasks:
    - name: Get shadow entry for each user
      shell: "grep {{ item }} /etc/shadow"
      register: shadow_entry
      with_items: "{{ hostvars[inventory_hostname].users }}"

    - name: Print shadow entry
      debug:
        msg: "{{ shadow_entry.results }}"

But this does not loop through each user list but rather goes and runs grep [user1,user2,user3] /etc/passwd.

Also tried different variations on setting the inventory file like:

hostname1 users=["user1","user2","user3"]
hostname1 users='["user1","user2","user3"]'
hostname1 users="user1","user2","user3"

Nothing seems to work.

答案1

得分: 1

以下是已翻译的内容:

如何循环遍历在Ansible清单文件中设置的变量列表?

对于一个名为 cat hosts 的文件

[test]
test.example.com USERS="['user1','user2','user3']"

一个示例的Playbook

---
- hosts: test
  become: false
  gather_facts: false

  tasks:

  - name: 显示用户
    debug:
      msg: "{{ item }}"
    loop: "{{ hostvars[inventory_hostname].USERS }}"

  - name: 显示用户
    debug:
      msg: "{{ item }}"
    loop: "{{ USERS }}"

将都产生以下输出:

任务 [显示用户] ***********************
ok: [test.example.com] => (item=user1) =>
  msg: user1
ok: [test.example.com] => (item=user2) =>
  msg: user2
ok: [test.example.com] => (item=user3) =>
  msg: user3

类似的问答


请注意,建议通过getent模块 - unix getent实用程序的包装器完全读取帐户数据库。

针对其各种数据库之一运行getent,并将信息返回到主机的事实中,以getent_为前缀的变量

查看问答

英文:

How to loop through a list of variables set-up in an Ansible inventory file?

For a file cat hosts

[test]
test.example.com USERS="['user1','user2','user3']"

an example playbook

---
- hosts: test
  become: false
  gather_facts: false

  tasks:

  - name: Show users
    debug:
      msg: "{{ item }}"
    loop: "{{ hostvars[inventory_hostname].USERS }}"

  - name: Show users
    debug:
      msg: "{{ item }}"
    loop: "{{ USERS }}"

will both result into an output of

TASK [Show users] ***********************
ok: [test.example.com] => (item=user1) =>
  msg: user1
ok: [test.example.com] => (item=user2) =>
  msg: user2
ok: [test.example.com] => (item=user3) =>
  msg: user3

Similar Q&A


Please take note that it is recommended to proceed further with reading the account database fully via getent module – A wrapper to the unix getent utility.

> Runs getent against one of it’s various databases and returns information into the host’s facts, in a getent_ prefixed variable

See Q&A

答案2

得分: 1

  • 在第一种情况下
hostname1 users=user1,user2,user3

如果要迭代列表,请分割项目

    - debug:
        msg: "{{ item }}"
      loop: "{{ users.split(',') }}"

得到

ok: [hostname1] => (item=user1) => 
  msg: user1
ok: [hostname1] => (item=user2) => 
  msg: user2
ok: [hostname1] => (item=user3) => 
  msg: user3
  • 在第二种情况下
hostname2 users=[user1,user2,user3]

字符串是有效的YAML列表。使用过滤器from_yaml将字符串转换为列表

    - debug:
        msg: "{{ item }}"
      loop: "{{ users|from_yaml }}"

得到相同的结果

ok: [hostname2] => (item=user1) => 
  msg: user1
ok: [hostname2] => (item=user2) => 
  msg: user2
ok: [hostname2] => (item=user3) => 
  msg: user3
  • 如果在字符串中加入空格,您必须引用该字符串,可以使用单引号或双引号
hostname2 users='[user1, user2, user3]'

  • 使用模块getent读取*/etc/shadow*。在远程系统上,查看man getent以确定数据库是否可用
    - getent:
        database: shadow

此模块将在变量ansible_facts.getent_shadow中创建一个字典。您可以使用它来迭代users,例如,给定users

hostname2 users=operator,nobody

下面的任务

    - debug:
        msg: "{{ item }}: {{ ansible_facts.getent_shadow[item]|to_yaml }}"
      loop: "{{ users.split(',') }}"

得到

ok: [hostname2] => (item=operator) => 
  msg: |- operator: ['*', '18397', '0', '99999', '7', '', '', '']
ok: [hostname2] => (item=nobody) => 
  msg: |- nobody: ['*', '18397', '0', '99999', '7', '', '', '']
英文:
  • Both options below are strings
hostname1 users=user1,user2,user3
hostname2 users=[user1,user2,user3]

You can test it

    - debug:
        var: users|type_debug

gives in both cases

  users|type_debug: str

See Defining variables in INI format

  • In the first case
hostname1 users=user1,user2,user3

split the items if you want to iterate the list

    - debug:
        msg: "{{ item }}"
      loop: "{{ users.split(',') }}"

gives

ok: [hostname1] => (item=user1) => 
  msg: user1
ok: [hostname1] => (item=user2) => 
  msg: user2
ok: [hostname1] => (item=user3) => 
  msg: user3
  • In the second case
hostname2 users=[user1,user2,user3]

the string is a valid YAML list. Use the filter from_yaml to convert the string to the list

    - debug:
        msg: "{{ item }}"
      loop: "{{ users|from_yaml }}"

gives the same result

ok: [hostname2] => (item=user1) => 
  msg: user1
ok: [hostname2] => (item=user2) => 
  msg: user2
ok: [hostname2] => (item=user3) => 
  msg: user3
  • You have to quote the string, either single or double if you put spaces into it
hostname2 users='[user1, user2, user3]'

<hr>

  • Use module getent to read /etc/shadow. On the remote system, see man getent whether the database is available or not
    - getent:
        database: shadow

This module will create a dictionary in the variable ansible_facts.getent_shadow. You can use it, instead of grep, to iterate users. For example, given the users

hostname2 users=operator,nobody

The task below

    - debug:
        msg: &quot;{{ item }}: {{ ansible_facts.getent_shadow[item]|to_yaml }}&quot;
      loop: &quot;{{ users.split(&#39;,&#39;) }}&quot;

gives

ok: [hostname2] =&gt; (item=operator) =&gt; 
  msg: |-
        operator: [&#39;*&#39;, &#39;18397&#39;, &#39;0&#39;, &#39;99999&#39;, &#39;7&#39;, &#39;&#39;, &#39;&#39;, &#39;&#39;]
ok: [hostname2] =&gt; (item=nobody) =&gt; 
  msg: |-
        nobody: [&#39;*&#39;, &#39;18397&#39;, &#39;0&#39;, &#39;99999&#39;, &#39;7&#39;, &#39;&#39;, &#39;&#39;, &#39;&#39;]

huangapple
  • 本文由 发表于 2023年1月6日 13:38:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/75027318.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定