Ansible 2.4:Playbook 中变量的多种使用方式

2.4:Playbook 中变量的多种使用方式

关于如何在Playbook中使用变量的官方文档:https://docs.ansible.com/ansible/latest/user_guide/playbooks_variables.html

在Playbook中调用变量的方式有:

  • 调用变量的值:{{ VARIABLE_NAME }}
  • 有时需要加双引号,避免被解析为内联字典:"{{ VARIABLE_NAME }}"
  • 当调用变量的字符串中有:时,避免被解析为key: value,也要为整个字符串加上引号:"STRING: {{ VARIABLE_NAME }}"
  • 当调用变量作为key: value中的value时,也需要加上引号:key: "{{ VARIABLE_NAME }}"
  • 调用变量名,则直接使用变量名,什么也不加:VARIABLE_NAME
    比如在Playbook中的某些模块中使用var参数来指定变量名:debug: var=VARIABLE_NAME

Playbook中调用的变量有以下来源:

  • setup模块获取的fact信息,其中就包含了大量的变量,可以直接调用。

  • 为Playbook传递的自定义变量,这其中包括了:

    1. 通过命令行 ansible-playbook -e VARIABLE_NAME=VALUE PLAYBOOK.yml 定义的变量;
    2. Playbook中通过var_files定义的变量文件中的变量;
    3. Playbook中通过vars定义的变量;
    4. Ansible项目中在host_vars/HOSTNAME文件中定义的主机变量(文件名是HOSTNAME,与主机清单中定义的主机名一致);
    5. 主机清单文件中定义的主机变量;
    6. Ansible项目中在group_vars/GROUPNAME文件中定义的主机组变量(文件名是GROUPNAME,与主机清单中定义的主机组名一致);
    7. Ansible项目中在group_vars/all文件中定义的公共变量(该文件中定义的变量对主机清单中的所有主机生效);
    8. 主机清单文件中定义的主机组变量。

    优先级从高到低。

  • 为Playbook的Role传递的自定义变量:

    1. roles/ROLE_NAME/vars/main.yml文件中定义的变量;
    2. roles/ROLE_NAME/defaults/main.yml文件中定义的变量。

    优先级从高到低。

2.4.1:使用 facts 信息中的变量

Playbook在执行时默认就会收集目标主机的facts信息并存为变量,可以指定变量来直接调用。当在Playbook中使用facts变量时,就不能将gather_facts设为no。

2.4.1.1:ansible_nodename

该变量保存的是目标主机的主机名。

示例:

- hosts: websrvs
  tasks:
    - name: ansible_nodename
      debug:
        msg: "目标主机名: {{ ansible_nodename }}"

执行结果:

在这里插入图片描述

2.4.1.2:ansible_IFNAME.ipv4.address

该变量保存的是目标主机特定网络接口的ipv4地址。

IFNAME为目标主机的网络接口名称,如eth0

也可以由ansible_facts.IFNAME.ipv4.address取得。

示例:

- hosts: websrvs
  tasks:
    - name: ansible_eth0.ipv4.address
      debug:
        msg: "eth0的ipv4地址: {{ ansible_eth0.ipv4.address }}"

执行结果:

在这里插入图片描述

2.4.1.3:ansible_facts.IFNAME.ipv4.address

该变量保存的同样是目标主机特定网络接口的ipv4地址。

示例:

- hosts: websrvs
  tasks:
    - name: ansible_facts.eth0.ipv4.address
      debug:
        msg: "eth0的ipv4地址: {{ ansible_facts.eth0.ipv4.address }}"

执行结果:

在这里插入图片描述

2.4.1.4:ansible_default_ipv4.address

该变量保存的是目标主机默认的ipv4地址。

示例:

- hosts: websrvs
  tasks:
    - name: ansible_default_ipv4.address
      debug:
        msg: "默认的ipv4地址: {{ ansible_default_ipv4.address }}"

执行结果:

在这里插入图片描述

2.4.1.5:使用 split 对变量值进行切分

通过指定分隔符和切分后的对象序号(序号从0开始),来取得变量值中需要的部分。

示例1:

