YAML是一个可读性高的用来表达资料序列的格式。YAML 官方网站:http://www.yaml.org
用于当关注的资源发生变化时,才会采取一定的操作。Notify可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作成为handler,也即notify中调用handler中定义的操作。
例如:方便直观看到变化,我们执行更新文件task(触发重启mysql服务的handler),然后执行关闭mysql服务task,最后观察重启的handler是否生效。
- - hosts: yzb
- remote_user: root
- tasks:
- - name: task1
- file: path=/opt/testfile
- state=touch
- notify: restart mysqld
- - name: task2
- systemd:
- name: mysqld
- state: stopped
- handlers:
- - name: restart mysqld
- systemd:
- name: mysqld
- state: restarted
可以看到此时mysql启动时间为18号17:15
我们使用ansible-playbook执行对应的playbook,可以看到连接成功,task对应颜色为黄色,表示执行成功且发生了变动。
此时我们回到被控制端,查看mysql状态,可以看到启动时间已经变为最近时间
由此我们可以得出结论,剧本是按照顺序执行的,但是handler仅在所有的变化发生完成后才会去一次性地执行指定操作。
handlers也可以触发多个
- - hosts: yzb
- remote_user: root
- tasks:
- - name: task1
- file: path=/opt/testfile
- state=touch
- notify:
- - restart mysqld
- - restart nginx
- - name: task2
- systemd:
- name: mysqld
- state: stopped
- handlers:
- - name: restart mysqld
- systemd:
- name: mysqld
- state: restarted
- - name: restart nginx
- systemd:
- name: nginx
- state: restarted
当然,也能实现立即执行对应handler,这要用到- meta: flush_handlers模块
通过指定标签来执行特定的动作
-t 指定执行某一标签对应的所有任务
--skip-tags 表示要跳过的指定的标签任务
- ---
- - hosts: websrvs
- remote_user: root
-
- tasks:
- - name: install httpd package
- yum: name=httpd
- tags: inshttpd
- - name: copy conf file
- copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
- notify: restart service
- - name: start service
- service: name=httpd state=started enabled=yes
- tags: rshttpd
-
- handlers:
- - name: restart service
- service: name=httpd state=restarted
[root@ansible145 ansible]# ansible-playbook -t rshttpd httpd.yml
- #执行多个tags
- [root@ansible145 ansible]# ansible-playbook -t inshttpd,rshttpd httpd.yml
ansible-playbook httpd.yml --skip-tags rshttpd
变量名:仅能由字母、数字和下划线组成,且只能以字母开头。
调用:通过“{{ variable_name }}”调用变量,且变量名前后建议加空格
- [root@120 ansible]# cat task-restart.yml
- - hosts: yzb
- remote_user: root
- tasks:
- - name: task1
- systemd:
- name: "{{ item }}"
- state: restarted
- loop:
- - mysqld
- - nfs
- [root@120 ansible]#
- 1.通过命令行指定变量,优先级最高
- ansible-playbook -e varname=value
-
- 2.在playbook文件中定义
- vars:
- - var1: value1
- - var2: value2
-
- 3.在独立的变量YAML文件中定义
- - hosts: all
- vars_files:
- - vars.yml
-
- 4.在 /etc/ansible/hosts 中定义
- 主机变量:主机组中主机单独定义,优先级高于组变量
- 组变量:针对主机组中所有主机定义统一变量
范例:
- vim var2.yml
- ---
- - hosts: websrvs
- remote_user: root
- tasks:
- - name: install package
- yum: name={{ pkname }} state=present
-
- ansible-playbook –e pkname=httpd var2.yml
范例:
- [root@120 ansible]# cat mysql-variables.yml
- - hosts: yzb
- remote_user: root
- vars:
- - service: mysqld
- tasks:
- - name: task1
- file: path=/opt/testfile
- state=touch
- notify: restart mysqld
- - name: task2
- systemd:
- name: "{{ service }}"
- state: stopped
- handlers:
- - name: restart mysqld
- systemd:
- name: "{{ service }}"
- state: restarted
-
- [root@120 ansible]# ansible-playbook mysql-variables.yml
可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的变量,比playbook中定义的变量优化级高
范例:
- [root@120 ansible]# cat mysql-variables-2.yml
- - hosts: yzb
- remote_user: root
- vars_files:
- - ./vars.yaml
- tasks:
- - name: task1
- file: path=/opt/testfile
- state=touch
- notify: restart mysqld
- - name: task2
- systemd:
- name: "{{ service }}"
- state: stopped
- handlers:
- - name: restart mysqld
- systemd:
- name: "{{ service }}"
- state: restarted
- [root@120 ansible]# cat vars.yaml
- service: mysqld
- [root@120 ansible]# ansible-playbook mysql-variables-2.yml
范例:
- vim /etc/ansible/hosts
-
- [websrvs]
- 192.168.0.101 hname=www1
- 192.168.0.102 hname=www2
-
- [websvrs:vars]
- mark=“-”
- domain=magedu.org
-
- ansible websvrs –m hostname –a ‘name={{ hname }}{{ mark }}{{ domain }}’
即用一个文件作为模板,传送到远程的被控机上去,并且针对被控机的配置去改写文件,一般是配置文件。template不能作为命令行调用,只能写在playbook中进行调用。
范例:以yum安装nginx为例
[root@ansible ansible]# mkdir templates
[root@ansible ansible]# cp /etc/nginx/nginx.conf templates/nginx.conf.j2
- ---
- - hosts: websrvs
- remote_user: root
-
- tasks:
- - name: install package
- yum: name=nginx
- - name: copy template
- template: src=/nginx.conf.j2 dest=/ect/nginx/nginx.conf
- - name: start service
- service: name=nginx state=started enabled=yes
注意:
如果j2文件放在templates文件下,可以直接写template: src=nginx.conf.j2,ansible可以自动识别出来;
如果j2文件没有放在templates文件下,需要加上绝对路径template: src=xx/xx/nginx.conf.j2
- [root@ansible145 ansible]# ansible-playbook -C testtempl.yml
-
- [root@ansible145 ansible]# ansible-playbook testtempl.yml
when 判断在用于控制在满足when所指定的条件的情况下 才执行相应的动作。
在when关键字中引用变量时,变量名不需要加"{{ }}",我们可以使用when关键字为任务指定条件,条件成立,则执行任务,条件不成立,则不执行任务。
根据不同操作系统,安装不同软件
- ansible_distribution 变量可以获取主机的发行版本
-
- [root@120 ansible]# ansible yzb -m setup -a 'filter=ansible_distribution'
- 192.168.255.123 | SUCCESS => {
- "ansible_facts": {
- "ansible_distribution": "CentOS",
- "discovered_interpreter_python": "/usr/bin/python"
- },
- "changed": false
- }
-
-
- playbook 如下
- [root@120 ansible]# cat when.yml
- - hosts: yzb
- remote_user: root
- tasks:
- - name: Centos install httpd
- yum:
- name: httpd
- state: installed
- when: ansible_distribution=="CentOS" <==判断版本语句,此处变量不需要{{ }}引用。
- # when也可以使用and与or方式进行多项匹配。
- - name: Ubuntu install httpd2
- yum:
- name: httpd2
- state: present
- when: (ansible_distribution == "CentOS") <==判断版本语句,此处变量不需要{{ }}引用。
判断kubelet.service 服务是否正常运行,运行就停止,不运行不作处理
- [root@k8s-master-1 test]# vim when.yaml
- ---
- - hosts: web
- remote_user: root
-
- tasks:
- - name: Check Nginx Status
- shell: systemctl status kubelet.service
- register: check_k8s
- - name: Print check_k8s
- debug:
- var:
- "check_k8s" <==#通过debug的var输出该变量的所有内容
- - name:
- service:
- name: kubelet.service
- state: stopped
- when: check_k8s.rc == 0 <==.rc是check_nginx变量中的执行结果,见下面的执行过程
迭代:当有需要重复性执行的任务时,可以使用迭代机制。对迭代项的引用,固定变量名为“item”,要在task中使用when_items给定要迭代的元素列表。
批量下载程序(和变量里使用loop一样)
- [root@ansible ansible]# vim testitem.yml
-
- ---
- - hosts: yzb
- remote_user: root
-
- tasks:
- - name: create some files
- file: name=/data/{{ item }} state=touch
- when: ansible_distribution_major_version == "7"
- with_items:
- - file1
- - file2
- - file3
- - name: install some packages
- yum: name={{ item }}
- with_items:
- - htop
- - sl
- - hping3
迭代嵌套子变量——批量创建用户名
- [root@ansible ansible]# vim testitem3.yml
-
- ---
- - hosts: yzb
- remote_user: root
-
- tasks:
- - name: create some group
- group: name={{ item }}
- when: ansible_distribution_major_version == "7"
- with_items:
- - g1
- - g2
- - g3
- - name: create some user
- user: name={{ item.name }} group {{ item.group }}
- with_items:
- - { name: 'user1', group: 'g1' }
- - { name: 'user2', group: 'g2' }
- - { name: 'user3', group: 'g3' }
tests会将判断后的布尔值返回,如果条件成立,则返回true,如果条件不成立,tests会返回false,我们通常会在条件判断时使用到tests
示例:
- ---
- - hosts: web
- remote_user: root
-
- vars:
- testpath: /tmp
- tasks:
- - name: test
- debug:
- msg: "file exist"
- when: testpath is exists
- "is exists"中的"exists"就是tests的一种,判断ansible主机中的对应路径是否存在(注意:是ansible控制主机中的路径,与目标主机没有关系),当对应的路径存在于ansible控制节点时,"is exists"为真。
- "is not exists"表示对应路径不存在时返回真。
示例:
- ---
- - hosts: web
- remote_user: root
-
- vars:
- test1: vl
- test2:
- tasks:
- - debug:
- msg: "test1 is defined"
- when: test1 is defined
- - debug:
- msg: "test1 is undefind"
- when: test2 is undefined
success或者succeeded:通过任务的返回信息判断任务的执行状态,任务执行成功则返回真
failure 或 failed:通过任务的返回信息判断任务的执行状态,任务执行失败则返回真
change 或 changed:通过任务的返回信息判断任务的执行状态,任务执行状态为changed则返回真
skip 或 skipped:通过任务的返回信息判断任务的执行状态,当任务没有满足条件,而被跳过执行时,则返回真