ansible是一个可以同时操作多台服务器的工具 (类似工具:saltstack)
引言:
天天说运维,究竟是干什么的?先看看工作流程呗。一般来说,运维工程师在一家企业里属于个位数的岗位,甚至只有一个。面对生产中NNN台服务器,NN个人员,工作量也是非常大的。
所以嘛,图中的我好歹也会配置盔甲的。
这就是我主要干的事情(呵呵)
就算你会很厉害的脚本,面对成百上千,甚至上万的主机,效率问题将会困扰你的。
因此,有没有解放的工具呢?这就是运维自动化的目的,下面我们看下一个运维自动化工具
一:Ansible的介绍
1:什么是Ansible
Ansible是自动化运维和DevOps中持续部署的必备神器,通过Playbook的自动化任务可以解放运维工作量
Ansible 简单的说是一个配置管理系统(configuration management system)。你只需要可以使用 ssh 访问你的服务器或设备就行。它也不同于其他工具,因为它使用推送的方式,而不是像 puppet 等 那样使用拉取安装agent的方式。你可以将代码部署到任意数量的服务器上!
Ansible实现了批量系统配置、批量程序部署、批量运行命令等功能。ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:
(1)、连接插件connection plugins:负责和被监控端实现通信;
(2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
(3)、各种模块核心模块、command模块、自定义模块;
(4)、借助于插件完成记录日志邮件等功能;
(5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
2:Ansible能做什么
ansible可以帮助我们完成一些批量任务,或者完成一些需要经常重复的工作。 比如:同时在100台服务器上安装nginx服务,并在安装后启动它们。 比如:将某个文件一次性拷贝到100台服务器上。 比如:每当有新服务器加入工作环境时,你都要为新服务器部署某个服务,也就是说你需要经常重复的完成相同的工作。 这些场景中我们都可以使用到ansible。
3:Ansible特性
(1)、no agents:不需要在被管控主机上安装任何客户端;
(2)、no server:无服务器端,使用时直接运行命令即可;
(3)、modules in any languages:基于模块工作,可使用任意语言开发模块;
(4)、yaml,not code:使用yaml语言定制剧本playbook;
(5)、ssh by default:基于SSH工作;
(6)、strong multi-tier solution:可实现多级指挥。
4:Ansible架构
5:任务执行流程
6:Ansible工作原理
7:Ansible主要组成部分功能说明
PLAYBOOKS: 任务剧本(任务集),编排定义Ansible任务集的配置文件,由Ansible顺序依次执行,通常是JSON格式的YML文件 INVENTORY: Ansible管理主机的清单/etc/anaible/hosts MODULES: Ansible执行命令的功能模块,多数为内置的核心模块,也可自定义,ansible-doc –l 可查看模块 PLUGINS: 模块功能的补充,如连接类型插件、循环插件、变量插件、过滤插件等,该功能不常用 API: 供第三方程序调用的应用程序编程接口 ANSIBLE: 组合INVENTORY、 API、 MODULES、PLUGINS的绿框,可以理解为是ansible命令工具,其为核心执行工具
注意:
执行ansible的主机一般称为主控端,中控,master或堡垒机 主控端Python版本需要2.6或以上 被控端Python版本小于2.4需要安装python-simplejson 被控端如开启SELinux需要安装libselinux-python windows不能做为主控端
8:Ansible与salt对比
-
相同 都是为了同时在多台机器上执行相同的命令 都是python开发 不同 agent(saltstack需要安装、ansible不需要) 配置(salt配置麻烦,ansible基本不用配置) 学习路线(salt比较陡峭,ansible比较平缓) 第三方工具(salt比较少) 开源社区的对接(salt比较少) 现有用户(salt还是ansible少一些) 二次开发扩展的能力(ansible比较差,尤其是2.0以后) 大规模并发(200以内一样,200以上salt会好一些,当然我们也可以对ansible做一些配置使其在200以上追上salt) Windows的支持(salt会好很多)
二:Ansible安装
请准备4台centos7.5虚拟机
【主控端】(被控端不需要做什么)
1:准备好epel源
wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
2:安装ansible
yum install -y ansible
3:生成密钥对并拷贝公钥到被控端,目的免秘钥对登录
ansible 通过ssh来连接并控制被控节点
ssh-keygen # 用来生成ssh的密钥对 ssh-copy-id 192.168.107.131 # 复制秘钥到远程主机
可以远程登录试一下是否成功
三:Ansible配置文件
查看安装ansible生成的文件
[root@ansible ~]# rpm -ql ansible|more
配置文件或指令 | 描述 |
---|---|
/etc/ansible/ansible.cfg | 主配置文件,配置ansible工作特性 |
/etc/ansible/hosts | 主机清单 |
/etc/ansible/roles/ | 存放角色的目录 |
/usr/bin/ansible | 主程序,临时命令执行工具 |
/usr/bin/ansible-doc | 查看配置文档,模块功能查看工具 |
/usr/bin/ansible-galaxy | 下载/上传优秀代码或Roles模块的官网平台 |
/usr/bin/ansible-playbook | 定制自动化任务,编排剧本工具 |
/usr/bin/ansible-pull | 远程执行命令的工具 |
/usr/bin/ansible-vault | 文件加密工具 |
/usr/bin/ansible-console | 基于Console界面与用户交互的执行工具 |
Ansible 配置文件/etc/ansible/ansible.cfg (一般保持默认) [defaults] #inventory = /etc/ansible/hosts # 主机列表配置文件 #library = /usr/share/my_modules/ # 库文件存放目录 #remote_tmp = $HOME/.ansible/tmp #临时py命令文件存放在远程主机目录 #local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录 #forks = 5 # 默认并发数 #sudo_user = root # 默认sudo 用户 #ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码 #ask_pass = True #连接时提示输入ssh密码 #remote_port = 22 #远程主机的默认端口,生产中这个端口应该会不同 #log_path = /var/log/ansible.log #日志 #host_key_checking = False # 检查对应服务器的host_key,建议取消注释。也就是不会弹出
ansible hosts文件:
# This is the default ansible 'hosts' file. # # It should live in /etc/ansible/hosts # # - Comments begin with the '#' character # 用#来表示注释 # - Blank lines are ignored # 空白行被忽略 # - Groups of hosts are delimited by [header] elements # 主机组 需要在【】下面 # - You can enter hostnames or ip addresses #可以写主机名或者ip地址 # - A hostname/ip can be a member of multiple groups # 一台主机可以在多个组里面 www[001:006].example.com #表示从www001到www006的机器
可以在host文件中填写的内容
ansible_ssh_host ansible通过ssh连接的IP或者FQDN ansible_ssh_port SSH连接端口 ansible_ssh_user 默认SSH连接用户 ansible_ssh_pass SSH连接的密码(这是不安全的,ansible极力推荐使用--ask-pass选项或使用SSH keys) ansible_sudo_pass sudo用户的密码 ansible_connection SSH连接的类型:local,ssh,paramiko,在ansible 1.2之前默认是paramiko,后来智能选择,优先使用基于ControlPersist的ssh(支持的前提) ansible_ssh_private_key_file SSH连接的公钥文件
四:ansible命令格式
[root@ansible ~]# ansible -h 查看帮助文档
ansible <host-pattern> [options] -a MODULE_ARGS, --args=MODULE_ARGS #模块的参数 -C, --check # 检查 -f FORKS, --forks=FORKS #用来做高并发的 --list-hosts #列出主机列表 -m MODULE_NAME #模块名称 --syntax-check # 语法检查 -k 输入密码
-v 输出详细信息
查看模块的帮助信息
[root@ansible ~]# ansible-doc -h -j #以json的方式返回ansible的所有模块 -l, --list#列出所有的ansible的模块 -s#以片段式显示ansible的帮助信息
五:命令相关模块
1:ping模块
查看模块的帮助信息 [root@ansible ~]# ansible-doc -s ping
操作:首先要相互ping通
[root@ansible ~]# ansible 192.168.107.121 -m ping
上面错误是因为在 /etc/ansible/hosts 文件中并没有对应的被控端IP,因此需要修改/etc/ansible/hosts
可以查看被控端主机列表
[root@ansible ~]# ansible web --list-hosts
测试单个主机
[root@ansible ~]# ansible 192.168.13.121 -m ping
测试所有
[root@ansible ~]# ansible all -m ping
测试单个组
[root@ansible ~]# ansible web -m ping
测试多个组 --并集
[root@ansible ~]# ansible 'web:db' -m ping [root@ansible ~]# ansible web,db -m ping
测试多个组 --交集
[root@ansible ~]# ansible 'web:&db' -m ping
测试多个组 --差集
[root@ansible ~]# ansible 'web:!db' -m ping web中存在但db中不存在的
2:command模块--不支持特殊符号
查看command模块帮助信息
[root@ansible ~]# ansible-doc -s command
-chdir 运行命令之前切换目录
-creates 文件名如果已经存在,这一步不会执行
-removes 文件名如果已经存在,这一步会执行
详细查看 [root@ansible ~]# ansible-doc command
不支持特殊符号
案例
ansible web -a 'ls /' ansible web -a 'pwd' ansible web -a 'chdir=/tmp pwd'# 切换目录执行命令,使用场景是编译安装时使用 ansible web -a 'creates=/tmp pwd' # 用来判断/tmp目录是否存在,存在就不执行操作 ansible web -a 'creates=/data pwd' # 因为data不存在,所有才会执行pwd命令 ansible web -a 'removes=/tmp pwd' #用来判断tmp目录是否存在,存在就执行操作 ansible web -a 'removes=/data pwd' #因为data不存在,所有才不会执行
对web组里所有主机上创建用户 [root@ansible ~]# ansible web -a 'useradd lilz'
[root@ansible ~]# ansible web -a 'echo "123" |passwd --stdin lilz'
尝试远程登录是失败的
3:shell模块--执行被控端脚本
[root@ansible ~]# ansible web -m shell -a 'echo "123" |passwd --stdin lilz'
![](https://img2018.cnblogs.com/blog/1451394/201902/1451394-20190219175857302-594392505.png)
查看模块帮助 [root@ansible ~]# ansible-doc -s shell
-
-
creates 文件存在,则不执行
-
removes 文件存在,就执行
-
shell、python、ruby、perl 被管控机
案例
ansible 192.168.107.131 -m shell -a 'bash a.sh' # 执行远程文件方式一 ansible 192.168.107.131 -m shell -a '/root/a.sh' #执行远程文件方式二,文件必须有执行权限 ansible 192.168.107.131 -m shell -a '/root/a.py' # 执行远端的Python脚本
4:script 模块-运行本地端和被控端的脚本
查看模块的参数
[root@ansible ~]# ansible-doc -s script
案例
ansible web -m script -a '/root/m.sh' # 执行本地的文件,在被管控机上运行 ansible web -m script -a 'removes=/root/m.sh /root/m.sh' # 用来判断被管控机上是不是存在文件,如果存在,存在就执行,不存在就不执行 ansible web -m script -a 'creates=/root/a.sh /root/m.sh' #用来判断被管控机上是不是存在文件,如果存在,就不执行
六:文件相关模块
1:copy模块
查看模块帮助
[root@ansible ~]# ansible-doc -s copy
把本地文件拷贝到远程机器上
backup 备份,以时间戳结尾
dest 目的地址
group 文件的属组
mode 文件的权限 r 4 w 2 x 1
owner 文件的属主
src 源文件
content 直接把文字输入到远程端文件中
# 通过md5码来判断是否需要复制
案例:
ansible db -m copy -a 'src=/root/m.sh dest=/tmp/a.sh' #复制本地文件的到远程主机 ansible db -m copy -a 'src=/root/m.sh dest=/tmp/a.sh mode=755' #修改文件的权限 ansible web -m copy -a 'src=/root/m.sh dest=/tmp/a.sh mode=755 owner=alex' 修改文件的属主 ansible web -m copy -a 'src=/etc/init.d dest=/tmp/ mode=755 owner=alex' # 复制本地目录到远程主机,如果改变文件的属性,则文件夹内的文件也会被改变 ansible web -m copy -a 'src=/etc/init.d/ dest=/tmp/ mode=755 owner=alex' # 复制本地目录内的所有文件到远程主机 ansible web -m copy -a "content='大弦嘈嘈如急雨,小弦切切如私语\n' dest=/tmp/b.txt" # 直接将文本内容注入到远程主机的文件中
2:file模块
[root@ansible ~]# ansible-doc -s file
设置文件属性
-
-
directory
-
touch
-
link
-
hard
-
absent
-
file
-
-
src
-
link
-
hard
-
-
path
案例
ansible db -m file -a 'path=/lzmly2 state=directory' #在远程机器上创建文件夹 ansible db -m file -a 'path=/root/q.txt state=touch' #用来在远程机器上创建文件 ansible db -m file -a 'path=/tmp/f src=/etc/fstab state=link' #创建软连接src是源地址,path是目标地址 ansible db -m file -a 'path=/tmp/f state=absent' #用来删除文件或者文件夹
3:fetch模块
[root@ansible ~]# ansible-doc -s fetch
获取远程节点的文件
dest 目的地址
src 源地址
案例
ansible web -m fetch -a 'src=/var/log/cron dest=/tmp' # 下载被控节点的文件到本地,对每台机器创建一个文件夹,并保留原来的目录结构
![](https://img2018.cnblogs.com/blog/1451394/201902/1451394-20190219201628387-669050905.png)
七:软件相关模块
1:yum模块
[root@ansible ~]# ansible-doc -s yum
disablerepo #禁用源
enablerepo #启用源
name #包名
state
absent #卸载
installed #安装
latest #安装最新的版本
present #安装
removed #卸载
案例
ansible web -m yum -a 'name=wget' # 安装wget
ansible web -m yum -a 'name=python2-pip' # 安装python2-pip
ansible web -m yum -a 'name=wget state=absent' # 卸载软件包
ansible web -m yum -a 'name="@Development Tools"' # 安装包组
回顾 yum grouplist # 查看包组信息 yum groupinstall # 安装包组
2:pip模块
查看模块参数帮助信息 [root@ansible ~]# ansible-doc -s pip
回顾
pip install 安装包 pip freeze > a.txt 将python的环境打包到文件中 pip install -r a.txt 安装文件中的包 pip list 查看所有的以安装成功的包
案例
ansible web -m pip -a 'name=flask' # 安装flask模块
八:其它模块
1:service模块
[root@ansible ~]# ansible-doc -s service name state
restarted
reloaded
started
stopped
enabled
案例
ansible web -m service -a 'name=nginx state=started' # 启动nginx ansible web -m service -a 'name=nginx state=stopped' # 关闭nginx
回顾
ps -ef|grep nginx #查看进程 ss -tnlp # 查看端口信息 systemctl start nginx # centos7 service nginx start # centos6 systemctl enabled nginx # centos7 开机自启动 chkconfig nginx on # centos6开机自启动
默认端口
nginx 80 http 80 https 443 mongodb 27017 redis 6379 mysql 3306 ssh 22 ftp 21 oracle 1521 window 远程桌面3389 windows iis 80 django 8000 flask 5000
2:cron模块
查看模块帮助
[root@ansible ~]# ansible-doc -s cron day 天 disabled 禁用,被注释掉了 hour 小时 job 任务 minute 分钟 month 月 name 任务名字 weekday 周
state
absent #删除
present #创建
回顾
* * * * * job 分 时 日 月 周 任务 0 */2 * * * job 每隔两个小时 0 12,13 * * * job 12点和13点 0 12-17 * * * job 12点到17点 0 12-17/2 * * 1,3,6,0 周1,周3,周6,周7 12点到17点每隔两个小时 crontab -e # 编辑计划任务 crontab -l # 查看计划任务 crontab -r # 删除计划任务
案例
[root@ansible ~]# ansible web -m cron -a 'minute=26 job="touch aa.text" name=touchfile' 在被控端检查 [root@localhost ~]# crontab -l #Ansible: touchfile 26 * * * * touch aa.text
ansible db -m cron -a 'minute=26 job="touch /tmp/xzmly.txt" name=touchfile' # 新建一个计划任务 ansible db -m cron -a 'name=touchfile state=absent' # 删除一个计划任务 ansible db -m cron -a 'minute=26 job="touch /tmp/xzmly.txt" name=touchfile disabled=yes' # 禁用计划任务,以#表示禁用
3:user模块
[root@ansible ~]# ansible-doc -s user group 组 groups 附加组 home 家目录 name 用户名 password 密码 remove 删除用户并删除用户家目录 shell 用户登录后使用的shell system 创建一个系统用户 uid 用来指定用户的id state 状态
案例
ansible db -m user -a 'name=wulaoshi uid=4000 home=/opt/wulaoshi groups=root shell=/sbin/nologin' #创建一个用户,并指定用户的id,用户的家目录,用户的附加组,用户的shell ansible db -m user -a 'name=wulaoshi state=absent' #删除用户但是不删除用户的家目录 ansible db -m user -a 'name=wulaoshi3 state=absent remove=yes' # 删除用户并删除用户的家目录
回顾
用户: 管理员 root 0 普通用户 系统用户 不能登录 1-999 centos7 1-499 centos6 登录用户 可以登录 1000-65535 centos7 500-65535 centos6 用户组: 管理员组 root 0 系统用户组 1-999 centos7 1-499 centos6 登录用户组 1000-65535 centos7 500-65535 centos6 -d 指定用户的家目录 -g 指定用户的组 -G 执行用户的附加组 -s 指定登录后使用的shell -r 创建一个系统组 useradd -r wusir 创建系统用户, 从999倒序 useradd -s /sbin/nologin alexsb 创建的是普通用户,从1000开始升序 useradd -d /opt/alexsb2 alexsb2 创建用户时指定用户的家目录 useradd -u 3000 alexsb6 # 创建用户并指定用户的uid userdel alex 删除用户 userdel -r alexsb2 删除用户并删除用户的家目录 groupadd yuchao 创建用户组 groupdel yuchao 删除用户组
4:group模块
[root@ansible ~]# ansible-doc -s group gid 组的id name 组名 system 系统组 state
案例
ansible db -m group -a 'name=wulaoshi system=yes' #创建系统组 ansible db -m group -a 'name=wulaoshi state=absent' # 删除组
5:setup模块
[root@ansible ~]# ansible-doc -s setup 查看帮助,(setup功能:收集远程主机信息)
查看web组远程端的主机信息
[root@ansible ~]# ansible web -m setup
ansible_all_ipv4_addresses # ipv4的所有地址 ansible_all_ipv6_addresses # ipv6的所有地址 ansible_date_time # 获取到控制节点时间 ansible_default_ipv4 # 默认的ipv4地址 ansible_distribution # 系统 ansible_distribution_major_version # 系统的大版本 ansible_distribution_version # 系统的版本号 ansible_domain #系统所在的域 ansible_env #系统的环境变量 ansible_hostname #系统的主机名 ansible_fqdn #系统的全名 ansible_machine #系统的架构 ansible_memory_mb #系统的内存信息 ansible_os_family # 系统的家族 ansible_pkg_mgr # 系统的包管理工具 ansible_processor_cores #系统的cpu的核数(每颗) ansible_processor_count #系统cpu的颗数 ansible_processor_vcpus #系统cpu的总个数=cpu的颗数*CPU的核数 ansible_python # 系统上的python
搜索信息(支持正则)
[root@ansible ~]# ansible web -m setup -a 'filter=*processor*'
6:template模板.
作用:和copy模板类似,将文件模板拷贝到远程服务器
copy和tamplate的区别
-
copy模块不替代参数
-
template模块替代参数
上面所说的参数就是系统参数,copy对于文件中的参数原封不动,而template则把根据远程端信息替换对应参数,如下图redis的配置文件,用参数替换IP,用template拷贝到远程端就会被对应的IP替换掉
案例:
a.yml
- hosts: web
tasks:
- name: installredis
yum: name=redis
- name: copyfile
template: src=redis.conf dest=/etc/redis.conf
- name: start
service: name=redis state=started
这里用了相对路径: 在当前目录(yml文件的那个目录)下新建一个templates目录,然后把要拷贝的文件放在templates目录里面
[root@ansible ~]# ansible-playbook --syntax-check a.yml 语法检查 [root@ansible ~]# ansible-playbook a.yml 运行
九:playbook剧本(可以重复执行)
Playbooks 与 ad-hoc 相比,是一种完全不同的运用 ansible 的方式,是非常之强大的.
简单来说,playbooks 是一种简单的配置管理系统与多机器部署系统的基础.与现有的其他系统有不同之处,且非常适合于复杂应用的部署.
Playbooks 可用于声明配置,更强大的地方在于,在 playbooks 中可以编排有序的执行过程,甚至于做到在多组机器间,来回有序的执行特别指定的步骤.并且可以同步或异步的发起任务.
playbook用yaml语言写的
[root@ansible ~]# ansible-playbook -h -C, --check # 检查,白跑,干跑 -f FORKS, --forks=FORKS #用来做并发 --list-hosts # 列出主机列表 --syntax-check # 语法检查
-t TAGS
1:ymal语言的格式:
两种形式:字典、列表
相当于{host:db,vars:{user:alex},task:{}}
2:编写ymal语言格式的任务
- hosts: web tasks: - name: creategroup group: name=alex10 - name: cretaeuser user: name=wusir10
注意:这个语言的格式及其严格
执行顺序: 从上往下
特性:幂等性 不管执行多少遍,结果都是一样的
-
-
等号后面不能有空格
-
- 后面也要有空格
-
严格对齐
a.yml
- hosts: web tasks: - name: creategroup group: name=alex10 - name: cretaeuser user: name=wusir10
[root@ansible ~]# ansible-playbook --syntax-check a.yml 检测语法
运行
[root@ansible ~]# ansible-playbook a.yml
![](https://img2018.cnblogs.com/blog/1451394/201902/1451394-20190220174641391-2100578496.png)
3:编写任务---参数
a.yml
- hosts: web tasks: - name: create{{ user }} user: name={{ user}}
方式一:
ansible-playbook -e 'user=alexsb10' a.yml
方式二:
[root@ansible ~]# vim /etc/ansible/hosts [web] 192.168.13.121 user=wusi 192.168.13.71 user=wusi 192.168.13.217 user=wusi
[root@ansible ~]# ansible-playbook a.yml 运行
方式三:
[root@ansible ~]# vim /etc/ansible/hosts [web] 192.168.13.121 192.168.13.71 192.168.13.217 [web:vars] #表示组的参数 user=wusi [root@ansible ~]# ansible-playbook a.yml
方式四:
[root@ansible ~]# vim a.yml - hosts: web vars: - user: wusi tasks: - name: create{{ user }} user: name={{ user }} [root@ansible ~]# ansible-playbook a.yml
方式五:
[root@ansible ~]# vim a.yml
- hosts: db
tasks:
- name: sum
shell: echo 7+8|bc
register: user #这个是shell运行结果产生的变量
- name: createuser
user: name={{user.stdout}} #如果把shell运行的结果放到一个文件中你就会发现ustdout=u结果 (Unicode存储)
[root@ansible ~]# ansible-playbook a.yml
优先级:
-e > playbook vars > hosts文件
4:条件判断 when
(不同系统、不同版本、不同环境用)
a.yml
- hosts: web
remote_user: root
tasks:
- name: createfile
copy: content="大弦嘈嘈如急雨" dest=/tmp/a.txt
when: a=="3"
- name: cratefile
copy: content="小弦切切如私语" dest=/tmp/a.txt
when: a=="4"
当执行的时候满足对应的when值就执行对应的任务
[root@ansible ~]# ansible-playbook --syntax-check a.yml 语法检查 [root@ansible ~]# ansible-playbook -e "a=3" a.yml 运行文件
5:tags
a.yml
- hosts: web
remote_user: root
tasks:
- name: createfile
copy: content="大弦嘈嘈如急雨" dest=/tmp/a.txt
tags: createfile
- name: cratefile
copy: content="小弦切切如私语" dest=/tmp/a.txt
[root@ansible ~]# ansible-playbook --syntax-check a.yml 语法检查
[root@ansible ~]# ansible-playbook -t createfile a.yml 执行createfile任务
6:循环 with_items
(一次性创建多个)
[root@ansible ~]# vim a.yml - hosts: web tasks: - name: crateuser user: name={{item}} with_items: - alex20 - alex21 - alex22 [root@ansible ~]# ansible-playbook --syntax-check a.yml playbook: a.yml [root@ansible ~]# ansible-playbook a.yml 运行
嵌套循环(需要多个属性时用)
[root@ansible ~]# vim a.yml - hosts: web tasks: - name: crategroup group: name={{item}} with_items: - wulaoshi30 - wulaoshi31 - wulaoshi32 - name: createuser user: name={{item.name}} group={{item.group}} with_items: - {'name':alex40,'group':wulaoshi30} - {'name':alex41,'group':wulaoshi31} - {'name':alex42,'group':wulaoshi32} [root@ansible ~]# ansible-playbook --syntax-check a.yml playbook: a.yml [root@ansible ~]# ansible-playbook a.yml
7:handlers
需要notify触发的任务,常用在修改配置文件重启应用
a.yml
- hosts: web tasks: - name: installredis yum: name=redis - name: copyfile template: src=redis.conf dest=/etc/redis.conf tags: copyfile notify: restart - name: start service: name=redis state=started handlers: - name: restart service: name=redis state=restarted
[root@ansible ~]# ansible-playbook --syntax-check a.yml 语法检查 [root@ansible ~]# ansible-playbook a.yml 运行
十:roles 目录结构
(目录明确、可以互相调用)
roles文件夹 文件夹里面是要创建的每一个角色,每一个角色一个文件夹 每一个角色里面都有tasks(必须的),templates,files,handlers,vars目录 每个目录都要有main.yml文件,通过import_tasks来调用 其中templates文件夹中的文件可以通过相对路径来调用 其中files文件夹中的文件是否可以通过相对路径来调用
1:roles目录
[root@ansible roles]# tree . ├── db #db组 │ └── tasks #任务目录 │ └── createuser.yml #具体任务 └── web #web组 ├── files #不需要系统参数拷贝的文件,用copy模块 ├── handlers #需要触发的任务 │ └── main.yml ├── tasks #任务目录 │ ├── copyfile.yml │ ├── install.yml │ ├── main.yml #这些任务文件最后在main.yml文件里集合,必须要有 │ ├── p1.yml │ └── start.yml ├── templates #需要系统参数拷贝的文件,用template模块 │ └── redis.conf.j2 └── vars #变量目录
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
- name: createuser
user: name=alex50
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
- name: restart
service: name=redis state=restarted
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
- import_tasks: install.yml - import_tasks: copyfile.yml - import_tasks: start.yml - import_tasks: roles/db/tasks/createuser.yml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
- name: copyfile template: src=redis.conf.j2 dest=/etc/redis.conf notify: restart tags: copyfile
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
- name: install
yum: name=redis
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
- name: start
service: name=redis state=started
2:调用roles目录结构的任务
在与roles目录同层下新建调用文件web.yml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
- hosts: web
remote_user: root
roles:
- web
3:测试运行任务
#ansible-playbook --syntax-check web.yml #ansible-playbook web.yml
参考资料:
https://docs.ansible.com/
http://blog.51cto.com/wangfeng7399/2338621
http://blog.51cto.com/191226139/2066936