- hosts: websrvs
  tasks:
    - name: split
      debug:
        msg: "eth0的ipv4地址中的最后一个数字: {{ ansible_facts.eth0.ipv4.address.split('.')[-1] }}"

执行结果1:

在这里插入图片描述

2.4.2:使用自定义变量

2.4.2.1:在 ansible-playbook 命令行中定义变量

使用ansible-playbook命令执行Playbook时,可以通过-e VARIABLE_NAME=VALUE来定义变量,或通过-e '@VARIABLE_FILE'来指定变量文件。

2.4.2.1.1:定义变量

Playbook 示例:

[root@ansible ~]# vim remove.yml
---
- hosts: websrvs
  tasks:
    - name: remove {{ rmfile_name }}
      file: path={{ rmfile_name }} state=absent
...

在命令行中定义变量并执行Playbook:

[root@ansible ~]# ansible-playbook -e rmfile_name=/etc/fstab -C remove.yml 

在这里插入图片描述

2.4.2.1.2:指定变量文件

可以将多个变量定义在一个变量文件中:

[root@ansible ~]# vim vars.yml
src_file: files/ports.conf
dest_file: /etc/apache2/ports.conf

Playbook 示例:

[root@ansible ~]# vim copy.yml 
---
- hosts: websrvs
  tasks:
    - name: copy {{ src_file }} to {{ dest_file }} on {{ ansible_nodename }}
      copy:
        src: "{{ src_file }}"
        dest: "{{ dest_file }}"
...

在命令行中指定变量文件并执行Playbook:

[root@ansible ~]# ansible-playbook -e '@vars.yml' -C copy.yml  

在这里插入图片描述

2.4.2.2:在 Playbook 中使用 vars_files 指定变量文件

上边定义的vars.yml变量文件可以在Playbook中使用vars_files这个Keyword来指定。

Playbook 示例:

[root@ansible ~]# vim copy.yml 
---
- hosts: websrvs
  vars_files:
    - vars.yml
  tasks:
    - name: copy {{ src_file }} to {{ dest_file }} on {{ ansible_nodename }}
      copy:
        src: "{{ src_file }}"
        dest: "{{ dest_file }}"
...

执行结果:

在这里插入图片描述

2.4.2.3:在 Playbook 中使用 vars 定义变量

上述变量文件中的变量可以在Playbook中使用vars来直接定义:

[root@ansible ~]# vim copy.yml                       
---
- hosts: websrvs
  vars:
    src_file: files/ports.conf
    dest_file: /etc/apache2/ports.conf
  tasks:
    - name: copy {{ src_file }} to {{ dest_file }} on {{ ansible_nodename }}
      copy:
        src: "{{ src_file }}"
        dest: "{{ dest_file }}"
...

执行结果:

在这里插入图片描述

2.4.2.4:在 Ansible 项目中通过 host_vars/HOSTNAME 文件定义主机变量

在 Ansible 项目中通过 host_vars/HOSTNAME 文件定义主机变量,可以实现为不同主机定义不同的变量,或为不同主机的同一变量传递不同的变量值。

创建一个简单的 Ansible 项目,分别为一台Ubuntu主机安装apahce2,为一台CentOS主机安装httpd,通过为不同主机的pkg_name变量传递不同值来实现。

在这里插入图片描述

2.4.2.4.1:编写 Playbook
[root@ansible ~]# mkdir ansible
[root@ansible ~]# vim ansible/install_web.yml 
---
- hosts: 192.168.1.111
  tasks:
    - name: "Ubuntu 安装 {{ pkg_name }}"
      apt:
        name: "{{ pkg_name }}"
        state: present
      when: ansible_os_family == "Debian"

- hosts: 192.168.1.203
  tasks:
    - name: "CentOS 安装 {{ pkg_name }}"
      yum:
        name: "{{ pkg_name }}"
        state: present
      when: ansible_os_family == "RedHat"
...
2.4.2.4.2:定义主机清单文件
[root@ansible ~]# vim ansible/hosts 
[websrvs]
192.168.1.111
192.168.1.203
2.4.2.4.3:准备主配置文件
[root@ansible ~]# cp /etc/ansible/ansible.cfg ansible/

