ansible

文章目录

一、ansible基本目录架构

yum install epel-release
yum install ansible

1、目录及文件说明

/etc/ansible/ansible.cfg   主配置文件,配置ansible工作特性
/etc/ansible/hosts			管理主机清单
/etc/ansible/roles			角色

常用二进制文件
/usr/bin/ansible
/usr/bin/ansible-doc
/usr/bin/ansible-playbook

2、主配置文件参数说明

cat /etc/ansible/ansible.cfg

#inventory      = /etc/ansible/hosts  #主机列表配置文件
#library        = /usr/share/my_modules/   #库文件存放目录
#remote_tmp     = ~/.ansible/tmp			#临时py命令文件存放在远程主机目录
#local_tmp      = ~/.ansible/tmp			#本机的临时命令执行目录
#forks          = 5							#默认并发数
#sudo_user      = root						#默认sudo用户
#ask_sudo_pass = True						#每次执行ansible命令是否询问ssh密码
#remote_port    = 22						
#host_key_checking = False					#检查对应服务器的host_key,建议取消注释
#log_path = /var/log/ansible.log			#日志文件

二、ansible SSH优化

1、关闭密钥检测(远程主机公钥检测,不要提示yes)

#vim /etc/ansible/ansible-cfg
host_key_checking=False
cat /etc/.ssh/known_hosts

2、openssh连接优化 (远程主机)

vim /etc/ssh/sshd_config
GSSAPIAuthentication no
UseDNS no

3、ansible facts缓存优化

在playbook中,加入:
gather_facts: no

4、ControlPcrsist SSH优化 (远程主机)

SSH会话保持功能,客户端 一次连接上SSH后,再去连接时,不用重新连接,直接复用会话

cat>>/root/.ssh/config <<-EOF        
Host *
  Compression yes
  ServerAliveInterval 60
  ServerAliveCountMax 5
  ControlMaster auto
  ControlPath ~/.ssh/%r@%h-%p
  ControlPersist 4h
EOF

三、ansible基本命令使用

1、语法简介

ansible  ansible-doc   ansible-playbook ansible-vault
ansible-console    ansible-galaxy ansible-pull

ansible-doc

ansible-doc: 后接模块名,显示模块帮助
	-a 显示所有模块的文档
	-l,--list 列出可用模块
	-s,--snippet 简短说明(常用),显示指定模块的playbook片段,如:ansible-doc ping ; ansible-doc -s ping 查看指定模块帮助用法

ansible通过ssh实现配置管理,应用部署,任务执行等功能,建议配置ansible端能基于密钥认证的方式联系各被管理节点
语法:
ansible <host-pattern> [-m module_name] [-a args]  
(ansible 主机 -m  模块名 -a  参数),如ansible all -m shell -a 'ping -c 2 www.baidu.com' -k
	--version 显示版本
	-m module 指定模块,默认为command
	-v 详细过程 -vv -vvv更详细
	--list-host 显示主机列表,可简写 --list
	-k,--ask-pass 提示输入ssh连接密码,默认key验证
	-K ,--ask-become-pass 提示输入sudo时的口令
	-C ,--check 检查,并不执行
	-T, --timeout=TimeOut 执行命令的超时时间,默认10s
	-u ,--user=Remote_user 执行远程执行的用户
	

2、ansible的host-pattern 匹配主机的列表

all: 表示所有的inventory中的所有主机
	* :通配符
		ansible "*"  -m ping 
		ansible 192.168.1.* -m ping
		ansible "*server" -m ping
	或关系 ":"
		ansible 'web:db' -m ping
		ansible '192.168.1.10:192.168.1.11' -m ping
	逻辑与 ":&"
		ansible 'web:&db' -m ping
		在web组并且在db组 中都存在的主机
	逻辑非
		ansible 'web:!db' -m ping
		在web组,但不在db组中的主机,注:这里为单引号
	综合逻辑
		ansible 'web:db:&app:!ftp' -m ping  #在web或db中,且在app中,且不在ftp中
	正则表达式
		ansible "web:&db" -m ping
		ansible "~(web|db).*\.otoyix\.com" -m ping

3、ansible命令执行过程

1)、加载自己的配置文件,默认/etc/ansible/ansible.cfg
2)、加载自动对应的模块文件,如command
3)、通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-xxxx/xxx.py文件
4)、给文件+x 执行权限
5)、执行并返回结果
6)、删除临时py文件,sleep 0 退出

