如何创建Ansible playbook以获取远程主机的操作系统版本?

19

我是ansible的新手。我的要求是需要获取托管在AWS上的超过450个Linux服务器的操作系统版本。AWS没有提供此功能,它建议我们从puppet或chef中获取。我创建了一些简单的playbooks,但无法运行。

---
- hosts: testmachine
user: ec2-user
sudo: yes
tasks:
- name: Update all packages to latest
yum: name=* state=latest

task:
- name: obtain OS version
shell: Redhat-release

playbook应该输出一个包含主机名和操作系统版本的文本文件。如有任何见解,将不胜感激。


大多数页面的答案需要 gather_facts: True - ishigoya
请查看以下链接 https://dev59.com/hbroa4cB1Zd3GeqPn5-S#70754268 - user3710949
6个回答

28

使用以下Jinja2表达式之一:

{{ hostvars[inventory_hostname].ansible_distribution }}
{{ hostvars[inventory_hostname].ansible_distribution_major_version }}
{{ hostvars[inventory_hostname].ansible_distribution_version }}

其中:

  • hostvarsansible_...是Ansible内置功能,会自动收集
  • ansible_distribution是被Ansible处理的主机

例如,假设您正在对运行CentOS 7分发版的主机 host.example.com 运行Ansible角色 test_role

---
- debug:
    msg: "{{ hostvars[inventory_hostname].ansible_distribution }}"
- debug:
    msg: "{{ hostvars[inventory_hostname].ansible_distribution_major_version }}"
- debug:
    msg: "{{ hostvars[inventory_hostname].ansible_distribution_version }}"

将为您提供:

TASK [test_role : debug] *******************************************************
ok: [host.example.com] => {
    "msg": "CentOS"
}

TASK [test_role : debug] *******************************************************
ok: [host.example.com] => {
    "msg": "7"
}

TASK [test_role : debug] *******************************************************
ok: [host.example.com] => {
    "msg": "7.5.1804"
}

你好 Gabriel, 应该是 "inventory_hostname 是被 Ansible 处理的主机" 而不是 ansible_distribution 吧? - Björn Albers
另外一种方法是使用ansible_facts['distribution'],它可以像{{ hostvars[inventory_hostname].ansible_distribution }}一样返回操作系统名称。 - snowpeak
现在只需要使用{{ ansible_distribution }},不需要显式地使用hostvars。 - nickolay.laptev
有没有一种方法可以获取单行信息? - majorgear

4
以结构化的方式:
- hosts: all
  become: no
  vars:
    output_file: os.csv
  tasks:
    - block:
        # For permisison setup.
        - name: get current user
          command: whoami
          register: whoami
          run_once: yes

        - name: clean file
          copy:
            dest: "{{ output_file }}"
            content: 'hostname,distribution,version,release'
            owner: "{{ whoami.stdout }}"
          run_once: yes

        - name: fill os information
          lineinfile:
            path: "{{ output_file }}"
            line: "{{ ansible_hostname }},\
              {{ ansible_distribution }},\
              {{ ansible_distribution_version }},\
              {{ ansible_distribution_release }}"
          # Tries to prevent concurrent writes.
          throttle: 1
      delegate_to: localhost

在执行文件夹中创建名为os.csv的逗号分隔文件。您可以使用任何变量来编辑line:

2

Ansible已经自动提供了关于远程主机的许多信息,这些信息可以在"hostvars"变量中找到。

如果您想查看名为"my_remote_box_name"的主机的信息,则可以执行以下操作:

- debug: var=hostvars['my_remote_box_name']

一些操作系统信息存储在

hostvars['my_remote_box_name']['ansible_lsb']

对于我的一个Ubuntu主机来说,可能会是这样:

{
  "hostvars['my_remote_box_name']['ansible_lsb']": {
    "codename": "xenial", 
    "description": "Ubuntu 16.04.1 LTS", 
    "id": "Ubuntu", 
    "major_release": "16", 
    "release": "16.04"
}

您可以在playbooks和模板中使用这些变量,使用“{{ variable_name }}”的表示方法。
- debug: msg="My release is {{ansible_lsb.release}}"

输出:

"msg": "My release is 16.04"

1

对于一些Windows实例:

    - debug:
        msg:
        - "ansible_distribution {{ hostvars[inventory_hostname].ansible_distribution }}"
        - "major version {{ hostvars[inventory_hostname].ansible_distribution_major_version }}"
        - "version {{ hostvars[inventory_hostname].ansible_distribution_version }}"

给出:
ok: [server1] => {
"msg": [
    "ansible_distribution Microsoft Windows Server 2008 R2 Standard ",
    "major version 6",
    "version 6.1.7601.65536"
]

}

ok: [server2] => {
"msg": [
    "ansible_distribution Microsoft Windows Server 2016 Standard",
    "major version 10",
    "version 10.0.14393.0"
]

}


0
"AWS不提供此功能" - 您可以检查文件/etc/os-release以获取aws实例的详细信息。
"例如"
[ec2-user@ip-xx-xx-xx ~]$ cat /etc/os-release
NAME="Amazon Linux AMI"
VERSION="2016.03"
ID="amzn"
ID_LIKE="rhel fedora"
VERSION_ID="2016.03"
PRETTY_NAME="Amazon Linux AMI 2016.03"
ANSI_COLOR="0;33"
CPE_NAME="cpe:/o:amazon:linux:2016.03:ga"
HOME_URL="http://aws.amazon.com/amazon-linux-ami/"

感谢Vor的回复,但是如果我要登录到450个Redhat服务器并且执行cat /etc/redhat-release命令,我很可能会在几个小时内崩溃...这就是我想使用Ansible自动化的原因。这里有任何Ansible专家吗? - AmigoSe
你还需要使用调试功能来打印cat命令的标准输出。 - MillerGeek

0
- name: obtain OS version
  shell: Redhat-release
  register: result

- name: print OS version
  debug: var=result.stdout

1
谢谢smiller171 我尝试了以下任务:
  • 名称:收集远程主机的操作系统版本 shell:cat /etc/redhat-release
  • 名称:打印操作系统版本 debug:var=result.stdout
任务[打印操作系统版本]************************************************************ 好的:[IP] => { "result.stdout":"变量未定义!" Var isnot defined came up
- AmigoSe
再看一遍我的例子。注册您的 shell 命令的结果非常重要。 - MillerGeek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接