• 一文搞懂 ansible 变量配置


    如何自定义变量

    - hosts: webservers
      vars:
        http_port: 80
    

    可以在temple 文件中使用 {{ }} 来使用变量

    My amp goes to {{ max_amp_value }}
    

    也可以在写playbook的时候使用变量

    template: src=foo.cfg.j2 dest={{ remote_install_path }}/foo.cfg
    

    这里有个小技巧,使用变量时,要用双引号引用。
    错误写法

    - hosts: app_servers
      vars:
          app_path: {{ base_path }}/22
    

    正确写法

    - hosts: app_servers
      vars:
           app_path: "{{ base_path }}/22"
    

    facts: 系统的信息

    从远程节点搜集到的系统信息称为facts。facts包括远程主机的IP地址,和操作系统类型,磁盘相关信息等等。

    执行下边的命令来查看都有哪些信息:

    - debug: var=ansible_facts
    
    ansible test -m setup
    

    返回内容类似下边这样:

    ansible linux-node2 -m setup  |head
    linux-node2 | SUCCESS => {
        "ansible_facts": {
            "ansible_all_ipv4_addresses": [
                "10.0.2.12",
                "192.168.56.12"
            ],
            "ansible_all_ipv6_addresses": [
                "fe80::250:56ff:fe3f:cc94",
                "fe80::250:56ff:fe30:8f96"
            ],
            ......省略若干行内容......
    

    可以在temple模板中使用上边返回的值:

    {{ ansible_devices.sda.model }}
    {{ ansible_facts['devices']['xvda']['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的文件,内容如下:

    mkdir -p /etc/ansible/facts.d
    cat >>/etc/ansible/facts.d/preferences.fact<<EOF
    [general]
    name=linux
    test=True
    EOF
    

    在控制节点获取自定义的信息:

    ansible linux-node2 -m setup -a "filter=ansible_local"
    linux-node2 | SUCCESS => {
        "ansible_facts": {
            "ansible_local": {
                "preferences": {
                    "general": {
                        "name": "linux",
                        "test": "True"
                    }
                }
            }
        },
        "changed": false
    }
    

    可以在playbooks或者模板中这样使用获取到的信息:

    {{ ansible_local.preferences.general.name }}
    

    linux-node2 服务器配置

    mkdir /etc/ansible/facts.d -p
    
    cat /etc/ansible/facts.d/ini.fact
    [mytest]
    niu=key
    
    cat /etc/ansible/facts.d/niu.fact
    { "name":"shencan" , "list":["three","one","two"], "Dict": {"A":"B"} }
    

    结果展示

    ansible -i inventory/ linux-node2 -m setup -a "filter=ansible_local"
    linux-node2 | SUCCESS => {
        "ansible_facts": {
            "ansible_local": {
                "ini": {
                    "mytest": {
                        "niu": "key"
                    }
                },
                "niu": {
                    "Dict": {
                        "A": "B"
                    },
                    "list": [
                        "three",
                        "one",
                        "two"
                    ],
                    "name": "shencan"
                },
                "preferences": {
                    "general": {
                        "name": "linux",
                        "test": "True"
                    }
                }
            }
        },
        "changed": false
    }
    

    缓存 facts数据

    编辑 ansible.cfg 添加如下内容,让数据缓存到redis中。

    [defaults]
    gathering = smart
    fact_caching = redis
    fact_caching_timeout = 86400
    # seconds
    

    需要安装相关的依赖程序

    yum install redis
    service redis start
    pip install redis
    

    使用facter扩展facts信息

    使用过Puppet的读者都熟悉facter是Puppet里面一个负责收集主机静态信息的组件,Ansible的facts功能也一样。Ansible的facts组件也会判断被控制机器上是否安装有facter和ruby-json包,如果存在的话,Ansible的facts也会采集facter信息。我们来查看以下机器信息:

    ansible linux-node2 -m shell -a 'rpm -qa ruby-json facter'
    
    ansible linux-node2 -m facter
    

    当然,如果直接运行setup模块也会采集facter信息
    所有facter信息在ansible_facts下以facter_开头,这些信息的引用方式跟Ansible自带facts组件收集的信息引用方式一致。

    使用ohai扩展facts信息

    ohai是Chef配置管理工具中检测节点属性的工具,Ansible的facts也支持ohai信息的采集。当然需要被管机器上安装ohai包。下面介绍ohai相关信息的采集:

    ansible linux-node2 -m shell -a 'gem list|grep ohai'
    

    如果主机上没有安装ohai包,可以使用gem方式进行安装。如果存在ohai包,可以直接运行ohai模块查看ohai属性:

    ansible linux-node2 -m ohai
    

    如果直接运行setup模块,也会采集ohai信息

    Registered 获取执行命令的输出

    register方式用于在task之间传递变量。

    在刚开始使用 ansible-playbook 做应用程序部署的时候,因为在部署的过程中有使用到 command 或 shell 模块执行一些自定义的脚本,而且这些脚本都会有输出,用来表示是否执行正常或失败。如果像之前自己写脚本做应用程序部署的,这很好实现。但现在是用 Ansible 做,那么要怎么样做可以获取到 ansible playbook 中 command 模块的输出呢? Ansible 也提供的解决办法,这时我们就可以通过使用 register 关键字来实现,register 关键字可以存储指定命令的输出结果到一个自定义的变量中,我们通过访问这个自定义变量就可以获取到命令的输出结果。Register 的使用很方便,只需要在 task 声明 register 关键字,并自定义一个变量名就可以。如下:

    - hosts: web_servers
    
      tasks:
    
         - shell: /usr/bin/foo
           register: foo_result
           ignore_errors: True
    
         - shell: /usr/bin/bar
           when: foo_result.rc == 5
    

    register 中存放的的数据其实是ansible stdout返回的json数据,拿到json数椐后就可以做相关使用和处理了。可以使用-v 查看上一个task的stdout 数据。

    - name: echo date
     command: date
     register: date_output
    
    - name: echo date_output
     command: echo "30"
     when: date_output.stdout.split(' ')[2] == "30"
    

    这里第 1 个 task 是执行了一个 date 命令,register 关键字将 date 命令的输出存储到 date_output 变量名。第 2 个 task 对输出进行分析,并使用 when 对关键字对分析后的进行判断,如果匹配,则执行这个 task,不匹配就不执行。这里要重点说下的,因为 register 获取到的输出内容都是字符串,而 ansible 又是 python 写的,你可以使用 python 字符串的方法对其做处理,比如本文中使用的 split,还可以使用 find 方法。个人觉得,真是非常灵活方便。

    注册变量

    register: xxx
    
    • xxx.stdout.find(sdf)
    • xxx.stdout_lines

    使用debug模块查看register中的数据

    ---
      - hosts: all
          gather_facts: False
          tasks:
              - name: register variable
                  shell: hostname
                  register: info
              - name: display variable
                  debug: msg="The varibale is  {{ info  }}"
    

    内置变量

    ansible 默认内置了一下变量,可以直接使用。hostvars, groups, group_names, and inventory_hostname

    hostvars

    hostvars 是用来调用指定主机变量,需要传入主机信息,返回结果也是一个 JSON 字符串,同样,也可以直接引用 JSON 字符串内的指定信息。如果主机执行获取了 facts 数据,则hosts中将会包含 facts 中的数据。

    - name: Get the masters IP
      set_fact: dns_master="{{ hostvars.ns1.ansible_default_ipv4.address }}"
    
    - name: Configure BIND
      template: dest=/etc/named.conf src=templates/named.conf.j2
    

    hostvars 例子

    {
    	'linux-node1': {
    		'inventory_file': '/data/db/playbooks/inventory/open_falcon',
    		'ansible_playbook_python': '/usr/bin/python2',
    		'falcon_mysql_port': 3306,
    		'ansible_check_mode': True,
    		'falcon_mysql_passwd': 123456,
    		'ansible_diff_mode': True,
    		'open_falcon_path': '/data/app/open-falcon',
    		'groups': {
    			'ungrouped': [],
    			'judge': ['linux-node2_judge1', 'linux-node2_judge2'],
    			'all': ['linux-node1', 'linux-node2_judge1', 'linux-node2_judge2'],
    			'open_falcon': ['linux-node2_judge1', 'linux-node2_judge2', 'linux-node1'],
    			'api': ['linux-node1']
    		},
    		'ansible_forks': 5,
    		'ansible_facts': {},
    		'inventory_hostname': 'linux-node1',
    		'ansible_inventory_sources': ['/data/db/playbooks/inventory/open_falcon'],
    		'target': 'judge',
    		'inventory_hostname_short': 'linux-node1',
    		'playbook_dir': '/data/db/playbooks/playbooks',
    		'omit': '__omit_place_holder__38ba14590a3d51c234a21046ca130054f96cc570',
    		'ansible_skip_tags': [],
    		'inventory_dir': '/data/db/playbooks/inventory',
    		'ansible_verbosity': 0,
    		'role': 'test',
    		'group_names': ['api', 'open_falcon'],
    		'falcon_mysql_host': '192.168.56.12',
    		'ansible_run_tags': ['test_vars'],
    		'ansible_version': {
    			'major': 2,
    			'full': '2.7.1',
    			'string': '2.7.1',
    			'minor': 7,
    			'revision': 1
    		},
    		'falcon_mysql_name': 'falcon'
    	},
      ’linux-node2_judge2‘: {
        'ansible_hostname': 'linux-node2',
    		'ansible_ssh_port': 52113,
        'ansible_ssh_host': 'linux-node2',
        'ansible_system': 'Linux',
    		'playbook_dir': '/data/db/playbooks/playbooks',
    		'ansible_run_tags': ['test_vars'],
    		'judge_http_port': 6081,
    		'ansible_python_version': '2.7.5'
      }
    }
    

    groups

    groups 变量是一个全局变量,引用了inventory文件里所有的主机以及主机组信息 它返回的是一个json字符串。

    {
    	'ungrouped': [],
    	u 'judge': [u 'linux-node2_judge1', u 'linux-node2_judge2'],
    	'all': [u 'linux-node1', u 'linux-node2_judge1', u 'linux-node2_judge2'],
    	u 'open_falcon': [u 'linux-node2_judge1', u 'linux-node2_judge2', u 'linux-node1'],
    	u 'api': [u 'linux-node1']
    }
    

    playbook中通过{{ groups }}或是{{ groups.属性}}的方式来引用

      - name: Create a user for all app servers
      with_items: groups.appservers
      mysql_user: name=kate password=test host={{ hostvars.[item].ansible_eth0.ipv4.address }} state=present
    
    {% for host in groups['app_servers'] %}
       {{ hostvars[host]['ansible_facts']['eth0']['ipv4']['address'] }}
    {% endfor %}
    
    etcd_initial_cluster: |-
          {% for item in groups['etcd'] -%}
            {{ hostvars[item]['node_name'] }}=http://{{ hostvars[item]['ansible_default_ipv4']['address'] }}:2380{% if not loop.last %},{% endif %}
          {%- endfor %}
    etcd_initial_cluster_state: "new"
    

    group_names

    group_names引用当前主机所在的group的名称

    {% if 'webserver' in group_names %}
       # some part of a configuration file that only applies to webservers
    {% endif %}
    
    - name: For secure machines
      set_fact: sshconfig=files/ssh/sshd_config_secure
      when: "'secure' in group_names"
    
    - name: For non-secure machines
      set_fact: sshconfig=files/ssh/sshd_config_default
      when: "'secure' not in group_names"
    
    • inventory_hostname 变量保存了在设备配置清单中服务器的主机名
    • inventory_hostname_short 变量跟inventory_hostname一样,只是去掉域名,比如inventory_hostname 是host.example 那么inventory_hostname_short就是host
    • inventory_dir 是设备清单文件的路径
    • inventory_file 是设备清单文件的文件名

    通过 vars_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
    

    /vars/external_vars.yml 文件内容

    ---
    # in the above example, this would be vars/external_vars.yml
    somevar: somevalue
    password: magic
    

    使用 --extra-vars (or -e ) 命令行传入 变量

    ansible-playbook release.yml --extra-vars "version=1.23.45 other_variable=foo"
    
    ansible-playbook release.yml --extra-vars "@some_file.json"
    
    ansible-playbook release.yml --extra-vars '{"version":"1.23.45","other_variable":"foo"}'
    ansible-playbook arcade.yml --extra-vars '{"pacman":"mrs","ghosts":["inky","pinky","clyde","sue"]}'
    

    变量读取的优先级

    读取顺序倒叙实现,最后一行是优先级最高的

    • command line values (eg “-u user”)
    • role defaults [1]
    • inventory file or script group vars [2]
    • inventory group_vars/all [3]
    • playbook group_vars/all [3]
    • inventory group_vars/* [3]
    • playbook group_vars/* [3]
    • inventory file or script host vars [2]
    • inventory host_vars/* [3]
    • playbook host_vars/* [3]
    • host facts / cached set_facts [4]
    • play vars
    • play vars_prompt
    • play vars_files
    • role vars (defined in role/vars/main.yml)
    • block vars (only for tasks in block)
    • task vars (only for the task)
    • include_vars
    • set_facts / registered vars
    • role (and include_role) params
    • include params
    • extra vars (always win precedence)

    定义一个roles 来测试执行顺序 vim roles/test/main.yaml

    - debug:
        msg: test_vars {{ test_vars }}
    

    playbook 中定义 vars vim playbooks/role.yaml

    - hosts: "{{ target }}"
      roles:
        - "{{ role }}"
      vars:
        - test_vars: playbook
    

    执行roles ansible-playbook -i inventory/ -e target=localhost -e role=test playbooks/role.yaml -t test_vars -CD

    TASK [test : debug] **************************************************************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "test_vars playbook"
    }
    

    第二步 在roles/vars中定义变量

    vim test/vars/main.yaml
    test_vars: test_vars
    

    执行roles ansible-playbook -i inventory/ -e target=localhost -e role=test playbooks/role.yaml -t test_vars -CD

    TASK [test : debug] **************************************************************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "test_vars test_vars"
    }
    

    第三步 在roles文件中定义 vim roles/test/main.yaml

    - debug:
        msg: test_vars {{ test_vars }}
      vars:
        - test_vars: block
    

    执行roles ansible-playbook -i inventory/ -e target=localhost -e role=test playbooks/role.yaml -t test_vars -CD

    TASK [test : debug] **************************************************************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "test_vars block"
    }
    

    第四步 命令行中使用 -e 传入变量

    ansible-playbook -i inventory/ -e target=localhost -e role=test playbooks/role.yaml  -t test_vars -CD  -e "test_vars=cmdline"
    
    TASK [test : debug] **************************************************************************************************************************************************************************************************
    ok: [localhost] => {
        "msg": "test_vars cmdline"
    }
    

    参考文档

    Using Variables

  • 相关阅读:
    阿里云OSS进行文件下载时,报NOSuchKeys: com.aliyun.oss.OSSException: The specified key does not exist.
    [JAVA异常]ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2 JDWP exit erro
    mybatis 中的<![CDATA[ ]]>
    HttpClients.custom的创建
    RestTemplate可以自定义重试次数
    RegxUtils正则表达式工具类
    MYSQL中 != 和 is not的区别
    ccna ccnp ccie 区别
    【IDEA】IDEA SpringBoot访问不到webapp下的内容
    日志 | logback | logback-spring.xml
  • 原文地址:https://www.cnblogs.com/biglittleant/p/13072981.html
Copyright © 2020-2023  润新知