[root@ansible ~]# vim ansible/ansible.cfg 
inventory      = ./hosts
2.4.2.4.4:定义主机变量文件
[root@ansible ~]# mkdir ansible/host_vars
[root@ansible ~]# vim ansible/host_vars/192.168.1.111
pkg_name: apache2
[root@ansible ~]# vim ansible/host_vars/192.168.1.203
pkg_name: httpd
2.4.2.4.5:查看 Ansible 项目结构
[root@ansible ~]# tree ansible/
ansible/
├── ansible.cfg
├── hosts
├── host_vars
│   ├── 192.168.1.111
│   └── 192.168.1.203
└── install_web.yml
2.4.2.4.6:为目标主机推送 ssh_key
[root@ansible ~]# vim key_push.sh 
#!/bin/bash
# Description: 向被管理主机批量推送管理端ssh公钥
# Variables set
export SSHPASS=123456
Hosts="
192.168.1.111
192.168.1.203"

for i in ${Hosts}; do
        sshpass -e ssh-copy-id  -o StrictHostKeyChecking=no ${i}
done

[root@ansible ~]# bash key_push.sh 
2.4.2.4.7:执行 Playbook

到Ansible项目目录中执行Playbook:

[root@ansible ~]# cd ansible
[root@ansible ansible]# ansible-playbook install_web.yml    

执行结果:

在这里插入图片描述

验证:

root@node111:~# dpkg-query -l apache2

在这里插入图片描述

[root@node203 ~]# rpm -q httpd
httpd-2.4.6-97.el7.centos.x86_64
2.4.2.5:在主机清单文件中定义主机变量

可以在主机清单文件的主机后面为单个主机定义变量:

[GROUP_NAME]
HOST1 VARIABLE1=VALUE1 VARIABLE2=VALUE2
HOST2 VARIABLE1=VALUE1 VARIABLE2=VALUE2
2.4.2.5.1:主机清单示例
[root@ansible ~]# vim ansible/hosts 
[websrvs]
192.168.1.111 pkg_name=apache2
192.168.1.203 pkg_name=httpd
2.4.2.5.2:Playbook 示例

Playbook和上一个示例相同:

[root@ansible ~]# vim ansible/install_web.yml 
---
- hosts: 192.168.1.111
  tasks:
    - name: "Ubuntu 安装 {{ pkg_name }}"
      apt:
        name: "{{ pkg_name }}"
        state: present
      when: ansible_os_family == "Debian"

- hosts: 192.168.1.203
  tasks:
    - name: "CentOS 安装 {{ pkg_name }}"
      yum:
        name: "{{ pkg_name }}"
        state: present
      when: ansible_os_family == "RedHat"
...
2.4.2.5.3:执行 Playbook

执行Playbook前,先进行一些恢复操作。

  1. 卸载两台目标主机上的apache2和httpd:
root@node111:~# apt remove apache2
[root@node203 ~]# yum remove httpd
  1. 删除host_vars主机变量目录(因为host_vars中定义的主机变量比主机清单中定义的主机变量优先级高,会优先调用):
[root@ansible ~]# rm -rf ansible/host_vars/

执行Playbook:

[root@ansible ~]# cd ansible
[root@ansible ansible]# ansible-playbook install_web.yml    

执行结果:

在这里插入图片描述

2.4.2.6:在 Ansible 项目中通过 group_vars/GROUPNAME 文件定义主机组变量

在 Ansible 项目中通过 group_vars/GROUPNAME 文件定义主机组变量,可以实现为不同主机组定义不同的变量,或为不同主机组的同一变量传递不同的变量值。

同样创建一个简单的 Ansible 项目,分别为ubuntu主机组安装apahce2,为centos主机组主机安装httpd,通过为不同主机组的pkg_name变量传递不同的变量值来实现。

在这里插入图片描述

2.4.2.6.1:编写 Playbook
[root@ansible ~]# vim ansible/install_web.yml 
---
- hosts: ubuntu
  tasks:
    - name: "Ubuntu 安装 {{ pkg_name }}"
      apt:
        name: "{{ pkg_name }}"
        state: present
      when: ansible_os_family == "Debian"

