侧边栏壁纸
博主头像
zyixin

当你觉得为时已晚的时候,恰恰是最早的时候

  • 累计撰写 66 篇文章
  • 累计创建 0 个标签
  • 累计收到 1 条评论

目 录CONTENT

文章目录

ansible的palybook

zyixin
2022-04-01 / 0 评论 / 0 点赞 / 3,057 阅读 / 19,226 字
温馨提示:
本文最后更新于 2022-04-01,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

1 Playbook

1.1 playbook介绍

playbook
playbook剧本是由一个或多个"play"组成的列表
play的主要功能在于将预定义的一组主机,装扮成事先通过ansible中的task定义好的角色,Task实际是调用ansible的一个module,将多个play组织在一个playbook中,既可以让它们联合起来,按事先编排的机制执行预定义的动作
Playbook文件是采用YAML语言编写的

1.2 YAML语言

1.2.1 YAML语言介绍

YAML是一个可读性高的用来表达资料序列的格式。YAML参考了其他多种语言,包括:XML、C语言、Pythen、Perl以及电子邮件格式RFC2822等,Clark Evans在2001年在首次发表了这种语言,另外lngy dot Net与Oren Ben-kiki也是这语言的共同设计者,目前很多软件中采有此格式的文件,如:ubuntu,ansible,docker,k8s等
YAML:YAML Ain’t Markup Language,即YAML不是XML。不过,在开发的这种语言时,YAML的意思其实是"Yet Another Markup Language"(仍是一种标记语言)

YAML官方地址:http://www.yaml.org

1.2.2 YAML语言特征

· YAML的可读性好
· YAML和脚本语言的交互性好
· YAML使用实现语言的数据类型
· YAML有一个一致的信息模型
· YAML抑郁实现
· YAML可以基于流来处理
· YAML 表达能力强,扩展性好

1.2.3 YAML语言简介

· 在单一文件第一行,用连续三个连字号"-"开始,还有选择性的连续三个点号(…)用来表示文件的结尾
· 此行开始正常写playbook的内容,一般建议写明该Playbook的功能
· 使用#号注释代码
· 缩进必须是统一的,不能空格和tab混用
· 缩进的级别也必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的,YAML文件内容是区分大小写的,key/value的值均需大小写敏感
· 多个k/v可同行写也可换行写,同行使用,分隔
· v可是个字符串,也可是一个列表
· 一个完整的代码块功能需最少元素需包括name和task
· 一个name只能包括一个task
· YAML文件扩展名通常为yml或yaml

YAML的语言和其他高阶语言相似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用"-“来表示,Map里的键值对用”:“分隔,下面介绍常见的数据结构YAML的语言和其他高阶语言相似,并且可以简单表达清单、散列表、标量等数据结构。其结构(Structure)通过空格来展示,序列(Sequence)里的项用”-“来表示,Map里的键值对用”:"分隔,下面介绍常见的数据结构

1.2.3.1 List列表

列表由多个元素组成,且所有元素前均使用"-"开头
范例:

# A list of tasty fruits
- Apple
- orange
- Strawberry
- Mango

[Apple,orange,Strawbetty,Mango]

1.2.3.2 Dictionary字典

字典通常由多个key与value构成
范例:

#An employee record
name: Example Developer
job: Developer
skill: Elite
#也可以将key:value放置于{}中进行表示,用,分隔多个key:value

#An employee record
{name: "Example Developer",job: "Developer",skill: "Elite"}

范例:

name: John Smith
age: 41
gender: Male
Spouse:
	name: Jane Smith
	age: 37
	gender: Female
children:
	- name: Jimmy Smith
	  age: 17
	  gender: Male
	- name: Jenny Smith
	  age: 13
	  fender: Female

1.2.4 三种常见的数据格式

· Extensible Markup Language, 可扩展标记语言,可用于数据交换和配置
· JSON:javaScript Object Notation,javaScript对象表记法, 主要用来数据交换和配置,不支持注释
· YAML:YAML Ain’t Markup Language YAML不是一种标记语言,主要用来配置,大小写敏感,不支持tab
三种数据格式-1024x462
可以用工具互相转换,参考网站:
https://www.json2yaml.com

1.3 Playbook核心元素

