playbook
是由一个或多个"play"
组成的列表
playbook
的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色。
Task实际是调用ansible的一个module,将多个play组织在一个playbook
中, 即可以让它们联合起来,按事先编排的机制执行预定义的动作
Playbook
采用YAML
语言编写
1 2 3 4 5 6 --- - hosts: test remote_user: root tasks: - name: Install Redis command: install redis
1.0 PlayBook核心元素
Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务,hosts用于指定要执行指定任务的主机,须事先定义在主机清单中.详细请看
remote_user
: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务.此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户.
varniables
: 内置变量或自定义变量在playbook中调用
Templates模板
: 可替换模板文件中的变量并实现一些简单逻辑的文件
Handlers和notify
: 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
tags
: 指定某条任务执行,用于选择运行playbook中的部分代码.
1 ansible-playbook -C hello.yaml
1.0.1 忽略错误信息 也可以使用ignore_errors
来忽略错误信息
1 2 3 4 tasks: - name: run this shell: /usr/bin/ls || /bin/true ignore_errors: True
1.0.2 常用选项
--check
: 只检测可能会发生的改变,但是不会执行
--list-hosts
: 列出运行任务的主机
--limit
: 主机列表,只针对主机列表中的主机执行
-v
: 显示过程
--list-tasks
: 查看任务列表
1 2 3 ansible-playbook hello.yaml --check ansible-playbook hello.yaml --list-hosts ansible-playbook hello.yaml --limit 10.1.6.111
2.0 Handlers和notify
由于playbook执行会有次序问题,所以当出现次序问题的时候,可以使用handlers结合notify
Handlers
: 是task
列表,这些task与前述的task没有本质的区别,用于当不同的资源发生变化的时候,才会采取一定的操作.
Notify
: 此action可以用在每个play的最后被触发,这样可以避免多次有改变的发生时每次都执行指定的操作,仅仅在所有变化发生完后,一次性执行制定操作,在notify中列出的操作称为hendler
,也就是notify中定义的操作.
Handlers
和notify
可以写多个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 --- - hosts: test remote_user: root tasks: - name: "create new file" file: name=/data/newfile state=touch - name: "create new user" user: name=test2 system=yes shell=/sbin/nologin - name: "install httpd" yum: name=httpd state=installed notify: restart service - name: "copy log" copy: src=/var/log/httpd/error_log dest=/data handlers: - name: restart service service: name=httpd state=restarted
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 --- - hosts: test remote_user: root tasks: - name: "create new file" file: name=/data/newfile state=touch tags: newfile - name: "create new user" user: name=test2 system=yes shell=/sbin/nologin tags: newuser - name: "install httpd" yum: name=httpd state=installed notify: restart service - name: "copy log" copy: src=/var/log/httpd/error_log dest=/data handlers: - name: restart service service: name=httpd state=restarted ansible-playbook -t newfile test.yaml ansible-playbook -t newfile,newuser test.yaml
4.0 PlayBook中变量的使用
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量的来源
通过setup
模块
在/etc/ansible/hosts
中定义
普通变量:主机组中的主机单独定义,优先级高于公共变量
公共变量:针对主机组所有主机定义统一变量
通过命令行指定变量: 优先级最高
4.0.1 通过命令行指定变量 1 2 3 4 5 6 7 8 9 --- - hosts: test remote_user: root tasks: - name: "create new file" file: name=/data/{{filename}} state=touch tags: newfile ansible-playbook -e 'filename=app1'
4.0.2 在playbook中定义 1 2 3 4 5 6 7 8 9 10 --- - hosts: test remote_user: root vars: - filename: app1 tasks: - name: "create new file" file: name=/data/{{filename}} state=touch tags: newfile
4.0.3 通过setup模块获取变量 1 2 3 4 5 6 ansible setup facts 远程主机的所有变量都可直接调用 (系统自带变量) setup模块可以实现系统中很多系统信息的显示 ansible all -m setup -a 'filter="ansible_nodename"' 查询主机名 ansible all -m setup -a 'filter="ansible_memtotal_mb"' 查询主机内存大小 ansible all -m setup -a 'filter="ansible_distribution_major_version"' 查询系统版本 ansible all -m setup -a 'filter="ansible_processor_vcpus"' 查询主机cpu个数
4.0.4 在hosts中定义变量
1 2 3 4 5 6 7 8 9 [test ] 192.168 .1 .1 http_port=81 192.168 .1 .2 http_port=82 --- - hosts: test remote_user: root tasks: - name: "create new file" hostname: name=www{{http_port}}.baidu.com
1 2 3 4 [test:vars ] nodename=www domain=baidu.com
4.0.5 通过文件加载变量 1 2 3 4 5 6 7 8 9 10 filename: applications - hosts: test remote_user: root vars_files: - vars.yaml tasks: - name: "create new file" file: name=/data/{{filename}}
5.0 模板Templates
采用Jinja2
语言,使用字面量,有下面形式
数字:整数,浮点数
列表:[item1, item2, …]
元组:(item1, item2, …)
字典:{key1:value1, key2:value2, …}
布尔型:true/false
算术运算:+, -, *, /, //, %, **
比较操作:==, !=, >, >=, <, <=
逻辑运算:and,or,not
流表达式:For,If,When
1 2 3 4 5 6 7 8 user nginx; worker_processes {{ansible_processor_vcpus**2 }}; error_log /var/log/nginx/error.log; pid /run/nginx.pid;
5.0.1 When语法
条件测试:如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试, 通过when语句实现,在task中使用,jinja2的语法格式
在task后添加when子句即可使用条件测试;when语句支持Jinja2表达式语法
当ansible_distribution
=CentOS的时候才会去执行template
1 2 3 4 5 6 7 8 9 10 11 --- - hosts: test remote_user: root tasks: - name: "Install Nginx" yum: name=nginx - name: Config conf template: src=/templates/nginx.conf.j2 dest=/etc/nginx/nginx.conf when: ansible_distribution == "CentOS" - name: start nginx service: name=nginx state=started enabled=yes
5.0.2 With_item
1 2 3 4 5 6 7 8 9 10 --- - hosts: test remote_user: root tasks: - name: "Create new file" file: name=/data/{{items}} state=touch with_items: - app1 - app2 - app3
1 2 3 4 5 6 7 - hosts: test remote_user: root tasks: - name: "Create new file" file: name=/data/{{item.name}}_{{item.date}} state=touch with_items: - {name: 'app1' , date: '2022' }
5.0.3 for循环 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 --- - hosts: test remote_user: root vars: ports: - 81 - 82 - 83 tasks: - name: copy template template: src=/root/templates/for.j2 dest=/data/for.conf --- - hosts: test remote_user: root vars: ports: - listen:81 - listen:82 - listen:83 tasks: - name: copy template template: src=/root/templates/for.j2 dest=/data/for.conf --- - hosts: test remote_user: root vars: config: - host1: port: 81 name: host1.do.com rootdir: /root/ tasks: - name: copy template template: src=/root/templates/for.j2 desc=/data/for.conf
创建一个模板文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 {%for i in ports% } server { listen {{i }} } {%endfor% } {%for i in ports% } server { listen {{i.listen }} } {%endfor% } {%for i in ports% } server { listen {{ i.port }} name {{ i.name }} } {%endfor% }
5.0.4 if判断 1 2 3 4 5 6 7 8 {%for i in ports%} server { listen {{ i.port }} {% if i.name is defind %} name {{ i.name }} {% endif %} } {%endfor%}a