4、执行状态

绿色:执行成功并且不需要做改变的操作
黄色:执行成功并且对目标主机做变更
红色:执行失败

5、ansible-vault

功能:管理加密解密yml文件
ansible-vault [create|decrypt|edit|encrypt|rekey|view]
ansible-vault encrypt hello.yml   #加密
ansible-vault decrypt hello.yml   #解密
ansible-vault view hello.yml    #查看 
ansible-vault edit hello.yml    #编辑加密文件
ansible-vault rekey hello.yml   #修改口令
ansible-vault create new.yml    #创新新文件

6、ansible-console: 2.0+ 新增加的,可交互执行命令,支持tab

执行用户@当前操作的主机组(当前组的主机数量)[f:并发数]$
设置并发数:forks 3 #设置并发为3
切换组: cd 主机组 #cd dbserver
列出当前组主机列表:list
列出所有的内置命令: ?或help
示例:

root@all (3)[f:5]$ cd 192.168.1.12
root@192.168.1.12 (1)[f:5]$ list
192.168.1.12
root@192.168.1.12 (1)[f:5]$ hostname name=1_12
192.168.1.12 | CHANGED => {
	"ansible_facts": {
		"ansible_domain": "", 
		"ansible_fqdn": "1_12", 
		"ansible_hostname": "1_12", 
		"ansible_nodename": "1_12", 
		"discovered_interpreter_python": "/usr/bin/python"
	}, 
	"changed": true, 
	"name": "1_12"
}

四、ansible常用模块 详解

1、Command模块 :

在远程主机执行命令,默认模块,可忽略-m选项

ansible dbserver -m command -a 'pwd'
 ansible all -m command -a 'pwd|grep oo'  不成功
注: 此命令在-a 中不支持 $varname < > | ; &等,可以用shell模块来实现

chdir : 相当于cd
	ansible all -a 'chdir=/boot ls' #进入boot目录中再执行命令ls
creates
	ansible all -a 'creates=/etc/passwd  df -Th' #如果/etc/passwd文件存在,则不执行后面的命令操作
removes
	ansible all -a 'removes=/etc/passwd2  df -Th' # 如果文件存在,则执行后面的操作,也就是如果文件不存在,则不执行后面的命令操作(与creates相反的意思)
	

2、shell 模块

和command相似,用shell执行命令

ansible all -m shell -a 'pwd|grep oo'
调用bash命令,支持command不支持的复杂命令。但也有可能会失败,建议先写脚本、copy到远程 再执行脚本,再把需要的结果拉回执行命令的机器
注:也同样使用cddir creates removes参数

3、script 模块

运行脚本

#不需要将脚本文件发送至远程服务器,只要ansible机器中存在,可以直接运行
ansible db -m script -a "/root/ansible/f1.sh"

4、copy 模块

backup  如果远程主机存在同名且内容不一致时的文件时,则会备份远程主机中的文件
dest   #远程主机 文件存放路径
mode   #权限
owner  #所有者
src	   #源,ansible机器中要复制的哪个文件
content #直接将内容写入到目标主机中 
ansible all -m copy -a 'content="hello\notoyix\nsss" dest=/tmp/f1.txt' #如果文件存在,则直接清除内容后写入
ansible all -m copy -a 'src=/root/test dest=/root/test backup=yes mode=0777 owner=test2 group=test2'
注:
1、当文件内容一样时,不会发重复制
2、目录时,会复制到dest/下,且backup时,不会备份整个目录,而是备份其中相同文件名(内容不一样时)
ansible 192.168.1.10,192.168.1.12 -m copy -a 'src=/root/dir dest=/root/ backup=yes mode=0777 owner=test2 group=test2'

5、Fetch 模块

从客户端拉取文件(一个文件且不能是目录)至ansible主机,与copy相反,目录时,建议先执行tar打包后 再拉取

ansible 192.168.1.12 -m fetch -a 'src=/data/a.log dest=/data/logs/'
拉取后,会多生成目录,上面一条路径为 /data/logs/192.168.1.12/data/a.log

6、file 模块

设置文件属性