· Hosts 执行的远程主机列表
· Tasks 任务集
· Variables 内置变量或自定义变量在playbook中调用
· Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
· Handlers 和 notify 结合使用,由特定条件触发得到操作,满足条件方才执行,否则不执行
· tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即使如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片段

1.3.1 hosts 组件

Hosts:playbook中的每一个play的目的都是为了让特定主机以某个指定的用户身份执行任务。hosts用于指定要执行指定任务的主机,须事先定义在主机清单中

one.example.com
one.example.com:two.example.com
192.168.139.100
192.168.139.*
websrvs:dbsrvs			#或者,俩个组的并集
websrvs:&dbsrvs			#与,俩个组的交集
webservers:!phoenix		#在websrvs组,但不在dbsrvs组

案例:

- hosts: websrvs:appsrvs

1.3.2 remote_user 组件

remote_user:可用于Host和task中,也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务:此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户

- host: websrvs
  rempte_user: root
  
  tasks:
    - name: test connection
	  ping:
	  remote_user: zyixin
	  sudo: yes				#默认sudo为root
	  sudo_user: zyixin		#sudo 为zyixin

1.3.3 task列表和action组件

play的主体部分是task list,task list中有一个或多个task,按次序逐个在hsots中指定的所有主机上执行,即在所有主机上完成第一个task后,再开始第二个task
task目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致
每个task都应该有其name,用于palybook的执行结果输出,建议其内容能清晰地描述任务执行步骤。如果未提供name,则action的结果将用于输出
task俩种格式:
(1) action: module arguments
(2) module: arguments #建议使用

注意:shell和command模块后面跟命令,而非key=value

---
- host: websrvs
  remote_user: root
  tasks:
    - name: install httpd
	  yum: name=httpd
	- name: start httpd
	  service: name=httpd state=started enabled=yes

1.3.4 其他组件

某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers任务可以通过"tags"打标签,可在ansible-playbook命令上使用-t指定进行调用

1.3.5 ShellScript VS Playbook 案例

#shell脚本实现
#!/bin/bash
# 安装apache
yum install --quiet -y httpd
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp /tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache,并设置开机启动
Systemctl enable --now httpd

#Playbook实现
---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: "安装Apache"
	  yum: name=httpd
	- name: "复制配置文件"
	  copy: src=/tmp/httpd.conf dest=/etc/httpd.conf/
	- name: "复制配置文件"
	  copy: src/tmp/vhosts.conf dest=/etc/httpd/conf.d/
	- name: "启动Apache,并设置开机启动"
	  service: name=httpd state=started enabled=yes

1.4 playbook命令

格式

ansible-playbook <filename.yml> ... [options]

常见选项:

-C --check			#只检测可能会发生的改变,但不真正执行操作
--list-hosts		#列出运行任务的主机
--list-tags			#列出tag
--list-tasks		#列出task
--limit 主机列表	#只针对主机列表中的主机执行
-v -vv -vvv			#显示过程

范例:

ansible-playbook file.yml --check		#只检测
ansible-playbook file.yml
ansible-playbook file.yml --limit websrvs

1.5 Playbook 初步

1.5.1 利用playbook 创建mysql用户

范例:mysql_user.yml

---
- hosts: dbsrvs
  remote_user: root
  
  tasks:
    - {name: create group, group: name=mysql system=yes gid=306}
	- name: create user
	  user: name=mysqld shell=/sbin/nologin system=yes group=mysql uid=306 home=/data/mysql create_home=no

1.5.2 利用playbook安装nginx

范例:install_nginx.yml

---
# install nginx
- hosts: websrvs
  remote_user: root
  tasks:
    - name: add group nginx
	  user: name=nginx state=present
	- name: add user nginx
	  user: name=nginx state=present group=nginx
	- name: Install Nginx
	  yum: name=nginx state=present
	- name: start Nginx
	  service: name=nginx state=started enabled=yes

1.5.3 利用playbook安装和卸载httpd

范例:install_httpd.yml

---
#install httpd
- hosts: websrvs
  remote_user: root
  gather_facts: no
  
  tasks:
    - name: Install httpd
	  yum: name=httpd state=present
	- name: Install configure file
	  copy: src=files/httpd.conf dest=/etc/httpd.conf/
	- name: web html
	  copy: src=files/index.html dest=/var/www/html/
	- name: start service
	  service: name=httpd start=started enabled=yes

