ansible——ansible的变量

一、ansible变量的作用

所谓的变量就是一个会变的值。

如果你有一个值,被后面的task,频繁的调用,那么你就可以将这个值定义成一个变量,然后将后面task只用的这个值换成变量。比如有10处调用了。在playbook开头定义这个变量。当开头的变量值改变之后,10处被使用这个值的地方,就都做了改变。

Ansible支持变量功能,能将value存储到变量中,这样就能在Ansible项目中重复使用了。这样就可以简化项目的创建和维护,减少错误率 。

变量提供了一个变量提供了一种方便的方法来管理ansible项目中给定环境的动态值。 变量可以是要创建的用户,要安装的包,要启动的服务,要删除的文件,要从互联网下载的文件等等。

变量由必须以字母开头的字符串组成,并且只能包含字母,数字和下划线组成。

二、定义变量

变量几乎可以定义在ansible项目中的任意位置。然而这有三种基本的范围级别:

  • Globe scope:从命令行设置变量或Ansible配置文件中设置变量

  • play scope:在play和相关结构中设置变量

  • host scope:通过inventory在主机组或单个主机中设置变量,fact采集变量或者register

如果在一个级别上定义了名字相同的两个变量,会选择先定义的那个。 在inventory中定义的变量会被playbook中定义的覆盖,playbook中定义的变量会被命令行定义的变量覆盖。

bash 复制代码
cmd > playbook > inventory

1、在playbook中定义变量

bash 复制代码
[root@control ansible_manage]# cat play_book/debug2.yaml 
---
- name: this is a var test
  hosts: all
  vars:
    user: nana
  tasks:
    - name: debug moudle text
      debug:
        msg: "{{ user }} is very handsome man ,but {{user}} is  very pool"

vars这里可以定义变量的值,在这里定义的变量是"user=nana"

引用变量必须以"{``{ vars }}"的格式来写

bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml 
...
ok: [manage1] => {
    "msg": "nana is very handsome man ,but nana is  very pool"
}
ok: [manage3] => {
    "msg": "nana is very handsome man ,but nana is  very pool"
}
ok: [manage2] => {
    "msg": "nana is very handsome man ,but nana is  very pool"
}
...

可以看到输出的结果是变量引用的值

2、在cmd中定义变量

bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml -e user=cui
...
ok: [manage1] => {
    "msg": "cui is very handsome man ,but cui is  very pool"
}
ok: [manage3] => {
    "msg": "cui is very handsome man ,but cui is  very pool"
}
ok: [manage2] => {
    "msg": "cui is very handsome man ,but cui is  very pool"
}
...

在yaml文件中的变量是uesr=nana,但是在cmd命令行中的定义了user=cui,这个时候变量就使用的是cmd中定义的变量,cmd中定义的变量优先级最高

3、在inventory中定义变量

单个设置
bash 复制代码
[root@control ansible_manage]# cat inventory 
manage1 user=jojo
manage2 user=dio
manage3 user=haha
bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml
...
ok: [manage1] => {
    "msg": "nana is very handsome man ,but nana is  very pool"
}
ok: [manage3] => {
    "msg": "nana is very handsome man ,but nana is  very pool"
}
ok: [manage2] => {
    "msg": "nana is very handsome man ,but nana is  very pool"
...

由于在playbook中变量的优先级比较高,先将play中的变量删除

bash 复制代码
[root@control ansible_manage]# cat play_book/debug2.yaml 
---
- name: this is a var test
  hosts: all
  vars: 
  tasks:
    - name: debug moudle text
      debug:
        msg: "{{ user }} is very handsome man ,but {{user}} is  very pool"

再次执行

bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml
    "msg": "jojo is very handsome man ,but jojo is  very pool"
}
ok: [manage2] => {
    "msg": "dio is very handsome man ,but dio is  very pool"
}
ok: [manage3] => {
    "msg": "haha is very handsome man ,but haha is  very pool"
}
使用组来设置