ansible 192.168.1.12 -m file -a 'path=/tmp/test.log state=touch' 
#创建文件,这里的path可以换成name或dest,效果一样
ansible web -m file -a 'src=/app/testfile dest=/app/testfile-link state=link'
state : 
directory(目录,没有则创建)、
file(与directory,返回文件的状态,不会创建)、	
touch(空文件) 、
link(软链接)、
absent(删除及递归删除)
也有mode owner group参数
ansible 192.168.1.12 -m file -a 'name=/tmp/test state=absent' #删除文件与目录

7、hostname 模块

修改主机名

ansible 192.168.1.12 -m hostname -a 'name=12' 
#立即且永久生效,centos7中改了/etc/hostname文件,但没有改/etc/hosts文件

8、cron 模块 :计划任务

支持时间:minute,hour,day,month,weekday
ansible web -m cron -a 'minute=*/5 weeekday=1,2,5 job="/usr/sbin/sh /data/sh/a.sh" name=a_script' #创建任务
ansible db -m cron -a 'state=absent name=a_script' #删除任务
ansible db -m cron -a 'disabled=true job="/usr/sbin/sh /data/sh/a.sh" name=a_script'   #禁用任务
ansible db -m cron -a 'disabled=flase job="/usr/sbin/sh /data/sh/a.sh" name=a_script'   #启动任务,disabled也可以使用yes或no

9、yum 模块 :包管理

ansible dbserver -m yum -a 'mane=httpd,vsftpd state=latest' #安装
ansible dbserver -m yum -a 'name=httpd,vsftpd state=absent' #卸载

state: 
	installed/latest/present(安装,默认选项) 、
	absent/removed(卸载)

ansible dbserver -m yum -a 'name=/data/xxx.rpm disable_gpg_check=yes' #在远程主机上安装离线rpm包,禁用gpg检查
ansible dbserver -m yum -a 'name=dstat update_cache=yes' #更新缓存(需要附带装一个包)

10、service 模块 :管理服务

pattern: 	模式
enabled :	是否开机启动
name: 	  	服务名
runlevel: 	启动级别
state:		stopped/started/reloaded/restarted
ansible  db -m service -a 'name=httpd state=started  enabled=yes'

11、User 模块 :管理用户

comment:		注释
create_home:	是否创建家目录
expires:		过期时间
group: 			主组
groups:			附加组
home:			家目录
shell:  		shell类型,/sbin/noloin等
name:			用户名
password:		加密口令
remove:			删除用户家目录
state: 			absent、persent(创建、修改 默认)等
system:			是否是系统帐号 
ansible all -m user -a 'name=user1 system=yes comment="test user" uid=1000 home=/home/user1 group=user1 groups=root,bin'#创建、修改用户
ansible all -m user -a 'name=user1 state=absent remove=yes'#删除用户及家目录

12、Group 模块 :管理组

gid :	组ID
name:	组名
state: 	absent、present(默认)
system:	yes/no(默认)
ansible all -m group -a 'name=testgroup system=yes'
ansible all -m group -a 'name=testgroup state=absent'
ansible all -m group -a 'name=test10 gid=1011' #常用 修改组ID

13、setup 模块 : 查看远程主机变量信息

(变量名查看,以被ansible-playbook引用)

filter:  过滤,返回 正则匹配后的信息
 ansible 192.168.1.12 -m setup -a 'filter=*address*'

14、template 模板

将一个文件当作为模块文件传至远程主机
注:
jinja2为模板语言 且 只能用于 playbook中,不用用于AD hoc

template 示例:
./
├── nginxtemplates.yml
└── templates
    └── nginx.conf.j2
	
cat nginxtemplates.yml 
---
- hosts: all
  remote_user: root
  tasks:
    - name: 'cp nginx.conf'
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf backup=yes
      notify: restart nginx
	  when: ansible_all_ipv4_addresses==192.168.1.12


cat templates/nginx.conf.j2 |grep process
#worker_processes auto;
worker_processes {{ ansible_processor_vcpus + 1 }};

五、ansible-galaxy

url https://galaxy.ansible.com 下载相应的roles

列出所有已安装的galaxy
	ansible-galaxy list
安装galaxy #联网安装
	ansible-galaxy install geerlingguy.nginx
	会自动下载解压 /root/.ansible/roles/geerlingguy.nginx
删除galaxy
	ansible-galaxy remove geerlingguy.nginx

六、ansible playbook基础

1、语法: ansible-playbook [options] playbook.yml [playbook2 …]

