当前位置: 首页 > news >正文

【网络运维】Playbook进阶: 管理变量

Playbook进阶: 管理变量

实验环境

# 新建文件夹
[furongwang@controller ~]$ mkdir web && cd web# 创建ansible配置文件
[furongwang@controller web]$ cat > ansible.cfg <<'EOF'
[defaults]
remote_user = furongwang
inventory = ./inventory[privilege_escalation]
become = True
become_user = root
become_method = sudo
become_ask_pass = False
EOF# 创建inventory主机目录
[furongwang@controller web]$ cat > inventory <<'EOF'
controller
node1
node2
node3
node4
EOF

管理变量 Variables

变量简介

ansible 利用变量来存储数据,以便在Ansible项目文件中重复引用,有利于简化项目的创建和维护,降低出错率。在playbook中可以针对如用户、软件包、服务、文件等进行变量定义。

变量命名规则
  • 只能包含字母、数字和下划线(如包含空格、点、$符号都为非法变量名)
  • 只能以字母开头
变量范围和优先级

ansible项目文件中多个位置支持定义变量,主要包含三个基本范围:

  • Global scope:从命令行或 Ansible 配置设置的变量。
  • Play scope:在play和相关结构中设置的变量。
  • Host scope:由清单、事实(fact)收集或注册的任务,在主机组和个别主机上设置的变量。

优先级从高到低顺序:Global -> Play -> Host

在多个级别上定义了相同名称的变量,则采用优先级别最高的变量。

变量引用

可将变量名称放在双花括号({{}})内引用变量。在任务执行时, Ansible会将变量替换为其值。

当变量用作值的第一元素时,变量引用必须使用引号(单引号或者双引号),否则会报错。

示例:配置playbook.yml

---
- name: deploy web serverhosts: node1tasks:- name: install the latest version of Apacheyum:name: httpdstate: latest- name: enable and start Apacheservice:name: httpdstate: startedenabled: yes- name: enable and start Firewalldservice:name: firewalldstate: startedenabled: yes- name: set firewall for httpfirewalld:service: httppermanent: yesimmediate: yesstate: enabled- name: prepare index.htmlcopy:content: "Hello Sol-3 From {{ node }}\n"dest: /var/www/html/index.html- name: check web serverhosts: node2tasks:- name: check web siteuri:url: http://node1.furongwang.cloud
...

验证:

[furongwang@controller web]$ ansible-playbook playbook.ymlPLAY [deploy web server] *******************************************************TASK [Gathering Facts] *********************************************************
ok: [node1]TASK [install the latest version of Apache] ************************************
ok: [node1]TASK [enable and start Apache] *************************************************
ok: [node1]TASK [enable and start Firewalld] **********************************************
ok: [node1]TASK [set firewall for http] ***************************************************
ok: [node1]TASK [prepare index.html] ******************************************************
ok: [node1]PLAY [check web server] ********************************************************TASK [Gathering Facts] *********************************************************
ok: [node2]TASK [check web site] **********************************************************
ok: [node2]PLAY RECAP *********************************************************************
node1                      : ok=6    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
node2                      : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

在这里插入图片描述

Host scope

主机变量应用于主机和主机组。主机变量优先级高于主机组变量。

主机清单中定义

较旧的做法是直接在清单文件中定义。不建议采用,但仍可能会遇到。

示例

[servers]
node1 user=furongwang
node2[servers:vars]
user=litangwang

验证:

[furongwang@controller web]$ ansible servers -m debug -a 'var=user'
node1 | SUCCESS => {"user": "furongwang"
}
node2 | SUCCESS => {"user": "litangwang"
}

缺点:使得清单文件更复杂,在同一文件中混合提供了主机和变量信息。

目录分层结构定义

在项目目录中创建如下目录:

  • group_vars,定义主机组变量。目录中文件名可以直接使用 主机组名 或者 主机组名.yml

  • host_vars,定义主机变量。目录中文件名可以直接使用 主机名 或者 主机名.yml

示例1:

[furongwang@controller web]$ cat inventory 
[servers]
node1
node2[furongwang@controller web]$ mkdir group_vars
[furongwang@controller web]$ vim group_vars/servers.yml
user: litangwang[furongwang@controller web]$ mkdir host_vars
[furongwang@controller web]$ vim host_vars/node1.yml
user: furongwang

验证:

[furongwang@controller web]$ ansible servers -m debug -a 'var=user'
node1 | SUCCESS => {"user": "furongwang"
}
node2 | SUCCESS => {"user": "litangwang"
}

目录结构定义主机和主机组的变量是首选做法

示例2