查看inventory文件

bash 复制代码
[root@control ansible_manage]# cat inventory 
manage1 
manage2
manage3 user=nana

[computer]
manage1
manage2
manage3

[computer:vars]         ## vars 表示定义这个组的变量,下面跟变量
user=mooooom

在这里定义了组的变量,computer组的变量user=mooooom,还定义了manage3用户的变量uers=nana

playbook文件

bash 复制代码
[root@control ansible_manage]# cat play_book/debug2.yaml
---
- name: this is a var test
  hosts: computer
  vars:
  tasks:
    - name: debug moudle text
      debug:
        msg: "{{ user }} is very handsome man ,but {{ user }} is  very pool"

执行文件

bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml 
...
    "msg": "mooooom is very handsome man ,but mooooom is  very pool"
}
ok: [manage2] => {
    "msg": "mooooom is very handsome man ,but mooooom is  very pool"
}
ok: [manage3] => {
    "msg": "nana is very handsome man ,but nana is  very pool"
}
...

当inventory文件中有重复的变量出现的时候,有限范围小的变量

4、变量文件

将变量放在playbook和inventory中是非常不可取的一种方案,容易有很多的问题,管理也不方便,但是将变量单独放在一个文件中的话,就不会有这样的问题

inventory文件

bash 复制代码
[root@control ansible_manage]# cat inventory 
manage1 
manage2
manage3 user=nana

[computer]
manage1
manage2
manage3

playbook文件

bash 复制代码
[root@control ansible_manage]# cat play_book/debug2.yaml
---
- name: this is a var test
  hosts: all
  vars_files:
    - ./debug2_vars.yaml
  tasks:
    - name: debug moudle text
      debug:
        msg: "{{ user1 }} is very {{ state1 }} man ,but {{ user2 }} is  very {{ state2 }}"

变量文件

bash 复制代码
[root@control ansible_manage]# cat play_book/debug2_vars.yaml 
user1: nana
user2: cui
state1: handsome
state2: poor

执行结果

bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug2.yaml 
...
*******************************************************************************************ok: [manage1] => {
    "msg": "nana is very handsome man ,but cui is  very poor"
}
ok: [manage2] => {
    "msg": "nana is very handsome man ,but cui is  very poor"
}
ok: [manage3] => {
    "msg": "nana is very handsome man ,but cui is  very poor"
}

三、主机变量与主机组变量

playbook文件中放的就是task

inventory 文件中放的就是host and group

variables文件中放的就是var files

每个文件都放自己应该放的内容,如果将变量放进其他两个文件中,就会变得非常不好管理。

如何定义主机变量和主机组变量,在ansible中定义了两个文件,用来存放主机变量和组变量, group_varshost_vars两个文件

  • host_vars文件下面创建对应主机的文本,创建的文本名称名称 是与inventory文件中host对应的文本

  • gruop _vars文件下面创建对应主机组的文本,创建的文本名称 必须是inventory文件中gruop对应的文本

1、inventory文件与host_varsgruop _vars之间的关系

  • inventoryhost_varsgruop _vars在同一目录下,或与对应playbook同于目录下

  • host_vars文件的命名必须是"host_vars",否则识别不到

  • gruop _vars文件的命名必须是"gruop _vars",否则识别不到

  • host_vars下的文件名必须与inventory文件中的主机名对应

  • gruop _vars下的文件必须与inventory文件中的主机组对应

bash 复制代码
[root@control ansible_manage]# cat inventory
manage1 
manage2
manage3 user=nana

[computer]
manage1
manage2
manage3
bash 复制代码
[root@control ansible_manage]# tree
.
├── ansible.cfg
├── group_vars
│   └── computer
├── host_vars
│   ├── manage1
│   ├── manage2
│   └── manage3
├── inventory
└── play_book
    └── debug3.yaml

比如在这个group_vars文件中的文件名就与inventory中的computer组的名字相同

