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,它可以将用于条件判断

相关推荐
风清再凯3 天前
自动化工具ansible,以及playbook剧本
运维·自动化·ansible
IT乌鸦坐飞机3 天前
ansible部署数据库服务随机启动并创建用户和设置用户有完全权限
数据库·ansible·centos7
遇见火星16 天前
如何使用Ansible一键部署MinIO集群?
ansible
粥周粥16 天前
ANSIBLE
ansible
码农101号16 天前
Linux中ansible模块补充和playbook讲解
linux·运维·ansible
码农101号16 天前
Linux的Ansible软件基础使用讲解和ssh远程连接
ansible
烟雨书信17 天前
ANSIBLE运维自动化管理端部署
运维·自动化·ansible
碎碎-li17 天前
ANSIBLE(运维自动化)
运维·自动化·ansible
@donshu@20 天前
Linux运维-ansible-python开发-获取inventroy信息
linux·运维·ansible
Kendra91923 天前
Ansible
ansible