- hosts: centos
  tasks:
    - name: "CentOS 安装 {{ pkg_name }}"
      yum:
        name: "{{ pkg_name }}"
        state: present
      when: ansible_os_family == "RedHat"
...
2.4.2.6.2::定义主机清单文件
[root@ansible ~]# vim ansible/hosts 
[ubuntu]
192.168.1.111

[centos]
192.168.1.203
2.4.2.6.3:准备主配置文件
[root@ansible ~]# cp /etc/ansible/ansible.cfg ansible/

[root@ansible ~]# vim ansible/ansible.cfg 
inventory      = ./hosts
2.4.2.6.4:定义主机组变量文件
[root@ansible ~]# mkdir ansible/group_vars
[root@ansible ~]# vim ansible/group_vars/ubuntu
pkg_name: apache2
[root@ansible ~]# vim ansible/group_vars/centos
pkg_name: httpd
2.4.2.6.5:查看 Ansible 项目结构
[root@ansible ~]# tree ansible/
ansible/
├── ansible.cfg
├── group_vars
│   ├── centos
│   └── ubuntu
├── hosts
└── install_web.yml
2.4.2.6.6:为目标主机推送 ssh_key
[root@ansible ~]# vim key_push.sh 
#!/bin/bash
# Description: 向被管理主机批量推送管理端ssh公钥
# Variables set
export SSHPASS=123456
Hosts="
192.168.1.111
192.168.1.203"

for i in ${Hosts}; do
        sshpass -e ssh-copy-id  -o StrictHostKeyChecking=no ${i}
done

[root@ansible ~]# bash key_push.sh 
2.4.2.6.7:执行 Playbook

执行前先卸载两个主机上之前安装了的apace2和httpd:

root@node111:~# apt remove apache2 -y
[root@node203 ~]# yum remove httpd -y

到Ansible项目目录中执行Playbook:

[root@ansible ~]# cd ansible
[root@ansible ansible]# ansible-playbook install_web.yml    

执行结果:

在这里插入图片描述

验证:

root@node111:~# dpkg-query -l apache2

在这里插入图片描述

[root@node203 ~]# rpm -q httpd
httpd-2.4.6-97.el7.centos.x86_64
2.4.2.7:在 Ansible 项目中通过 group_vars/all 文件定义公共变量

在一个Ansible项目中,还可以在group_vars/all文件中为主机清单的所有主机定义公共变量,改文件中的变量对整个主机清单生效。

在上述Ansible项目中再编写一个Playbook,用于删除各主机上的apache2或httpd(使用公共变量pkg_state,为所有主机传递absent变量值)。

在这里插入图片描述

2.4.2.7.1:编写 Playbook
[root@ansible ~]# vim ansible/remove_web.yml
---
- hosts: ubuntu
  tasks:
    - name: "Ubuntu 卸载 {{ pkg_name }}"
      apt:
        name: "{{ pkg_name }}"
        state: "{{ pkg_state }}"
      when: ansible_os_family == "Debian"

- hosts: centos
  tasks:
    - name: "CentOS 卸载 {{ pkg_name }}"
      yum:
        name: "{{ pkg_name }}"
        state: "{{ pkg_state }}"
      when: ansible_os_family == "RedHat"
...
2.4.2.7.2:定义公共变量文件
[root@ansible ~]# vim ansible/group_vars/all
pkg_state: absent
2.4.2.7.3:查看 Ansible 项目结构
[root@ansible ~]# tree ansible/
ansible/
├── ansible.cfg
├── group_vars
│   ├── all
│   ├── centos
│   └── ubuntu
├── hosts
├── install_web.yml
└── remove_web.yml
2.4.2.7.4:执行 Playbook
[root@ansible ~]# cd ansible
[root@ansible ansible]# ansible-playbook remove_web.yml 

执行结果:

在这里插入图片描述

验证:

root@node111:~# dpkg-query -l apache2

在这里插入图片描述

[root@node203 ~]# rpm -q httpd       
package httpd is not installed
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值