文章目录
一、ansible变量简介
- 为什么要设定变量:将 playbook 中的某些值使用变量代替,从而简化 playbook 的编写
- 变量包含的值:要创建的用户、要安装的软件包、要重启的服务、要删除的文件、要从互联网检索的文档
- 命令变量的格式:变量名称必须以字母开头,并且只能含有字母、数字和下划线
示例:web_server、remote_file、file1 - 定义变量的三个范围级别:
(1)全局范围:从命令行或 ansible 配置设置的变量
(2)play 范围:在 play 和相关结构中设置的变量
(3)主机范围:由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量
注意:如果多个级别上定义了相同名称的变量,优先采用级别最高的变量,窄范围优先于广范围
二、playbook中的变量
1. 定义变量
- 常见方式:在playbook开头的vars块中:
- host: all
vars: #使用vars块
user: student #定义变量user为student
home: /home/student #定义变量user家目录为/home/student
- 在外部文件定义playbook变量:
(1)编写变量文件users.yml:注意此文件和playbook1最好在同一目录
(2)在playbook中指定变量文件:
2. 使用变量
将变量名称放在花括号内即可:
注意:当变量用作开始一个值的第一元素时,必须使用引号
---
- hosts: all
vars:
user: jia #定义变量名称用户user为jia
tasks:
- name: Create user {{ user }} #变量名称为user放在了{{}}内
user:
name: "{{ user }}" #注意:当变量用作开始一个值的第一元素时,必须使用引号
3. 变量分类:主机变量和组变量
直接应用于主机的清单变量分为两大类:
(1)主机变量:应用于特定主机
(2)组变量:应用于一个主机组或一组主机组中的所有主机
主机变量优先于组变量,但是 playbook 中定义的变量比这两者更高。
3.1 定义主机变量和组变量
方式一:比较旧,不建议采用
缺点:这种做法使的清单文件难以处理,在同一文件中混合提供主机和变量信息,语法也过时
#定义 server1.example.com 的 ansible_user 主机变量:
[webservers]
server1.example.com ansible_user=student
#定义 dbservers 主机组的 user 组变量:
[dbserver]
dbserver1.example.com
dbserver2.example.com
[dbservers:vars]
user=student
#定义嵌套组 user 变量:
[servers1]
node1.example.com
node2.example.com
[servers2]
node3.example.com
node4.example.com
[servers:children]
servers1
servers2
[servers:vars]
user=student
方法二:使用目录填充主机和组变量
定义主机和主机组变量的首选做法是:在与清单文件或目录相同的工作目录中
(1)创建 group_vars和 host_vars 两个目录,这两个目录分别包含用于定义组变量和主机变量的文件
(2)创建 group_vars/servers 的 YAML 文件,设置变量为值:user: student
(3)在 host_vars 目录中创建名称与主机匹配的文件来存放主机变量
所以一个项目目录中包含:ansible.cfg、group_vars、host_vars、inventory、playbook.yml
方法三:使用数组定作为变量
users:
lilei:
first_name: lei
last_name: li
home_dir: /home/lilei
hanmeimei:
first_name: meimei
last_name: han
home_dir: /home/hanmeimei
调用方式:
(1)例如:users.lilei.first_name;users.hanmeimei.home_dir
(2)变量被定义为 python 字典,可以使用替代语法。例如:users[‘lilei’][‘first_name’] ;users[‘hanmeimei’][‘home_dir’]
3.2 使用已注册变量捕获命令输出
管理员可以使用 register 语句捕获命令输出
---
- name: Install a Package
hosts: servera.lab.example.com
tasks:
- name: Install
yum:
name: httpd
state: installed
register: installed_result #将安装的结果注册变量
- debug:
var: installed_result #输出返回值
...
4. 管理变量的练习
创建 playbook,来安装 apache 并开启,使可被访问,playbook 查询 web 服务器并确认它已经设置好并在运行
编辑playbook.yml:
---
- name: Configure Apache #第一个剧本:设定Apache
hosts: servera.lab.example.com
vars: #使用vars模块
web_pkg: httpd #指定要安装的web服务器软件包
firewall_pkg: firewalld #指定要安装的防火墙软件包
web_service: httpd #指定要管理的web服务
firewall_service: firewalld #指定要管理的防火墙服务
python_pkg: python3-PyMySQL #指定uri模块所需软件包
rule: http #指定要在火墙中添加的服务
tasks:
- name: Install Packages #确保安装软件包且是最新的
yum:
name:
- "{{ web_pkg }}"
- "{{ firewall_pkg }}"
- "{{ python_pkg }}"
state: latest
- name: The {{ web_pkg }} started and enabled #确保 firewalld 和 apache 开机启动
service:
name: "{{ web_pkg }}"
enabled: true
state: started
- name: The {{ firewall_pkg }} started and enabled
service:
name: "{{ firewall_pkg }}"
enabled: true
state: started
- name: Configure index.html #配置默认发布页面
copy:
content: "Hello Apache!"
dest: /var/www/html/index.html
- name: Firewalld permits httpd #使防火墙允许 http
firewalld:
service: "{{ rule }}"
permanent: true
immediate: true
state: enabled
- name: Verity the Apache #第二个剧本:验证 apache 服务
hosts: localhost
become: false #在本机测试,不必更改身份
tasks:
- name: Curl servera
uri:
url: http://servera.lab.example.com
return_content: yes
status_code: 200
...
5. 使用魔法变量
常见的四个魔法变量:
hostvars :包含受管主机的变量,可以用于获取另一台受管主机的变量的值
group_names:列出当前受管主机所属的所有组
groups :列出清单中的所有组和主机
inventory_hostname :包含清单中配置的当前受管主机的主机名称
用途之一:使用 debug 模块报告特定主机的 hostvars 的值:ansible localhost -m debug -a ‘var=hostvars[“servera.lab.example.com”]’
三、管理机密
- 目标:使用 ansible vault 加密敏感变量,并运行 vault 加密变量文件的playbook
- ansible 可能需要访问密码或者 api 密钥等敏感数据,以便配置主机。
- 加密解密工具:ansible-vault 命令。ansible vault 不实施自有的加密函数,而使用外部 python 工具集
1. 加密文件
命令:ansible-vault create filename
(1)新建加密文件:ansible-vault create secret.yml
(2)创建加密文件同时将密码保存到密码文件
注意:密码文件中必须先写入密码
命令:ansible-vault create –vault-password-file=passwd secret1.yml
(3)加密现有的文件:
原理:将文件解密为一个临时文件,并编辑;保存时,复制内容并删除临时文件
命令:ansible-vault encrypt filename filename 参数可以是多个
注意:可以使用 –output=filename 将加密文件保存为新的名称,使用此参数时输入文件只能是一个
2. 查看加密文件
查看文件命令:ansible-vault view filename
编辑文件命令:ansible-vault edit filename
edit 命令始终重写文件,因此只有在更改文件时使用,查看尽量使用 view
3. 解密文件
(1)解密文件:ansible-vault decrypt filename
(2)解密文件的同时重新改名解密文件:ansible-vault decrypt webserver.yml --output=web.yml
4. 更改加密文件密码
命令:ansible-vault rekey filename
注意:可以一次更新多个文件密码
5. 运行加密的playbook
(1)交互式提供密码:ansible-playbook --vault-id @prompt user.yml
(2)在加密文件后,将秘密存在文件中,添加参数运行playbook:ansible-playbook --vault-password-file=password user.yml
注意使用文件系统权限对文件进行保护
四、管理事实
事实包括:主机名称、内核版本、网络接口、IP 地址等
1. 描述ansible事实
(1)编写playbook查看主机信息:
---
- name: Fact
hosts: all
tasks:
- name: Print all facts
debug:
var: ansible_facts #系统变量名 可以直接使用
...
(2)再将事实替换为动态的值:
---
- name: Fact
hosts: all
tasks:
- name: Print all facts
debug:
var: ansible_facts
- hosts: all
tasks:
- name: Print ansible facts
debug:
msg: #打印信息
The IPv4 address of {{ ansible_facts.fqdn }} is {{ ansible_facts.all_ipv4_addresses }}
#使用字典的方式查询值 ansible_facts.fqdn表示域名
...
2. ansible 事实作为变量注入
(1)使用 setup 模块显示所有事实信息:ansible servera.lab.example.com -m setup
(2)关闭事实收集,提升执行速度:
---
- name: Configure User
hosts: servera.lab.example.com
gather_facts: no #关闭事实收集
tasks:
- name: Student User
user:
name: student
uid: 1000
state: present
...
3. 创建自定义事实
创建自定义事实可以使用 INI 格式或者 JSON 格式。自定义格式不能使用 ymal 格式,使用最为接近的 json 最好
#INI 格式
[packages]
web_package = httpd
db_package = mariadb-server
[users]
user1 = westos
user2 = redhat
#JSON 格式
{
"packages": {
"web_package": "httpd",
"db_package": "mariadb-server"
},
"users": {
"user1": "Linux",
"user2": "redhat"
}
}
注意:创建自定义事实时,最好在目录 /etc/ansible/facts.d下创建,并且事实必须以.fact结尾。
示例:
五、总结
- 变量能够让 playbook 复用
- 可以给清单中的主机和主机组定义变量
- 可以使用事实和外部文件定义变量,也可以在命令行中
- register 关键字何以用于捕获命令输出
- ansible vault
- ansible 事实是从受管主机自动检测到的变量