1. 管理变量
将playbook中的某些值使用变量代替,从而简化playbook的编写
总结:
- 1.变量能够让playbook复用
- 2.可以给清单中的主机和主机组定义变量
- 3.可以使用事实和外部文件定义变量,也可以在命令行中
- 4.register关键字何以用于捕获命令输出
- 5.ansiblevault
- 6.ansible事实是从受管主机自动检测到的变量
1.1 ansible变量简介
-
变量可能包含下面这些值: 要创建的用户、要安装的软件包、 要重启的服务、 要删除的文件、 要从互联网检索的文档 。
-
命名变量: 变量名称必须以字母开头,并且只能含有字母、数字和下划线
示例: web_server 、 remote_file 、 file1 -
定义变量的三个范围级别:
全局范围: 从命令行或ansible配置设置的变量
play范围: 在play和相关结构中设置的变量
主机范围: 由清单、事实收集或注册的任务,在主机组和个别主机上设置的变量
如果多个级别上定义了相同名称的变量,优先采用级别最高的变量,窄范围优先于广范围
1.2 在playbook中定义变量
1.2.1 在playbook开头的vars块中定义变量
较常见
1.2.2 在外部文件定义playbook变量
1.3 在playbook中使用变量
---
- name: testvar
hosts: all
vars:
user: leo
tasks:
- name: Create user {
{
user }}
user:
name: "{
{ user }}"
注意:
1.将变量名称放在花括号内即可
2.当变量用作开始一个值的第一元素时,必须使用引号
1.4 变量的分类
直接应用于主机的清单变量分为两大类:
1.主机变量:应用于特定主机
2.组变量:应用于一个主机组或一组主机组中的所有主机主机变量优先于组变量,但是playbook中定义的变量比这两者更高。(范围越小优先级越高)
1.4.1 定义主机变量和组变量
- Way1:比较旧,不建议采用
定义主机的变量:
定义主机组的变量:
定义嵌套组user变量:
这种做法使得清单文件难以处理,在同一文件中混合提供主机和变量信息,语法也过时,不建议使用。
- Way2:使用目录填充主机和组变量
定义主机和主机组变量的首选做法是:在与清单文件或目录相同的工作目录中
- 创建group_vars:包含组变量 和 host_vars:包含主机变量 两个目录
- 创建groups_vars/servers的yaml文件,设置变量值未key:value
- 在host_vars目录中创建名称与主机匹配的文件来存放主机变量
所以一个项目目录中包含: ansible.cfg、group_vars、host_vars、hosts、playbook.yml
从命令行覆盖变量 清单变量可以被playbook中设置的变量覆盖 两者又可通过命令行参数覆盖
- Way3:使用数组作为变量
1.4.2 使用已注册变量捕获命令输出
管理员可以使用register语句捕获命令输出
---
- name: Install a package
hosts: server2
tasks:
- name: Install
yum:
name: httpd
state: installed
register: installed_result
- debug:
var: installed_result
1.5 管理变量的练习
创建playbook,来安装apache并开启,使可被访问,查询web服务器并确认它已经设置好并在运行
---
- name: Configure Apache
hosts: server2
vars:
web_pkg: httpd
firewall_pkg: firewalld
web_service: httpd
firewall_service: firewalld
python_pkg: python3-PyMySQL
rule: http
tasks:
- name: Install Packages
yum:
name:
- "{
{ web_pkg }}"
- "{
{ firewall_pkg }}"
- "{
{ python_pkg }}"
state: latest
- name: The {
{
web_pkg }} started and enabled
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 new u,nice boy !!!"
dest: /var/www/html/index.html
- name: Firewalld permits httpd
firewalld:
service: "{
{ rule }}"
permanent: true
immediate: true
state: enabled
- name: Verity the Apache
hosts: localhost
tasks:
- name: Curl server2
uri:
url: http://server2
return_content: yes
status_code: 200
2. 魔法变量
2.1 常用的魔法变量
魔法变量 | 解释 |
---|---|
hostvars | 包含受管主机的变量,可以用于获取另一台受管主机的变量的值 |
group_names | 列出当前受管主机所属的所有组 |
groups | 列出清单中的所有组和主机 |
inventory_hostname | 包含清单中配置的当前受管主机的主机名称 |
2.2 魔法变量的用途
使用debug模块报告特定主机的hostvars的值
ansible localhost -m debug-a 'var=hostvars["server2"]'
3. 管理事实
事实包括:主机名称、内核版本、网络借口、IP地址等
3.1 查看主机信息
-
Way1:使用setup模块显示所有事实信息
ansible server2 -m setup
-
Way2:ansible_facts系统变量名显示所有事实信息
3.2 再将事实替换为动态的值
---
- name: Fact dump
hosts: server2
tasks:
- name: Print IP and Domain Name
debug:
msg:
This IPV4 address of {
{
ansible_fqdn }} is {
{
ansible_all_ipv4_addresses }}
或者使用字典的方式查询:
3.3 关闭事实收集,提升执行速度
---
- name: Configure User
hosts: server2
gather_facts: no #关闭事实收集
tasks:
- name: devops User
user:
name: devops
uid: 1001
state: present
...
3.4 创建自定义事实
可以使用INI格式或者JSON格式,自定义格式不能使用ymal格式,使用最为接近的json最好
3.4.1 INI格式
[packages]
web_package=httpd
db_package=mariadb-server
[users]
user1=westos
user2=redhat
3.4.2 JSON格式
{
"packages":{
"web_package":"httpd",
"db_package":"mariadb-server"
},
"users": {
"user1":"linux",
"user2":"redhat"
}
}
3.4.3 自定义事实
mkdir /etc/ansible/facts.d
建议创建目录存放事实文件
vim custom.fact
事实文件以.fact结尾
ansible localhost -m setup
查看本机事实
自定义事实的使用方式和默认事实相同,使用变量提高playbook的复用性。
3.5 自定义事实练习
3.5.1 创建事实文件并安装httpd
-
创建自定义事实
-
将控制节点上的事实文件拷贝到受管主机指定位置
---
- name: Install facts
hosts: server3
vars:
remote_dir: /etc/ansible/facts.d
facts_file: user.fact
tasks:
- name: Create Directory
file:
state: directory
recurse: yes
path: "{
{ remote_dir }}"
- name: Install new facts
copy:
src: "{
{ facts_file }}"
dest: "{
{ remote_dir }}"
...
ansible server3 -m setup
查看受管主机事实
- 编写主playbook,安装新的事实
---
- name: Install and start Apache
hosts: server3
tasks:
- name: Install Apache
yum:
name: "{
{ ansible_facts['ansible_local']['user']['devops']['packages'] }}"
state: latest
- name: Start Apache
service:
name: "{
{ ansible_facts['ansible_local']['user']['devops']['service'] }}"
state: "{
{ ansible_facts['ansible_local']['user']['devops']['state'] }}"
enabled: "{
{ ansible_facts['ansible_local']['user']['devops']['enabled'] }}"
- 查看结果
ansible server3 -m command -a 'systemctl status httpd'
3.5.2 使用基本身份认证的httpd
---
- name: webserver Vars
hosts: webservers
become: yes
vars:
firewall_pkg: firewalld ###火墙的包
firewall_srv: firewalld ###火墙服务
web_pkg: httpd ##Apache的包
web_srv: httpd ##Apache的服务
ssl_pkg: mod_ssl ##Apache加密需要的插件
httpdconf_src: files/httpd.conf ##指定的httpd配置文件源
httpdconf_dest: /etc/httpd/conf/httpd.conf ##httpd配置文件存放目的地
secrets_dir: /etc/httpd/secrets ##加密目录
secrets_src: files/htpasswd ##用户加密文件
secrets_dest: "{
{ secrets_dir }}/htpasswd"
web_root: /var/www/html ##httpd默认发布页面目录
name: Install Packages
yum:
name:
- "{
{ firewall_pkg }}"
- "{
{ web_pkg }}"
- "{
{ ssl_pkg }}"
state: latest
- name: Configure service
copy:
src: "{
{ httpdconf_src }}"
dest: "{
{ httpdconf_dest }}"
owner: root
group: root
mode: 0644
- name: Creat secrets directory
file:
path: "{
{ secrets_dir }}"
state: directory
owner: apache
group: apache
mode: 0500
- name: Create htpasswd
copy:
src: "{
{ secrets_src }}"
dest: "{
{ secrets_dest }}"
owner: apache
group: apache
mode: 0400
- name: Create index.html
copy:
content: "{
{ ansible_facts['fqdn'] }} ({
{ ansible_facts['all_ipv4_addresses'] }})\n"
dest: "{
{ web_root }}/index.html"
- name: Configure furewalld service
service:
name: "{
{ firewall_srv }}"
state: started
enabled: true
- name: Firewalld permits https
firewalld:
service: https
state: enabled
immediate: true
permanent: true
- name: Configure Apache Servicr
service:
name: "{
{ web_srv }}"
state: started
enabled: true
- name: Test Apache
hosts: localhost
become: no
gather_facts: no
vars:
- web_user: admin
vars_files:
- vars/secret.yml
tasks:
- name: Connect Apache with Auth
uri:
url: https://serverc.rhel8.com
validate_certs: no
force_basic_auth: yes
user: "{
{ web_user }}"
passwd: "{
{ web_pass }}"
return_content: yes
status_code: 200
register: auth_test
- debug:
var: auth_test.content
测试:
就是在浏览器输入网址,进行用户认证后,查看页面内容!!