范例:remove_httpd.yml

#remove_httpd.yml
---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: remove httpd package
	  yum: name=httpd state=absent
	- name: remove apache user
	  user: name=apache state=absent
	- name: remove data file
	  file: name=/etc/httpd state=absent

1.5.4 利用playbook安装mysql

范例:安装mysql-5.6.46-linux-glibc2.12

[root@ansible ~]# ls -l /data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_46.tar.gz
-rw-r--r-- 1 root root 403177622 Dec  4 13:05  /data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz

[root@ansible ~]# cat /data/ansible/files/my.cnf
[mysqld]
socket=/tmp/mysql.sock
user=mysql
symbolic-links=0
datadir=/data/mysql
innodb_file_per_tables=1
log-bin
pid-file=/data/mysql/mysqld.pid

[client]
port=3306
socket=/tmp/mysql.sock

[mysqld_safe]
log-error=/var/log/mysqld.log


[root@ansible ~]# cat /data/ansible/files/secure_mysql.sh
#!/bin/bash
/usr/local/mysql/bin/mysql_secure_installation <<EOF

y
zyixin
zyixin
y
y
y
y
EOF


[root@ansible ~]# cat /data/ansible/install_mysql.yml
---
# install mysql
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: install packages
	  yum: name=libaio,perl-Data-Dumper,perl-Getopt-Long
	- name: create mysql group
	  group: name=mysql gid=306
	- name: create mysql user
	  user: name=mysql uid=306 group=mysql shell=/sbin/nologin system=yes create_home=no hone=/data/mysql
	- name: copy tar to remote host and file mode
	  unarchive: src=/data/ansible/files/mysql-5.6.46-linux-glibc2.12-x86_64.tar.gz dest=/usr/local/ owner=root group=root
	- name: create linkfile /user/local/mysql
	  file: src=/usr/local/mysql-5.6.46-linux-glibc2.12-x86_64 dest=/usr/local/mysql state=link
	- name: data dir
	  shell: chdir=/usr/local/mysql/ ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
	  tags: data
	- name: config my.cnf
	  copy: src=/data/ansible/files/my.cnf dest=/etc/my.cnf
	- name: service script
	  shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
	- name: enable service
	  shell: /etc/init.d./mysqld start; chkconfig --add mysqld;chkconfig mysqld on
	  tags: service
	- name: PATH variable
	  copy: content='PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh
	- name: secure script
	  script: /data/ansible/files/secure_mysql.sh
	  tags: script

范例:install_mariadb.yml

---
#Installing MariaDB Binary Tarballs
- hosts: dbsrvs
  remote_user: root
  
  tasks:
    - name: create group
	  group: name=mysql gid=27 system=yes
	- name: create user
	  user: name=mysql uid=27 system=yes shell=/sbin/nologin home=/data/mysql create_home=no
	- name: mkdir datadir
	  file: path=/data/mysql owner=mysql group=mysql state=directory
	- name: unarchive package
	  unarchive: src=/data/ansible/files/mariadb-10.2.27-linux-x86_64.tar.gz dest=/usr/local/ owner=root group=root
	- name: link
	  file: src=/usr/local/mariadb-10.2.27-linux-x86_64 path=/usr/local/mysql state=link
	- name: install database
	  shell: chdir=/usr/local/mysql ./scripts/mysql_install_db --datadir=/data/mysql --user=mysql
	- name: config file
	  copy: src=/data/ansible/files/my.cnf dest=/etc/ backup=yes
	- name: service script
	  shell: /bin/cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
	- name: start service
	  service: name=mysqld state=started enabled=yes
	- name:PATH variable
	  copy: content='/PATH=/usr/local/mysql/bin:$PATH' dest=/etc/profile.d/mysql.sh

1.6 Playbook中使用handlers和notify

Handlers本质是task list,类似于Mysql中的触发器触发的行为,其中的task与前述的task并没有本质上的不同,主要用于当关注的资源发生变化时,才会采取一定的操作,而Notify对应的action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作,在notify中列出的操作称为handler,也即notify中调用handler中定义的操作
案例:

