自动化运维实践 | Ansible变量

2020-08-17 14:53:29 浏览数 (1)

Ansible使用变量的几个场景

在playbook中, 常用的几种变量包括以下几种情况:

1)在playbook中用户自定义的变量

2)用户无须自定义。Ansible会在执行playbook之前去远程主机上搜集关于远程节点系统信息的变量。

3)在文件模板中,可以直接使用上述两种变量

4)把任务的运行结果作为一个变量来使用,这个变量叫做注册变量

5)为了使playbook更灵活、通用性更强,允许用户在执行playbook时传入变量的值,这个时候就需要用到"额外变量"。

1. 在playbook中用户自定义的变量

  • 用户可以在playbook中,通过vars关键字自定义变量,使用时用{{}}引用起来即可。

例如,下面的例子中,用户定义的变量名为http_port,其值为80。

通过{{ http_port }}来引用。

代码语言:javascript复制
---
- hosts: web
  vars:
    http_port: 80
  remote_user: root
  tasks:
    - name: insert firewalld rule for httpd
      firewalled: port={{ http_port }}/tcp permanent=true state=enabled immediate=yes
  • 也可以把变量放到单独的文件里。

当变量较多时,或者变量需要在多个playbook中重用的时候,可以把变量放到一个单独的文件中,通过关键字"vars_file"把文件中定义的变量引用到playbook中。

代码语言:javascript复制
---
- hosts: web
  remote_user: root
  vars_file:
    - vars/server_vars.yml
  tasks:
    - name: insert firewalld rule for httpd
      firewalled: port={{ http_port }}/tcp permanent=true state=enabled immediate=yes

变量文件vars/server_var.yml中的内容为:

代码语言:javascript复制
http_port: 80

2. 远程主机的系统变量(Facts)

Ansible会通过模块"setup"来搜集主机的信息,这些搜集到的系统信息叫做Facts。每个playbook在执行前都会默认执行setup模块,所以这些Facts信息可以直接以变量的形式使用。

  • 哪些Facts变量可以引用呢?可以通过命令行上调用setup模块命令查看。

ansible all -m setup -u root

  • 使用复杂的Facts变量

可以通过下面两种方式访问复杂变量中的子属性:

中括号:

代码语言:javascript复制
{{ ansible_ens3["ipv4"]["address"] }}

点号:

代码语言:javascript复制
{{ ansible_ens3.ipv4.address }}

3. 把运行结果当做变量使用-注册变量

把任务的执行结果当做一个变量的值也是可以的。这个时候就需要用到"注册变量",即把执行结果注册到一个变量中,待后面的任务使用。把执行结果注册到变量中的关键字是register, 使用方法如下:

代码语言:javascript复制
---
- hosts: all
  remote_user: root
  tasks:
    - shell: ls
      register: result  ##result变量记录了ls的返回值
      ignore_errors: True

    - shell: echo "{{ result.stdout }}"
      when: result.rc==

    - debug: msg="{{ result.stdout }}"

执行结果如下:

4. 用命令行传递参数

为了使playbook更灵活,通用性更强,允许用户在执行的时候传入变量的值,这时候就需要用到"额外变量"。

  • 定义命令行变量
代码语言:javascript复制
---
- hosts: '{{ hosts }}'
  remote_user: '{{ user }}'
  tasks:
    - ...

上述playbook中hosts和user都定义为变量,需要从命令行传递变量值。如果在命令中不传入值,执行会报错。

  • 使用命令行变量
代码语言:javascript复制
ansible-playbook test.yml --extra-vars "hosts=web user=root"

Ansible变量作用域

  • Global,作用域为全局: --- Ansible配置文件中定义的变量 --- 环境变量 --- ansible/ansible-playbook命令行中传进来的变量
  • Play, 作用域为play(一个playbook由多个play组成) --- Play中vars关键字下定义的变量 --- 通过模块include_vars定义的变量 --- role在文件default/main.yml和vars/main.yml中定义的变量
  • Host,作用域为某个主机 --- 定义在主机清单中的变量 --- 主机的系统变量 --- 注册变量

Ansible中变量的优先级

Ansible变量的优先级(由低到高)

role defaults

dynamic inventory variables

inventory variables

inventory group_vars

inventory host_vars

playbook group_vars

plsybook host_vars

host facts

registered variables

set_facts

play variables

play vars_prompt

play vars_files

role variables and include variables

block variables

task variables

extrd variables

从上面的优先级列表中,我们可以总结出大体的规律,除了role defaults变量外,其他变量的作用域越小越精确,变量的优先级越高。

1. role defaults

role x的默认变量放在文件roles/x/default/main.yml中

2. inventory vars

在inventory文件中定义的变量

代码语言:javascript复制
#file: /etc/ansible/hosts
host1 ansible_ssh_port= ntp_server=inventory.ntp.com