2、实例

inventory文件

bash 复制代码
[root@control ansible_manage]# cat inventory
manage1 
manage2
manage3 user=nana

[computer]
manage1
manage2
manage3

host_vars文件

bash 复制代码
[root@control ansible_manage]# cat host_vars/manage{1..3}
hello: wordssssssssssssssssssssssss    # manage1
hello: china                           # manage2
hello: ansible                         # manage3

group_vars文件

bash 复制代码
[root@control ansible_manage]# cat group_vars/computer 
user1: cui
state1: handsome

yaml文件

bash 复制代码
[root@control ansible_manage]# cat play_book/debug3.yaml 
---
- name: this is a var test
  hosts: all
  tasks:
    - name: debug moudle text
      debug:
        var: user1    ## var后面可以直接跟变量,不需要"{{}}"
    - debug:
        var: state1
    - debug:
        var: hello
    - debug:
        var: nihao

执行文件

bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug3.yaml 
...
TASK [debug moudle text] *******************************************************************************************ok: [manage1] => {
    "user1": "cui"
}
ok: [manage2] => {
    "user1": "cui"
}
ok: [manage3] => {
    "user1": "cui"
}

TASK [debug] *******************************************************************************************************ok: [manage1] => {
    "state1": "handsome"
}
ok: [manage2] => {
    "state1": "handsome"
}
ok: [manage3] => {
    "state1": "handsome"
}

TASK [debug] *******************************************************************************************************ok: [manage1] => {
    "hello": "wordssssssssssssssssssssssss"
}
ok: [manage2] => {
    "hello": "china"
}
ok: [manage3] => {
    "hello": "ansible"
}

TASK [debug] *******************************************************************************************************ok: [manage1] => {
    "nihao": "VARIABLE IS NOT DEFINED!"
}
ok: [manage2] => {
    "nihao": "VARIABLE IS NOT DEFINED!"
}
ok: [manage3] => {
    "nihao": "VARIABLE IS NOT DEFINED!"
}
...

四、变量矩阵

如果需要设置许多十分近似的变量,就可以使用变量矩阵的方式来写

例如:

bash 复制代码
user_nana_name=jinzhuren
user_nana_money=10000w
user_nana_home=sxpi
user_cui_name=cheng
user_cui_money=1k
user_cui_home=scdd

就可以写成这种模式

bash 复制代码
user:
  nana:
    name: jinzhuren
    money: 10000w
    home: sxpi
  cui:
    name: cheng
    money: 1k
    home: scdd

在playbook中定义变量

bash 复制代码
---
- name: this is a var test
  hosts: manage1
  vars_files:
    ./debug4_var.yaml
  tasks:
    - name: debug moudle text
      debug:
        var: user['nana']['name']   ##  建议使用这种方式写变量,虽然这种写法真麻烦
    - debug:
        var: user['nana']['money']
    - debug:
        var: user['nana']['home']
    - debug:
        var: user.cui.name         ## 也可以使用这种方式写变量,但是容易与python冲突。
    - debug:
        var: user.cui.home
    - debug:
        var: user.cui.money

执行

bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug4.yaml
...
TASK [debug moudle text] *******************************************************************************************ok: [manage1] => {
    "user['nana']['name']": "jinzhuren"
}

TASK [debug] *******************************************************************************************************ok: [manage1] => {
    "user['nana']['money']": "10000w"
}

TASK [debug] *******************************************************************************************************ok: [manage1] => {
    "user['nana']['home']": "sxpi"
}

TASK [debug] *******************************************************************************************************ok: [manage1] => {
    "user.cui.name": "cheng"
}

TASK [debug] *******************************************************************************************************ok: [manage1] => {
    "user.cui.home": "scdd"
}

TASK [debug] *******************************************************************************************************ok: [manage1] => {
    "user.cui.money": "1k"
}
...

五、register变量

可以将tasks运行状态记录下来

