Ansible变量全解析:定义、作用域与实战

发布于:2025-09-03 ⋅ 阅读:(12) ⋅ 点赞:(0)

Ansible 变量

定义变量规则

  • 变量名由字母、数字、下划线组成,且必须以字母开头。
  • 不能使用 Ansible 内置关键字作为变量名。

变量作用域与优先级

Ansible 变量可分为三个范围,优先级从高到低依次为:

  1. Global 范围(高):从命令行或 Ansible 配置中设置的变量。
  2. Play 范围(中):在 Play 及相关结构中设置的变量。
  3. Host 范围(低):在 Inventory、Facts 或 Register 中设置的变量,包括主机组和个别主机上定义的变量。

若变量重复定义,优先级高的将覆盖优先级低的。


定义变量的多种方式

Ansible 支持多种定义变量的方式,包括:

  1. 将模块执行结果注册为变量(register
  2. 直接定义字典类型的变量
  3. 在 Role 文件中定义变量
  4. 通过命令行传递变量
  5. 使用 with_items 迭代将多个任务结果赋值给一个变量
  6. 在 Inventory 中定义主机或主机组变量
  7. 使用内置变量
  8. 使用事实变量(Facts)

变量定义示例

使用 vars 定义变量

- name: test
  hosts: node1
  vars:
    - aa: 11
    - bb: 22
    - cc:
        a1: c31
        a2: c32
  tasks:
    - name: create debug1
      debug:
        msg: "{{ aa }}"

    - name: create debug2
      debug:
        msg: "{{ bb }}"

    - name: create debug3
      debug:
        msg: "{{ cc.a1 }}"

    - name: create debug4
      debug:
        msg: "{{ cc.a2 }}"

使用 vars_files 引入外部变量文件

- name: test1234
  hosts: node1
  vars_files: /home/student/ansible/var.yml
  tasks:
    - name: debug1
      debug:
        msg: "{{ aa }}"

    - name: debug2
      debug:
        msg: "{{ bb }}"

    - name: debug3
      debug:
        msg: "{{ cc.a1 }}"

    - name: debug4
      debug:
        msg: "{{ cc.a2 }}"

使用 register 注册变量

使⽤register选项,可以将当前task的输出结果赋值给⼀个变量。

- name: test a playbook
  hosts: node1
  tasks:
    - name: shell
      shell: "cat /tmp/zz"
      register: zz

    - name: create debug
      debug:
        var: zz

输出示例:

"zz": {
  "changed": true,
  "cmd": "cat /tmp/zz",
  "delta": "0:00:00.005195",
  "end": "2020-07-29 10:06:17.704232",
  "failed": false,
  "rc": 0,
  "start": "2020-07-29 10:06:17.699037",
  "stderr": "",
  "stderr_lines": [],
  "stdout": "zz",
  "stdout_lines": ["zz"]
}

也可以提取特定字段:

- name: create debug
  debug:
    msg: "{{ zz.rc }}"

使用 set_fact 定义变量

set_fact和register的功能很相似,也是将值赋值给变量。它更像shell中变量的赋值⽅式,可以将某个变量的值赋值给另⼀个变量,也可以将字符串赋值给变量

通过’ansible node1 -m setup’ 可以查询node1主机所有的事实变量

- name: test a playbook
  hosts: node1
  tasks:
    - name: hostname
      debug:
        msg: "{{ ansible_fqdn }}"
        
 #输出示例
  "msg": "node1.example.com"

使用事实变量(Facts)

- name: abc
  hosts: node1
  tasks:
    - name: test
      debug:
        msg: "The IPv4 address of {{ ansible_nodename }} is {{ ansible_ens160.ipv4.address }}"
        
#输出示例
 "msg": "the ipv4 address of node1.example.com is 172.16.30.10"

通过命令行传递变量

- name: test4
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "My name is {{ name1 }}"

    - name: create debug2
      debug:
        msg: "My name is {{ name2 }}"

执行命令:

ansible-playbook d.yml -e 'name1=tom name2=marry'

#输出示例
"msg": "my name is tom"
"msg": "my name is marry"

在 Inventory 中定义变量

编辑 /host/student/ansible/inventory

node1
node2

[net]
node1
node2

[net:vars]
vars1='hello'
vars2='hi'

Playbook 示例:

- name: test5
  hosts: node1
  tasks:
    - name: create debug1
      debug:
        msg: "say {{ vars1 }}"

    - name: create debug2
      debug:
        msg: "say {{ vars2 }}"
        
 #输出示例
  "msg": "say hello"
  "msg": "say hi"

使用 group_varshost_vars

/home/student/ansible/ 下创建 host_vars 目录,并为主机定义变量:

# /home/student/ansible/host_vars/node1
vars1: groupvars1
vars2: groupvars2

或使用 YAML 文件:

# /host/student/ansible/host_vars/node1.yml
vars1: abc
vars2: bcd

Playbook

- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: my name is {{vars1}}

    - name: create debug2
      debug:
        msg: my name is {{vars2}}
        
 #输出示例
 "msg": "my name is groupvars1"
 "msg": "my name is groupvars2"

删除/etc/ansible/host_vars/node1 保留/etc/ansible/host_vars/node1.yml,再次执行playbook

#输出示例
"msg": "my name is abc"
"msg": "my name is bcd"

若同时存在 node1node1.yml,则 node1 的优先级更高。


内置变量示例

ansible_version(ansible版本)

- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{ ansible_version }}"

