1 Dev开发环境
使用者:程序员
功能:程序员开发软件,测试BUG的环境
管理者:程序员
2 测试环境
使用者:QA测试工程师
功能:测试经过Dev环境测试通过的软件的功能
管理者:运维
说明:测试环境往往有多套,测试环境满足测试功能即可,不宜过多
(1)测试人员希望测试环境有多套,公司的产品多产品线并发,即多个版本,意味着多个版本同步测试
(2)通常测试环境有多少套和产品线数量保持一样
3 发布环境:代码发布机,有些公司为堡垒机(安全屏障)
使用者:运维
功能:发布代码至生产环境
管理者:运维(有经验)
发布机:往往需要有2台(主备)
4 生产环境
使用者:运维,少数情况开放权限给核心开发人员,极少数公司将权限完全开放给开发人员并其维护
功能:对用户提供公司产品的服务
管理者:只能是运维
生产环境服务器数量:一般比较多,且应用非常重要。往往需要自动工具协助部署配置应用
5 灰度环境(生产环境的一部分)
使用者:运维
功能:在全量发布代码前将代码的功能面向少量精准用户发布的环境,可基于主机或用户执行灰度发布
案例:共100台生产服务器,先发布其中的10台服务器,这10台服务器就是灰度服务器
管理者:运维
灰度环境:往往该版本功能变更较大,为保险起见特意先让一部分用户优化体验该功能,待这部分用户使用没有重大问题的时候,再全量发布至所有服务器
把原来的旧版本保留
/webapp/tuangou-1.1
/webapp/tuangou
/webapp/tuangou-1.2
-
- ansible是基于key的,所以需要将主机间实现key验证。当然用密码也可以,只是比较麻烦
rpm包安装: EPEL源
yum install ansible
ansible不是一个服务/etc/hosts是最重要的文件
ansible是一个管理端
编译安装
yum -y install python-jinja2 PyYAML python-paramiko
python-babel python-crypto
tar xf ansible-1.5.4.tar.gz
cd ansible-1.5.4
python setup.py build
python setup.py install
mkdir /etc/ansible
cp -r examples/* /etc/ansible
Git方式
git clone git://github.com/ansible/ansible.git --
recursive
cd ./ansible
source ./hacking/env-setup
pip安装: pip是安装Python包的管理器,类似yum
yum install python-pip python-devel
yum install gcc glibc-devel zibl-devel rpm-bulid openssl-devel
pip install --upgrade pip
pip install ansible --upgrade
配置文件
/etc/ansible/ansible.cfg 主配置文件,配置ansible工作特性
/etc/ansible/hosts 主机清单被管理端的主机存放,如果将主机不写入这个文件则无法管理这个主机
/etc/ansible/roles/ 存放角色的目录
[root@centos7 yum.repos.d]# ansible 192.168.27.101 -m ping
[WARNING]: Could not match supplied host pattern, ignoring: all
[WARNING]: provided hosts list is empty, only localhost is available
[WARNING]: Could not match supplied host pattern, ignoring: 192.168.27.101
[WARNING]: No hosts matched, nothing to do
[root@centos7 yum.repos.d]# vim /etc/ansible/hosts
# - Blank lines are ignored
# - Groups of hosts are delimited by [header] elements
# - You can enter hostnames or ip addresses
# - A hostname/ip can be a member of multiple groups
192.168.27.[101:103] 也可以写成这种格式这表示192.168.27.101到103直接的ip
# Ex 1: Ungrouped hosts, specify before any group headers.
## green.example.com
## blue.example.com
## 192.168.100.1
## 192.168.100.10
# Ex 2: A collection of hosts belonging to the 'webservers' group
## [webservers]
## alpha.example.org
## beta.example.org
## 192.168.1.100
## 192.168.1.110
# If you have multiple hosts following a pattern you can specify
# them like this:
## www[001:006].example.com
# Ex 3: A collection of database servers in the 'dbservers' group
## [dbservers]
##
## db01.intranet.mydomain.net
## db02.intranet.mydomain.net
## 10.25.1.56
## 10.25.1.57
# Here's another example of host ranges, this time there are no
# leading 0s:
## db-[99:101]-node.example.com
[root@ansible ~]# cd ~
[root@ansible ~]# cd .ssh/
[root@ansible .ssh]# ls
id_rsa id_rsa.pub known_hosts
[root@ansible .ssh]#
程序
/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界面与用户交互的执行工具
ntp.magedu.com
[webservers]
www1.magedu.com:2222
www2.magedu.com
[dbservers]
db1.magedu.com
db2.magedu.com
db3.magedu.com
示例
[websrvs]
www[01:100].example.com
[dbsrvs]
db-[a:f].example.com
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 # 默认并发数,如果有100台主机就会5台5台的执行,分批次的,也可以调100,要求机器性能好
#sudo_user = root # 默认sudo 用户,需要在被管理主机上做sudo配置
#ask_sudo_pass = True #每次执行ansible命令是否询问ssh密码
#ask_pass = True
#remote_port = 22 因为是基于ssh,ssh默认是22端口,如果ssh端口号改成其它的,这里也是要改的
#host_key_checking = False # 检查对应服务器的host_key,建议取消注释
ansible ansible-doc ansible-playbook ansible-vault
ansible-console ansible-galaxy ansible-pull
ansible-doc [options] [module...]
-a 显示所有模块的文档
-l, --list 列出可用模块
-s, --snippet 显示指定模块的playbook片段
示例
ansible-doc –l 列出所有模块
ansible-doc ping 查看指定模块帮助用法
ansible-doc –s ping 查看指定模块帮助用法简要信息
--version 显示版本
-m module 指定模块,默认为command模块
-v 详细过程 –vv -vvv更详细
--list-hosts 显示主机列表,可简写—list
-k, --ask-pass 提示连接密码,默认Key验证
-K, --ask-become-pass 提示输入sudo
-C, --check 检查,并不执行,只是模拟的执行一次,并不会在真正的主机上执行
-T, --timeout=TIMEOUT 执行命令的超时时间,默认10s
-u, --user=REMOTE_USER 执行远程执行的用户,指定以哪个用户执行,如果不指定则默认是root
-b, --become 代替旧版的sudo 切换
usermod -aG wheel guo
> Command:在远程主机执行命令,默认模块,可忽略-m选项
-a是后面要执行的参数
- 参数
+ chdir 运行command命令前先cd到这个目录
+ creates 如果这个参数对应的文件存在,就不运行command
+ executable 将shell切换为command执行,这里的所有命令需要使用绝对路径
+ removes 如果这个参数对应的文件不存在,就不运行command
```bash
ansible srvs -m command -a 'service vsftpd start'
ansible srvs -m command -a 'echo magedu |passwd --stdin wang' 不成功
此命令不支持 $VARNAME < > | ; & 等,用shell模块实现
用chdir进入到某个目录来执行参数
[root@ansible ~]# ansible 'dbser' -m command -a 'chdir=/app/ ls'
192.168.27.102 | SUCCESS | rc=0 >>
123
192.168.27.128 | SUCCESS | rc=0 >>
1
aaa
access_log
awk.txt
dir
f1.txt
f2
lost+found
passwd
[root@ansible ~]# ansible 'dbser' -m command -a 'chdir=/app/ creates=123 ls'
192.168.27.102 | SUCCESS | rc=0 >>
skipped, since 123 exists 这里写着123这个文件存在就跳过,而另一个主机没有对应的文件所有执行ls
192.168.27.128 | SUCCESS | rc=0 >>
1
aaa
access_log
awk.txt
dir
f1.txt
f2
lost+found
passwd
"se-preview-section-delimiter">
Shell:和command相似,用shell执行命令
ansible srv -m shell -a 'echo magedu |passwd –stdin wang'
调用bash执行命令 类似 cat /tmp/stanley.md | awk -F'|''{print $1,$2}' &> /tmp/example.txt 这些复杂命令,即使使用shell也可能会失败,解决办法:写到脚本时,copy到远程,执行,再把需要的结果拉回执行命令的机器
查看主机名
[root@ansible ~]# ansible 'dbser' -m shell -a 'echo $HOSTNAME'
192.168.27.102 | SUCCESS | rc=0 >>
102
192.168.27.128 | SUCCESS | rc=0 >>
centos6.magedu.com
体验shell和command的区别,先cd到某个需要编译的目录,执行condifgure然后,编译,然后安装。
ansible -i hosts all -m shell -a "./configure && make && make insatll" chdir=/xxx/yyy/
shell也支持条件判断&&||
[root@ansible ~]# ansible 'dbser' -m shell -a 'grep -q root /etc/passwd && ls /app'
192.168.27.102 | SUCCESS | rc=0 >>
123
192.168.27.128 | SUCCESS | rc=0 >>
1
aaa
access_log
awk.txt
dir
f1.txt
f2
lost+found
passwd
[root@ansible ~]# ansible 'dbser' -m shell -a 'grep -q rootsd /etc/passwd && ls /app'
192.168.27.102 | FAILED | rc=1 >>
non-zero return code 如果没有则会出现非0错误码
192.168.27.128 | FAILED | rc=1 >>
non-zero return code
"se-preview-section-delimiter">
Script:运行脚本
- 相当于先把脚本传到远方节点,然后在执行
-
-a "/PATH/TO/SCRIPT_FILE"
snsible websrvs -m script -a f1.sh
"se-preview-section-delimiter">
Copy:从服务器复制文件到客户端
- 常用参数
+ src
+ 用于定位ansible执行的机器上的文件,需要绝对路径。如果拷贝的是文件夹,那么文件夹会整体拷贝,如果结尾是”/”,那么只有文件夹内的东西被考过去。一切的感觉很像rsync,源地址
+ content
+ 用来替代src,用于将指定文件的内容,拷贝到远程文件内
+ dest
+ 用于定位远程节点上的文件,需要绝对路径。如果src指向的是文件夹,这个参数也必须是指向文件夹,目标文件
+ backup
+ 备份远程节点上的原始文件,在拷贝之前。如果发生什么意外,原始文件还能使用。
+ directory_mode
+ 这个参数只能用于拷贝文件夹时候,这个设定后,文件夹内新建的文件会被拷贝。而老旧的不会被拷贝
+ follow
+ 当拷贝的文件夹内有link存在的时候,那么拷贝过去的也会有link
+ force
+ 默认为yes,会覆盖远程的内容不一样的文件(可能文件名一样)。如果是no,就不会拷贝文件,如果远程有这个文件
+ group
+ 设定一个群组拥有拷贝到远程节点的文件权限
+ mode
+ 等同于chmod,参数可以为“u+rwx or u=rw,g=r,o=r”
+ owner
+ 设定一个用户拥有拷贝到远程节点的文件权限
- 把复制selinux配置文件
-
-
- 看一下备份文件
-
- 也可以改权限,所属组,或所有者
-
-
[root@ansible ~]# ansible cen7 -m copy -a 'content="df-h\nhhhhhhhhhhh\nls\n" dest=/app/f1.sh'
[root@ansible ~]# ansible cen7 -a 'cat /app/f1.sh'
192.168.27.102 | SUCCESS | rc=0 >>
df-h
hhhhhhhhhhh
ls
192.168.27.101 | SUCCESS | rc=0 >>
df-h
hhhhhhhhhhh
ls
"se-preview-section-delimiter">
ansible srv -m copy -a "src=/root/f1.sh dest=/tmp/f2.sh owner=wang mode=600 backup=yes"
如目标存在,默认覆盖,此处指定先备份
ansible srv -m copy -a "content='test content\n' dest=/tmp/f1.txt" 利用内容,直接生成目标文件
Cron:计划任务
支持时间:minute,hour,day,month,weekday
ansible srv -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null'
name=Synctime" 创建任务
ansible srv -m cron -a 'state=absent
name=Synctime' 删除任务
范例1:每五分钟周六周日执行
[root@ansible ~]# ansible cen7 -m cron -a 'minute=*/5 weekday=0,6 job="/usr/bin/wall cront job" name="test"'
name就是给这个计划任务起个名字
job表示要执行的命令或操作但是命令要写绝对路径
[root@ansible ~]# ansible cen7 -a 'crontab -l'
192.168.27.102 | SUCCESS | rc=0 >>
#Ansible: test
*/5 * * * 0,6 /usr/bin/wall cront job
范例2:禁用范例1的计划任务
[root@ansible ~]# ansible cen7 -m cron -a 'disabled=true job="/usr/bin/wall cront job" name=test '
必须要job
[root@ansible ~]# ansible cen7 -a 'crontab -l'
192.168.27.101 | SUCCESS | rc=0 >>
#Ansible: test
#* * * * * /usr/bin/wall cront job
开启是disabled=no
Fetch:从客户端取文件至服务器端,copy相反,目录可先tar
ansible srv -m fetch -a 'src=/root/a.sh dest=/data/scripts'
[root@ansible ~]# ansible cen7 -m fetch -a 'src=/etc/passwd dest=/app/'
这里的src是远程主机的路径,dest是本地路径文件要复制到哪里
在本机会成一个远程主机ip名字的一个目录里面存放着文件
[root@ansible ~]# tree /app/
/app/
├── 192.168.27.101
│ └── etc
│ └── passwd
└── 192.168.27.102
└── etc
└── passwd
[root@ansible ~]# ansible cen7 -m shell -a 'tar Jcf /app/log.tar.xz /var/log/*.log'
[root@ansible ~]# ansible cen7 -m fetch -a 'src=/app/log.tar.xz dest=/app/'
File:设置文件属性和管理文件
- file模块它包含了文件、文件夹、超级链接类的创立、拷贝、移动、删除操作。
- 常见参数
+ follow
+ 如果原来的文件是link,拷贝后依旧是link
+ force
+ 强制执行,没说的
+ group
+ 设定所属组权限
+ mode
+ 等同于chmod,参数可以为“u+rwx or u=rw,g=r,o=r”
+ owner
+ 设定文件的所有者
+ path
+ 目标路径,也可以用dest,name代替
+ src
+ 待拷贝文件/文件夹的原始位置。
+ state = ile/link/directory/hard/touch/absent
+ file代表拷贝后是文件;link代表最终是个软链接;directory代表文件夹;hard代表硬链接;touch代表生成一个空文件;absent代表删除
ansible srv -m file -a "path=/root/a.sh owner=wang mode=755"
ansible web -m file -a 'src=/app/testfile dest=/app/testfile-link state=link'
[root@ansible ~]# ansible cen7 -m file -a 'path=/app/testfile state=touch'
192.168.27.101 | SUCCESS => {
"changed": true,
"dest": "/app/testfile",
"gid": 0, 组id
"group": "root", 所属组
"mode": "0644", 文件权限
"owner": "root", 所有者
"secontext": "unconfined_u:object_r:default_t:s0",
"size": 0, 大小
"state": "file",
"uid": 0
}
[root@ansible ~]# ansible cen7 -m file -a 'src=/app/testfile path=/app/testlink state=link'
[root@ansible ~]# ansible cen7 -a 'ls -l /app/' ansible不支持别名命令
lrwxrwxrwx. 1 root root 13 Jan 14 20:18 testlink -> /app/testfile
方法一[root@ansible ~]# ansible cen7 -a 'mkdir /app/mk1'
方法二[root@ansible ~]# ansible cen7 -m file -a 'path=/app/mk2 state=directory'
[root@ansible ~]# ansible cen7 -m file -a 'path=/app/mk1 state=absent'
[root@ansible ~]# ansible cen7 -m file -a 'path=/app/fstab state=absent'
[root@ansible ~]# ansible cen7 -m shell -a 'rm -rf /app/*'
ansible cen7 -m file -a 'path=/app state=absent'
Hostname:管理主机名这里改名是永久改,会把配置文件改掉
ansible node1 -m hostname -a "name=websrv"
ansible 192.168.27.101 -m hostname -a 'name=g101.com'
Yum:管理包
- 常用参数
+ disable_gpg_check
+ 在安装包前检查包,只会影响state参数为present或者latest的时候
+ name
+ 你需要安装的包的名字,也能如此使用name=python=2.7安装python2.7
+ state present/latest/absent
+ 用于描述安装包最终状态,present/latest用于安装包,absent用于remove安装包
+ update_cache
+ 用于安装包前执行更新list,只会影响state参数为present/latest的时候
- 范例1:安装一个包,做这些一定要yum配置好
[root@ansible ~]# ansible cen7 -m yum -a 'name=tree state=present'
name是要安装的包名,
如果是安装的话默认可以不写state=present,默认是安装
当然也可以用命令模块安装或卸载包
[root@ansible ~]# ansible cen7 -m yum -a 'name=dstat state=latest'
[root@ansible ~]# ansible cen7 -m yum -a 'name=httpd,vsftpd state=present'
ansible srv -m yum -a 'name=httpd state=latest' 安装
ansible srv -m yum -a 'name=httpd state=absent' 删除
Service:管理服务
- 常用参数
+ enabled
+ 启动os后启动对应service的选项。使用service模块的时候,enabled和state至少要有一个被定义,设置成开机启动
+ name
+ 需要进行操作的service名字
+ state stared/stoped/restarted/reloaded
+ service最终操作后的状态。
- 范例1启动服务并设置开机启动
[root@ansible ~]# ansible cen7 -m service -a 'name=httpd state=started enabled=yes'
这相当于先启动服务,然后在把服务设置成开机启动
ansible srv -m service -a 'name=httpd state=stopped'
ansible srv -m service -a 'name=httpd state=started'
ansible srv –m service –a 'name=httpd state=reloaded'
ansible srv -m service -a 'name=httpd state=restarted'
User:管理用户
- 常用参数
+ home
+ 指定用户的家目录
+ groups
+ 用户的所属组可以指定多个用逗号分隔
+ uid
+ 指定用户uid
+ name
+ 要创建的用户名
+ createhome
+ 是否创建家目录 yes|no
+ system
+ 是否为系统用户
+ remove
+ 当state=absent时,remove=yes则表示连同家目录一起删除,等价于userdel -r
+ state
+ 是创建还是删除,默认是创建
+ shell
+ 指定用户的shell环境
+ password
+ 指定用户的密码
- 范例1:创建一个test1用户,uid=2000,主组是guo,附属组是root,bin.指定家目录为根下 还有描述
[root@ansible ~]# ansible cen7 -m user -a 'name=test1 comment="test is user" uid=2000 home=/test group=guo groups=root,bin'
192.168.27.101 | SUCCESS => {
"changed": true,
"comment": "test is user",
"createhome": true,
"group": 1000,
"groups": "root,bin",
"home": "/test",
"name": "test1",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 2000
}
[root@ansible ~]# ansible cen7 -m user -a 'name=systemuser system=yes createhome=no'
192.168.27.102 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": false,
"group": 996,
"home": "/home/systemuser", 虽然这里显示是创建的,但是事实是没有创建
"name": "systemuser",
"shell": "/bin/bash",
"state": "present",
"system": true,
"uid": 998
}
[root@ansible ~]# ansible cen7 -m user -a 'name=test1 state=absent remove=yes'
192.168.27.101 | SUCCESS => {
"changed": true,
"force": false,
"name": "test1",
"remove": true,
"state": "absent"
}
ansible srv -m user -a 'name=user1 comment="test user” uid=2048 home=/app/user1 group=root'
ansible srv -m user -a 'name=sysuser1 system=yes home=/app/sysuser1 '
ansible srv -m user -a 'name=user1 state=absent remove=yes'
删除用户及家目录等数据
Group:管理组
+ 和user参数一样
- 范例1:创建组
[root@ansible ~]# ansible cen7 -m group -a 'name=group1'
[root@ansible ~]# ansible cen7 -m group -a 'name=group1 state=absent'
ansible srv -m group -a "name=testgroup system=yes"
ansible srv -m group -a "name=testgroup state=absent"
bash
[root@ansible ~]# ansible-galaxy install geerlingguy.nginx
bash
[root@ansible ~]# ls .ansible/roles/geerlingguy.nginx/
defaults handlers LICENSE meta README.md tasks templates tests vars
[root@ansible ansible]# vim hellow.yml
---
- hosts: cen7
remote_user: root
tasks:
- name: test yml
command: /usr/bin/wall "hellow word"
[root@ansible ansible]# vim hellow.yml
---
- hosts: cen7
remote_user: root
tasks:
- name: test yml
file: name=/app/test12 state=touch
bash
[root@ansible ansible]# ansible-vault encrypt hellow.yml
New Vault password:
Confirm New Vault password:
Encryption successful
bahs
root@all (2)[f:5]$ list
root@all (2)[f:5]$ cd appsrvs
root@appsrvs (2)[f:5]$ list
root@appsrvs (2)[f:5]$ yum name=httpd state=present
root@appsrvs (2)[f:5]$ service name=httpd state=started
# A list of tasty fruits
- Apple
- Orange
- Strawberry
- Mango
特性
YAML的可读性好
YAML和脚本语言的交互性好
YAML使用实现语言的数据类型
YAML有一个一致的信息模型
YAML易于实现
YAML可以基于流来处理
YAML表达能力强,扩展性好
---
# 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
gender: Female
ansible-playbook –t tagsname useradd.yml
[root@ansible ansible]# vim test.yml
---
- hosts: cen7 要执行的主机
remote_user: root 用哪个用户执行
tasks: 任务集
- name: install package 一条任务要有一个名字
yum: name=httpd 调用的模块,和参数
- name: start service
service: name=httpd state=started enabled=yes
[root@ansible ansible]# ansible-playbook test.yml --list-host
playbook: test.yml
play #1 (cen7): cen7 TAGS: []
pattern: [u'cen7']
hosts (2):
192.168.27.101
192.168.27.102
ERROR! You must specify a playbook file to run
[root@ansible ansible]# ansible-playbook test.yml --list-tasks
playbook: test.yml
play #1 (cen7): cen7 TAGS: []
tasks:
install package TAGS: []
start service TAGS: []
- hosts: cen7
remote_user: root
tasks:
- name: isntall httpd
yum: name=httpd
- name: copy config httpd
copy: src=/app/httpd.conf dest=/etc/httpd/conf/ backup=yes
- name: start httpd
service: name=httpd state=started enabled=yes
---
- hosts: cen7
remote_user: root
tasks:
- name: isntall httpd
yum: name=httpd
- name: copy config httpd
copy: src=/app/httpd.conf dest=/etc/httpd/conf/ backup=yes
notify: restart httpd 当copy发生改变时会执行notify所指定的名字任务
- name: start httpd
service: name=httpd state=started enabled=yes
handlers: handlers是一个特殊的tasks也可以写多个任务
- name: restart httpd
service: name=httpd state=restarted
bash
one.example.com
one.example.com:two.example.com
192.168.1.50
192.168.1.*
- hosts: websrvs
remote_user: root
tasks:
- name: test connection
ping:
remote_user: magedu
sudo: yes 默认sudo为root
sudo_user:wang sudo为wang
tasks:
- name: disable selinux
command: /sbin/setenforce 0
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand || /bin/true
tasks:
- name: run this command and ignore the result
shell: /usr/bin/somecommand
ignore_errors: True
ansible-playbook ... [options]
常见选项
–check 只检测可能会发生的改变,但不真正执行操作
–list-hosts 列出运行任务的主机
–limit 主机列表 只针对主机列表中的主机执行
-v 显示过程 -vv -vvv 更详细
- 范例
ansible-playbook file.yml --check 只检测
ansible-playbook file.yml
ansible-playbook file.yml --limit websrvs
[root@ansible app]# ansible-playbook httpd.yml --limit 192.168.27.101
只针对101主机执行并不是所有主机
#!/bin/bash
# 安装Apache
yum install --quiet -y httpd
# 复制配置文件
cp /path/to/config/httpd.conf
/etc/httpd/conf/httpd.conf
cp/path/to/httpd-vhosts.conf
/etc/httpd/conf/httpd-vhosts.conf
# 启动Apache,并设置开机启动
service httpd start
chkconfig httpd on
---
- hosts: all
tasks:
- name: "安装Apache"
command: yum install -q -y httpd
- name: "复制配置文件"
command: cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
command: cp /tmp/httpd-vhosts.conf /etc/httpd/conf/httpd-vhosts.conf
- name: "启动Apache,并设置开机启动"
service: name=httpd state=started enabled=yes
示例:system.yml
---
-hosts: all
remote_user: root
tasks:
- name: create mysql user
user: name=mysql system=yes uid=36
- name: create a group
group: name=httpd system=yes
- 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/
- name: start service
service: name=httpd state=started enabled=yes
- 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 is running
service: name=httpd state=started enabled=yes
handlers:
- name: restart httpd
service: name=httpd status=restarted
- 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
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
- name: Check Nginx process
shell: killall -0 nginx > /tmp/nginx.log
示例:httpd.yml
- 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/
tags: conf
- name: start httpd service
tags: service
service: name=httpd state=started enabled=yes
[root@ansible app]# ansible-playbook -t conf,service httpd.yml
bash
vars:
ansible cen7 -m setup
[root@ansible app]# ansible cen7 -m setup -a 'filter=*hostname*'
192.168.27.102 | SUCCESS => {
"ansible_facts": {
"ansible_hostname": "g102"
},
"changed": false
}
192.168.27.101 | SUCCESS => {
"ansible_facts": {
"ansible_hostname": "g101"
},
"changed": false
}
[root@ansible app]# ansible cen7 -m setup -a 'filter=*nodename*'
192.168.27.101 | SUCCESS => {
"ansible_facts": {
"ansible_nodename": "g101.com"
},
"changed": false
}
192.168.27.102 | SUCCESS => {
"ansible_facts": {
"ansible_nodename": "g102.com"
},
"changed": false
}
[root@ansible app]# ansible cen7 -m setup -a 'filter=*fqdn*'
192.168.27.102 | SUCCESS => {
"ansible_facts": {
"ansible_fqdn": "g102.com"
},
"changed": false
}
192.168.27.101 | SUCCESS => {
"ansible_facts": {
"ansible_fqdn": "g101.com"
},
"changed": false
}
ct, raw, meta
[root@ansible app]# ansible cen7 -m setup -a 'filter=*addr*'
192.168.27.102 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.27.102"
],
"ansible_all_ipv6_addresses": [
"fe80::20c:29ff:fe8b:f0dd"
]
},
"changed": false
}
192.168.27.101 | SUCCESS => {
"ansible_facts": {
"ansible_all_ipv4_addresses": [
"192.168.27.101"
],
"ansible_all_ipv6_addresses": [
"fe80::20c:29ff:fec3:887f"
]
},
"changed": false
}
ansible-playbook –e 选项指定
ansible-playbook test.yml -e "hosts=www user=mageedu"
- hosts: websrvs
remote_user: root
tasks
- name: install package
yum: name={{ pkname }} state=present
# ansible-playbook -e pkname=httpd var.yml
[root@ansible ansible]# vim var2.yml
---
- hosts: cen7
remote_user: root
vars: //如果要在play中第一变量要用vars
- username: user123 //变量名:赋值
- groupname: group123
tasks:
- name: create group
group: name={{ groupname }} //调用变量
- name: create uesr
user: name={{ username }} group={{ groupname }} home=/app/{{ username }}dir //可以写变量加其它字段
[root@ansible ansible]# ansible-playbook var2.yml
[root@ansible ansible]# ansible cen7 -a 'getent passwd user123'
192.168.27.101 | SUCCESS | rc=0 >>
user123:x:1001:1001::/app/user123dir:/bin/bash
# vim var2.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 }} state=present
# ansible-playbook var2.yml
# ansible-playbook -e "username=user2 groupname=group2” var2.yml
hosts: cen7
remote_user: root
tasks:
[root@ansible ansible]# ansible-playbook -e pkname=vsftpd var1.yml 用-e 写要指定定的变量名然后赋值
- 范例4:使用多个变量名
```bash
[root@ansible ansible]# vim var1.yml
---
- hosts: cen7
remote_user: root
tasks:
- name: install package
yum: name={{ pkname }} //第一个变量
- name: copy file
copy: src=/app/{{ filename }} dest=/app/ //第二个变量
[root@ansible ansible]# ansible-playbook -e "pkname=dstat filename=httpd.conf" var1.yml
要赋值多个变量要用双引号引起来,
[root@ansible ansible]# ansible cen7 -m yum -a 'name=dstat,httpd state=absent'
"se-preview-section-delimiter">
[root@ansible ansible]# vim var2.yml
---
- hosts: cen7
remote_user: root
vars:
- username: user123
- groupname: group123
tasks:
- name: create group
group: name={{ groupname }}
- name: create uesr
user: name={{ username }} group={{ groupname }} home=/app/{{ username }}dir
[root@ansible ansible]# ansible cen7 -m setup -a 'filter="*nodename*"'
192.168.27.102 | SUCCESS => {
"ansible_facts": {
"ansible_nodename": "g102.com"
},
"changed": false
}
[root@ansible ansible]# ansible cen7 -m setup -a 'filter="*hostname*"'
192.168.27.102 | SUCCESS => {
"ansible_facts": {
"ansible_hostname": "g102"
},
"changed": false
}
[root@ansible ansible]# vim var3.yml
---
- hosts: cen7
remote_user: root
tasks:
- name: create file
file: name=/app/{{ ansible_hostname }}.txt state=touch //ansible_hostnam 是setup中的变量,我们可以直接调用
[root@ansible ansible]# ansible-playbook var3.yml
- 这里101主机定义的http_port是85,102直接定义的是86,虽然变量名都是同一个,针对不同的主机可以设置不同的值
- 然后我们可以调用用命令行
[root@ansible ~]# ansible webser -m hostname -a 'name=web{{ http_port }}' //修改主机名,会针对不同的主机的变量值不一样
[root@ansible ~]# ansible webser -a 'hostname'
192.168.27.101 | SUCCESS | rc=0 >>
web85 这是针对某个主机设置不同的值
192.168.27.102 | SUCCESS | rc=0 >>
web86
[root@ansible ansible]# vim var4.yml
---
- hosts: webser
remote_user: root
tasks:
- name: set hostname
hostname: name={{ hostname }}-{{ http_port}}
[root@ansible ansible]# ansible webser -a 'hostname'
192.168.27.101 | SUCCESS | rc=0 >>
web1-88
192.168.27.102 | SUCCESS | rc=0 >>
web2-86
[root@ansible ansible]# ansible-playbook -e "http_port=9090 hostname=abc.com" var4.yml
[root@ansible ansible]# ansible webser -a 'hostname'
192.168.27.101 | SUCCESS | rc=0 >>
abc.com-9090
192.168.27.102 | SUCCESS | rc=0 >>
abc.com-9090
[websrvs]
www1.magedu.com http_port=80 maxRequestsPerChild=808
www2.magedu.com http_port=8080 maxRequestsPerChild=909
[websrvs]
www1.magedu.com
www2.magedu.com
[websrvs:vars] 这个相当于是在websrvs组中的所有主机公用的,叫做组公共变量
ntp_server=ntp.magedu.com
nfs_server=nfs.magedu.com
[root@ansible ansible]# vim var4.yml
---
- hosts: webser
remote_user: root
tasks:
- name: set hostname
hostname: name={{ hname }}-{{ http_port}}
[root@ansible ansible]# ansible-playbook var4.yml
[root@ansible ansible]# ansible webser -a 'hostname'
192.168.27.102 | SUCCESS | rc=0 >>
ansible-91
192.168.27.101 | SUCCESS | rc=0 >>
ansible-90
[websrvs]
192.168.99.101 http_port=8080 hname=www1
192.168.99.102 http_port=80 hname=www2
[websvrs:vars]
http_port=808
mark=“_”
[websrvs]
192.168.99.101 http_port=8080 hname=www1
192.168.99.102 http_port=80 hname=www2
# ansible websvrs –m hostname –a ‘name={{ hname }}{{ mark }}{{http_port }}’
ansible websvrs –e http_port=8000 –m hostname –a ‘name={{hname }}{{ mark }}{{ http_port }}’
[root@ansible ~]# vim add.yml
host: 123 在文件中定义变量是这中格式 host是变量名 :后面是值 这是和上面定义变量是用区别的
filen: 456
[root@ansible ansible]# vim var5.yml
---
- hosts: cen7
remote_user: root
vars_files: 一定要写vars_files
- /root/add.yml 这里是定义变量的文件路径,然后就可以调用里面的变量了
tasks:
- name: create file
file: name=/app/{{host}}-{{filen}}.log state=touch mode=600 owner=guo
[root@ansible ansible]# ansible cen7 -a 'ls /app/'
192.168.27.102 | SUCCESS | rc=0 >>
123-456.log
192.168.27.101 | SUCCESS | rc=0 >>
123-456.log
f2
f3
字符串:使用单引号或双引号
数字:整数,浮点数
列表:[item1, item2, ...]
元组:(item1, item2, ...)
字典:{key1:value1, key2:value2, ...}
布尔型:true/false
./
├── temnginx.yml
└── templates
└── nginx.conf.j2
# 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
# ansible-playbook temnginx.yml
首先要在本机上安装相同的服务,然后把配置文件复制一份到template目录下改后缀为j2
1. [root@ansible ansible]# cp /etc/nginx/nginx.conf templates/nginx.conf.j2 首先把要准备一份模板文件,后缀名必须是j2
[root@ansible ansible]# vim temnginx.yml
---
- hosts: cen7
remote_user: root
tasks:
- name: install nginx
yum: name=nginx
- name: template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf //src=这个可以写绝对路径,也可以这样写,因为我的template目录和这playbook文件是在同一目录,默认play会到template目录下找。
tags: instconf
- name: start service
service: name=nginx state=started
[root@ansible ansible]# ansible-playbook temnginx.yml 运行这个playbook,安装服务,并生成模板文件
[root@ansible ansible]# ansible cen7 -m setup -a 'filter="*cpu*"'
192.168.27.101 | SUCCESS => {
"ansible_facts": {
"ansible_processor_vcpus": 1 这个就是显示CPU变量的
},
"changed": false
}
192.168.27.102 | SUCCESS => {
"ansible_facts": {
"ansible_processor_vcpus": 4
},
"changed": false
}
[root@ansible ansible]# vim temnginx.yml
---
- hosts: cen7
remote_user: root
tasks:
- name: install nginx
yum: name=nginx
- name: template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: instconf
- name: start service
service: name=nginx state=started
handlers:
- name: restart nginx
service: name=nginx state=restarted
看一下各自的配置文件
还可以做运算
worker_processes {{ ansible_processor_vcpus }};
# cat temnginx2.yml
---
- hosts: websrvs
remote_user: root
tasks:
- name: template config to remote hosts
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
# ansible-playbook temnginx2.yml
# vim nginx.conf.j2
worker_processes {{ ansible_processor_vcpus*2 }};
worker_processes {{ ansible_processor_vcpus+2 }};
- 修改模板文件
- 执行playbook
- 查看监听端口是否改变
- 我们也可以在playbook中定义变量让模板调用
[root@ansible ansible]# vim temnginx.yml
---
- hosts: cen7
remote_user: root
vars:
- http_port: 6060 在playbook中定义http_port变量值为6060
tasks:
- name: install nginx
yum: name=nginx
- name: template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: instconf
- name: start service
service: name=nginx state=started
handlers:
- name: restart nginx
service: name=nginx state=restarted
命令行定义变量> playbook中定义的> hosts主机清单中定义的变量> 模板文件中
tasks:
- name: "shutdown RedHat flavored systems"
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
yum: name=nginx state=present
- name: restart Nginx
service: name=nginx state=restarted
when: ansible_distribution_major_version == "6"
tasks:
- name: install conf file to centos7
template: src=nginx.conf.c7.j2
when: ansible_distribution_major_version == "7"
- name: install conf file to centos6
template: src=nginx.conf.c6.j2
when: ansible_distribution_major_version == "6"
[root@ansible ansible]# vim when.yml
---
- hosts: all
remote_user: root
tasks:
- name: install httpd
yum: name=httpd
- name: template
▽ template: src=httpd-6.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution_major_version=="6" 当版本==6时会执行,不然就不执行
- name: template
template: src=httpd-7.conf.j2 dest=/etc/httpd/conf/httpd.conf
when: ansible_distribution_major_version=="7"
- name: start service
service: name=httpd state=started
- name: add several users
user: name={{ item }} state=present groups=wheel //item是个关键字,必须这样写
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
[root@ansible ansible]# vim with_items.yml
---
- hosts: cen7
remote_user: root
tasks:
- name: create servel users
user: name={{ item }} group=root groups=guo
with_items:
- xiaoming
- xiaowang
- xiaoguo
````
- 示例:将多个文件进行copy到被控端
"se-preview-section-delimiter">
```bash
---
- hosts: testsrv
remote_user: root
tasks
- name: Create rsyncd config
copy: src={{ item }} dest=/etc/{{ item }}
with_items:
- rsyncd.secrets
- rsyncd.conf
- 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: install some packages
yum: name={{ item }} state=present
with_items:
- nginx
- memcached
- php-fpm
- hosts:websrvs
remote_user: root
tasks:
- name: add some groups
group: name={{ item }} state=present
with_items:
- group1
- group2
- group3
- name: add some users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
- { name: 'user1', group: 'group1' }
- { name: 'user2', group: 'group2' }
- { name: 'user3', group: 'group3' }
[root@ansible ~]# vim qiantaoitem.yml
---
- hosts: cen7
remote_user: root
tasks:
- name: create group
group: name={{ item }}
with_items:
- igroup1
- igroup2
- igroup3
- name: create user
user: name={{item.username }} group={{item.groupname}}
with_items:
- {username: 't1', groupname: 'igroup1' } 一行有两个变量,用逗号隔开冒号后面有空格
- {username: 't2', groupname: 'igroup2' }
- {username: 't3', groupname: 'igroup3' }
{%for 变量 in 列表%}
循环体
{%endfor}
这种是用于template模板中,在playbook中定义列表
[root@ansible ansible]# vim for.yml
---
- hosts: cen7
remote_user: root
vars:
▽ ports: //这里定义列表名,里面有几个值for就循环几遍
- 81
- 82
- 83
tasks:
- name: test for1
template: src=for1.conf.j2 dest=/app/for1.conf
[root@ansible ansible]# vim templates/for1.conf.j2 在模板文件里写for循环
{%for port in ports %} port类似shell,for循环中的i可以随便写,ports必须写列表名
server { 这里是循环体
listen {{port}}; 这里调用{{port}}这里的值就是列表里的值
}
{%endfor%} 结束循环体
运行playbook文件
[root@ansible-90 ~]# cat /app/for1.conf
server {
listen 81;
}
server {
listen 82;
}
server {
listen 83;
}
[root@ansible ansible]# vim for2.yml
---
- hosts: cen7
remote_user: root
vars:
ports: 这是列表名
- http_port: 81 写成这样相当于子变量
- http_port: 82
- http_port: 83
tasks:
▽ - name: template file
template: src=for2.conf.j2 dest=/app/for2.conf
模板文件
[root@ansible ansible]# vim templates/for2.conf.j2
{%for port in ports %}
server {
listen {{port.http_port}}; 这种类似于item的写法port相当于http_port,然后把http_port的变量名替换成值
}
{%endfor%}
---------------------------------------------------------------------------------------
[root@ansible-90 ~]# cat /app/for2.conf
server {
listen 81;
}
server {
listen 82;
}
server {
listen 83;
}
[root@ansible ansible]# vim for3.yml
---
- hosts: cen7
remote_user: root
vars:
hhh: 一个列表中可以有对个元素
- web1:
port: 88
name: web1.server
root: /app/web1.server
- web2:
port: 89
name: web2.server
root: /app/web2.server
- web3:
port: 90
name: web3.server
root: /app/web3.server
tasks:
- name: test for3
template: src=for3.conf.j2 dest=/app/for3.con
模板文件
{%for i in hhh%}
server {
listen {{i.prot}}
servername {{i.name}}
rootdir {{i.root}}
}
{%endfor%}
生成结果
[root@ansible-90 ~]# cat /app/for3.conf
server {
listen 88
servername web1.server
rootdir /app/web1.server
}
server {
listen 89
servername web2.server
rootdir /app/web2.server
}
server {
listen 90
servername web3.server
rootdir /app/web3.server
}
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen | default('80 default_server') }};
{% if vhost.server_name is defined %} //这表示如果vhost.server_name被定义了有值了则就用这里定义的值,如果没有定义就不用
server_name {{ vhost.server_name }};
{% endif %}
{% if vhost.root is defined %}
root {{ vhost.root }};
{% endif %}
-范例
[root@ansible ansible]# vim for4-if.yml
---
- hosts: cen7
remote_user: root
vars:
hhh:
- web1:
▽ port: 88
#name: web1.server 我们把web1中name注释
root: /app/web1.server
- web2:
port: 89
name: web2.server
root: /app/web2.server
- web3:
port: 90
#name: web3.server web#中name注释 这样用if时就不会定义这个name
root: /app/web3.server
tasks:
- name: test for3
template: src=for4-if.conf.j2 dest=/app/for4-if.conf
模板文件
[root@ansible ansible]# vim templates/for4-if.conf.j2
{%for i in hhh %}
service {
listen {{i.port}}
{%if i.name is defined %} 一点要顶头写这些,当i.name被定义就调用,如果没有被定义则不调用
servername {{i.name}}
{%endif%} if这种格式一点要顶头写
rootdir {{i.root}}
}
{%endfor%}
结果
[root@ansible-90 ~]# cat /app/for4-if.conf
service {
listen 88
rootdir /app/web1.server
}
service {
listen 89
servername web2.server 这里只有web2的name有名字
rootdir /app/web2.server
}
service {
listen 90
rootdir /app/web3.server
}
// temnginx.yml
---
- hosts: testweb
remote_user: root
vars:
nginx_vhosts:
- listen: 8080
//templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost.listen }}
}
{% endfor %}
生成的结果
server {
listen 8080
}
```bash
// templates/nginx.conf.j2
{% for vhost in nginx_vhosts %}
server {
listen {{ vhost }}
}
{% endfor %}
生成的结果:
server {
listen web1
}
server {
listen web2
}
server {
listen web3
}
roles/ 这个文件夹名比较小是roles是固定的
mysql/
httpd/
nginx/
memcached/
- git是一个角色
+ 下面有一个tasks目录,里面放着所有的任务 这人文件必须要有
+ 而tasks文件夹里必要要有个文件是main.yml这个playbook。当我们调用git这个服务角色时,它会自动去找tasks下的main.yml这是整个任务的入口,相当于主联系人。这个文件必须存在
+ file则是放着要用的文件
+ vars放着所有的变量
- 当roles写好后要有人调用,则userconf.yml就相当于调用这些服务
playbook.yml 这是调用的剧本是和roles是在同一目录是平级的
roles/
project/
tasks/
files/
vars/ 不常用
default/ 不常用
templates/
handlers/
meta/ 不常用
- roles这个文件夹在哪里创建都可以,但是官方有一个推荐位置/etc/ansible/目录下有一个roles
- 而roles目录创建完里面的目录可以根据需求来创建,但是tasks必须要有
- 范例
site.yml
webservers.yml
dbservers.yml
roles/
common/
files/
templates/
tasks/
handlers/
vars/
meta/
webservers/
files/
templates/
tasks/
handlers/
vars/
meta/
- hosts: websrvs
remote_user: root
roles:
- mysql 这是调用roles,就是roles目录中所创建的
- memcached
- nginx
传递变量给角色
- hosts:
remote_user:
roles:
- mysql
- { role: nginx, username: nginx }
键role用于指定角色名称
后续的k/v用于传递变量给角色
roles:
- { role: nginx, username: nginx, when:ansible_distribution_major_version== '7' }
# ansible-playbook --tags="nginx,httpd,mysql" nginx-role.yml
// nginx-role.yml
---
- hosts: testweb
remote_user: root
roles:
- { role: nginx ,tags: [ 'nginx', 'web' ] ,when:ansible_distribution_major_version == "6“ }
- { role: httpd ,tags: [ 'httpd', 'web' ] }
- { role: mysql ,tags: [ 'mysql', 'db' ] }
- { role: marridb ,tags: [ 'mysql', 'db' ] }
- { role: php }
[root@ansible tasks]# ls
groupadd.yml install.yml start.yml useradd.yml
[root@ansible tasks]# cat groupadd.yml
- name: add group
group: name=nginx
[root@ansible tasks]# cat useradd.yml
- name: create user
user: name=nginx group=nginx system=yes shell=/sbin/nologin
[root@ansible tasks]# cat install.yml
- name: install package
yum: name=nginx
[root@ansible tasks]# cat start.yml
- name: start service
service: name=nginx state=started enabled=yes
[root@ansible tasks]# cat main.yml
- import_tasks: groupadd.yml
- import_tasks: useradd.yml
- import_tasks: install.yml
- import_tasks: start.yml
[root@ansible ansible]# ls
1 nginx-roles.yml roles这个是目录
[root@ansible ansible]# cat nginx-roles.yml
- hosts: cen7
remote_user: root
roles:
- role: nginx 这是调用角色
[root@ansible ansible]# cat nginx-roles.yml
- hosts: cen7
remote_user: root
roles:
- role: nginx 这是调用角色
- role: filecopy 也可以调用复制文件的角色
- name: file copy
copy: src=fstab dest=/app/
- name: file create
file: name=/app/testfile state=touch mode=600
- import_tasks: roles/nginx/tasks/install.yml //这是调用另一个角色中的一个剧本 ,一般不推荐这样使用
[root@ansible roles]# ls
filecopy httpd memcached nginx
[root@ansible ansible]# vim tags-roles.yml
---
- hosts: cen7
remote_user: root
roles:
- { role: nginx, tags: ['nginx','web' ] } 一个服务可以有多个标签,也可以和其它标签名相同tags:后一定要有空格,标签用单引号,多个标签用中括号分隔
- { role: httpd, tags: ['httpd','web' ] }
- { role: filecopy, tags: 'copyfile' }
mkdir {tasks,templates,handlers,vars}
[root@ansible ~]# cat /root/ansible/roles/nginx/tasks/main.yml
- name: install package 安装nginx包
yum: name=nginx
- name: template
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
tags: 123 这里也可以定义标签
notify: restart service 当template任务发生变化时则执行restart service
- name: start service
service: name=nginx state=started
[root@ansible ~]# cat /root/ansible/roles/nginx/handlers/main.yml
- name: restart service 这个名字必须和notify所表示的名字一样,当template任务发生变化时执行这里的任务
service: name=nginx state=restarted
cp /etc/nginx/nginx.conf templates/nginx.conf.j2
[root@ansible ~]# cat /root/ansible/roles/nginx/vars/main.yml
lport: 8080
[root@ansible ~]# cat ansible/testnginx.yml
- hosts: all
remote_user: root
roles:
- { role: nginx, when: ansible_distribution_major_version=='7' } 判断如果系统版本号为7就执行这个角色
lport: 9090 在这里也定义了变量,这里的变量优先级比vars目录中的变量优先级高这里会生效
- role: filecopy 还可以调用多个角色
when: ansible_nodename=='ansible-90' 也是判断,当主机名为ansible-90就执行这个角色