[furongwang@controller web]$ tree
.
├── ansible.cfg
├── group_vars
│   ├── dc
│   ├── dc1
│   └── dc2
├── host_vars
│   └── node1.yml
├── inventory
└── playbook.yml[furongwang@controller web]$ vim inventory
[dc1]
node1
node2[dc2]
node3
node4[dc:children]
dc1
dc2[furongwang@controller web]$ grep . group_vars/* host_vars/*
group_vars/dc:package: httpd
group_vars/dc1:package: httpd
group_vars/dc2:package: apache
host_vars/node1.yml:package: mariadb-server[furongwang@controller web]$ ansible all -m debug -a 'var=package'
node1 | SUCCESS => {"package": "mariadb-server"
}
node3 | SUCCESS => {"package": "apache"
}
node2 | SUCCESS => {"package": "httpd"
}
node4 | SUCCESS => {"package": "apache"
}
主机连接特殊变量列表(部分)
  • ansible_connection,与主机的连接类型,可以是 smart、ssh 或 paramiko。默认为smart。

  • ansible_host,要连接的主机的名称,默认值就是主机清单名称。

  • ansible_port,ssh 端口号,如果不是 22。

  • ansible_user,ssh 用户名。

  • ansible_ssh_pass,要使用的 ssh 密码。切勿以纯文本形式存储此变量,始终使用保管库。

  • ansible_ssh_private_key_file,ssh 使用的私钥文件。如果使用多个密钥并且您不想使用 SSH 代理,这很有用。

  • ansible_ssh_common_args,此设置始终附加到 sftp、scp 和 ssh 的默认命令行。

  • ansible_sftp_extra_args,此设置始终附加到默认的 sftp 命令行。

  • ansible_scp_extra_args,此设置始终附加到默认的 scp 命令行。

  • ansible_ssh_extra_args,此设置始终附加到默认的 ssh 命令行。

  • ansible_become,等效于 ansible_sudo 或 ansible_su,允许强制提权。

  • ansible_become_method,允许设置权限提升方法。

  • ansible_become_user,等效于 ansible_sudo_user 或 ansible_su_user,允许设置您通过权限升级成为的用户。

  • ansible_become_pass,等效于 ansible_sudo_pass 或 ansible_su_pass,允许您设置权限提升密码(切勿以纯文本形式存储此变量;始终使用保管库。请参阅变量和保管库)。

数组变量

除了将与同一元素相关的配置数据(软件包列表、服务列表和用户列表等)分配到多个变量外,管理员也可以使用数组变量,将多个值存储在同一变量中。

示例:

user1_first_name: Bob
user1_last_name: Jones
user1_home_dir: /users/bjones
user2_first_name: Anne
user2_last_name: Cook
user2_home_dir: /users/acook

改写如下:

users:bjones:first_name: Boblast_name: Joneshome_dir: /users/bjonesacook:first_name: Annelast_name: Cookhome_dir: /users/acook

数组变量引用方式一:

# Returns 'Bob'
users.bjones.first_name
# Returns '/users/acook'
users.acook.home_dir

数组变量引用方式二:

# Returns 'Bob'
users['bjones']['first_name']
# Returns '/users/acook'
users['acook']['home_dir']

引用方式总结:

  • 如果使用方法一 .分隔符 引用的关键字与python的功能函数同名,例如discard、copy、add,那么就会出现问题。方法二[‘’]引用方式可以避免这种错误。
  • 尽管两种方法都可以使用,为了减少排故难度,Ansible中统一使用其中一种方法。

示例1:

---
- name: test vars statement in playhosts: node1vars: users:furongwang:user_name: furongwanghome_path: /home/furongwanglitangwang:user_name: litangwanghome_path: /home/litangwangtasks:- name: add user {{ users.furongwang.user_name }}user:name: '{{ users.furongwang.user_name }}'home: "{{ users.furongwang.home_path }}"- name: debug litangwangdebug: msg: >username is {{ users['litangwang']['user_name'] }}home_path is {{ users['litangwang']['home_path'] }}

示例2:

---
- name: test vars statement in playhosts: node1vars: users:- user_name: furongwang1home_path: /home/furongwang1- user_name: furongwang2home_path: /home/furongwang2tasks:- name: add user {{ users.0.user_name }}user:name: "{{ users.0.user_name }}"home: "{{ users.0.home_path }}"- name: debug {{ users[1].user_name }}debug: msg: "{{ users[1].user_name }}"
register 语句

register 语句捕获任务输出。 输出保存在一个临时变量中,稍后在playbook中可用于调试用途或者达成其他目的。

示例:

---
- name: Installs a package and prints the resulthosts: node1tasks:- name: Install the packageyum:name: httpdstate: installedregister: install_result- debug: var: install_result
MAGIC 变量

magic 变量由 Ansible 自动设置,可用于获取与特定受管主机相关的信息。

配置inventory内容为:

controller[webs]
node1
node2[dbs]
node3
node4

常用的四个 Magic 变量:

  • inventory_hostname,包含清单中配置的当前受管主机的主机名称。这可能因为各种原因而与FACTS报告的主机名称不同。

    [furongwang@controller web]$ ansible node1 -m debug -a 'var=inventory_hostname'
    node1 | SUCCESS => {"inventory_hostname": "node1"
    }
    
  • group_names,列出当前受管主机所属的所有主机组。

    [furongwang@controller web]$ ansible node1 -m debug -a 'var=group_names'
    node1 | SUCCESS => {"group_names": ["webs"]
    }
    
  • groups,列出清单中的所有组,以及组中含有的主机。

    [furongwang@controller web]$ ansible node1 -m debug -a 'var=groups'
    node1 | SUCCESS => {"groups": {"all": ["workstation","node1","node2","node3","node4"],"dbs": ["node3","node4"],"ungrouped": ["controller"],"webs": ["node1","node2"]}
    }
    
  • hostvars,包含所有受管主机的变量,可用于获取另一台受管主机的变量的值。如果还没有为受管主机收集FACTS,则它不会包含该主机的 FACTS。

    例如:hostvars.controller.group_names

    # 查询所有主机变量信息
    [furongwang@controller web]$ ansible node1 -m debug -a var=hostvars# 查询特定主机(node2)变量信息
    [furongwang@controller web]$ ansible node1 -m debug -a var=hostvars.node2.group_names
    node1 | SUCCESS => {"hostvars.node2.group_names": ["nodes", "webs"]
    }
    # 查询node2 group名
    

管理 SECRETS

Ansible Vault 简介

Ansible可能需要访问密码或API密钥等敏感数据,此信息可能以纯文本形式存储在清单变量或其他Ansible文件中。任何有权访问Ansible文件的用户或存储这些Ansible文件的版本控制系统都能够访问此敏感数据。

这显然存在安全风险。Ansible随附的 Ansible Vault 可以加密任何由Ansible使用的结构化数据文件,包括清单变量、playbook中含有的变量文件、在执行playbook时作为参数传递的变量文件,以及Ansible角色中定义的变量。

ansible-vault 命令
[furongwang@controller web]$ ansible-vault -h
usage: ansible-vault [-h] [--version] [-v]{create,decrypt,edit,view,encrypt,encrypt_string,rekey} ...encryption/decryption utility for Ansible data filespositional arguments:{create,decrypt,edit,view,encrypt,encrypt_string,rekey}create              Create new vault encrypted filedecrypt             Decrypt vault encrypted fileedit                Edit vault encrypted fileview                View vault encrypted fileencrypt             Encrypt YAML fileencrypt_string      Encrypt a stringrekey               Re-key a vault encrypted fileoptions:--version             show program's version number, config file location, configuredmodule search path, module location, executable location and exit-h, --help            show this help message and exit-v, --verbose         Causes Ansible to print more debug messages. Adding multiple -v willincrease the verbosity, the builtin plugins currently evaluate up to-vvvvvv. A reasonable level to start is -vvv, connection debuggingmight require -vvvv. This argument may be specified multiple times.See 'ansible-vault <command> --help' for more information on a specific command.

ansible-vault create和edit命令使用默认编辑器vi打开文件。您可以设置和导出EDITOR环境变量指定其他默认编辑器。

例如,若要将默认编辑器设为vim, 可设置为export EDITOR=vim

[furongwang@controller web]$ export EDITOR=vim
# 或者添加到bash配置文件中
[furongwang@controller web]$ echo 'export EDITOR=vim' >> ~/.bashrc
[furongwang@controller web]$ source ~/.bashrc# 创建加密文件,内容是yaml格式,例如 password: 123
[furongwang@controller web]$ ansible-vault create secret.yml
New Vault password: `123`
Confirm New Vault password: `123`
password: 123[furongwang@controller web]$ cat secret.yml 
$ANSIBLE_VAULT;1.1;AES256
35346165313633633862323064376139623339643639373164306339393231653637363933353339
3337386665303463633834643061643436613839316538640a356330613330313534336135616537
35363037636633633061336363326362306234376236616539613964353831303763623939353433
3334363938613131370a623166373737343737393730343863323433336366383432373036303262
63303438393936303133336635313463633863383037643039353664313432653631# 查看加密文件
[furongwang@controller web]$ ansible-vault view secret.yml
Vault password: `123`
password: 123# 使用 --vault-password-file 选项从文件中读取加密和解密密码
[furongwang@controller web]$ echo 123 > pass
[furongwang@controller web]$ ansible-vault view secret.yml --vault-password-file=pass
password: 123# 还可以在ansible.cfg的defaults中设置vault_password_file
[furongwang@controller web]$ vim ansible.cfg 
vault_password_file = ./pass# 编辑加密文件
[furongwang@controller web]$ ansible-vault edit secret.yml --vault-password-file=pass
password: 123# 解密文件
[furongwang@controller web]$ ansible-vault decrypt secret.yml --vault-password-file=pass
Decryption successful
[furongwang@controller web]$ cat secret.yml 
password: 123# 加密文件
[furongwang@controller web]$ ansible-vault encrypt secret.yml --vault-password-file=pass
Encryption successful# 更改加密文件密码
[furongwang@controller web]$ ansible-vault rekey secret.yml --vault-password-file=pass
New Vault password: `123`
Confirm New Vault password: `123`
Rekey successful# 还可以使用选项 --new-vault-password-file 指定新密码所在文件位置
[furongwang@controller web]$ ansible-vault rekey secret.yml --vault-password-file=pass --new-vault-password-file=pass-new
Rekey successful
综合案例

playbook.yml 内容如下:

---
- name: config mariadb serverhosts: node1vars_files:- vault/mysql.ymltasks:- name: install mariadb-serveryum:name: - mariadb-server- python3-PyMySQLstate: present- name: enable and start mariadbservice:name: mariadbenabled: yesstate: started- name: config user {{ user }}mysql_user:name: "{{ user }}"password: "{{ password }}"host: "{{ host }}"priv: "{{ priv }}"state: present
[furongwang@controller web]$ mkdir vault
[furongwang@controller web]$ ansible-vault create vault/mysql.yml
user: furongwang
password: 123
host: '%'
priv: '*.*:ALL'# 如果 ansible.cfg 中未配置vault_password_file
# 可使用--ask-vault-pass选项以交互方式提供vault密码
[furongwang@controller web]$ ansible-playbook playbook.yml --ask-vault-pass

验证:

# 防火墙未放行,从本地验证
[root@node1 ~]# mysql -u furongwang -p123
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 9
Server version: 10.3.11-MariaDB MariaDB ServerCopyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.MariaDB [(none)]> 
http://www.lryc.cn/news/619368.html

相关文章:

  • Windows11 运行IsaacSim GPU Vulkan崩溃
  • ADB 无线调试连接(Windows + WSL 环境)
  • 药房智能盘库系统:基于CV与时间序列预测的库存革命
  • vue3 el-select el-button 在同一行显示
  • Vue:实现一个无线滚动列表的解决方案
  • 【密码学实战】国密SM2算法介绍及加解密/签名代码实现示例
  • 2021 年全国硕士研究生招生考试真题笔记
  • 若依前后端分离版学习笔记(九)——登录和操作日志
  • Android中获取状态栏高度
  • 算法题打卡力扣第11题:盛最多水的容器(mid)
  • [AI React Web]`意图识别`引擎 | `上下文选择算法` | `url内容抓取` | 截图捕获
  • 【递归、搜索与回溯算法】穷举、暴搜、深搜、回溯、剪枝
  • BGE:智源研究院的通用嵌入模型家族——从文本到多模态的语义检索革命
  • 海洋通信系统技术文档(1)
  • 高可用实战之Nginx + Apache篇
  • QT常用类解析
  • ubuntu20.04下C++实现点云的多边形区域过滤(2种实现:1、pcl的CropHull滤波器;2、CUDA上实现射线法)
  • 在Ubuntu24.04中使用ssh连接本地git仓库到github远程仓库
  • C++QT HTTP与HTTPS的使用方式
  • 【网络安全测试】OWASP ZAP web安全测试工具使用指导及常用配置(有关必回)
  • Spring事务管理实战:从注解到进阶
  • Spring 源码学习(十)—— DispatcherServlet
  • 【一步AI】模型压缩:减小模型体积与计算量
  • YOLOv8 级联检测:在人脸 ROI 内检测眼镜(零改源码方案)
  • 第十六届蓝桥杯青少组C++省赛[2025.8.9]第二部分编程题(1 、庆典队列)
  • Excel怎么筛选重复项?【图文详解】查找/删除重复项?查找重复项公式?如何去重?
  • [QtADS]解析demo.pro
  • HarmonyOS NDK的JavaScript/TypeScript与C++交互机制
  • Electron自定义菜单栏及Mac最大化无效的问题解决
  • XML头部声明发送者信息的实现方法