options:
	-C,--check :#只检查不真正执行
	--list-hosts :	#列出运行任务的主机
	--limit #主机列表,只在特定主机列表中的主机执行 ,也可以为单台主机,示例:ansible-playbook file.yml --limit webs #只在webs中执行
	-v ,-vv ,-vvv 更详细
	--list-tasks #查看tasks任务列表
	--list-tags #只看tags
ansible-playbook hello.yml
cat hello.yml
---(这里习惯写---开头,可以不写)
#hello world yml file
- hosts: webs
  remote_user: root
  
  tasks:
    - name: hello word
	  command: /usr/bin/wall hello word

2、原理:

playbook是由一个或多个’play’组成的列表
play的主要功能在于将事先归并为一组的主机装扮成事先通过ansible中的task定义好的角色。从根本上来讲,所谓task无非是调用ansible的一个module。将多个play组织在一个playbook中,即可以让它们连同起来按事先编排的机制同唱一台大戏
playbook采用yaml语言编写

3、playbook核心元素

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

ansible-playbook -t tagsname useradd.yml

4、playbook基础组件

hosts:

playbook中的每一个play的目的都是为了让某个或些主机以某个指定的用户身份执行任务。
hosts用于指定要执行指定任务的主机,须事先定义在主机清单中:
可以是如下形式:
	a.otoyix.com
	a.otoyix.com:b.otoyix.com
	192.168.1.12
	192.168.1.*
	webs:dbs	 #两个组的并集
	webs:&dbs #两个组的交集
	webs:!dbs #webs,但不在dbs组中
	
示例: - hosts: webs:dbs
remote_user:
可用于hosts和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;
此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
- hosts: webs
  remote_user: root
  tasks:
	- name: test connect
	  ping:
	  remote_user: test
	  sudo: yes			#默认sudo为root
	  sudo_user: wang	#sudo为wang

task列表和action

play的主体部分是task list。task list中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后再开始第二个。在运行自上而下某playbook时,如果中途发生错误,所有已执行任务都将回滚,因此,在更正playbook后重新执行一次即可
task的目的是使用指定的参数执行模块,而在模块参数中可以使用变量。模块执行是幂等的,这意味着多次执行是安全的,因为其结果均一致。
每个task都应该有其name,用于playbook的执行结果输出,建议其内容尽可能清晰地描述任务执行步骤。如果未提供name ,则action的结果将用于输出

格式语法:
	语法方法一: action: module arguments
	语法方法二: module: arguments (建议使用)
方法二语法格式示例:
	tasks:
	  - name: path
	    shell: pwd

注:shell和command模块后面跟命令,而非 key=value
1、 某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers。
2、 任务可以通过"tags" 打标签,而后可以ansible-playbook命令上使用-t指定进行调用。
3、在tasks中,一个name对应一个模块,哪怕是相同的模块,如果有,会有一个不执行,建议分多个name中

5、playbook错误不退出,继续执行的方法

方法一:||/bin/true 或一个为真的语句,让此行的整体结果为真
	tasks:
	  - name: run command
	    shell: /usr/bin/xxxx || /bin/true  #在后面加上||/bin/true,相当于在后面 或了一个为真的执行语句,这样整体结果值为 真了,就不会能出 
	    
方法二:使用ignore_errors来忽略错误信息
	tasks:
	  - name: run command
	    shell: /usr/bin/xxx
        ignore_errors: True  #加上ignore_errors: True

注:playbook中的相对路径为 /root/ansible/ (用户家目录下的ansible目录)

七、notify 与 handlers、tags 及 变量使用

1、notify和 handlers结合使用触发条件

handlers 是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作
notify此action可用于每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作
notify和 handlers示例:
- hosts: webs
  remote_user: root
  
  tasks:
    - name: "安装httpd包"
	  yum: name=httpd
	- name: "复制替换配置文件"
	  copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
	  notify: 		#当这块action发生变化时,会触发notify,会通知下面的两个handlers 动作,这里可以匹配1个或多个 handlers 动作
	    - restart service  
	    - check process
	- name: "启动服务"
	  service: name=httpd state=started enabled=yes
	  
  handlers:
    - name: restart service
	  service: name=httpd state=started
	- name: check process
	  shell: killall -0 httpd >>/var/log/test.log

2、playbook中tags使用

注:如果 ansible-playbook 时没有加上 -t 或–tags 时,那么代表标签不生效,代表自动匹配上了所有的标签,会执行有或没有标签的任务
tags示例:

