ansible变量详解

ansible变量详解

1、为什么需要变量呢?

  1. 避免重复写一样的内容

    • 三台服务器上面的端口,都需要修改,就需要修改三次,如果用一个变量port来表示,只需要将port=80改成这样,其他服务器只需要引用这个变量就能实现修改
  2. 不同服务器使用不同的配置

    • 不同服务器之间的端口不一样,使用不同的变量文件直接跑
  3. 让剧本从固定脚本 变成了智能的工具

2、主机清单中定义变量

直接在主机清单中定义变量,优先级比ansible.cfg高

ansible_user=root ansible_port=2222

[root@master ansible]# cat hosts 
master
node1 port=111  # 只有node1可以使用这个变量
node2
[nodes]
node1 
node2
[nodes:vars]  # 定义主机组变量,属于这个主机组的主机可以直接使用变量
os_name=openeuler 

1、主机目录定义变量

创建一个host_vars目录,在这个下面创建以主机名命名的文件,这样主机就能引用

文件的内容是以key: value形式的

[root@master host_vars]# pwd
/etc/ansible/host_vars
[root@master host_vars]# cat node1 
name: 123

2、主机组目录定义变量

创建一个group_vars目录,下面创建主机组命名的文件

[root@master group_vars]# pwd
/etc/ansible/group_vars
[root@master group_vars]# cat nodes 
name: 999

3、剧本中定义变量

1、vars定义变量

位置在tasks上面定义变量

[root@master test]# cat vars.yml 
- hosts: node1
  vars:  # 定义单个变量,只在这个yml文件生效
    name: qq
    age: 11
  tasks:
    - debug:
        msg: "{{name}}"
    - debug:
        msg: "{{age}}"
    - debug:
        msg: "this {{name}} age: {{age}}"

2、vars_files定义变量

引用外部的变量文件

里面的内容是键值对的方式

不能是列表的-这样的

[root@master test]# cat vars_files 
user:
  user1:
    name1: qq
    age: 10
  user2:
    name2: www
    age: 20

[root@master test]# cat vars.yml 
- hosts: node1
  vars_files:
  - vars_files
  vars:
    name: qq
    age: 11
  tasks:
    - debug:
        msg: "{{user.user1.name1}}" # 以.来进行引用
    - debug:
        msg: "{{user.user2.name2}}"

3、注册变量(常用的)

将任务的执行的结果注册成一个变量

可以使用这个变量 变量.rc 的返回值为0,判断为0,就执行下面的操作,否则,不执行

register定义

[root@master test]# cat register.yml 
- hosts: node1
  tasks:
  - shell: ls /etc/passwd
    register: get_status  # 将上面的执行结果注册成这个变量,都保存在里面了
  - debug:
      msg: "{{get_status}}"  


TASK [debug] **********************************************************************************
ok: [node1] => {
    "msg": {
        "changed": true,
        "cmd": "ls /etc/passwd",
        "delta": "0:00:00.009663",
        "end": "2026-04-11 13:30:08.004732",
        "failed": false,
        "msg": "",
        "rc": 0,   # 命令的返回值,用这个来进行判断,常用的
        "start": "2026-04-11 13:30:07.995069",
        "stderr": "",
        "stderr_lines": [],
        "stdout": "/etc/passwd",  # 正确输出
        "stdout_lines": [
            "/etc/passwd"
        ]
    }
}


案例,将主机密钥文件保存到被控节点上面

# 将这个注册成一个变量即可
cat /etc/ssh/ssh_host_ecdsa_key.pub 

# 然后获取这个输出的信息,使用copy模块中content,复制到其他主机上即可

4、命令行方式定义变量

直接在ad-hoc中使用-e选项,在执行剧本的时候传入变量

临时传入变量

[root@master test]# cat vars.yml 
- hosts: node1
  tasks:
    - debug:
        msg: "{{age}}" # 没有定义这个变量

# 执行的时候,传入变量即可
[root@master test]# ansible-playbook vars.yml  -e age=123

4、事实变量(fact)

也是一个非常重要的变量,收集被控节点的信息

setup模块专门收集的变量,可以使用这个事实变量

非常多的变量

# 收集node1节点的信息保存到一个文件中
[root@master test]# ansible node1 -m setup > node1.fact 

