Ansible变量与机密管理总结

发布于:2025-09-02 ⋅ 阅读:(19) ⋅ 点赞:(0)

Ansible变量与机密管理总结

一、Ansible变量基础

1. 变量定义规则

  • 组成字符:仅允许字母、数字、下划线(_
  • 命名开头:必须以字母开头,不能以数字或下划线开头
  • 关键字限制:不可使用Ansible内置关键字(如taskshosts等)作为变量名

2. 变量优先级(从高到低)

优先级 变量范围 说明
1 Global(全局) 命令行传递变量(-e参数)、Ansible配置文件(ansible.cfg)中定义的变量
2 Play(剧本) Playbook中通过varsvars_files定义的变量
3 Host(主机) Inventory清单、主机事实变量(Facts)、register注册的变量、host_vars/group_vars目录定义的变量

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

二、变量分类与详细用法

1. 事实变量(Facts)

定义

由Ansible自动收集的受控主机信息(如系统版本、IP地址、硬件配置等),无需手动定义,可直接调用。

查看方式

通过setup模块收集指定主机的所有事实变量,输出到文件查看:

ansible node1 -m setup > node1_facts.txt
常用事实变量及作用
变量名 作用 示例用法
ansible_default_ipv4.address 获取受控主机默认IPv4地址 msg: "主机IP: {{ ansible_default_ipv4.address }}"
ansible_<网卡名>.ipv4.address 获取指定网卡的IPv4地址(如ansible_ens160.ipv4.address msg: "ens160网卡IP: {{ ansible_ens160.ipv4.address }}"
ansible_fqdn 获取受控主机完全合格域名(FQDN) msg: "FQDN: {{ ansible_fqdn }}"
ansible_hostname 获取受控主机短主机名 msg: "主机名: {{ ansible_hostname }}"
ansible_memtotal_mb 获取受控主机总内存大小(单位:MB) msg: "总内存: {{ ansible_memtotal_mb }}MB"
ansible_bios_version 获取受控主机BIOS版本 msg: "BIOS版本: {{ ansible_bios_version }}"
ansible_devices.<硬盘名>.size 获取指定硬盘大小(如ansible_devices.vda.size msg: "vda硬盘大小: {{ ansible_devices.vda.size }}"
ansible_lvm.vgs 获取受控主机LVM卷组信息 msg: "LVM卷组: {{ ansible_lvm.vgs }}"

2. 内置变量(Built-in Variables)

定义

Ansible自带的通用变量,用于获取清单、主机组等基础信息,无需手动定义。

常用内置变量及作用
变量名 作用 示例用法
groups.all 列出Inventory中所有主机 msg: "所有主机: {{ groups.all }}"(输出如[node1, node2]
group_names 列出当前主机所属的所有主机组 msg: "所属组: {{ group_names }}"(输出如[net]
inventory_hostname 获取当前主机在Inventory中的名称 msg: "清单主机名: {{ inventory_hostname }}"(输出如node1
play_hosts 列出当前Play中所有目标主机 msg: "Play目标主机: {{ play_hosts }}"(输出如[node1, node2]
inventory_dir 获取Inventory清单文件所在目录路径 msg: "清单目录: {{ inventory_dir }}"(输出如/etc/ansible
ansible_version 获取Ansible版本信息(含主版本、次版本等) msg: "Ansible版本: {{ ansible_version.full }}"(输出如2.9.18

3. 自定义变量(手动定义)

(1)vars直接定义(Play内临时变量)
  • 作用:在Playbook的vars段中直接定义变量,仅在当前Play内生效。
  • 用法示例:
---
- name: 测试vars定义变量
  hosts: node1
  vars:
    aa: 11  # 普通变量
    bb: 22  # 普通变量
    cc:     # 字典类型变量
      a1: c31
      a2: c32
  tasks:
    - name: 输出普通变量aa
      debug: 
        msg: "{{ aa }}"  # 输出11
    - name: 输出字典变量cc的a1值
      debug:
        msg: "{{ cc.a1 }}"  # 输出c31
(2)vars_files引用变量文件(外部变量文件)
  • 作用:将变量存储在外部YAML文件中,通过vars_files引用,便于批量管理变量。
  • 用法示例:
    1. 创建外部变量文件/etc/ansible/var.yml
    aa: 11
    bb: 22
    cc:
      a1: c31
      a2: c32
    
    1. 在Playbook中引用:
    ---
    - name: 测试vars_files引用变量
      hosts: node1
      vars_files: /etc/ansible/var.yml  # 引用外部变量文件
      tasks:
        - name: 输出变量aa
          debug: 
            msg: "{{ aa }}"  # 输出11
    
(3)register注册变量(任务结果变量)
  • 作用:将某个任务的执行结果(如命令输出、返回码)注册为变量,供后续任务调用。
  • 用法示例:
---

- name: 测试register注册变量
  hosts: node1
  tasks:
    - name: 执行shell命令(查看/tmp/zz文件)
      shell: "cat /tmp/ycy"
      register: ycy  # 将命令结果注册为变量ycy
    - name: tast
      debug: 
        msg: "{{ ycy }}" ##输出结果如下
    - name:
      debug:
        var: ycy ##输出ycy的值
    - name: 输出变量ycy的返回码(rc=0表示执行成功)
      debug: 
        msg: "{{ ycy.rc }}"  # 输出0
    - name: 输出命令的标准输出
      debug: 
        msg: "{{ ycy.stdout }}"  # 输出/tmp/ycy文件内容
  • 常用结果字段:

    • zz.rc:任务返回码(0=成功,非0=失败)

    • zz.stdout:任务标准输出

    • zz.stderr:任务错误输出

    • zz.changed:是否修改了主机状态(true/false

    • [student@master ansible]$ ansible-playbook test3.yml
      ok: [node1] => {
          "msg": {
              "changed": true,
              "cmd": "cat /tmp/ycy",
              "delta": "0:00:00.003165",
              "end": "2025-09-02 01:52:54.778478",
              "failed": false,
              "msg": "",
              "rc": 0,
              "start": "2025-09-02 01:52:54.775313",
              "stderr": "",
              "stderr_lines": [],
              "stdout": "add",
              "stdout_lines": [
                  "add"
              ]
          }
      }
      
      TASK [debug] *****************************************************************************************************
      ok: [node1] => {
          "ycy": {
              "changed": true,
              "cmd": "cat /tmp/ycy",
              "delta": "0:00:00.003165",
              "end": "2025-09-02 01:52:54.778478",
              "failed": false,
              "msg": "",
              "rc": 0,
              "start": "2025-09-02 01:52:54.775313",
              "stderr": "",
              "stderr_lines": [],
              "stdout": "add",
              "stdout_lines": [
                  "add"
              ]
          }
      }
      
      TASK [debug] *****************************************************************************************************
      ok: [node1] => {
          "msg": "0"
      }
      
      TASK [debug] *****************************************************************************************************
      ok: [node1] => {
          "msg": "add"
      }
      node1                      : ok=6    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
      
      
      
(4)set_fact定义变量(动态变量)
  • 作用:类似Shell的变量赋值,可将现有变量值或字符串赋值给新变量,支持动态计算。
  • 用法示例:
---
- name: 测试set_fact定义变量
  hosts: node1
  tasks:
    - name: 将事实变量赋值给新变量
      set_fact:
        host_ip: "{{ ansible_default_ipv4.address }}"  # 新变量host_ip=默认IP
    - name: 输出新变量
      debug: 
        msg: "主机IP: {{ host_ip }}"  # 输出默认IP
(5)命令行传递变量(-e参数)
  • 作用:通过ansible-playbook命令行临时传递变量,优先级最高,适合临时修改变量值。
  • 用法示例:
    1. 创建Playbookd.yml
    ---
    - name: 测试命令行传递变量
      hosts: node1
      tasks:
        - name: 输出命令行变量name1
          debug: 
            msg: "name1: {{ name1 }}"
        - name: 输出命令行变量name2
          debug:
            msg: "name2: {{ name2 }}"
    
    1. 命令行传递变量并执行:
    ansible-playbook d.yml -e 'name1=tom name2=marry'
    
    • 输出结果:姓名1: tom姓名2: marry
(6)Inventory清单变量
  • 作用:在Inventory清单文件中为单个主机或主机组定义变量,仅对目标主机/组生效。
① 清单内直接定义
  • 示例(/etc/ansible/hosts):
# 单个主机变量(直接跟在主机后)
node1 vars1=hello vars2=hi

# 主机组变量(通过[组名:vars]段定义)
[net]
node1
node2

[net:vars]
vars1=hello  # 所有net组主机的变量vars1=hello
vars2=hi     # 所有net组主机的变量vars2=hi
  • Playbook引用示例:
---
- name: 测试清单变量
  hosts: node1
  tasks:
    - name: 输出清单变量vars1
      debug:
        msg: "vars1: {{ vars1 }}"  # 输出hello
host_vars/group_vars目录定义
  • 作用:通过专用目录存储变量文件,结构更清晰,支持YAML格式。

  • 目录规则:

    • host_vars:存储单个主机的变量,文件名为主机名(如node1node1.yml
    • group_vars:存储主机组的变量,文件名为组名(如netnet.yml
  • 优先级:同目录下,无后缀文件名(如node1)优先级高于YAML后缀文件(如node1.yml)。

  • 示例:

    1. 创建host_vars目录及变量文件:
    mkdir /etc/ansible/host_vars
    vim /etc/ansible/host_vars/node1  # 无后缀文件
    vim /etc/ansible/host_vars/node1.yml ##优先级低于node1 当两个文件同时存在相同的变量,会优先执行node1的变量值。
    
    1. 写入变量(YAML格式):
    vars1: groupvars1
    vars2: groupvars2
    
    1. Playbook引用:
    ---
    - name: 测试host_vars变量
      hosts: node1
      tasks:
        - name: 输出vars1
          debug: 
            msg: "{{ vars1 }}"  # 输出groupvars1
    
(7)with_items迭代变量(多值变量)
  • 作用:为变量赋予多个值,通过循环执行任务,适合批量操作(如批量输出、批量创建文件)。
  • 用法示例:
---
- name: 测试with_items迭代变量
  hosts: node1
  tasks:
    - name: 循环执行shell命令(输出多个值)
      shell: "echo {{ item }}"
      with_items:  # 变量item依次取haha、heihei、hehe
        - haha
        - heihei
        - hehe
      register: hi_var  # 注册循环结果到hi_var
    - name: 输出第一个值的结果
      debug: 
        var: hi_var.results[0].stdout  # 输出haha
    - name: 输出第二个值的结果
      debug:
        var: hi_var.results[1].stdout  # 输出heihei
  • 关键字段:hi_var.results为列表,存储每次循环的结果,通过索引([0]/[1])访问单个结果。

    [student@master ansible]$ ansible-playbook ycy7.yml
    
    ok: [node1]
    
    TASK [test shell cmd] ********************************************************************************************
    changed: [node1] => (item=ycy)
    changed: [node1] => (item=namcy)
    changed: [node1] => (item=gd)
    
    TASK [print test1] ***********************************************************************************************
    ok: [node1] => {
        "msg": "luoqi_var.results[0].sudout"
    }
    
    TASK [print test2] ***********************************************************************************************
    ok: [node1] => {
        "msg": "luoqi_var.results[1].sudout"
    }
    node1                      : ok=4    changed=1
    

三、Ansible机密管理(Ansible Vault)

1. 作用

加密存储敏感数据(如密码、API密钥、用户密码等),避免敏感信息以明文形式存储在Playbook或变量文件中,降低安全风险。

2. 核心命令(ansible-vault

命令 作用 示例
ansible-vault create <file> 创建新的加密文件(默认用vi编辑) ansible-vault create secret.yml(需输入密码)
ansible-vault view <file> 查看加密文件内容(需输入密码) ansible-vault view secret.yml
ansible-vault edit <file> 编辑加密文件(需输入密码,编辑后自动重新加密) ansible-vault edit secret.yml
ansible-vault encrypt <file> 加密已存在的明文文件 ansible-vault encrypt plain.yml(需输入密码)
ansible-vault decrypt <file> 永久解密加密文件(解密后为明文) ansible-vault decrypt secret.yml(需输入密码)
ansible-vault decrypt <file> --output <newfile> 解密文件并保存为新文件(原文件仍加密) ansible-vault decrypt secret.yml --output plain.yml
ansible-vault rekey <file> 修改加密文件的密码 ansible-vault rekey secret.yml(需输入旧密码和新密码)

3. 执行加密Playbook的方法

加密后的Playbook无法直接执行,需通过以下方式提供解密密码:

(1)交互式输入密码(--ask-vault-pass
ansible-playbook --ask-vault-pass secret.yml
# 执行时会提示输入Vault密码,输入正确后执行
(2)密码文件传递(--vault-id <密码文件>
  1. 创建密码文件(如secret.txt),写入Vault密码(仅一行):
echo "redhat" > secret.txt
chmod 600 secret.txt  # 限制文件权限,避免他人访问
  1. 通过密码文件执行加密Playbook:
ansible-playbook --vault-id secret.txt secret.yml
(3)临时交互密码(--vault-id @prompt
ansible-playbook --vault-id @prompt secret.yml
# 效果同--ask-vault-pass,提示输入密码

以下是Ansible变量执行方法的总结,涵盖不同类型变量的定义、调用及执行流程:

一、变量执行核心流程

  1. 定义变量:通过不同方式声明变量(内置/自定义/事实变量等)
  2. 调用变量:在Playbook中使用{{ 变量名 }}语法引用
  3. 执行验证:通过ansible-playbook运行并查看变量生效结果

二、各类变量的执行方法

1. 事实变量(Facts)
  • 执行特点:自动收集,无需手动定义,直接调用

  • 执行步骤

    1. 无需额外配置,Playbook默认自动收集(可通过gather_facts: no关闭)
    2. 在任务中直接使用{{ 事实变量名 }}调用
    3. 执行Playbook验证结果
  • 示例执行

    # playbook.yml
    - hosts: node1
      tasks:
        - name: 显示主机IP
          debug:
            msg: "IP地址: {{ ansible_default_ipv4.address }}"
    

    运行命令:ansible-playbook playbook.yml

2. 内置变量
  • 执行特点:Ansible自带,无需定义,直接在任意Playbook中调用

  • 执行步骤

    1. 直接在任务中使用{{ 内置变量名 }}
    2. 执行Playbook查看结果
  • 示例执行

    # playbook.yml
    - hosts: all
      tasks:
        - name: 显示当前主机名
          debug:
            msg: "当前主机: {{ inventory_hostname }}"
    

    运行命令:ansible-playbook playbook.yml

3. 自定义变量(核心执行方法)
定义方式 执行步骤 示例命令
vars直接定义 1. 在Playbook的vars段声明变量
2. 任务中用{{ 变量名 }}调用
3. 直接执行Playbook
ansible-playbook playbook.yml
vars_files引用文件 1. 创建外部变量文件(如vars.yml
2. Playbook中通过vars_files引用
3. 执行Playbook
ansible-playbook playbook.yml
register注册变量 1. 在任务中用register: 变量名捕获结果
2. 后续任务中调用{{ 变量名.字段 }}
3. 执行Playbook查看输出
ansible-playbook playbook.yml
set_fact动态定义 1. 用set_fact: 新变量={{ 源变量 }}定义
2. 任务中调用新变量
3. 执行Playbook
ansible-playbook playbook.yml
命令行传递(-e) 1. Playbook中预留变量名
2. 执行时通过-e "变量=值"传递
3. 动态生效
ansible-playbook playbook.yml -e "user=admin port=8080"
Inventory清单变量 1. 在清单文件或host_vars/group_vars中定义
2. Playbook中直接调用
3. 执行Playbook
ansible-playbook -i inventory.yml playbook.yml
with_items迭代变量 1. 用with_items: [值1, 值2]定义列表
2. 任务中用{{ item }}循环调用
3. 执行Playbook查看循环结果
ansible-playbook playbook.yml
4. 加密变量(Ansible Vault)
  • 执行特点:需解密后执行,保护敏感变量
  • 执行步骤
    1. 创建加密变量文件:ansible-vault create secret.yml
    2. 在Playbook中引用加密文件:vars_files: secret.yml
    3. 执行时提供解密密码:
      • 交互式:ansible-playbook --ask-vault-pass playbook.yml
      • 密码文件:ansible-playbook --vault-id pass.txt playbook.yml

三、变量执行优先级验证方法

  1. 创建测试Playbook
    # priority_test.yml
    - hosts: node1
      vars:
        test_var: "Play级变量"
      tasks:
        - name: 输出变量值
          debug:
            var: test_var
    
  2. 通过不同方式定义同名变量
    • 清单文件定义:node1 test_var="清单变量"
    • 命令行传递:-e "test_var=命令行变量"
  3. 依次执行验证覆盖关系
    ansible-playbook priority_test.yml  # 输出Play级变量
    ansible-playbook -i inventory.yml priority_test.yml  # 输出清单变量
    ansible-playbook priority_test.yml -e "test_var=命令行变量"  # 输出命令行变量
    

四、常见执行问题及解决

  1. 变量未定义错误

    • 检查变量名拼写(区分大小写)
    • 确认变量定义位置是否在当前作用域内
  2. 事实变量无法获取

    • 检查是否禁用了facts收集(gather_facts: no
    • 确保受控主机网络通畅,Ansible可正常连接
  3. 加密变量解密失败

    • 确认密码正确
    • 检查加密文件是否损坏(可尝试重新加密)

通过以上方法,可清晰掌握Ansible各类变量的执行逻辑,确保变量在自动化任务中正确生效。


网站公告

今日签到

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