Ansible从多个Json文件访问相同的变量

Ansible从多个Json文件访问相同的变量,ansible,Ansible,我在本地主机上有多个.json文件,我将playbook放在其中: json-file-path/{{ testName }}.json —- - host: localhost tasks: - name: construct json files vars: my_vars: a_key: “{{ a_value }}” b_key: “{{ b_value }}” with_dict: “{

我在本地主机上有多个.json文件,我将playbook放在其中:

json-file-path/{{ testName }}.json
—-
- host: localhost 
  tasks:
    - name: construct json files
      vars:
        my_vars:
          a_key: “{{ a_value }}”
          b_key: “{{ b_value }}”
        with_dict: “{{ testName }}”
      copy:
        content: “{{ my_vars | to_nice_json }}”
        dest: /json-file-path/{{ testName }}.json
---

- hosts: localhost
  connection: local
  # Set some example vars, tho these could be placed in a variety of places
  vars:
    local_src_dir: /some/local/path
    remote_host: <some_inventory_hostname>
    remote_dest_dir: /some/remote/path
    value_threshold: 3
  tasks:
    - name: Loop through all *json files, passing matches to include.yaml
      include: include.yaml
      loop: "{{ lookup('fileglob', local_src_dir + '/*json').split(',') }}"
- name: Loop through all *json files, passing matches to include.yaml
  include: include.yaml
  with_fileglob:
    - "{{ local_src_dir }}/*json"
{{testName}}.json是:testA.json、testB.json、testC.json。。。等等

所有.json文件都具有相同的键和不同的值,如下所示:

 {
    “testName”: “testA”
        {
           “a_key”: “a_value1”
           “b_key”: “b_value1”
  }
json文件路径/testA.json:

{
   “a_key”: “a_value1”
   “b_key”: “b_value1”
 }
json文件路径/testB.json:

{
   “a_key”: “a_value2”
   “b_key”: “b_value2”
 }
json文件路径/testC.json:

{
   “a_key”: “a_value3”
   “b_key”: “b_value3”
 }

.....
我需要访问所有.json文件中的键值变量,如果这些值满足某些条件,我将在目标主机中执行一些任务。例如,我有:

a_value1=3
a_value2=4
a_value3=1
我一个接一个地检查.json文件,如果一个_key[value]>3,我将把这个.json文件复制到目标主机,否则跳过任务。在本例中,我只将testC.json复制到目标主机

我将如何实现这一点?我正在考虑使用{{testName}}作为dict的动态键重新构建.json文件,如下所示:

 {
    “testName”: “testA”
        {
           “a_key”: “a_value1”
           “b_key”: “b_value1”
  }
所以我可以以{{testName}}的形式访问我的变量。到目前为止,我还没能做到这一点

我在我的剧本中尝试了以下内容:

json-file-path/{{ testName }}.json
—-
- host: localhost 
  tasks:
    - name: construct json files
      vars:
        my_vars:
          a_key: “{{ a_value }}”
          b_key: “{{ b_value }}”
        with_dict: “{{ testName }}”
      copy:
        content: “{{ my_vars | to_nice_json }}”
        dest: /json-file-path/{{ testName }}.json
---

- hosts: localhost
  connection: local
  # Set some example vars, tho these could be placed in a variety of places
  vars:
    local_src_dir: /some/local/path
    remote_host: <some_inventory_hostname>
    remote_dest_dir: /some/remote/path
    value_threshold: 3
  tasks:
    - name: Loop through all *json files, passing matches to include.yaml
      include: include.yaml
      loop: "{{ lookup('fileglob', local_src_dir + '/*json').split(',') }}"
- name: Loop through all *json files, passing matches to include.yaml
  include: include.yaml
  with_fileglob:
    - "{{ local_src_dir }}/*json"
我更新的剧本是:

/mypath/tmp/include.yaml:

—-
- hosts: remote_hostName
  tasks:
  - name: load json files
    set_fact:
      json_data: “{{ lookup(‘file’, item) | from_json }}”
  - name: copy json file if condition meets
    copy:
      src: “{{ item }}”
      dest: “{{ /remote_host_path/tmp}}/{{item | basename }}”
    delegate_to: “{{ remote_hostName }}”
    when: json_data.a_key|int>5

/mypath/test.yml:
—-
- hosts: localhost
  vars:
    local_src_ dir: /mypath/tmp
    remote_host: remote_hostName
    remote_dest_dir: /remote_host_path/tmp
  tasks:
    - name: looping
      include: include.yaml
      with_fileglob:
         - “{{ local_src_dir }}/*json”
localhost上/mypath/tmp/下的所有json文件

最新版本的剧本。它现在正在工作:

/mypath/tmp/include.yaml:
—-
- name: loafing json flies
  include_vars:
    file: “{{ item }}”
    name: json_data
- name: copy json file to remote if condition meets
  copy: 
    src: “{{ item }}”
    dest: ‘/remote_host_path/tmp/{{item | basename}}’
  delegate_to: “{{ remote_host }}”
  when: json_data.a_key > 5

/mypath/test.yml:

—-
- hosts: localhost
  vars: 
    local_src_dir: /mypath/tmp
    remote_host: remote_hostName
    remote_dest_dir: /remote_host_path/tmp
  tasks:
    - name: looping json files
      include: include.yaml
      with_fileglob:
         - “{{ local_src_dir }}”/*json”

我希望我正确理解了您的要求,这有助于推动您前进

基本上,您可以加载每个JSON文件,以便可以将值作为本机Ansible变量进行查询。因此,您可以循环浏览所有文件,读取每个文件,比较您感兴趣的值,然后通过委派的任务有条件地复制到远程主机。因此,请尝试一下:

创建包含文件
include.yaml

---
# 'item' contains a path to a local JSON file on each pass of the loop

- name: Load the json file
  set_fact:
    json_data: "{{ lookup('file', item) | from_json }}"
- name: Delegate a copy task to the remote host conditionally
  copy:
    src: "{{ item }}"
    dest: "{{ remote_dest_dir }}/{{ item | basename }}"
  delegate_to: "{{ remote_host }}"
  when: json_data.a_key > value_threshold
然后在你的剧本中:

json-file-path/{{ testName }}.json
—-
- host: localhost 
  tasks:
    - name: construct json files
      vars:
        my_vars:
          a_key: “{{ a_value }}”
          b_key: “{{ b_value }}”
        with_dict: “{{ testName }}”
      copy:
        content: “{{ my_vars | to_nice_json }}”
        dest: /json-file-path/{{ testName }}.json
---

- hosts: localhost
  connection: local
  # Set some example vars, tho these could be placed in a variety of places
  vars:
    local_src_dir: /some/local/path
    remote_host: <some_inventory_hostname>
    remote_dest_dir: /some/remote/path
    value_threshold: 3
  tasks:
    - name: Loop through all *json files, passing matches to include.yaml
      include: include.yaml
      loop: "{{ lookup('fileglob', local_src_dir + '/*json').split(',') }}"
- name: Loop through all *json files, passing matches to include.yaml
  include: include.yaml
  with_fileglob:
    - "{{ local_src_dir }}/*json"
在你的剧本中:

json-file-path/{{ testName }}.json
—-
- host: localhost 
  tasks:
    - name: construct json files
      vars:
        my_vars:
          a_key: “{{ a_value }}”
          b_key: “{{ b_value }}”
        with_dict: “{{ testName }}”
      copy:
        content: “{{ my_vars | to_nice_json }}”
        dest: /json-file-path/{{ testName }}.json
---

- hosts: localhost
  connection: local
  # Set some example vars, tho these could be placed in a variety of places
  vars:
    local_src_dir: /some/local/path
    remote_host: <some_inventory_hostname>
    remote_dest_dir: /some/remote/path
    value_threshold: 3
  tasks:
    - name: Loop through all *json files, passing matches to include.yaml
      include: include.yaml
      loop: "{{ lookup('fileglob', local_src_dir + '/*json').split(',') }}"
- name: Loop through all *json files, passing matches to include.yaml
  include: include.yaml
  with_fileglob:
    - "{{ local_src_dir }}/*json"

非常感谢@clockworknet!我在上面进行了尝试,但“在可用的查找插件中查找名为“{lookup('fileglob',local_srcdir+'/*json').split(',')}}”的查找时意外失败。”。斯普利特在这里做什么?嗯,那句话对我很管用。你能用你尝试过的代码和你正在使用的Ansible版本更新你的问题吗。旧版本不支持“fileglob”查找,但它是在1.4中引入的,这是很久以前的事了。查找返回一个以逗号分隔的值列表,因此
split(',')
将输出转换为一个可以循环的列表。
loop:“{{lookup('fileglob',local_src_dir+'/*.json')。split(',')}”
test.yml中有一个输入错误(开头有两个)-这在您的实际代码中吗?也在'include.yaml'中更改
时:{{json_data.a_key{int}>5
时:json_data.a_key{int>5
。您不使用
{}“
在when语句中,一开始并不总是直观的。奇怪。不知道为什么这对你不起作用。查找将生成与模式匹配的文件列表。然后对其进行循环,以便对每个匹配调用include.yaml一次,并将完整路径作为
变量传入。我已经更新了我的答案,以包含用于指定fileglob循环的旧的备用语法。试一试。根据你问题中的代码,你的代码和我的不一样。您已经将
/mypath/tmp/include.yaml
变成了一个剧本。事实并非如此。此外,当您运行的是Ansible的旧版本时,可能是当您开始工作时,include文件中的查找将失败。我已经更新了我的答案,也包括了该部分的旧语法。