输出:

{
  "full": "2.9.18",
  "major": 2,
  "minor": 9,
  "revision": 18,
  "string": "2.9.18"
}

inventory_hostname(当前主机的主机名称)

- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{ inventory_hostname }}"

输出:

"msg": "node1"

play_hosts(当前play所操作的所有主机的主机名列表)

- name: test
  hosts: net
  tasks:
    - name: create debug
      debug:
        msg: "{{ play_hosts }}"

输出:

"msg": [
        "node1",
        "node2"
    ]
"msg": [
        "node1",
        "node2"
    ]

groups(获取到清单中”所有分组”的”分组信息”)

- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{ groups }}"

输出:

 "msg": {
        "all": [
            "node1",
            "node2"
        ],
        "net": [
            "node1",
            "node2"
        ],
        "ungrouped": []
    }

group_names(获取到当前主机所在分组的组名)

- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{ group_names }}"

输出:

"msg": [
        "net"
    ]

inventory_diransible主机中清单文件的存放路径

- name: test
  hosts: node1
  tasks:
    - name: create debug
      debug:
        msg: "{{ inventory_dir }}"

输出:

"msg": "/home/student/ansible"

使用 with_items 迭代赋值

- name: test
  hosts: node1
  tasks:
    - name: abc
      shell:
        cmd: echo "{{ item }}"
      with_items:
        - haha
        - heihei
        - hehe
      register: hi_var

    - name: debug1
      debug:
        var: hi_var.results[0].stdout

    - name: debug2
      debug:
        var: hi_var.results[1].stdout

    - name: debug3
      debug:
        var: hi_var.results[2].stdout

输出:

"hi_var.results[0].stdout": "haha"
"hi_var.results[1].stdout": "heihei"
"hi_var.results[2].stdout": "hehe"
   - name: abc
      shell:
        cmd: echo "{{item}}"
      with_items:
        - haha
        - heihei
        - hehe
      register: hi_var

    - name: debug1
      debug:
        msg: "{{hi_var}}"

输出:

"msg": {
        "changed": true,
        "msg": "All items completed",
        "results": [
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": "echo \"haha\"",
                "delta": "0:00:00.003206",
                "end": "2021-04-09 00:36:52.433624",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo \"haha\"",
                        "_uses_shell": true,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "haha",
                "rc": 0,
                "start": "2021-04-09 00:36:52.430418",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "haha",
                "stdout_lines": [
                    "haha"
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": "echo \"heihei\"",
                "delta": "0:00:00.002276",
                "end": "2021-04-09 00:36:52.676159",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo \"heihei\"",
                        "_uses_shell": true,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "heihei",
                "rc": 0,
                "start": "2021-04-09 00:36:52.673883",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "heihei",
                "stdout_lines": [
                    "heihei"
                ]
            },
            {
                "ansible_loop_var": "item",
                "changed": true,
                "cmd": "echo \"hehe\"",
                "delta": "0:00:00.002589",
                "end": "2021-04-09 00:36:52.920442",
                "failed": false,
                "invocation": {
                    "module_args": {
                        "_raw_params": "echo \"hehe\"",
                        "_uses_shell": true,
                        "argv": null,
                        "chdir": null,
                        "creates": null,
                        "executable": null,
                        "removes": null,
                        "stdin": null,
                        "stdin_add_newline": true,
                        "strip_empty_ends": true,
                        "warn": true
                    }
                },
                "item": "hehe",
                "rc": 0,
                "start": "2021-04-09 00:36:52.917853",
                "stderr": "",
                "stderr_lines": [],
                "stdout": "hehe",
                "stdout_lines": [
                    "hehe"
                ]
            }
        ]
    }