---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: Install httpd
      yum: name=httpd state=present
    - name: Install configure file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/
      notify: restart httpd
    - name: ensure apache in running
      service: name=httpd state=started enabled=yes

  handlers:
    - name: restart httpd
      service: name=httpd state=restarted

案例:

---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: add group nginx
      user: name=nginx state=present
    - name: add user nginx
      user: name=nginx state=present group=nginx
    - name: Install nginx
      yum: name=nginx state=present
    - name: config
      copy: src=/root/config.txt dest=/etc/nginx/nginx.conf
      notify:
        - Restart nginx
        - Check nginx process

  handlers:
    - name: Restart nginx
      service: name=nginx state=restarted enabled=yes
    - Check nginx process
      shell: killall -0 nginx &> /tmp/nginx.log

1.7 Playbook中使用tags组件

在playbook文件中,可以利用tags组件,为特定task指定标签,当在执行playbook时,可以只执行特定tags的task,而非整个playbook文件
案例:

---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: Install httpd
      yum: name=httpd state=present
    - name: Install configure file
      copy: name=files/httpd.conf dest=/etc/httpd/conf/
      tags: conf
    - name: start httpd service
      tags: service
      service: name=httpd state=started enabled=yes

__________________________________________________________________

[root@ansible ~]# ansible-playbook -t conf,service httpd.yml

1.8 Playbook中使用变量

变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量定义:

key=value

范例:

http_port=80

变量调用方式
通过{{ Variable_name }}调用变量,且变量名前后建议加空格,有时用"{{ Variable_name }}"才生效

变量来源
1、ansible的setup facts 远程主机的所有变量都可直接调用
2、通过命令行指定变量,优先级最高

ansible-playbook -e varname=value

3、在playbook文件中定义

vars:
  - var1: value1
  - var2: value2

4、在独立的变量YAML文件中定义

- hosts: all
  vars_files:
    - vars.yml

5、在/etc/ansible/hosts中定义
主机(普通)变量:主机组中主机单独定义,优先级高于公共变量
组(公共)变量:针对主机组中所有主机定义统一变量
6、在role中定义

1.8.1 使用 setup 模块中变量

案例:使用setup变量

---
#var.yml
- hosts: all
  remote_user: root
  
  tasks:
    - name: create log file
	  file: name=/data/{{ ansible_nodename }}.log state=touch owner=root mode=600

ansible-playbook var.yml

1.8.2 在playbook命令行中定义变量

范例:

[root@ansible ~]# vim var2.yml
---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: install package
	  yum: name={{ pkname }} state=present

[root@ansible ~]# ansible-playbook -e pkname=httpd var2.yml

1.8.3 在playbook文件中定义变量

范例:

[root@ansible ~]# vim var3.yml
---
- hosts: websrvs
  remote_user: root
  vars:
    - username: user1
	- groupname: group1
  
  tasks:
    - name: create group
	  group: name={{ groupname }} state=present
	- name: create user
	  user: name={{ username }} group={{ groupname }} state=present
	  
[root@ansible ~]# ansible-playbook -e "username=user2 groupname=group2" var3.yml

1.8.4 使用变量文件

可以在一个独立的playbook文件中定义变量,在另一个playbook文件中引用变量文件中的文件,比playbook中定义的变量优先级高

[root@ansible ~]# vim vars.yml
---
# variables file
package_name: vsftpd
service_name: vsftpd

[root@ansible ~]# vim install_app.yml
---
- hosts: appsrvs
  remote_user: root
  vars_files:
    - vars.yml
	
  tasks:
    - name: install package
	  yum: name={{ package_name }}
	  tags:install
	- name: start service
	  service: name={{ service_name }} state=started enabled=yes

范例:

[root@ansible ~]# cat vars2.yml
---
var1: httpd
var2: nginx

[root@ansible ~]# cat var5.yml
---
- hosts: websrvs
  remote_user: root
  vars_files:
    - vars2.yml
	
  tasks:
    - name: create httpd log
	  file: name=/app/{{ var1 }}.log state=touch
	- name: create nginx log
	  file: name=/app/{{ var2 }}.log state=touch

1.8.5 主机清单文件中定义变量

