自动化运维Ansible之变量使用

1、Playbook 变量

ansible中使用变量,能够让我们的工作变得更加灵活

定义变量

变量名应该由字母、数字、下划线组成,变量名需要字母开头,ansible内置的关键字不能作为变量名使用

2、Playbook 变量定义

使用vars关键字可以在当前playbook中进行变量定义,让我们要使用变量的时候,则需要引用对应变量名,使用{{ 变量名 }}可以引用对应变量。

变量简单定义

- hosts: all
  vars:     #定义变量
    file_name: jsn_yaml_vars    #变量名(随意):file_name,变量的内容:jsn_yaml_vars
  tasks:    #{{ file_name }}引用上面定义的变量
  - name: 应用变量名:file_name
    file: path=/tmp/{{ file_name }} state=touch

定义多个变量

- hosts: all
  vars:   
    t1: v1
    t2: v2

除了上述语法,也可用YAML快序列语法定义变量

- hosts: all
  vars:   
    - t1: v1
    - t2: v2

定义变量时,还可以类似以"属性"的方式定义变量

- hosts: 10.4.7.7
  vars:
    nginx:
      proxy_1: /etc/nginx/conf.d/nginx_1.proxy
      proxy_2: /etc/nginx/conf.d/nginx_2.proxy
  tasks:
  - name: task1
    file:
      path: "{{ nginx.proxy_1 }}"
      state: touch
  - name: task1
    file:
      path: "{{ nginx['proxy_2'] }}" # 第二种引用变量.属性的方法
      state: touch

Node:注意我们在使用变量使用了双引号,而在最开头的例子中并没有在引用变量的时候使用双引号,那是因为第一个实例中变量在被引用的时候,并没有处于开头的位置path=/tmp/{{ file_name }},所以在不需要双引号,但是path: "{{ nginx.proxy_1 }}"处于开头位置的变量,就需要双引号

定义变量写入到指定文件中,然后在playbook中引用

1.创建nginx_vars.yaml文件,定义变量

nginx:
  proxy_1: /etc/nginx/conf.d/nginx_1.proxy
  proxy_2: /etc/nginx/conf.d/nginx_2.proxy

2.在nginx_vars.yaml文件中定义完变量后,即可在playbook中引入包含变量的文件

- hosts: 10.4.7.7
  vars_files:
    - ~/nginx_vars.yaml
  tasks:
  - name: task1
    file:
      path: "{{ nginx.proxy_1 }}"
      state: touch
  - name: task1
    file:
      path: "{{ nginx['proxy_2'] }}" 
      state: touch

该例中使用vars_files关键字引入对应的变量文件,然后使用文件中的变量,该关键字可以引入一个变量文件,也可以引入多个变量文件,每个被引入的文件都需要以-开头,varsvars_files可以同时使用

playbook引用变量,执行的时候指定赋值变量

1.创建yaml

- hosts: all
  tasks:
  - name: Create New File
    file: path=/tmp/{{ file_name }} state=touch

2.playbook执行的时候参数--extra-vars指定赋值给变量

$ ansible-playbook f1.yaml --extra-vars "file_name=jsn_extra-vars"

3、Playbook 变量注册

register关键字可以存储指定命令的输出结果到一个自定义的变量中,它还有一个非常棒的用法,就是我们需要判断对执行了某个操作或某个命令后,如何做出相应的响应处理(执行其它的ansible语句),也会用到它。

register简单实用

1.f1.yaml文件内容如下

- hosts: 10.4.7.7
  tasks:
    - name: register vars
      shell: hostname
      register: System_Status
    - name: display vars
      debug: msg={{ System_Status.stdout }}

2.执行playbook

[root@m01 ~]#  ansible-playbook f1.yaml

PLAY [10.4.7.7] ****************************************************************

TASK [Gathering Facts] *********************************************************
ok: [10.4.7.7]

TASK [register vars] ***********************************************************
changed: [10.4.7.7]

TASK [display vars] ************************************************************
ok: [10.4.7.7] => {
    "msg": "web01"
}

PLAY RECAP *********************************************************************
10.4.7.7                   : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
  • 第一个shell执行完后,使用register获取数据到System_Status
  • System_Status是一个key/value字典
  • debug输出System_Status.stdout的具体内容

register生产示例

我需要判断sda1是否存在,如果存在则执行文件拷贝

- hosts: 10.4.7.7
  tasks:
    - name:  Create a register to represent the status if the /dev/sda1 exsited
      shell: df -h  | grep sda1
      register: dev_sda1_result
      ignore_errors: True
      
    - name: Copy test.sh to all hosts
      copy: src=/root/test.sh dest=/tmp/test.sh mode=755
      when: dev_sda1_result.rc == 0 

df -h | grep sda1执行后,会在dev_sda1_result里写入执行结果,然后dev_sda1_result.rc 里的rc就是命令的返回状态,非0表示执行失败,ignore_errors关键字一定要设置为True,否则如果命令执行不成功,即echo $?不为0,则在语句后面的ansible语句不会被执行,导致程序中止。

register多条件判断

然后在when中用and或者or来组合判断。比如当两种条件之一成功:

    - name: Copy test.sh to all hosts
      copy: src=/root/test.sh dest=/tmp/test.sh mode=755
      when: ( dev_sda1_result.rc == 0 ) or ( dev_sda2_result.rc == 0  )
posted @ 2020-04-06 00:30  jasonminghao  阅读(1344)  评论(0编辑  收藏  举报