- hosts: webs
  remote_user: root
  tasks:
    - name: install httpd
	  yum: name=httpd
    - name: cp config file
	  copy: src=files/httpd.conf dest=/etc/httpd/conf/
	  tags: conf     #这里
    - name: start httpd service
	  tags: service  #这里
	  service: name=httpd state=started enabled=yes
	  
可以 
  tags: 
    - install
    - deploy

ansible-playbook -t conf httpd.yml #只执行 指定conf标签的动作,其他不作执行

注: 在一个yml文件中,tags可以相同,ansible-playbook时按先后顺序执行,ansible-playbook时也可以使用多个–tag= --tag=

3、playbook 变量

优先级:playbook -e > epl.yml > hosts
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源:
1)、ansible setup facts 远程主机的所有变量都可直接调用
		ansible  -m setup 
2)、在/etc/ansible/hosts中定义
		变通变量:主机组中主机单独定义,优先级高于公共变量
		[websrvs]
		192.168.1.12 http_port=82
		192.168.1.11 http_port=81
		公共(组)变量:针对主机组中所有主机定义统一变量
		[websrvs]
		......
		[websrvs:vars]  #对websrvs组中所有成功有效
		env=www
		domainname=otoyix.com
3)、通过命令行指定变量,优先级最高

示例

---
- hosts: appsrvs
  remote_user: root
  
  tasks:
    - name: '安装软件包'
	  yum: name={{ appname }}
    - name: '启动服务 及 设置开机自动启动'
	  service: name={{ appname }} state=started enabled={{ appenable }}

调用
	ansible-playbook xxx.yml -e 'appname="nginx" appenable="yes"'
4)、在playbook中定义

示例:
---
- hosts: appsrvs
  remote_user: root
  vars:
    - appname: vsftpd
	- appenable: yes
  tasks:
    - name: '安装软件包'
	  yum: name={{ appname }}
    - name: '启动服务 及 设置开机自动启动'
	  service: name={{ appname }} state=started enabled={{ appenable }}			  
		
5)、在role中定义(vars.yml文件)

使用变量文件中定义

示例:

tree .
.
├── appinstll.yml
└── vars.yml

cat vars.yml 
var1: httpd
var2: vsftpd


cat appinstll.yml 
- hosts: web12
  remote_user: root
  vars_files:
    - vars.yml
  tasks:
    - name: install package
      yum: name={{ var1 }}
    - name: create file
      file: name=/tmp/{{ var2 }}.log state=touch mode=644

八、playbook 模板templates

文本文件,嵌套有脚本(使用模板编程语言编写)

1、Jinja2语言,使用字面量,有下面形式

字符串:		使用单引号或双引号
数字:		整数,浮点数
列表:		[item1,item2...]
元组:		(item1,item2,...)
字典:		{key1:value1,key2:value2,...}
布尔型:		true/false
算术运算:	+,-,*,/,//(整除,不要小数点),%(取模),**(幂次方,取指数)
比较运算:	==,!=,>,>=,<,	<=
逻辑运算:	and,or,not
流表达式:	For  IF  When

2、templates功能:

根据模块文件动态生成对应的配置文件

templates文件必须存放在templates目录下,且命名为.j2结尾
yaml/yml文件需和templates目录平级,目标结构如下:

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

基础 templates示例:
cp /etc/nginx/nginx.conf templates/nginx.conf.j2
vim testtemplates.yml
---
- hosts: 192.168.1.12
  remote_user: root
  
  tasks:
    - name: install package
	  yum: name=nginx
	- name: cp templates
	  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf  #这里的模块文件得放至templates目录中,或写绝对路径
	- name: start nginx
	  service: name=nginx state=started enabled=yes
	
ansible-playbook testtemplates.yml
变量 templates 示例
./
├── nginxtemplates.yml
└── templates
    └── nginx.conf.j2
	
cat nginxtemplates.yml 
---
- hosts: all
  remote_user: root

  tasks:
    - name: 'install package'
      yum: name=nginx
    - name: 'cp nginx.conf'
      template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf backup=yes
      notify: restart nginx
	  when: ansible_all_ipv4_addresses==192.168.1.12
    - name: 'service nginx'
      service: name=nginx state=started enabled=yes
  handlers:
    - name: restart nginx
      service: name=nginx state=restarted

cat templates/nginx.conf.j2 |grep process
#worker_processes auto;
worker_processes {{ ansible_processor_vcpus + 1 }};