# 这些都是node1上面的事实变量,可以直接拿来进行使用
[root@master test]# head -n 10 node1.fact 
node1 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "172.26.18.51"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::216:3eff:fe30:b739"
        ],
        "ansible_apparmor": {
            "status": "disabled"


1、setup模块中的filter参数

筛选出自己想要的事实变量

# 筛选出node1的ip地址即可
[root@master test]# ansible node1 -m setup -a "filter=ansible_all_ipv4_addresses"
node1 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "172.26.18.51"
        ],
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false
}


# 也可以使用通配符*
[root@master test]# ansible node1 -m setup -a "filter=ansible*addresses"
node1 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "172.26.18.51"
        ],
        "ansible_all_ipv6_addresses": [
            "fe80::216:3eff:fe30:b739"
        ],
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false
}

2、怎么使用事实变量

直接使用即可

  • {} 形式里面就是key:value形式的,因此的话,直接.就行了

  • [] 里面有多个值,因此的话,可以直接获取,获取一整块,但是想要获取单独一个块,可以使用索引来进行获取,第一个值对应的索引就是0 ansible_all_ipv6_addresses.0 这样的形式获取即可

- hosts: node1
  gather_facts: yes  # 开启收集事实变量这个功能,默认是开启的
  tasks:
    - debug:
        msg: "{{ansible_os_family}}"

3、禁用事实变量

将gather_facts: no 即可

5、set_fact模块生成变量

可以直接自定义一个变量

也可以将多个facts变量整合一下即可

[root@master test]# cat set_fact.yml 
- hosts: node1
  tasks:
    - set_fact:  # 整合多个事实变量
        get_version: "{{ansible_distribution}}--{{ansible_distribution_version}}"
    - set_fact:  # 自定义一个变量即可
        version: "x86"
    - debug:
        var: get_version
    - debug:
        var: version

6、lookup变量(非常常用)

这个也是生成变量的

获取的是主控节点的信息,保存到一个变量中

可以从文件,命令,变量中作为变量的值

1、从文件中获取变量

就是直接将一个文件的内容保存到一个变量中

[root@master test]# cat file.yml 
- hosts: node1
  tasks:
    - set_fact:  # 将文件内容复制到这个变量中
       content: "{{lookup('file','/etc/passwd')}}"
    - debug:  # 直接输出这个变量
         var: content

2、从命令中获取

[root@master test]# cat file.yml 
- hosts: node1
  tasks:
    - set_fact:
       content: "{{lookup('file','/etc/passwd')}}"
    - set_fact:  # 将命令的结果保存到这个变量
       get_c: "{{lookup('pipe','date +%T')}}"
    - debug:  # 输出变量的值
        msg: "{{get_c}}"

3、使用env获取

使用的是环境变量保存到这个变量里面即可

[root@master test]# cat file.yml 
- hosts: node1
  tasks:
    - set_fact:
       content: "{{lookup('file','/etc/passwd')}}"
    - set_fact:
       get_c: "{{lookup('pipe','date +%T')}}"
    - set_fact:  # 将$HOME的值保存到这个变量里面
        home: "{{lookup('env','HOME')}}"
    - debug:
        msg: "{{home}}" 

7、魔法变量(常用的)

1、hostvars

获取指定主机的变量的信息,还是输出的事实变量

不能再ad-hoc中使用,因为是临时命令,默认不收集被空节点信息

[root@master test]# cat magic.yml 
- hosts: node1
  tasks:
    - debug:
        msg: "{{hostvars['node1'].ansible_hostname}}"

2、inventory_hostname

列出当前运行的主机是谁,判断中常常使用,经常和when使用

- hosts: node1
  tasks:
    - debug:
        var: ansible_hostname
      when: inventory_hostanme == "node1"

3、groups(非常有用)

groups.all 列出所有的主机

groups.主机组 列出这个主机组中的所有主机

group_names 列出当前运行的主机属于哪个主机组(这个非常的灵活,常用的)

[root@master test]# cat group.yml 
- hosts: all
  tasks:
  - debug:
      msg: "echo node1"
    when: "'nodes' in group_names"   # 当前运行的主机属于的主机组是nodes,也就说挡墙运行的主机属于nodes这个组就执行

后续

jinja2模版文件

nginx.conf里面的配置文件

upstream {

{% for i in groups.webserver %}  # 需要获取这个webserver这个事实变量
    server {{hostvars[i].ansible.ipv4.address}}:80;
{%endfor%}

}

posted @ 2026-04-11 14:07  乔的港口  阅读(6)  评论(0)    收藏  举报