写一个install.yaml

bash 复制代码
[root@control ansible_manage]# cat play_book/install.yaml
---
- name: install a pkg
  hosts: manage1
  tasks:
    - name: install httpd
      yum:
        name: httpd
        state: present
      register: ergou      ## 使用ergou这个变量,记录运行状态

    - name: degue ergou
      debug:
        var: ergou         ## 条用这个二狗
bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/install.yaml
...
TASK [degue ergou] *****************************************************************************************************************************ok: [manage1] => {
    "ergou": {
        "changed": true,
        "failed": false,
        "msg": "",
        "rc": 0,
        "results": [
            "Installed: mod_http2-1.15.19-5.el9.x86_64",
            "Installed: httpd-2.4.57-5.el9.x86_64"
        ]
    }
}

PLAY RECAP *************************************************************************************************************************************manage1                    : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

运行之后可以看到使用register变量,搭配debug显示出了运行状态

rc的值为0,表示运行正常,若不为0,则表示出现了问题。常常使用rc的返回值来做条件判断

六、facts变量

能够轻松的获取到被控制节点主机的信息

获取其他host节点的信息

bash 复制代码
[root@control ansible_manage]# ansible manage1 -m setup

生成的是一个json文件,它里面包含了被管理主机的绝大多数信息,可以很轻易的知到被管理主机的资源信息等。它使用的是ansiblesetup模块

在每次运行playbook的时候,ansible会默认的自动运行这个模块

1、使用debug模块获取主机的内存

使用ansible manage1 -m setup获取到合适的变量,进行筛选,编写playbook

bash 复制代码
[root@control ansible_manage]# cat play_book/debug5.yaml 
---
- name: this is a var test
  hosts: all
  tasks:
    - name: debug moudle text
      debug:
        msg: "{{ ansible_hostname }}'s current free mem is {{ ansible_memfree_mb }}"
bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug5.yaml 

PLAY [this is a var test] ***************************************************************************************

## [Gathering Facts] 这个就是自动执行了setup模块获取信息
TASK [Gathering Facts] ******************************************************************************************
ok: [manage1]
ok: [manage3]
ok: [manage2]

TASK [debug moudle text] ****************************************************************************************
ok: [manage1] => {
    "msg": "manage1's current free mem is 69"
}
ok: [manage2] => {
    "msg": "manage2's current free mem is 67"
}
ok: [manage3] => {
    "msg": "manage3's current free mem is 872"
}
...

运行结束后,可以看到返回的信息,获取到了三台主机的内存信息

2、关闭facts变量的采集

如果集群过于大的情况下,采集信息是非常消耗时间的一件事情。

在playbook中使用gather_facts: no就可以变比变量的采集

bash 复制代码
[root@control ansible_manage]# cat play_book/debug6.yaml
---
- name: this is a var test
  hosts: all
  gather_facts: no
  tasks:
    - name: debug moudle text
      debug:
        var:
             - ansible_hostname
             - ansible_memfree_mb
bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug6.yaml

PLAY [this is a var test] ***************************************************************************************

TASK [debug moudle text] ****************************************************************************************
ok: [manage1] => {
    "<class 'list'>": "VARIABLE IS NOT DEFINED!"
}
ok: [manage2] => {
    "<class 'list'>": "VARIABLE IS NOT DEFINED!"
}
ok: [manage3] => {
    "<class 'list'>": "VARIABLE IS NOT DEFINED!"
}
...

可以看到已经没有使用setbug模块

3、自定义faces的变量

在faces中有一个"ansible_local": {},的变量,这个变量是提供给用户自定义变量使用的

bash 复制代码
 [root@control ansible_manage]# ansible manage1 -m setup
...
        "ansible_local": {},
...

自定义变量默认的目录是/etc/ansible/facts.d/目录,创建的文件必须是以.fact结尾,这个目录如果没有,就需要自己创建(必须要在被管理主机上创建,必须有root的权限)