主机变量:
在inventory 主机清单文件中为指定的主机定义变量以便于在playbook中使用
范例:

[websrvs]
www1.zyixin.com http_port=80 maxRequestsPerChild=808
www2.zyixin.com http_port=8080 maxRequestsPerChild=909

组(公共)变量:
在inventory 主机清单文件中赋予给指定组内所有主机上的在playbook中可用的变量
范例:

[websrvs]
www1.zyixin.com
www2.zyixin.com

[websrvs:vars]
ntp_server=ntp.zyixin.com
nts_server=nfs.zyixin.com

范例:

[root@ansible ~]# vim /etc/ansible/hosts
[websrvs]
192.168.139.100 http_port=8080 hname=www1
192.168.139.200 http_port=80   hname=www2

[websrvs:vars]
http_port=808
mark="-"
[websrvs]
192.168.139.100 http_port=8080 hname=www1

192.168.139.200 http_port=80 hanme=www2

[root@ansible ~]# ansible websrvs -m hostname -a 'name={{ hname }}{{ mark }}{{ http_port }}'

#命令行指定变量:
ansible websrvs -e http_port=8000 -m hostname -a 'name={{ hname }}{{ mark }}{{ http_port }}'

1.9 template 模板

模板是一个文本文件,可以做为生成文件的模板,并且模板文件中还可嵌套jinja语言

1.9.1 jinja2语言

jinja2 语言使用字面量,有下面形式:
字符串:使用单引号或双引号
数字:整数,浮点数
列表:[item1,item2,…]
元组:[item1,item2,…]
字典:{key1:value1,key2:value2,…}
布尔型:true/false
算术运算:+,-,,/,//,%,*
比较操作:==,!=,>,>=,<,<=
逻辑运算:and,or,not
流表达式:For,if,When
jinja2相关

字面量:
表达式最简单的形式就是字面量。字面量表示诸如字符串和数值的Pythen对象。如"Hello World"
双引号或单引号中间的一切都是字符串。无论何时你需要在模板中使用一个字符串(比如函数调用、过滤器或只是包含或继承一个模板的参数),如42,42.23
数值可以为整数和浮点数。如果有小数点,则为浮点数,否则为整数。在Pythen里,42和42.0是不一样的

算术运算:
jinja2允许用计算值。支持下面的运算符
+:把两个对象加到一起。通常对象是素质,但是如果两者是字符串或列表,你可以用这种方式来衔接它们。无论如何这不是首选的连接字符串的方式!连接字符串见 ~ 运算符。{{ 1+1 }}等于2
-:用第一个数减去第二个数。{{ 3-2 }}等于1
/:对两个数做除法。返回值会是一个浮点数。{{ 1/2 }}等于{{ 0.5 }}
//:对两个数做除法,返回整数商。{{ 20//7 }}等于2
%:计算整数除法的榆树。{{ 11%7 }}等于4
* :用右边的数乘左边的操作数。{{ 2*2 }}会返回4.也可以用于重复一个字符串多次。{{ '='80 }}会打印80个等号的横条
** :取左操作数的右操作数次幂。{{ 2 *
3 }}会返回8

比较操作符
== 比较两个对象是否相等
!= 比较两个对象是否不等
> 如果左边大于右边,返回true
>= 如果左边大于等于右边,返回true
< 如果左边小于右边,返回true
<= 如果左边小于等于右边,返回true

逻辑运算符
对于if语句,在for过滤或if表达式中,它可以用于联合多个表达式
and 如果左操作数和右操作数同为真,返回true
or 如果左操作数和右操作有一个为真,返回true
not 对一个表达式取反
(expr)表达式组
true / false true 永远是true,而false始终是false

1.9.2 template

template功能:可以根据和参考模块文件,动态生成相类似的配置文件
template文件必须存放于templates目录下,且命名为.j2结尾
yaml/yml文件需和template目录平级,目录结构如下

	./
	├── temnginx.yml
	└── templates
		└── nginx.conf.j2

范例:利用template同步nginx配置文件

#准备templates/nginx.conf.j2文件
[root@ansible ~]# vim temnginx.yml
---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: template config to remote hosts
	  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
	  
[root@ansible ~]# ansible-playbook temnginx.yml

