ansible常用的定义变量方式和变量注册facts缓存和template的使用
回顾
可以使用自定义主机组的方式定义hosts,这样可以减少重复任务的代码(不推荐使用,因为自定义主机组的话,剧本中的all将无法使用) ansible和saltstack都要使用yml语法,yml语法中最好使用2468空格 service和systemd启动服务,不支持列表的形式(只能用循环了) [ ~]# hostname m01 [ ~]# hostname -I 10.0.0.61 172.16.1.61 [ ~]# hostnamectl set-hostname www.m01.com [ ~]# #显示不完整主机名 "{{ ansible_fqdn }}" 无论是自定义变量还是系统变量的调用,写到剧本中的路径里的话不要加引号,单独的调用需要加引号
变量自定义
1.通过命令行进行变量定义
2.在play文件中进行变量定义
3.通过Inventory主机信息文件中进行变量定义
变量优先级:命令行 > playbook文件 > Inventory文件
playbook中vars定义变量
playbook变量可以通过多种方式进行定义,最简单的方式就是在playbook的开头通过vars进行定义。(以列表或者ad-hoc的方式定义变量)
#方法一: - hosts: web_group vars: packages: - httpd - mariadb-server - php - php-mysql - php-pdo tasks: - name: Install httpd mariadb php Server yum: name: "{{ packages }}" #方法二:(#name不支持列表!!!) - hosts: web_group vars: - web_server: httpd - db_server: mariadb-server - php_server: - php - php-mysql - php-pdo tasks: - name: Install httpd mariadb php Server yum: name: - "{{ web_server }}" - "{{ db_server }}" - "{{ php_server }}" # "{{ php_server }}" ,ansible中里面空格加不加都行,saltstack里面必须加空格,但是引号必须要加 #变量列表只能在支持列表的模块中使用 #file模块不能使用变量列表 [ ~]# vim ansible/cs.yml - hosts: web01 vars: dir: a tasks: - name: create dir file: path: /root/{{ dir }} state: directory
使用vars_file定义变量
刚才我们学到在playbook中使用vars
定义变量,有一个缺陷,就是其他的play无法使用该变量。所以我们可以采取第二种定义变量的方式,在vars_file
中定义变量。
#定义阶段 [ ~]# vim /vars/vars1.yml web_server: httpd [ ~]# vim /vars/vars2.yml db_server: mariadb-server #或者以列表形式定义 web_server: - tree - unzip #调用阶段 - hosts: web_group vars_files: /root/vars1.yml tasks: - name: Install httpd mariadb php Server yum: name: "{{ web_server }}" #调用阶段(name尽量不要使用列表项) - hosts: web_group vars_file: - /root/vars1.yml - /root/vars2.yml tasks: - name: Install httpd mariadb php Server yum: name: - "{{ web_server }}" - "{{ db_server }}" #获取Ansible内置变量(内外变量结合) - hosts: web_group vars: - remote_ip: "{{ ansible_default_ipv4[‘address‘] }}" - remote_hostname: "{{ ansible_fqdn }}" tasks: - name: Touch IP File file: path: /root/{{ remote_ip }} state: touch - name: Touch Hostname File file: path: /root/{{ remote_hostname }} state: touch
在Inventory中定义变量
注意:在Inventory中定义变量,主机的变量要高于主机组的变量,所以该方法不推荐使用,容易将环境弄乱。(主机变量在动作中调用,主机组变量在hosts中调用)
#定义阶段 [ ~]# vim /etc/ansible/hosts [web_group] web01 ansible_ssh_host=10.0.0.7 web02 ansible_ssh_host=10.0.0.8 #主机的定义变量 [web_group:vars] web_server=httpd index_file=index.html #主机组的定义变量 [rsync_server:children] web_group backup_group #调用阶段 - hosts: web_group tasks: - name: Install httpd Server yum: name: "{{ web_server }}" - name: Create Index File file: path: /tmp/{{ index_file }} state: touch
官方推荐变量定义
之前的几种变量定义都不是很好用,比较好用的是在Ansible项目目录下创建两个变量目录:
host_vars
:优先级高,目录名和目录位置是固定的(项目目录下)group_vars
:优先级低
切记,目录名字一定要一致,不能做任何修改。
执行的yml文件在哪,哪就是该yml文件的项目目录
1.主机组定义变量,对某组来说可以调用
#定义阶段 [ ~]# mkdir group_vars #切记定义变量所在的文件必须以组名为文件名(组名是主机组变量调用的令牌),包含主机变量 #组名必须是主机清单中的标签名 [ ~]# vim /root/group_vars/web_group web_server: httpd (#名值对) #调用阶段 - hosts: web_group tasks: - name: Install httpd Server yum: name: "{{ web_server }}"
如果我想要所有组都能使用变量,该如何做?
2.主机定义变量,对某主机来说,可以调用
#定义阶段 [ ~]# mkdir host_vars #切记定义变量的文件必须以主机名为文件名 [ ~]# vim /root/host_vars/web01 web_server: nginx #调用阶段 - hosts: web01 tasks: - name: Install httpd Server yum: name: "{{ web_server }}"
命令行定义变量(优先级最高)
通过命令行覆盖变量,Inventory的变量会被playbook文件中覆盖,这两种方式的变量都会被命令行直接指定变量所覆盖,使用--extra-vars
或者-e
设置变量
#调用 [ ~]# vim test.yml - hosts: web_group tasks: - name: Install httpd Server yum: name: "{{ web_server }}" #定义阶段 [ ~]# ansible-playbook test.yml -e "web_server=vsftpd" [ ~]# vim test.yml - hosts: web_group tasks: - name: Install httpd Server yum: name: - "{{ web_server }}" - "{{ db_server }}" #定义阶段 [ ~]# ansible-playbook test.yml -e "web_server=vsftpd" -e "db_server=mariadb-server"
变量优先级测试
[ ~]# vim touch_file.yml - hosts: web_group vars: filename: vars #2 vars_files: - ./vars1.yml #1 tasks: - name: Touch vars File file: path: /root/{{ filename }} #不能带引号 state: directory #定义vars_files [ ~]# vim vars1.yml filename: vars_files #定义group_vars中的web_group #3 [ ~]# vim group_vars/web_group filename: group_vars_web_group #定义host_vars中的web01 [ ~]# vim host_vars/web01 #4 filename: host_vars #定义group_vars中的all [ ~]# vim group_vars/all filename: group_vars_all #测试命令行 [ ~]# ansible-playbook touch_file.yml -e "filename=vars_command" #测试所有(依次删除剧本中同一变量的指定) [ ~]# ansible-playbook touch_file.yml
变量注册
为什么要学变量注册?
当absible
的模块在运行之后,其实都会返回一些result
结果,就像是执行脚本,我们有的时候需要脚本给我们一些return
返回值,我们才知道,上一步是否可以执行成功,
但是...默认情况下,ansible
的result
并不会显示出来,所以,我们可以把这些返回值存储到变量中,这样我们就能通过调用对应的变量名,从而获取到这些result
,
这种将模块的返回值,写入到变量中的方法被称为变量注册
那么咋样将返回值注册到变量,如下一个playbook
示例:
#编辑剧本 [ ~]# vim register.yml - hosts: web_group tasks: - name: Test Register Vars shell: "ls -l /" #查看执行结果 [ ~]# ansible-playbook register.yml
如上执行结果可见,当我们使用shell模块执行ls -l /
时,ansible给我们返回的只有changed我们无法看到执行之后的结果,所以此时我们需要使用到变量注册
playbook如下:
register:注册
#编辑playbook [ ~]# vim register.yml - hosts: web_group tasks: - name: Test Register Vars shell: "ls -l /" register: list_dir #注册变量 - name: Return Result debug: var=result verbosity=0 #调试输出的结果 msg: "{{ list_dir }}" #输出 # debug 调试模块,用于在调试中输出信息 常用参数: msg:调试输出的消息 var:将某个任务执行的输出作为变量传递给debug模块,debug会直接将其打印输出 verbosity:debug的级别(默认是0级,全部显示) #查看执行结果 [ ~]# ansible-playbook register.yml #只输出自己想要的内容 [ ~]# vim register.yml - hosts: web_group tasks: - name: Test Register Vars shell: "ls -l /" register: list_dir - name: Return Result debug: msg: "{{ list_dir.stdout_lines }}" #msg: "{{ list_dir[‘stdout_lines‘] }}" #查看结果 [ ~]# ansible-playbook register.yml #debug模块常用参数 msg: #调试输出的消息 var: #将某个任务执行的输出作为变量传递给debug模块,debug会直接将其打印输出 verbosity: #debug的级别(默认是0级,全部显示) debug #偶尔调试
变量注册,忽略错误的使用
[ ~]# vim cs.yml - hosts: web01 tasks: - name: Test Register Vars shell: "ls -l /etc/nginx" #注册变量 register: list_dir #忽略错误 ignore_errors: yes #输出shell指定的信息 - name: return debug: msg: "{{ list_dir.stdout_lines }}" #解压 - name: jieya nginx.pkg unarchive: src: /root/nginx_php.tar.gz dest: /root when: list_dir.rc != 0 #通过变量的注册,判断shell的执行结果(rc) #卸载 - name: shanchu shell: yum remove -y php-common #忽略错误 ignore_errors: yes #安装 - name: install shell: "cd /root && yum localinstall -y *rpm" ignore_errors的作用就是忽略错误步骤,继续执行下一步(错误输出还是会输出)
层级定义变量
像是自己做字典,使用 [‘ ‘] 或者 . 调用下一级
#编辑变量文件 [ ~]# vim vars_file.yml lamp: framework: web_package: httpd db_package: mariadb-server php_package: php lnmp: framework: web_package: nginx db_package: mysql php_package: php lnmt: framework: web_package: nginx db_package: mysql java_package: tomcat #编辑playbook文件 [ ~]# vim test.yml - hosts: web_group vars_files: ./vars_file.yml tasks: - name: Install LAMP httpd yum: name: "{{ lamp.framework.web_package }}" - name: Install LAMP mariadb-server yum: name: "{{ lamp.framework.db_package }}" - name: Install LAMP php yum: name: "{{ lamp.framework.php_package }}" #官方推荐写法 [ ~]# vim test.yml - hosts: web_group vars_files: ./vars_file.yml tasks: - name: Install LAMP httpd yum: name: "{{ lamp[‘framework‘][‘web_package‘] }}" - name: Install LAMP mariadb-server yum: name: "{{ lamp[‘framework‘][‘db_package‘] }}" - name: Install LAMP php yum: name: "{{ lamp[‘framework‘][‘php_package‘] }}" #执行playbook [ ~]# ansible-playbook test.yml #层级调用变量也只能调用一次
ansible内置变量----facts缓存
Ansible facts是在被管理主机上通过Ansible自动采集发现的变量。facts
包含每台特定的主机信息。比如:被控端的主机名、IP地址、系统版本、CPU数量、内存状态、磁盘状态等等。
facts使用场景
1.通过facts
缓存检查CPU,来生成对应的nginx配置文件
2.通过facts
缓存检查主机名,生成不同的zabbix配置文件
3.通过facts
缓存检索物理机的内存大小来生成不通的mysql配置文件
综上所述的Ansible facts类似于saltstack
中的grains
对于做自动化的小伙伴是非常有用滴。
facts基本用法
#编辑 [ ~]# vim facts.yml - hosts: web_group tasks: - name: Get Host Info debug: msg: > Hostname "{{ ansible_fqdn }}" and IP "{{ ansible_default_ipv4.address }}" #执行 [ ~]# ansible-playbook facts.yml #msg: > 可以识别中文,打印出变量
关闭facts
[ ~]# vim facts.yml - hosts: web_group gather_facts: no #关闭信息采集 tasks: #一般在用不到变量的剧本中才会使用,提高生产效率
template的使用
facts生成zabbix配置文件,生成nginx的配置文件,生成saltstack配置文件
- hosts: web_group tasks: - name: copy zabbix agent conf template: src: ./zabbix_agentd.conf dest: /tmp/zabbix_agentd.conf #template模块,可以将剧本中的主机信息被 脚本中的变量调用 ,语法和copy类似 #该模块适用于做配置文件的修改
facts生成mysql配置文件
- hosts: db_group tasks: - name: Install mysql server yum: name: mariadb-server state: present - name: copy mysql conf template: src: ./my.cnf dest: /etc/my.cnf [ ~]# vim /etc/my.cnf [mysqld] basedir=/usr datadir=/var/lib/mysql/ socket=/var/lib/mysql/mysql.sock log_error=/var/log/mariadb/mariadb.log innodb_buffer_pool_size={{ ansible_memtotal_mb * 0.8 }} #ansible变量支持计算
需求:使用ansible在web机器创建“/backup/web01_172.16.1.31_2020-6-11”目录
#剧本中支持显示子信息 [ ~]# vim bl.yml - hosts: web01 tasks: - name: ip file: path: /backup/{{ ansible_fqdn }}_{{ ansible_default_ipv4[‘address‘] }}_{{ ansible_date_time[‘date‘] }} state: directory recurse: yes
[ ~]# ansible web01 -m setup -a ‘filter=ansible_default_ipv4‘ web01 | SUCCESS => { "ansible_facts": { "ansible_default_ipv4": { "address": "10.0.0.7", "alias": "eth0", "broadcast": "10.0.0.255", "gateway": "10.0.0.2", "interface": "eth0", "macaddress": "00:0c:29:6e:25:1b", "mtu": 1500, "netmask": "255.255.255.0", "network": "10.0.0.0", "type": "ether" }, "discovered_interpreter_python": "/usr/bin/python" }, "changed": false } #命令行不支持显示子信息 [ ~]# ansible web01 -m setup -a ‘filter=ansible_default_ipv4.address‘ web01 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false }