主机清单:
主机组 IP地址
[root@test7 opt]# vim /etc/ansible/hosts [xy102] 192.168.60.40 ansible_port=22 ansible_user=root ansible_password=123
ansible_port=22 #目标主机的端口
ansible_user=root #登录目标主机的用户名
ansible_password=123 #登录目标主机的密码
#批量匹配IP地址 [root@test7 opt]# vim /etc/ansible/hosts 192.168.60.[0:9]0 ansible_port=22 ansible_user=root ansible_password=123
组嵌套
[web] 192.168.60.80 [web1] 192.168.60.90 [web:children] web web1
ansible的脚本 playbook(剧本)
playbook的组成
1、tsaks 任务,每一个tasks就是一个模块
2、variables 变量,存储和传递数据,自定义变量,也可以是全局变量,也可以是脚本外传参
3、Templates 模块,用于生成配置文件和多任务的编排。
4、handlers 处理器,用于满足某些条件时触发的操作,一般用于重启等操作
5、roles 角色,组织和封装剧本的过程,变量,模板,处理器,组合成一个可用的单元。
[root@test7 opt]# vim test1.yaml - name: first play #定义这个剧本的名称,可以不写 gather_facts: false #表示在执行剧本之前是否收集目标主机的信息,false表示不收集,可以加快执行速度,如果不写默认收集。 hosts: 192.168.60.80 #指定目标主机,可以是组名,也可以是IP地址 remote_user: root #在目标主机的执行用户 tasks: - name: test connection #定义一个任务的名称,可以自定义 ping: #ping就是模块的名称 - name: close selinux command: '/sbin/setenforce 0' ignore_errors: True #如果在任务执行中报错,返回码非0,报错,task就会停止,ignore_errors: True就会忽略错误,继续执行下一个任务。 - name: close firewalld service: name=firewalld state=stopped #调用service模块,关闭防火墙 - name: install httpd yum: name=httpd state=latest #latest,安装当前库中的最新版本的软件 - name: interview shell: echo "this is httpd" > /var/www/html/index.html #指定shell模块,修改默认的访问页面 notify: restart httpd # ansible在执行完任务之后不会立即执行重启,通过notify指令对应的名称传给触发器,让触发器在任务的最后执行重启,避免在任务中多次执行重启,影响执行的 效率。 handlers: - name: restart httpd service: name=httpd state=restarted #执行test1.yaml脚本 [root@test7 opt]# ansible-playbook test1.yaml
安装nginx,传一个配置文件到目标主机,修改默认端口8080,访问页面的内容 this is nginx 安装方式yaml
[root@test7 opt]# vim nginx.yaml - name: first play gather_facts: false hosts: 192.168.60.90 remote_user: root tasks: - name: test connection ping: - name: close selinux command: '/sbin/setenforce 0' ignore_errors: True - name: close firewalld service: name=firewalld state=stopped - name: install nginx yum: name=nginx state=latest - name: interview shell: echo "this is nginx" > /usr/share/nginx/html/index.html - name: nginx.conf copy: 'src=/opt/nginx.conf dest=/etc/nginx/' notify: restart nginx handlers: - name: restart nginx service: name=nginx state=restarted [root@test7 opt]# ansible-playbook nginx.yaml
定义变量,引用变量:
脚本当中定义,以及脚本外传参
[root@test7 opt]# vim test2.yaml - name: second play hosts: 192.168.60.90 remote_user: root vars: #定义变量 groupname: mysql username: nginx1 tasks: - name: create group group: name: "{{ groupname }}" system: yes gid: 306 - name: create user user: name: "{{ username }}" uid: 306 group: "{{ groupname }}" [root@test7 opt]# ansible-playbook test2.yaml #在脚本外面传参 [root@test7 opt]# ansible-playbook test2.yaml -e 'groupname=test1 username=test2'
总结:脚本外的参数比脚本中的参数优先级高
#检查脚本中有没有语法错误 [root@test7 opt]# ansible-playbook test2.yaml --syntax-check #检测脚本中有几个任务 [root@test7 opt]# ansible-playbook test2.yaml --list-task #检测脚本对哪些主机生效 [root@test7 opt]# ansible-playbook test2.yaml --list-hosts #执行全局的部分和指定执行的部分 [root@test7 opt]# ansible-playbook test2.yaml --start-at-task='create user' -e 'username=test3 groupname=nginx'
[root@test7 opt]# vim test2.yaml - name: second play hosts: 192.168.60.90 remote_user: dn become: yes #先用普通用户执行,但是需要切换到其他用户,列如切换到管理员 become_user: root vars: groupname: mysql username: nginx1
满足条件的执行,不满足的跳过
[root@test7 opt]# vim test3.yaml #如何在脚本中实现条件判断: #when 满足条件的主机执行,不满足的跳过。 - name: this is if hosts: all remote_user: root tasks: - name: test when debug: msg='条件满足' #debug相当于echo echo "条件满足" when: ansible_default_ipv4.address == "192.168.60.90"
取反
[root@test7 opt]# vim test3.yaml #如何在脚本中实现条件判断: #when 满足条件的主机执行,不满足的跳过。 - name: this is if hosts: all remote_user: root tasks: - name: test when debug: msg='条件满足' #debug相当于echo echo "条件满足" when: ansible_default_ipv4.address != "192.168.60.90"
with_items:
[root@test7 opt]# vim test4.yaml #循环结构:ansible有多种循环方式,一般都命名为with_items,定义循环的内容。 #with_item 单循环输出: - name: item test hosts: 192.168.60.80 remote_user: root gather_facts: false tasks: - debug: msg: "{{ item }}" with_items: - [a,b,c,d] - [1,2,3,4]with_list #输出item的值,with_items:a b c d 依次传入。
with_list整个列表作为一个整体,继续输出
[root@test7 opt]# vim test4.yaml #循环结构:ansible有多种循环方式,一般都命名为with_items,定义循环的内容。 #with_item 单循环输出: - name: item test hosts: 192.168.60.80 remote_user: root gather_facts: false tasks: - debug: msg: "{{ item }}" with_list: - [a,b,c,d] - [1,2,3,4] #输出item的值,with_items:a b c d 依次传入。
wiht_together,作为整体,一列一列,两两配对输出
[root@test7 opt]# vim test4.yaml #循环结构:ansible有多种循环方式,一般都命名为with_items,定义循环的内容。 #with_item 单循环输出: - name: item test hosts: 192.168.60.80 remote_user: root gather_facts: false tasks: - debug: msg: "{{ item }}" with_together: - [a,b,c,d] - [1,2,3,] #输出item的值,with_items:a b c d 依次传入。
with_nested:每一层都是遍历执行一般,输出结果
[root@test7 opt]# vim test4.yaml #循环结构:ansible有多种循环方式,一般都命名为with_items,定义循环的内容。 #with_item 单循环输出: - name: item test hosts: 192.168.60.80 remote_user: root gather_facts: false tasks: - debug: msg: "{{ item }}" with_nested: - [a,b,c,d] - [1,2,3,] #输出item的值,with_items:a b c d 依次传入。
条件判断,主机的ip
才会执行性,一次性创建4个文件,/opt/a /opt/b /opt/c /opt/d 循环 with_items
[root@test7 opt]# vim test5.yaml - name: this is if hosts: all remote_user: root tasks: - name: test when file: path: "{{ item }}" state: touch with_items: [/opt/a,/opt/b,/opt/c,/opt/d] when: ansible_default_ipv4.address == "192.168.60.90" [root@test7 opt]# ansible-playbook test5.yaml [root@test9 opt]# ls a b c d