Ansible Vault 管理机密

Ansible Vault 用于加密敏感数据(如密码、API 密钥等),避免以明文形式存储。

使用ansible vault,可通过一个名为ansible-vault的命令行工具创建、编辑、加密、解密和查看文件。Ansible vault可以加密任何由ansible使用的结构化数据文件。这可能包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件,或者ansible角色中定义的变量。

创建加密文件

ansible-vault create test.yml
输入密码:redhat
确认密码:redhat

要创建新的加密文件,使用ansible-vault create filename命令,默认使用vi编辑

查看加密文件

ansible-vault view test.yml
Vault password:    #输入设置的密码redhat
---
- name: test1
  hosts: node1
  tasks: 
    - name: create user2
      user: 
        name: user2
        state: present

编辑加密文件

ansible-vault edit test.yml

加密现有文件

ansible-vault encrypt a.yml
输入密码:redhat
确认密码:redhat 

解密文件

# 直接解密,永久解密
ansible-vault decrypt test.yml

# 解密并另存为其他文件(原文件仍加密)
ansible-vault decrypt a.yml --output=a-secret.yml

使用密码文件加密/解密

# 加密
ansible-vault encrypt e.yml --vault-id secret.txt

# 执行 Playbook
ansible-playbook e.yml --vault-id secret.txt

修改加密文件的密码

ansible-vault  rekey  filename  #命令可以修改

ansible-vault rekey a.yml
输入旧密码
输入新密码
确认新密码

执行加密的 Playbook

# 使用提示输入密码
ansible-playbook --vault-id @prompt a.yml

# 使用交互式输入密码
ansible-playbook --ask-vault-pass a.yml

# 检查模式(Dry-run)
ansible-playbook --ask-vault-pass a.yml -C

Ansible 变量参考手册

一、 事实变量 (Facts)

这些变量通过 ansible.builtin.setup 模块收集自受控节点(Managed Node)。使用 ansible node1 -m setup 命令可以获取。

变量分类 变量名 描述 示例/备注
网络信息 ansible_default_ipv4.address 主IPv4地址 获取默认路由所使用的IP地址
ansible_<interface>.ipv4.address 指定网卡的IPv4地址 <interface> 替换为实际网卡名,如 ansible_eth0.ipv4.address
系统信息 ansible_fqdn 完全合格域名 (FQDN) node1.example.com
ansible_hostname 主机名称 (短名称) node1
ansible_memtotal_mb 总内存大小 (单位: MB) 1024 (表示 1GB 内存)
ansible_bios_version BIOS 版本号 xx.xx.xx
存储信息 ansible_devices.vda.size vda 硬盘的总容量 通常表示第一块虚拟磁盘
ansible_devices.vdb.size vdb 硬盘的总容量 通常表示第二块虚拟磁盘
ansible_lvm.vgs 逻辑卷管理器 (LVM) 中的卷组信息 返回一个字典结构,包含所有VG的详细信息

二、 内置变量 (Magic Variables)

这些变量由Ansible自动提供,无需收集,主要用于获取清单(Inventory)信息。

变量名 描述 示例/用途
groups 一个包含所有清单分组及其主机列表的字典。 groups['web'] 返回 [web1, web2]
groups.all 一个列表,包含所有清单中的主机。 groups.all 返回 [node1, node2, web1, db1]
group_names 当前正在执行任务的主机所属的组名列表。 在Playbook中用于条件判断: when: "'db' in group_names"
inventory_hostname 当前正在执行任务的主机在Ansible清单中定义的名字 可能不同于 ansible_hostname(系统实际主机名),特别是当你使用了别名时。

网站公告

今日签到

点亮在社区的每一天
去签到