首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用HTTP获取YAML文件,并将其用作Ansible剧本中的变量

使用HTTP获取YAML文件,并将其用作Ansible剧本中的变量
EN

Stack Overflow用户
提问于 2021-08-10 15:47:15
回答 3查看 1.2K关注 0票数 2

背景

我在网络服务器上有这样的YAML文件。我试图阅读它,并使用户帐户在文件中的Ansible剧本。

代码语言:javascript
运行
复制
users:
  - number: 20210001
    name: Aoki Alice
    id: alice
  - number: 20210002
    name: Bob Bryant
    id: bob
  - number: 20210003
    name: Charlie Cox
    id: charlie

我试过的

为了确认如何使用include_vars动态读取下载的YAML文件,我编写了如下所示的剧本:

代码语言:javascript
运行
复制
- name: Add users from list
  hosts: workstation
  tasks:
    - name: Download yaml
      get_url:
        url: http://fqdn.of.webserver/path/to/yaml.yml
        dest: "/tmp/tmp.yml"
      notify:
        - Read yaml
        - List usernames

  handlers:
    - name: Read yaml
      include_vars:
        file: /tmp/tmp.yml
        name: userlist

    - name: List usernames
      debug:
        var: "{{ item }}"
      loop: "{{ userlist.users }}"

问题

在处理程序Read yaml中,我得到了以下错误消息。在目标计算机(workstation.example.com)上,/tmp/tmp.yml被正确下载。

代码语言:javascript
运行
复制
RUNNING HANDLER [Read yaml] *****
fatal: [workstation.example.com]: FAILED! => {"ansible facts": {"userlist": []},
"ansible included var files": [], "changed": false, "message": "Could not find o
r access '/tmp/tmp. yml' on the Ansible Controller.\nIf you are using a module a
nd expect the file to exist on the remote, see the remote src option"}

问题

如何使用HTTP获取YAML文件并将其用作include_vars变量

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2021-08-11 05:27:47

另一个选项是使用uri模块将值检索到一个Ansible变量中,然后使用from_yaml过滤器来解析它。

类似于:

代码语言:javascript
运行
复制
- name: Add users from list
  hosts: workstation
  tasks:
    - name: Download YAML userlist
      uri:
        url: http://fqdn.of.webserver/path/to/yaml.yml
        return_content: yes
      register: downloaded_yaml
    - name: Decode YAML userlist
      set_fact:
        userlist: "{{ downloaded_yaml.content | from_yaml }}"

请注意,uri在Ansible Controller上工作,而get_url在目标主机(或delegate_to中指定的主机)上工作;根据您的网络配置,您可能需要使用不同的代理设置或防火墙规则来允许下载。

票数 3
EN

Stack Overflow用户

发布于 2021-08-10 17:24:08

include_vars任务查找本地(控件)主机上的文件,但您已经将该文件下载到远程主机上的/tmp/tmp.yml。有很多方法可以让这件事发挥作用。

也许最简单的方法就是在控制机器上运行下载任务(注意delegate_to的使用):

代码语言:javascript
运行
复制
  tasks:
    - name: Download yaml
      delegate_to: localhost
      get_url:
        url: http://fqdn.of.webserver/path/to/yaml.yml
        dest: "/tmp/tmp.yml"
      notify:
        - Read yaml
        - List usernames

这将将该文件下载到本地系统上的/tmp/tmp.ymlinclude_vars将在该系统中使用该文件。例如,如果我运行这个剧本(它从我刚刚创建的示例gist获取YAML内容).

代码语言:javascript
运行
复制
- hosts: target
  gather_facts: false
  tasks:
    - name: Download yaml
      delegate_to: localhost
      get_url:
        url: https://gist.githubusercontent.com/larsks/70d8ac27399cb51fde150902482acf2e/raw/676a1d17bcfc01b1a947f7f87e807125df5910c1/example.yaml
        dest: "/tmp/tmp.yml"
      notify:
        - Read yaml
        - List usernames

  handlers:
    - name: Read yaml
      include_vars:
        file: /tmp/tmp.yml
        name: userlist

    - name: List usernames
      debug:
        var: item
      loop: "{{ userlist.users }}"

...it产生以下输出:

代码语言:javascript
运行
复制
RUNNING HANDLER [Read yaml] ******************************************************************
ok: [target]

RUNNING HANDLER [List usernames] *************************************************************
ok: [target] => (item=bob) => {
    "ansible_loop_var": "item",
    "item": "bob"
}
ok: [target] => (item=alice) => {
    "ansible_loop_var": "item",
    "item": "alice"
}
ok: [target] => (item=mallory) => {
    "ansible_loop_var": "item",
    "item": "mallory"
}

附带注意:根据我在您的剧本中看到的,我不确定您是否希望在这里使用notify和处理程序。如果你第二次运行你的剧本,什么也不会发生,因为文件/tmp/tmp.yml已经存在,所以处理程序不会被调用。

票数 1
EN

Stack Overflow用户

发布于 2021-08-11 06:12:55

通过@Larsks的回答,我制作了一本在我的环境中正确工作的剧本:

代码语言:javascript
运行
复制
- name: Download users list
  hosts: 127.0.0.1
  connection: local
  become: no
  tasks:
  - name: Download yaml
    get_url:
      url: http://fqdn.of.webserver/path/to/yaml/users.yml
      dest: ./users.yml

- name: Add users from list
  hosts: workstation
  tasks:
  - name: Read yaml
    include_vars:
      file: users.yml
  - name: List usernames
    debug:
      msg: "{{ item.id }}"
    loop: "{{ users }}"

在控件主机上运行get_url

正如@Larsks所说,您必须在控制主机而不是目标主机上运行get_url模块。

become: no添加到在控件主机上运行的任务中

如果没有“变成:否”,您将得到以下错误消息:

代码语言:javascript
运行
复制
TASK [Gathering Facts] ******************************************************
fatal: [127.0.0.1]: FAILED! => {"ansible_facts": {}, "changed": false, "msg":
 "The following modules failed to execute: setup\n setup: MODULE FAILURE\nSee
 stdout/stderr for the exact error\n"}

使用connection: local而不是local_action

如果您使用的是local_action而不是像这样的connection: local

代码语言:javascript
运行
复制
- name: test get_url
  hosts: workstation
  tasks:
  - name: Download yaml
    local_action:
      module: get_url
      url: http://fqdn.of.webserver/path/to/yaml/users.yml
      dest: ./users.yml
  - name: Read yaml
    include_vars:
      file: users.yml
  - name: output remote yaml
    debug:
      msg: "{{ item.id }}"
    loop: "{{ users }}"

您将得到以下错误消息:

代码语言:javascript
运行
复制
TASK [Download yaml] ********************************************************
fatal: [workstation.example.com]: FAILED! => {"changed": false, "module_stde
rr": "sudo: a password is required\n", "module_stdout":"", "msg":"MODULE FAIL
URE\nSee stdout/stderr for the exact error", "rc": 1}

get_url将文件存储在控件主机上。

在这种情况下,get_url模块将users.yml存储在控制主机上(在当前目录中)。因此,如果不想离开users.yml,就必须删除它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68729876

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档