一.Ansible-Task判断语句
判断在ansible任务中的使用频率非常高。比如yum模块可以检测软件包是否已经安装,而在这个过程中我们不用做太多的人工干预。但是也有部分任务需要进行判断。比如:web服务器角色都需要安装nginx仓库,但其他的服务器角色并不需要,此时就会用到when判断。
比如:Centos与Ubuntu系统都需要安装Apache,可Centos系统的Apache软件包是httpd,而Ubuntu系统的Apache软件包是httpd2,那么此时就需要判断主机系统,然后为不同的主机系统安装不同的软件包。
1.playbook判断语句 (使用facts变量ansible_distribution)
根据被控端操作系统进行判断安装不同的软件包.
[root@mananger tasks]# cat t1.yaml
- hosts: webservers
tasks:
- name: Installed Httpd Server [ CentOS ]
yum:
name: httpd
state: present
when: ( ansible_distribution == "CentOS" )
- name: Installed Httpd2 Server [ Ubuntu ]
yum:
name: httpd2
state: present
when: ( ansible_distribution == "Ubuntu" )
因为这里的webservers主机组中有两台web 一台7 一台8 都是centos系统,所以在ubuntu系统上安装httpd2操作就直接skipping跳过
我们可以通过那些fact变量进行针对web集群软件的安装?
1.主机名 (规范)
2.物理的cpu+内存
3.根据IP地址判断
4.不判断直接所有机器都安装
2.根据被控端主机的名称,进行判断
针对使用nginx的节点配置nginx库
[root@mananger tasks]# cat t2.yaml
- hosts: all
tasks:
- name: Add Nginx Yum Repository
yum_repository:
name: nginx
description: Nginx Repository
baseurl: http://nginx.org/packages/centos/7/$basearch/
gpgcheck: no
when: ( ansible_hostname is match ("web*")) or ( ansible_hostname is match ("lb*"))
判断语句 当匹配到以web或lb开头的主机名的主机时进行操作
对所有hosts进行操作,通过主机名匹配以web或lb开头的主机名的主机进行配置nginx仓库,所以没有匹配到的直接跳过.
3.根据命令执行的结果进行判断
**检查httpd服务是否存活,如果存活,就重启,否则就不重启. **
[root@mananger tasks]# cat t3.yaml
- hosts: webservers
tasks:
- name: Check Httpd Server
shell: systemctl is-active httpd
ignore_errors: yes 忽略错误
register: check_httpd 将命令的结果通过register赋予一给一个变量名
- name: Restart Httpd Server
systemd:
name: httpd
state: restarted
when: ( check_httpd.rc == 0 ) 判断语句
我这里web01开启了httpd服务 ,web02 没有开启
4.对nginx服务进行安装 配置 检查 启动
每次修改配置,都需要检查语法,如果语法错误,则不重启Nginx
[root@mananger tasks]# cat t4.yaml
- hosts: webservers
tasks:
- name: Installed Nginx Server
yum:
name: nginx
state: present
- name: Configure Nginx Server
copy:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx Server
- name: Check Nginx Status
shell: /usr/sbin/nginx -t
register: Check_ngx
ignore_errors: yes
- name: Systemd Nginx Started
systemd:
name: nginx
state: started
enabled: yes
when: ( Check_ngx.rc == 0 )
handlers:
- name: Restart Nginx Server
systemd:
name: nginx
state: restarted
when: ( Check_ngx.rc == 0 )
二. Ansible-Task循环语句
有时候我们写playbook的时候发现了很多task都要重复引用某个模块,比如一次启动10个服务,或者一次拷贝10个文件,如果按照传统的写法最少要写10次,这样会显得playbook很臃肿。如果使用循环的方式来编写playbook,这样可以减少重复使用某个模块
我们这里举例子用部署web集群的剧本进行一步一步修改
列表 ---->按照多个软件包
1.ansible官方格式
#方法一:(task列表)
- name: ensure a list of packages installed
yum:
name: "{{ item }}" (item 固定的变量(会在loop列表中依次提取对应的值 ))
state:present
loop: (loop或with_items)
- nginx
- php-fpm
#方法二:
- name: ensure a list of packages installed
yum:
name: "{{ packages }}"
state:present
vars:
packages:
- httpd
- httpd-tools
2.用列表精简web集群的剧本
- hosts: webservers
tasks:
- name: Configure Nginx Repo
yum_repository:
name: ansible_nginx
description: ansible_nginx_repo
baseurl: http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck: yes
gpgkey: https://nginx.org/keys/nginx_signing.key
- name: Configure Php Repo
yum_repository:
name: ansible_php
description: ansible_php_repo
baseurl: http://10.0.0.10/
gpgcheck: no
- name: Installed Nginx PHP
yum:
name: "{{ packages }}"
state: present
vars:
packages:
- nginx
- php71w
- php71w-cli
- php71w-common
- php71w-devel
- php71w-embedded
- php71w-gd
- php71w-mcrypt
- php71w-mbstring
- php71w-pdo
- php71w-xml
- php71w-fpm
- php71w-mysqlnd
- php71w-opcache
- php71w-pecl-memcached
- php71w-pecl-redis
- php71w-pecl-mongodb
- name: Configure Nginx Server nginx.conf
copy:
src: ./files/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: 0644
notify: Restart Nginx Server
- name: Configure PHP Server php-fpm.conf
copy:
src: ./files/php-www.conf.j2
dest: /etc/php-fpm.d/www.conf
owner: root
group: root
mode: 0644
notify: Restart PHP Server
- name: Configure PHP Server php.ini
copy:
src: ./files/php.ini.j2
dest: /etc/php.ini
owner: root
group: root
mode: 0644
notify: Restart PHP Server
- name: Add kcloud.etiantian.org Web Site
copy:
src: ./files/kcloud.etiantian.org.conf.j2
dest: /etc/nginx/conf.d/kcloud.etiantian.org.conf
owner: root
group: root
mode: 0644
notify: Restart Nginx Server
- name: Add Group www
group:
name: www
gid: 666
- name: Add User www
user:
name: www
uid: 666
group: '666'
shell: /sbin/nologin
create_home: no
- name: Add Kcloud Code Directory
file:
path: /code/kcloud
state: directory
owner: www
group: www
mode: 0755
- name: Unzip Kodcloud Code
unarchive:
src: ./files/kodbox.1.13.zip
dest: /code/kcloud/
owner: www
group: www
mode: 0755
creates: /code/kcloud/index.php
- name: Check Nginx Status
shell: /usr/sbin/nginx -t
register: Check_ngx
ignore_errors: yes
- name: Check PHP Status
shell: /usr/sbin/php-fpm -t
register: Check_php
ignore_errors: yes
- name: Systemd Nginx php-fpm Started
systemd:
name: "{{ item }}"
state: started
enabled: yes
when: (Check_ngx.rc == 0 ) or (Check_php.rc == 0 )
loop:
- nginx
- php-fpm
# - name: Systemctl PHP Server Started
# systemd:
# name: php-fpm
# state: started
# enabled: yes
handlers:
- name: Restart Nginx Server
systemd:
name: nginx
state: restarted
- name: Restart PHP Server
systemd:
name: php-fpm
state: restarted
首先分别检测nginx 和 php-fpm 两个服务的状态(配置文件是否有错)
然后 register分别把nginx 和 php-fpm 两个服务的状态赋予定义的变量(check_nginx check_php)
然后通过or 把两个 whem判断服务状态语句 进行连接,从而不影响两个服务之间检测之后的各自启动
最后用循环语句把两个服务通过列表的方式整合起来
字典----->拷贝多个文件
1.ansible官方格式
- name: Create two hard links
file:
src: '/tmp/{{ item.src }}'
dest: '{{ item.dest }}'
state: hard
loop:
- { src: x, dest: y }
- { src: z, dest: k }
2.用字典精简web集群的剧本
- hosts: dbservers
tasks:
#配置nginx官方仓库
- name: Configure Nginx Repo
yum_repository:
name: ansible_nginx
description: ansible_nginx_repo
baseurl: http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck: yes
gpgkey: https://nginx.org/keys/nginx_signing.key
#自己搭建的本地yum仓库10.0.0.10
- name: Configure Php Repo
yum_repository:
name: ansible_php
description: ansible_php_repo
baseurl: http://10.0.0.10/
gpgcheck: no
#按照nginx和php的软件包
- name: Installed Nginx PHP
yum:
name: "{{ packages }}"
state: present
vars:
packages:
- nginx
- php71w
- php71w-cli
- php71w-common
- php71w-devel
- php71w-embedded
- php71w-gd
- php71w-mcrypt
- php71w-mbstring
- php71w-pdo
- php71w-xml
- php71w-fpm
- php71w-mysqlnd
- php71w-opcache
- php71w-pecl-memcached
- php71w-pecl-redis
- php71w-pecl-mongodb
# 推送nginx主配置文件nginx.conf
- name: Configure Nginx Server nginx.conf
copy:
src: ./files/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: 0644
notify: Restart Nginx Server
# 推送php配置文件用字典方式
- name: Configure php-fpm.conf php.ini
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: "{{ item.owner }}"
group: "{{ item.group }}"
mode: "{{ item.mode }}"
notify: Restart PHP Server
loop:
- { src: ./files/php-www.conf.j2 , dest: /etc/php-fpm.d/www.conf , owner: root , group: root , mode: 0644 }
- { src: ./files/php.ini.j2 , dest: /etc/php.ini , owner: root , group: root , mode: 0644 }
#推送php配置文件 原先格式
# - name: Configure PHP Server php-fpm.conf
# copy:
# src: ./files/php-www.conf.j2
# dest: /etc/php-fpm.d/www.conf
# owner: root
# group: root
# mode: 0644
# notify: Restart PHP Server
# - name: Configure PHP Server php.ini
# copy:
# src: ./files/php.ini.j2
# dest: /etc/php.ini
# owner: root
# group: root
# mode: 0644
# notify: Restart PHP Server
- name: Add kcloud.etiantian.org Web Site
copy:
src: ./files/kcloud.etiantian.org.conf.j2
dest: /etc/nginx/conf.d/kcloud.etiantian.org.conf
owner: root
group: root
mode: 0644
notify: Restart Nginx Server
- name: Add Group www
group:
name: www
gid: 666
- name: Add User www
user:
name: www
uid: 666
group: '666'
shell: /sbin/nologin
create_home: no
- name: Add Kcloud Code Directory
file:
path: /code/kcloud
state: directory
owner: www
group: www
mode: 0755
- name: Unzip Kodcloud Code
unarchive:
src: ./files/kodbox.1.13.zip
dest: /code/kcloud/
owner: www
group: www
mode: 0755
creates: /code/kcloud/index.php
#首先分别检测nginx 和 php-fpm 两个服务的状态(配置文件是否有错)
#然后 register分别把nginx 和 php-fpm 两个服务的状态赋予定义的变量(check_nginx check_php)
#然后通过or把两个 whem判断服务状态语句 进行连接,从而不影响两个服务之间检测之后的各自启动
#最后用循环语句把两个服务通过列表的方式整合起来
- name: Check Nginx Status
shell: /usr/sbin/nginx -t
register: Check_ngx
ignore_errors: yes
- name: Check PHP Status
shell: /usr/sbin/php-fpm -t
register: Check_php
ignore_errors: yes
- name: Systemd Nginx php-fpm Started
systemd:
name: "{{ item }}"
state: started
enabled: yes
when: (Check_ngx.rc == 0 ) or (Check_php.rc == 0 )
loop:
- nginx
- php-fpm
# - name: Systemctl PHP Server Started
# systemd:
# name: php-fpm
# state: started
# enabled: yes
handlers:
- name: Restart Nginx Server
systemd:
name: nginx
state: restarted
- name: Restart PHP Server
systemd:
name: php-fpm
state: restarted
三.Ansible-Task-Tags标签语句(调试场景)
1.Tags应用
默认情况下,Ansible在执行一个playbook时,会执行playbook中定义的所有任务。
Ansible的标签(Tags)功能可以给单独任务甚至整个playbook打上标签,然后利用这些标签来指定要运行playbook中的个别任务,或不执行指定的任务
2.Tags应用方式(打标签方式)
1.对一个task打一个标签
2.对一个task打多个标签
3.对多个task打一个标签
3.Tags使用命令
-t:执行指定的tag标签任务
--skip-tags: 执行--skip-tags之外的标签任务
4.Tags实列
- name: Add Group www
group:
name: www
gid: 666
tags: test1 # 定义标签名称 ( 名称随意 )
[root@mananger web_cluster]# ansible-playbook nginx_php_server.yaml --skip-tags test1
[root@mananger web_cluster]# ansible-playbook nginx_php_server.yaml -t test1
四.playbook-Handlers
1.handlers概念
Handlers是一个触发器,也是一个tasks,只不过是一个特殊的tasks,它是需要被tasks触发才会运行。
只要配置文件发生变更,则会触发handlers执行重启服务操作,如果配置文件不发生任何变化则不重启。
2.handlers实列
当nginx主配置文件在控制端(ansible服务端)内容发生变化,则会重启nginx服务
- hosts:
- name: Configure Nginx Server nginx.conf
copy:
src: ./files/nginx.conf.j2
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: 0644
notify: Restart Nginx Server #notify与模块名称同层
handlers: #handlers与hosts同层
- name: Restart Nginx Server #定义的handlers名称与notify一致
systemd:
name: nginx
state: present
五.Ansible-Task-Ignore_errors
1.Ignore_errors概念
默认playbook会检测Tasks执行的返回状态,如果遇到错误则会立即终止playbook的后续的tasks执行。然而有些时候playbook即使执行错误了也要让其继续执行。
加入参数 ignore_errors:yes 忽略错误
2.编写剧本
编写playbook,当有task执行失败则会立即终止后续task运行
[root@mananger tasks]# cat t10.yaml
- hosts: webservers
tasks:
- name: Comamand
shell: /bin/false
ignore_errors: yes
- name: Touch FIle
file:
path: /tmp/tt
state: touch
六.Ansible-Tasks-异常处理
通常情况下,当task失败后,play将会终止,任何在前面已经被task
notify的handlers都不会执行。如果你在play中设置了force_handlers:yes
参数,被通知的handlers就会强制执行(有些特殊场景可能会使用)
1.强制调用handlers运行 ( 少 )
[root@mananger tasks]# cat t11.yaml
- hosts: webservers
force_handlers: yes
tasks:
- name: Touch File
file:
path: /tmp/ansible_tt
state: touch
notify: Restart Nginx Server
- name: Installed Packages
yum:
name: sb
state: present
handlers:
- name: Restart Nginx Server
systemd:
name: nginx
state: restarted
2.如果tasks任务对被控端没有影响,但每次都是change状态时, 我们可以抑制状态
[root@mananger tasks]# cat t12.yaml
- hosts: webservers
tasks:
- name: Get Netstat State
shell:
cmd: netstat -lntp
register: Net_status
changed_when: false
- name: Output Net Status Vaiables
debug:
msg: "{{ Net_status.stdout_lines }}"
3.使用changed_when判断服务的状态
[root@mananger tasks]# cat t13.yaml
- hosts: webservers
tasks:
- name: Installed Nginx Server
yum:
name: nginx
state: present
- name: Configure Nginx Server
copy:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify: Restart Nginx Server
- name: Check Nginx Status
shell: /usr/sbin/nginx -t
register: Check_ngx
changed_when:
- Check_ngx.stdout.find('successful') # 如果有successful则认为成功,继续. 否则就抛出异常
- false
- name: Systemd Nginx Started
systemd:
name: nginx
state: started
enabled: yes
handlers:
- name: Restart Nginx Server
systemd:
name: nginx
state: restarted