#注:上面 notify触发handlers的执行器,变量为ansible_processor_vcpus

七、playbook 条件判断when

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

示例:

- name: 'cp nginx.conf'
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf backup=yes
  notify: restart nginx
  when: ansible_all_ipv4_addresses == ["192.168.1.12"]
	  

九、playbook字典 with_items

1、迭代:当有需要重复性执行的任务时,可以使用迭代机制

对迭代项的引用,固定变量名为“item”
要在task中使用with_items给定要迭代的元素列表
表格格式:
	字符串
	字典

示例:

---
- hosts: web
  remote_user: root

  tasks:
    - name: '创建多个文件'
      file: name=/tmp/{{ item }} state=touch mode=755
      with_items:
        - file1
        - file2
        - file3
    - name: install package
      yum: name={{ item }}
      with_items:
        - vsftpd
        - sl
        - hping3		

2、playbook中迭代嵌套子变量:

示例:创建user1 user2 user3分别属于g1 g2 g3组,用户与组ID分别为 1051 1052 1053

---
- hosts: web
  remote_user: root
  tasks:
    - name: create some groups
      group: name={{ item.name }} gid={{ item.gid }}
      with_items:
        - {name: 'g1',gid: '1051'}
        - {name: 'g2',gid: '1052'}
        - {name: 'g3',gid: '1053'}
    - name: create users
      user: name={{ item.name }}  uid={{ item.uid }} group={{ item.gruop }}
      with_items:
        - {name: 'user1',uid: '1051',gruop: 'g1'}
        - {name: 'user2',uid: '1052',gruop: 'g1'}
        - {name: 'user3',uid: '1053',gruop: 'g1'}

3、template中使用 for

cat testfor.yml

---
- hosts: web
  remote_user: root
  vars:
    ports:
      - 81
      - 82
      - 83
  tasks:
    - name: copy conf
      template: src=testfor.conf.j2 dest=/tmp/for.conf

cat templates/testfor.conf.j2 
{% for port in ports %}
server {
    listen {{ port }}
}
{% endfor%}

结果:目标主机
 cat /tmp/for.conf 
server {
    listen 81
}
server {
    listen 82
}
server {
    listen 83
}

另:“template中使用 for” 可以演变为 字典 键值对形式

vim testfor.yml(改vars中的一段)
  vars:
    ports:
      - web1:
        domain: a.otoyix.com
        port: 81
      - web2:
        domain: b.otoyix.com
        port: 82
      - web3:
        domain: c.otoyix.com
        port: 83
vim templates/testfor.conf.j2
{% for listenport in ports %}
server {
    listen {{ listenport.port }} #注:这里的web1后也可以写内容,与domain port是平级的,这里为了好看,就没有写内容了
}
{% endfor%}
结果一样

4、template中使用 if

vim testif.yml
---
- hosts: web
  remote_user: root
  vars:
    ports:
      - web1:
        domain: a.otoyix.com
        port: 81
      - web2:
        domain: b.otoyix.com
        port: 82
      - web3:
        domain: c.otoyix.com
        port: 83
  tasks:
    - name: copy conf
      template: src=testif.conf.j2 dest=/tmp/if.conf
	  
vim templates/testif.conf.j2
{% for p in ports %}
server {
    listen {{ p.port }}
    {% if p.domain is defined %}  #意思是:如果p.domain被定义,则下面执行下面一下,否则跳过本次if
    servicename {{ p.domain }}
    {% endif%}
}
{% endfor%}

结果:
server {
    listen 81
        servicename a.otoyix.com
    }
server {
    listen 82
        servicename b.otoyix.com
    }
server {
    listen 83
        servicename c.otoyix.com
    }

十、ansible roles

roles
ansible自1.2版本引入新特性,用于层次性、结构性地组织playbook。roles能够根据层次型结构自动装载变量文件、tasks以及handlers等。要使用roles只需要在playbook中使用include指令即可。简单来讲,roles就是通过分别将变量、文件、任务、模板及处理器放置于单独的目录中,并可以便捷地include它们的一种机制。角色一般用于基于主机构建服务的场景中,但也可以是用于构建守护进程等场景中。
也就是将之前一个playbook中的内容,全部拆分,在多个目录中,像templates files等,把变量 task 主机等放至不同的目录中。