template变更替换
范例:

# 修改文件nginx.conf.j2
[root@ansible ~]# mkdir templates
[root@ansible ~]# vim templates/nginx.conf.j2
worker_processes {{ ansible_processor_vcpus }};

[root@ansible ~]# vim template.yml
---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: install nginx
	  yum: name=nginx
    - name: template config to remote hosts
	  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
	- name: start service
	  service: name=nginx state=started enabled=yes
	  
[root@ansible ~]# ansible-playbook temnginx.yml

template算术运算
范例:

[root@ansible ~]# vim nginx.conf.j2
worker_processes {{ ansible_processor_vcpus**2 }}
worker_processes {{ ansible_processor_vcpus+2 }}

1.9.3 template中使用流程控制 for 和 if

template中也可以使用流程控制 for 循环和 if 条件判断,实现动态生成文件功能
范例:

[root@ansible ~]# cat temnginx1.yml
#temnginx1.yml
---
- hosts: websrvs
  remote_user: root
  vars:
    nginx_vhosts:
	  - listen: 8080
  tasks:
    - name: config file
	  template: src=nginx.conf1.j2 desr=/data/nginx2.conf
	  

[root@ansible ~]# cat templates/nginx.conf1.j2
{% for vhost in nginx_vhosts %}
server {
  listen {{ vhost.listen }}
}
{% endfor %}

#生成的结果
server{
  listen 8080
}

范例:

[root@ansible ~]# cat temnginx2.yml
---
- hosts: websrvs
  remote_user: root
  vars:
    nginx_vhosts:
	  - 81
	  - 82
	  - 83
  tasks:
    - name: template config
	  template: src=nginx.conf2.j2 dest=/etc/nginx/nginx.conf
	  
[root@ansible ~]# cat templates/nginx.conf2.j2
{% for vhost in nginx_vhosts %}
server{
  listen {{ vhost }} ;
}
{% endfor %}

#生成的结果
server{
  listen 81
}
server{
  listen 82
}
server{
  listen 83
}

范例:

[root@ansible ~]# cat temnginx3.yml
#temnginx3.yml
- hosts: websrvs
  remote_user: root
  vars:
    nginx_vhosts:
	  - listen:8080
	    server_name: "web1.zyixin.com"
		root: "/var/www/nginx/web1"
      - listen: 8081
	    server_name: ""web2.zyixin.com
		root: "/var/www/nginx/web2"
	  - {listen: 8082, server_name: "web3.zyixin.com", root:"/var/www/nginx/web3"}
  tasks:
    - name: template config
	  template: src=nginx3.conf.j2 dest=/data/nginx3.conf
	  
[root@ansible ~]# cat templates/nginx3.conf.j2
# templates/nginx3.conf.j2
{% for vhost in nginx_vhosts %}
server {
   listen {{ vhost.listen }}
   server_name {{ vhost.server_name }}
   root {{ vhost.root }}
}
{% endfor %}

#生成的结果
server{
   listen 8080
   server_name web1.zyixin.com
   root /var/www/nginx/web1/
}
server{
   listen 8081
   server_name web2.zyixin.com
   root /var/www/nginx/web2/
}
server{
   listen 8082
   server_name web3.zyixin.com
   root /var/www/nginx/web3/
}

在模块文件中还可以使用if条件判断,决定是否生成相关的配置信息
范例:

[root@ansible ~]# cat templnginx5.yml
- hosts: websrvs
  remote_user: root
  vars:
    nginx_vhosts:
	  - web1:
	    listen: 8080
		root: "/var/www/nginx/web1/"
	  - web2:
	    listen: 8080
		server_name: "web2.zyixin.com"
		root: "/var/www/nginx/web2/"
	  - web3:
	    listen: 8080
		server_name: "web3.zyixin.com"
		root: "/var/www/nginx/web3/"
  tasks:
    - name: template config to
	  template: src=nginx5.conf.j2 dest=/data/nginx5.conf
	  
[root@ansible ~]# cat templates/nginx5.conf.j2
#templates/nginx5.conf.j2
{% for vhost in nginx_vhosts %}
server{
   listen {{ vhost.listen }}
   {% if vhost.server_name is defined %}
server_name {{ vhost.server_name }}
   {% endif %}
root {{ vhost.root }}
}
{% endfor %}


