shell变量:
定义: Host=oldxu.com
使用:${Host}
Ansible变量:
定义: Host=oldxu.com
使用:{{ Host }}
变量:以一个固定的字符串去表示一个不固定的值。
X=? 就是一个固定的字符串,但是?可以是任意的数。
使用了变量,只会在以后的操作着,简单便捷化。
ansible定义变量的三种方式?
1) 通过命令行进行变量定义
2) 在play文件中进行定义变量
3) 通过inventory在主机组或单个主机中设置变量
变量的优先级( 变量读取的顺序 )
1.play文件的定义变量
1.1》通过vars关键字进行定义变量
[root@manager ansible_variables]# cat var1.yml
-
hosts: webservers
vars: #定义变量关键字- web_packages: httpd
- ftp_packages: vsftpd
tasks:
- name: Installed Rpm Packages "{{ web_packages }}" "{{ ftp_packages }}"
yum:
name:
- "{{ web_packages }}"
- "{{ ftp_packages }}"
state: present
这样就可以执行成功,显示结果
但是:
cp var1.yml var2.yml
vim var2.yml 删除vars变量。
再次执行就会报错。说有未定义的变量
所以:
vars关键字定义的变量,无法与其他的playbook进行共享。只能自己单独用
1.2》 通过vars_files来进行定义变量
把所有想设置的变量都放在一个文件中。然后通过vars_files的方式去加载这个文件,就相当于加载了整个文件中的所有变量,然后使用哪个就提取哪个使用。
1.2.1》创建定义变量的存放文件。
[root@manager ansible_variables]# cat vars.yml
web_packages: httpd-tools
ftp_packages: vsftpd
注意:每一个变量都顶格写,然后一条一条写下去就行
1.2.2》将存放变量的文件,通过vars_files的方式加载
[root@manager ansible_variables]# cat var1.yml
- hosts: webservers
vars_files: vars.yml (加载这个文件)
[root@manager ansible_variables]# cat var2.yml
- hosts: webservers
vars_files: vars.yml (加载这个文件)
@@@@@@@@@@@@@@@@@@@@@@@@
通过inventory在主机组或单个主机中设置变量
注意:主机变量的优先级要高于主机组的变量
在ansible项目目录中创建两个变量的目录
host_vars 和 group_vars
[root@manager ansible_variables]# mkdir host_vars
[root@manager ansible_variables]# mkdir group_vars
[root@manager ansible_variables]# cat group_vars/webservers(在规定的项目目录下创建一文件,在文件中写入变量)
web_packages: wget
ftp_packages: tree
[root@manager ansible_variables]# cat var4.yml
- hosts: webservers (加载这个变量)
tasks:- name: Install Rpm Packages "{{ web_packages }}" "{{ ftp_packages }}"
但是如果想换成db组,那么webservers这个定义的文件就不能使用的。
所以,需要在规定的组目录下,创建一个all的文件,
all=特殊的文件(代表所有的主机)当没有定义变量或者不需要定义变量的时候,会自动去加载all文件里的变量。
[root@manager ansible_variables]# cat group_vars/all(创建这个all文件)
web_packages: nfs-utils
ftp_packages: rsync
[root@manager ansible_variables]# cat var5.yml
- hosts: db (没创建db这个组,但创建了all文件,就会自动加载这个文件的变量)
tasks:- name: Install Rpm Packages "{{ web_packages }}" "{{ ftp_packages }}"
注意: 当已经创建有对应的文件变量时,会优先选择对应创建的。
- name: Install Rpm Packages "{{ web_packages }}" "{{ ftp_packages }}"
@@@@@@@@@@@@@@@@@@@@@@@@
通过命令行进行变量定义
命令行--extra-vars或-e外置传参设置变量
[root@manager ansible_variables]# cat var6.yml
- hosts: webservers
tasks:- name: Install Rpm Packages "{{ test_packages }}"
yum:
name:
- "{{ test_packages }}"
state: present
- name: Install Rpm Packages "{{ test_packages }}"
[root@manager ansible_variables]# ansible-playbook var6.yml -e "test_packages=sl"
test_packages这个变量没有设置,那么执行就会报错,但是你通过外置的方式添加-e "test_packages=sl",在执行就不会报错了。
@@@@@@@@@@@@@@@@@@@@@@@@
总结:变量的查找顺序到底是怎么样的?
方法:设定同一个变量,不同的值,去测试,看谁优先被使用。
filename=
1)在plabook中定义vars变量
2)在playbook中定义vars_files变量
3)在host_vars中定义变量
4)在group_vars中定义变量
5)通过执行命令传递变量
变量的查找优先级:
1.外置传参 -e
2.playbook
vars_files (先去加载文件,文件里的变量)
vars (再去加载关键字)
3.host_vars
4.group_vars/组名
4.group_vars/all
变量注册:
将执行的结果存储至变量中,后期可以通过结果进行判断的操作。
[root@manager ansible_variables]# cat var9.yml
- hosts: webservers
tasks:-
name: Get Network Status
shell: netstat -lntp (命令模块,想查询什么)
register: System_Net (查询的结果,存在变量)将shell命令的执行输出结果,存储至System_Net变量中
name: Print Variables (打印变量)
debug:
msg: "{{ System_Net.stdout_lines }}"
-
{{ System_Net }} 能看到变量的所有信息
{{ System_Net.stderr }} #能捕获到错误,如果没有就是空,如果有错误就会限制在终端窗口
facts变量
ansible facts 用来自动采集,“被控端主机”自身的状态信息。比如:主机名,ip地址,系统版本,cpu数量,内存状态,磁盘状态
在编写前,先采集主机的状态指标(setup)
[root@manager ansible_variables]# ansible localhost -m setup
(其实就是一个字典)
基础验证:
[root@manager ansible_variables]# cat var10.yml
- hosts: webservers
tasks:- name: Output variables ansible facts (输出变量可转变)
debug:(模块)
msg: >(输出一段话)
this default IPv4 address "{{ ansible_fqdn }}" is "{{ ansible_default_ipv4.address }}"
(ipv4默认地址,第一个变量是主机名,第二个变量对应的ip地址)
- name: Output variables ansible facts (输出变量可转变)
每一次的运行,都会先去加载facts,就会影响服务的反应,可是把facts变量关闭,就会出现找不到变量的报错。
- hosts: webservers
gather_facts: no (关闭信息采集)
tasks:
实战教案:
一:根据不同的ip地址生成不同的redis配置
最Redis配置,一般都是在bind这将ip地址写死。但是这次想要答案的结果是:
映射到: web01 bind 172.16.1.7
web02 bind 172.16.1.8
与之前写死唯一的不同之处就在于,我们在redis.conf的这个配置文件中,将bind 的ip地址写成了一个变量
bind 127.0.0.1 {{ ansible_eth1.ipv4.address }}
然后在Redis的playbook中,将hosts的db组改成webservers组 ,并且将copy模块名改成 template模块。
对变量的查找:
[root@manager ansible_variables]# ansible localhost -m setup > ~/1.txt
(将加载出来的所有内容,放在一个文件,然后进行vim搜索获取)
二:根据cpu核心生成不同的nginx配置。
前期准备:
web01 1核心 1GB
web02 2核心 2GB
操作:去配置nginx的配置文件
结果:拷贝谁,就能得谁的CPU值
[root@manager ansible_variables]# cat nginx.yml
- hosts: webservers
tasks:- name: Configure Nginx.conf
template:
src: ./nginx.conf.j2
dest: /tmp/nginx.conf
- name: Configure Nginx.conf
[root@manager ansible_variables]# cat nginx.conf.j2
worker {{ ansible_processor_vcpus * 2 }};
cpu核心数是vcpu,并且还可以直接乘2
三:根据主机内存生成不同Memcache配置
[root@manager ansible_variables]# cat /etc/sysconfig/memcached
PORT="11211" (端口)
USER="memcached" (进程的用户)
MAXCONN="1024" (最大连接数)
CACHESIZE="64" (缓存大小)
OPTIONS=""
一般情况,缓存会占到物理机内存的一半。
web01 1G 512
web02 2G 1024
方法:找到物理内存的变量,然后除以2
[root@manager ansible_variables]# cp /etc/sysconfig/memcached ./memcached.j2 (拷贝配置文件)
将CACHESIZE="64" 改成变量
CACHESIZE="{{ ansible_memtotal_mb //2 }}" (除以2,用双斜线)
然后写playbook。运行查看内存就可以了。
抒写playbook:
[root@manager ansible_variables]# cat memcached.yml
-
hosts: webservers
tasks:name: Installed Memcached Server
yum:
name: memcached
state: presentname: Configure Memcached Server
template:
src: memcached.j2
dest: /etc/sysconfig/memcached
notify: Restart Memcached Servername: Started Memcached Server
systemd:
name: memcached
state: started
enabled: yes
handlers:
- name: Restart Memcached Server
systemd:
name: memcached
state: restarted
四:据不同的主机名称生成不同的zabbix配置
其实就是去添加主机名称的变量,然后当你在运行其他的一个,就会得到那一个的主机名称。
Hostname={{ ansible_hostname }}
主机名变量
facts优化:
facts变量的开启会影响playbook运行的效率,关闭又会造成无法提取被控制端的状态,那么最佳的方案就是《使用缓存》。
1.安装一个redis 172.16.1.51 安装过了,就不要需要安装,直接使用就行了。
2.配置ansible配置文件,让其支持redis缓存:
[root@manager ansible_variables]# cat ansible.cfg
[defaults]
inventory = ./hosts
gathering = smart
fact_caching_timeout = 86400
fact_caching = redis
fact_caching_connection = 172.16.1.7:6379
配置文件只能卸载这个项目里。
yum install python-pip
pip install redis
还需要安装pip