模块化:把不同内容分类至不同的目录中,使用时,直接引用即可,可重复调用

复杂场景:建议使用roles,代码复用高
变更指定主机或主机组
如命名不规范维护和传承成本大
某些功能需多个playbook,通过includes即可实现

角色(roles): 角色集合

在任意目录下创建roles目录,官方建议放在/etc/ansible/roles

1、 roles目录结构

每个角色,以特定的层级目录结构进行组织
roles目录结构:

blaybook_role.yml
roles/
  project/
    tasks/
      main.yml
      group.yml
      user.yml
      copyfile.yml
      start.yml
	files/
	vars/  不常用
	  main.yml
	default/ 不常用
	templates/
	handlers/
	  main.yml
	meta/    不常用

2、roles各目录作用

/roles/project/: 	项目名称,有以下子目录
files/: 			存放由copy或script模块等调用的文件
templates/: 		template模块查找所需要模板文件的目录
tasks/:				定义task,role的基本元素,至少应该包含一个名为main.yml的文件;其他的文件需要在些文件中通过include进行包含调用
handlers/:			至少应该包含一个名为main.yml的文件;其他的文件需要在些文件中通过include进行包含调用
vars/:				定义变量,至少应该包含一个名为main的文件;其他的文件需要在些文件中通过include进行包含调用
meta/:				定义当前角色的特殊设定及其依赖关系,至少应该包含一个名为main的文件,其他的文件需要在些文件中通过include进行包含调用
default/:			设置默认变量时使用此目录中的main.yml文件

3、roles示例

[root@ansible ~]# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg
├── hosts
├── hosts.bak
├── nginx_role.yml
└── roles
    ├── httpd
    ├── mysql
    └── nginx
        ├── tasks
        │   ├── group.yml
        │   ├── main.yml
        │   ├── restart.yml
        │   ├── start.yml
        │   ├── templ.yml
        │   ├── user.yml
        │   └── yum.yml
        └── templates
            └── nginx.conf.j2

cat nginx_role.yml 
- hosts: web
  remote_user: root
  roles:
    - role: nginx
	
cat roles/nginx/tasks/main.yml
- include: group.yml
- include: user.yml
- include: yum.yml
- include: templ.yml
- include: start.yml

cat roles/nginx/tasks/group.yml
- name: '创建组www'
  group: name=www gid=1010

cat roles/nginx/tasks/restart.yml
- name: restart nginx
  service: name=nginx state=restarted

cat roles/nginx/tasks/start.yml
- name: start nginx
  service: name=nginx state=started enabled=yes

cat roles/nginx/tasks/templ.yml
- name: copy conf
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf

cat roles/nginx/tasks/user.yml
- name: '创建用户www'
  user: name=www uid=1010 group=www system=yes shell=/sbin/noloin

cat roles/nginx/tasks/yum.yml
- name: 'install package'
  yum: name=nginx


cat roles/nginx/templates/nginx.conf.j2 |head
user www;
worker_processes {{ ansible_processor_vcpus + 1 }};

结果: ps -ef|grep nginx
root      30022      1  0 13:49 ?        00:00:00 nginx: master process /usr/sbin/nginx
www       30023  30022  0 13:49 ?        00:00:00 nginx: worker process
www       30024  30022  0 13:49 ?        00:00:00 nginx: worker process
www       30025  30022  0 13:49 ?        00:00:00 nginx: worker process

4、可以调用多个角色

 xxxx_role.yml
- hosts: web
  remote_user: root
  roles:
    - role: nginx
	- role: redis

5、引用另外一个角色的任务(task)

vim main.yml
- include: roles/vsftpd/tasks/copyfile.yml 
- 
#这里的roles 会自动向上找,这里为上上一级的roles目录。
注:如果有相对的文件,需要把文件放在本main.yml角色下的files/templates中 或绝对路径

6、角色中也可以加标签tags

 hosts: web
  remote_user: root
  roles:
    - { role: nginx, tags: ['deploy','web'] }
	- { role: vsftpd, tags: ['deploy','web'] }
  执行playbook时,可以匹配执行相关标签
也可以加when
  roles:
    - { role: nginx, tags: ['deploy','web'],when: ansible_distribution_major_version == "7" }

十一、roles 结合 上面内容综合示例

(未测试)

mkdir -p /etc/ansible/roles/app
cd /etc/ansible/roles/app
mkdir tasks templates vars handlers files

