在平时运维工作中有时候需要根据不同的远程节点或者针对不同的IP的系统做不同的配置部署.如,Ansible可以根据不同的IP地址来对各个节点上的配置文件做不同的处理,这里就需要用到变量。
可以在playbooks文件中直接定义变量:
- hosts: webservers vars: http_port: 80
定义了一个变量名为http_port的变量,值为80.
通过文件包含和角色定义变量
[root@web1 ~]# cat /etc/ansible/roles/webservers/vars/main.yml --- http_port: 8099 max_clients: 321
在角色目录下的vars/main.yml直接定义变量即可。在执行该角色的时候会自动将该文件包含进去。
变量的使用
在模板文件中使用变量:
My amp goes to {{ max_amp_value }}也可以直接在playbooks文件中使用变量:
template: src=foo.cfg.j2 dest={{ remote_install_path }}/foo.cfg使用变量值来确定文件在远程节点上的存储位置。
在定义变量中引用其他变量:
- hosts: app_servers
  vars:
       app_path: "{{ base_path }}/22"要是双引号将变量的值(如app_path的值)包括起来才行。
系统的信息:facts
还有另外一个地方可以获取一些变量,但这些变量的值是ansible自己搜集来的。
从远程节点搜集到的系统信息称为facts。
facts包括远程主机的IP地址,和操作系统类型,磁盘相关信息等等。
执行下边的命令来查看都有哪些信息:
ansible hostname -m setup
返回内容类似下边这样:
[root@web1 ~]# ansible webservers -m setup
192.168.1.65 | success >> {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "192.168.1.65"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::250:56ff:fe93:a885"
        ], 
        "ansible_architecture": "x86_64", 
        "ansible_bios_date": "01/07/2011", 
        "ansible_bios_version": "6.00", 
        "ansible_cmdline": {
            "KEYBOARDTYPE": "pc", 
            "KEYTABLE": "us", 
            "LANG": "en_US.UTF-8", 
            "SYSFONT": "latarcyrheb-sun16", 
            "crashkernel": "129M@0M", 
            "quiet": true, 
            "rd_NO_DM": true, 
            "rd_NO_LUKS": true, 
            "rd_NO_LVM": true, 
            "rd_NO_MD": true, 
            "rhgb": true, 
            "ro": true, 
            "root": "UUID=c3e6eda7-d67d-4787-8f9f-6534941f11fd"
        }, 
        "ansible_date_time": {
            "date": "2015-07-30", 
            "day": "30", 
            "epoch": "1438241766", 
            "hour": "15", 
            "iso8601": "2015-07-30T07:36:06Z", 
            "iso8601_micro": "2015-07-30T07:36:06.373646Z", 
            "minute": "36", 
            "month": "07", 
            "second": "06", 
            "time": "15:36:06", 
            "tz": "CST", 
            "tz_offset": "+0800", 
            "weekday": "Thursday", 
            "year": "2015"
        }, 
        "ansible_default_ipv4": {
            "address": "192.168.1.65", 
            "alias": "eth1", 
            "gateway": "192.168.1.254", 
            "interface": "eth1", 
            "macaddress": "00:50:56:93:a8:85", 
            "mtu": 1500, 
            "netmask": "255.255.255.0", 
            "network": "192.168.1.0", 
            "type": "ether"
        }, 
       #省略若干行内容
        "ansible_eth1": {
            "active": true, 
            "device": "eth1", 
            "ipv4": {
                "address": "192.168.1.65", 
                "netmask": "255.255.255.0", 
                "network": "192.168.1.0"
            }, 
            "ipv6": [
                {
                    "address": "fe80::250:56ff:fe93:a885", 
                    "prefix": "64", 
                    "scope": "link"
                }
            ], 
            "macaddress": "00:50:56:93:a8:85", 
            "module": "vmxnet3", 
            "mtu": 1500, 
            "promisc": false, 
            "type": "ether"
        }, 
        "ansible_fips": false, 
        "ansible_form_factor": "Other", 
        "ansible_fqdn": "db2", 
        "ansible_hostname": "db2", 
        "ansible_interfaces": [
            "lo", 
            "eth1"
        ], 
        
        ......省略若干行内容......可以以一下方式使用上边返回的值:
{{ ansible_devices.sda.model }}要获取系统的主机名:
{{ ansible_hostname }}facts会经常在条件语句及模板中使用。如,根据不同的linux发行版,执行不同的包管理程序。
关闭facts
如果你确信不需要主机的任何facts信息,而且对远程节点主机都了解的很清楚,那么可以将其关闭。远程操作节点较多的时候,关闭facts会提升ansible的性能。
只需要在play中设置如下:
- hosts: whatever gather_facts: no
本地facts(facts.d)
如果远程节点系统上存在etc/ansible/facts.d目录,这个目录下的以.fact为后缀的文件,里面的内容可以是JSON格式,或者ini格式书写;或者是一个可以返回json格式数据的可执行文件,都可以用来提供本地facts信息。
在远程节点创建一个/etc/ansible/facts.d/preferences.fact的文件,内容如下:
[general] asdf=1 bar=2
在控制节点获取自定义的信息:
[root@web1 ~]# ansible webservers -m setup -a "filter=ansible_local"
192.168.1.65 | success >> {
    "ansible_facts": {
        "ansible_local": {
            "preferences": {
                "general": {
                    "asdf": "1", 
                    "bar": "2"
                }
            }
        }
    }, 
    "changed": false
}filter来指定一个过滤条件。
可以在playbooks或者模板中这样使用获取到的信息:
{{ ansible_local.preferences.general.asdf }}注册变量
一个任务的运行结果都可以保存到一个变量中,供稍后使用,有时候需要将运行的命令的角色保存起来,并作为下一个人任务的执行条件。在运行playbooks的时候可以使用-v参数来显示执行过程中的结果信息。
具体格式如下:
- hosts: web_servers tasks: - shell: /usr/bin/foo register: foo_result ignore_errors: True - shell: /usr/bin/bar when: foo_result.rc == 5
使用register将shell 模块执行的结果保存到变量foo_result中,并在之后引用该变量。
示例:
#远程节点上创建一个shell脚本 [root@db2 ~]# cat /tmp/test.sh #!/bin/bash echo 123 #控制节点 [root@web1 ~]# cat /etc/ansible/register.yml --- - hosts: webservers remote_user: root tasks: - shell: /tmp/test.sh register: rst_value ignore_errors: True - name: touch file in tmp named register.log file: state=touch dest=/tmp/register.log when: rst_value.stdout == "123" #远程节点 [root@db2 ~]# ll /tmp/register.log -rw-r--r--. 1 root root 0 Jul 30 16:42 /tmp/register.log
当远程节点脚本/tmp/test.sh运行结束并输出123的时候,在远程节点上创建文件/tmp/register.log。
访问复杂的变量
在facts信息中,网络相关的信息是一个嵌套的数据结构,想获取IP地址:
{{ ansible_eth0["ipv4"]["address"] }}或者:
{{ ansible_eth0.ipv4.address }}访问数组的第一个元素:
{{ foo[0] }}将变量定义到单独的文件中
也可以将变量定义到一个单独的文件中,然后在playbooks中使用var_files导入文件即可:
--- - hosts: all remote_user: root vars: favcolor: blue vars_files: - /vars/external_vars.yml tasks: - name: this is just a placeholder command: /bin/echo foo
变量文件也是YMAL格式:
--- # in the above example, this would be vars/external_vars.yml somevar: somevalue password: magic
当你在自动化工作中使用了ansible的角色,就不需要想上边那样定义变量文件了,在角色目录下的vars/main.yml中定义的变量,会自动导入到playbooks中,不需要显式包含变量文件。
命令行传递变量
除了上边介绍的变量定义形式,还可以通过命令行传递变量,如,有一个较为通用的节点部署playbooks,在每次部署的时候传递一个版本号进去:
ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"
也可以向playbooks传递主机组和远程用户信息:
---
- hosts: ‘{{ hosts }}‘
  remote_user: ‘{{ user }}‘
  tasks:
     - ...
ansible-playbook release.yml --extra-vars "hosts=vipers user=starbuck"playbooks中的变量使得ansible在使用的时候更加灵活,功能更加健全,可以对远程节点以“因材施教”的方式执行不同的操作,使节点系统达到所需的状态。
本文出自 “diannaowa” 博客,请务必保留此出处http://diannaowa.blog.51cto.com/3219919/1680732
原文:http://diannaowa.blog.51cto.com/3219919/1680732