3. inventory group_vars

有两个地方可以定义group_vars:一个是在inventory中直接定义;二是在inventory文件同级的文件夹groups_vars下定义,放在group同名的文件中。

所有group中都生效的变量放在文件/etc/ansible/group_vars/all中。

代码语言:javascript复制
#file: /etc/asnible/hosts
[group1:vars]
ntp_server=inventory_group_vars.example.com


#file: /etc/ansible/group_vars/all
ntp_server: default-time.example.com

4. inventory hos_vars

有两个地方可以定义host_vars:一个是在inventory中直接定义;二是在inventory文件同级的文件夹host_vars下,与host用吗的文件中定义。

代码语言:javascript复制
#file: /etc/asnible/hosts
host1  ntp_server=inventory_host_vars.example.com


#file: /etc/ansible/host_vars/hosts1
ntp_server: default-time.example.com

5. Playbook group_vars

和playbook文件同级的子目录下定义的变量。例如:当前的playbook放在~/playbooks目录下,那么Group "group1"的变量放在下面的文件中:

代码语言:javascript复制
#~/playbooks/group_vars/group1
ntp_server: default-time.example.com

6. Playbook host_vars

Playbook文件同级的子目录Host-vars下定义的变量。例如:当前的playbook放在~/playbooks目录下,那么对应的Host "host1"的变量放在下面的文件中:

代码语言:javascript复制
#~/playbooks/host_vars/host1
ntp_server: default-time.example.com

7. Host facts

Ansible在执行playbook时,会自动搜索远程直接的信息。关于这些主机的系统变量都可以在playbook中直接使用。

8. Play vars

代码语言:javascript复制
- hosts: web
  vars:
    http_port: 80
    defined_name: "Hello, my name is Yuki"

9. play vars_prompt

vars_prompt是需要用户在执行playbook的时候输入变量值的变量。

代码语言:javascript复制
--- 
- hosts: all
  remote_user: root
  gether_facts: no

  vars: 
      test: "camelot"

  vars_prompt:
     - name: "name"
        prompt: "what is your name? "
     - name: "favcolor"
        prompt: "what is you favorite color?"

   tasks:
     - debug: msg="Hello {{name}}, your favorite color is {{favcolor}}"

10. Play vars_files

把一个变量单独放在一个文件中,通过关键字vars_file从文件加载进来的变量就是play vars_file.

代码语言:javascript复制
- host: web
  vars_file:
      - apache_vars.yml

11. registered vars

把执行结果注册到一个动态值的变量中,这个变量就是registered vars。

代码语言:javascript复制
tasks:
    - shell: ls
      register: result  ##result变量记录了ls的返回值
      ignore_errors: True
    
    - debug: msg="{{ result.stdout }}"

12. set_facts

set_facts 是一个模块的名字,在任务中通过set_facts加入以下Facts变量。

代码语言:javascript复制
- set_facts:
   one_fact: "something"
   other_fact: "{{local_var}}"

13. role and include vars

代码语言:javascript复制
role vars
---
# file: roles/x/vars/main.yml
http_port:

14. role include vars

在role/x/tasks/main.yml include 中, 通过关键字include 加载进来的变量

代码语言:javascript复制
---
# file: roles/x/vars/apache.yml
http_port:80

---
# file: roles/x/tasks/main.yml
- name: Add apache variables
  include_vars: "apache.yml"

15. block vars

只能在playbook的任务中的某个block里定义和使用的变量。

代码语言:javascript复制
  tasks: 
- bloack:
    - yum: name={{ service }} state=installed
    - service: name={{ status }} state=started enabled=True
    vars:
       service: httpd
       status: started

16. tasks vars

只能在该任务里使用的变量

代码语言:javascript复制
tasks:
 - debug: msg="{{ service }} is {{ status }}"
   vars: 
       service=httpd
       status=started

17. extrd vars

通过命令行传递进来的变量

代码语言:javascript复制
ansible-playbook test.yml --extra-vars "hosts=web user=root"

未完待续!

参考资料:

Ansible快速入门, 技术原理与实战。

希望此文对大家有所帮助,也希望大家持续关注转载。关注公众号获取相关资料请回复:typescript,springcloud,springboot,nodejs,nginx,mq,javaweb,java并发实战,java并发高级进阶,实战java并发,极客时间dubbo,kafka,java面试题,ES,zookeeper,java入门到精通,区块链,java优质视频,大数据,kotlin,瞬间之美,HTML与CSS,深入体验java开发,web开发CSS系列,javaweb开发详解,springmvc,java并发编程,spring源码,python,go,redis,docker,即获取相关资料。回复001,获取价值1w的课程视频,需要其他视频可以联系小编。

0 人点赞