cd tasks
vim group.yml
- name: create group app
  group: name=app system=yes gid=1011
vim user.yml
- name: create group app
  user: name=app uid=1011 group=app system=yes shell=/sbin/noloin
vim yum.yml
- name: install nginx
  yum: name=nginx
vim restart.yml
- name: start service
  service: name=nginx state=started enabled=yes

vim templ.yml
- name: copy templ conf
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
  notify: restart service

 
vim ../templates/nginx.conf.j2 #下面2段
user {{ username }};
worker_processes {{ ansible_processor_vcpus + 1 }};

    server {
        listen       {{ hpptport }};
        listen       [::]:{{ httpport }};

vim ../vars/main.yml
username: app
httpport: '80'

vim handlers/main.yml
- name: restart service
  service: name=nginx state=restarted

touch files/vhosts.conf

vim tasks/copyfile.yml
- name: copy file
  copy: src=vhosts.conf dest=/etc/nginx/vhosts/ owner=app mode=755

cd tasks
vim main.yml
- include: group.yml
- include: user.yml
- include: yum.yml
- include: templ.yml
- include: copyfile.yml
- include: start.yml

vim /etc/ansible/app_reloe.yml
---
- hosts: web
  remote_user: root
  
  roles:
    - app
	
--------------------	

十二、结合jenkins前端发版本,示例 (已测试)

pipeline脚本

pipeline {
    agent any
    environment {
		ProJect_Name = 'exam'
		PROJECT_PATH = "/var/www/${ProJect_Name}"
		Host = "web"
    }
    stages {
        stage('pull') {
			dir ("${env.PROJECT_PATH}") {
				steps {
					script {
						sh "node --version"
						sh "npm --version"
						sh "git fetch origin && git checkout ${env.branch} && git checkout ./* && git pull"
					}
				}
			}
        }
        stage('build') {
			dir ("${env.PROJECT_PATH}") {
				steps {
					script {
						sh "npm install"
						sh "npm run build:test"
						sh "\cp -rf dist /etc/ansible/roles/frontend_deploy/files/${ProJect_Name}/"
						sh "ls -l /etc/ansible/roles/frontend_deploy/files/${ProJect_Name}/dist/"
					}
				}
			}
        }
        stage('Deploy') {
            steps {
                script {
                    sh "ansible-playbook -e 'ProJect_Name=${ProJect_Name} hosts=${Host}' -t frontend_deploy /etc/ansible/frontend_deploy_roles.yml"
                }
            }
        }
    }
}

roles

mkdir -p /etc/ansible/roles/frontend_deploy/{files,tasks}
cd /etc/ansible/roles/frontend_deploy/tasks

tree /etc/ansible/ 
/etc/ansible/
├── ansible.cfg
├── frontend_deploy_roles.yml
├── hosts
├── hosts.bak
└── roles
    ├── frontend_deploy
    │   ├── files
    │   │   └── exam
    │   │       ├── dist
    │   │       │   └── test.txt
    │   └── tasks
    │       ├── copyfile.yml
    │       ├── group.yml
    │       ├── main.yml
    │       └── user.yml

roles/frontend_deploy/tasks/copyfile.yml
- name: '将dist目录使用mv 备份'
  shell: mv /var/www/{{ ProJect_Name }} /var/www{{ ProJect_Name }}.bak`date +%Y-%m-%d--%H-%M-%S`
  tags:
    - frontend_deploy
- name: '将dist目录至远程服务器/var/www/{{ ProJect_Name }}/dist'
  copy: src={{ProJect_Name}}/dist dest=/var/www/ owner=www group=www mode=755 backup=yes
  tags:
    - frontend_deploy

roles/frontend_deploy/tasks/group.yml
- name: '创建组www'
  group: name=www gid=1020
  tags:
    - frontend_deploy
    - install

roles/frontend_deploy/tasks/main.yml
- include: group.yml
- include: user.yml
- include: copyfile.yml

roles/frontend_deploy/tasks/user.yml
- name: '创建www用户'  
  user: name=www uid=1020 group=www
  tags:
    - frontend_deploy
    - install

---
- hosts: "{{ hosts }}"
  remote_user: root

  roles:
    - frontend_deploy



ansible-playbook -e 'ProJect_Name=exam hosts=web' -t frontend_deploy  /etc/ansible/frontend_deploy_roles.yml

---------------------------end

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值