定义一个文件

bash 复制代码
[root@manage1 ~]# mkdir -p /etc/ansible/facts.d/
[root@manage1 ~]# vim /etc/ansible/facts.d/test.fact
[root@manage1 ~]# cat /etc/ansible/facts.d/test.fact 
[nana]
name=nananananananananana
bash 复制代码
[root@control ansible_manage]# ansible manage1 -m setup | grep -A 5 ansible_local
        "ansible_local": {
            "test": {
                "nana": {
                    "name": "nananananananananana"
                }
            }

可以看到ansible_local已经出现了值

playbook使用debug调用一下

bash 复制代码
[root@control ansible_manage]# cat play_book/debug7.yaml 
---
- name: this is a var test
  hosts: manage1
  tasks:
    - name: debug moudle text
      debug:
        var: ansible_local['test']['nana']['name']
bash 复制代码
[root@control ansible_manage]# ansible-playbook play_book/debug7.yaml

PLAY [this is a var test] ***************************************************************************************

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

TASK [debug moudle text] ****************************************************************************************
ok: [manage1] => {
    "ansible_local['test']['nana']['name']": "nananananananananana"
}

PLAY RECAP ******************************************************************************************************
manage1                    : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=
0

七、magic变量

就是主机变量和主机组变量

bash 复制代码
[root@control ansible_manage]# ansible manage1 -m debug -a "var=hostvars['manage1']"
manage1 | SUCCESS => {
    "hostvars['manage1']": {
        "ansible_check_mode": false,
        "ansible_config_file": "/root/ansible_manage/ansible.cfg",
        "ansible_diff_mode": false,
        "ansible_facts": {},
        "ansible_forks": 5,
        "ansible_inventory_sources": [
            "/root/ansible_manage/inventory"
        ],
        "ansible_playbook_python": "/usr/bin/python3",
        "ansible_verbosity": 0,
        "ansible_version": {
            "full": "2.14.9",
            "major": 2,
            "minor": 14,
            "revision": 9,
            "string": "2.14.9"
        },
        "group_names": [
            "computer"
        ],
        "groups": {
            "all": [
                "manage1",
                "manage2",
                "manage3"
            ],
            "computer": [
                "manage1",
                "manage2",
                "manage3"
            ],
            "ungrouped": []
        },
        "hello": "wordssssssssssssssssssssssss",
        "inventory_dir": "/root/ansible_manage",
        "inventory_file": "/root/ansible_manage/inventory",
        "inventory_hostname": "manage1",
        "inventory_hostname_short": "manage1",
        "omit": "__omit_place_holder__1d6935aaefc1e64ad57756c57c90f8ad4cc240af",
        "playbook_dir": "/root/ansible_manage",
        "state1": "handsome",
        "user1": "cui"
    }
}

最有用的是inventory_hostnamegroups,它可以将用于条件判断

相关推荐
学Linux的语莫1 小时前
Ansible Playbook剧本用法
linux·服务器·云计算·ansible
Nightwish52 小时前
ansible操作随记(一)
ansible
qq_383139846 小时前
ansible playbook安装nacos
ansible
Aimyon_364 天前
⾃动化运维利器 Ansible-Jinja2
运维·ansible
柒月VII5 天前
【Ansible常用命令+模块+Playbook+Roles】
linux·服务器·ansible
Linux运维技术栈5 天前
生产环境centos8 & Red Hat8部署ansible and 一键部署mysql两主两从ansible脚本预告
运维·数据库·mysql·自动化·ansible
Aimyon_365 天前
⾃动化运维利器 Ansible-最佳实战
linux·运维·ansible
饭桶也得吃饭5 天前
运维工具Ansible部署、配置
运维·服务器·ansible
陪小七许个愿5 天前
Ansible一键部署Kubernetes集群
容器·kubernetes·ansible
Aimyon_366 天前
⾃动化运维利器 Ansible-变量
运维·ansible