#生成的结果
server{
   listen 8080
   root /var/www/nginx/web1/
}
server{
   listen 8080
   server_name web2.zyixin.com
   root /var/www/nginx/web2/
}
server{
   listen 8080
   server_name web3.zyixin.com
   root /var/www/nginx/web3/
}

1.10 playbook使用when

when语句,可以实现条件测试。如果需要根据变量、facts或此前任务的执行结果来做为某task执行与否的前提时要用到条件测试,通过在task后添加when子句即可使用条件测试,jinja2的语句格式
范例:

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: "shutdown RedHat flavored system"
	  command: /sbin/shutdown -h now
	  when: ansible_os_family == "RedHat"

范例:

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: add group nginx
	  tags: user
	  user: name=nginx state=present
	- name: add user nginx
	  user: name=nginx state=present group=nginx
	- name: Install Nginx
	  service: name=nginx state=restarted
	  when:ansible_distribution_major_version == "6"

范例:

---
- hosts: websrvs
  remote_user: root
  tasks:
    - name: install conf file to centos7
	  template: src=nginx.conf.c7.j2 dest=/data/nginx_7.conf
	  when: ansible_distribution_major_version == "7"
	- name: install conf file to centos6
	  template: src=nginx.conf.c6.j2 dest=/data/nginx_6.conf
	  when: ansible_distrbution_major_version == "6"

1.11 playbook 使用迭代 with_items

迭代:当有需要重复性执行的任务时,可以使用迭代机制
对迭代项的引用,固定变量名为"item"
要在task中使用with_items给定要迭代的元素列表

列表元素格式
· 字符串
· 字典

范例:

---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: add serverl users
	  user: name={{ item }} state=present group=wheel
	  with_items:
	    - testuser1
		- testuser2

#上面语句的功能等同于下面的语句
    - name: add user testuser1
	  user: name=testuser1 state=present groups=wheel
	- name: add user testuser2
	  user: name=testuser2 state=present groups=wheel

范例:

---
#remove mariadb server
- hosts: dbsrvs:!192.168.139.200
  remote_user: root
  
  tasks:
    - name: stop service
	  shell: /etc/init.d/mysqld stop
	- name: delete files and dir
	  file: path={{ item }} state=absent
	  with_items:
	    - /usr/local/mysql
		- /usr/local/mariadb-10.2.27-linux-x86_64
		- /etc/init.d/mysqld
		- /etc/profile.d/mysql.sh
		- /etc/my.cnf
		- /data/mysql
	- name: delete user
	  user: name=mysql state=absent remove=yes

范例:

---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: install some packages
	  yum: name={{ item }} state=present
	  with_items:
	    - nginx
		- memcached
		- php-fpm

范例:

---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: copy file
	  copy: src={{ item }} dest=/tmp/{{ item }}
	  with_items:
	    - file1
		- file2
		- file3
	- name: yum install httpd
	  yum: name={{ item }} state=present
	  with_items:
	    - apr
		- apr-util
		- httpd

迭代嵌套子变量: 在迭代中,还可以嵌套子变量,并联多个变量在一起使用
示例:

---
- hosts: websrvs
  remote_user: root
  
  tasks:
    - name: add some groups
	  group: name={{ item }} state=present
	  with_items:
	    - nginx
		- mysql
		- apache
	- name: add some users
	  user: name={{ item.name }} group={{ item.group }} state=present
	  with_items:
	    - { name: 'nginx', group: 'nginx' }
		- { name: 'mysql', group: 'mysql' }
		- { name: 'apache', group: 'apache' }

范例:

---
- hosts: websrvs
  remote_user: root

  tasks:
    - name: add some groups
      group: name={{ item }} state=present
      with_items:
        - g1
        - g2
        - g3
    - name: add some users
      user: name={{ item.name }} group={{ item.group }} home={{ item.home }} create_home=yes state=present
      with_items:
        - { name: 'user1', group: 'g1', home: '/data/user1' }
        - { name: 'user2', group: 'g2', home: '/data/user2' }
        - { name: 'user3', group: 'g3', home: '/data/user3' }

0

评论区