Ansible 系统由控制主机对被管节点的操作方式可分为两类,即adhoc和playbook:
使用单个模块,支持批量执行单条命令。ad-hoc 命令是一种可以快速输入的命令,而且不需要保存起来的命令。就相当于bash中的一句话shell。
是Ansible主要管理方式,也是Ansible功能强大的关键所在。playbook通过多个task集合完成一类功能,如Web服务的安装部署、数据库服务器的批量备份等。可以简单地把playbook理解为通过组合多条ad-hoc操作的配置文件。
YAML(/ˈjæməl/,尾音类似camel骆驼)是一个可读性高,用来表达数据序列化的格式。
YAML是"YAML Ain’t a Markup Language"(YAML不是一种标记语言)的递归缩写。在开发的这种语言时,YAML 的意思其实是:“Yet Another Markup Language”(仍是一种标记语言),但为了强调这种语言以数据做为中心,而不是以标记语言为重点,而用反向缩略语重命名。
YAML的语法和其他高级语言类似,并且可以简单表达清单、散列表,标量等数据形态。它使用空白符号缩进和大量依赖外观的特色,特别适合用来表达或编辑数据结构、各种配置文件、倾印调试内容、文件大纲(例如:许多电子邮件标题格式和YAML非常接近)。YAML 的配置文件后缀为 .yml,如:test.yml 。
#(1)格式为key: value,冒号后面加一个空格
url: http://192.168.20.1
#(2)表示server: {host: node1}
server:
host: node1
#(3)使用缩进表示层级关系
key:
key1: value1
key2: value2
#上面还支持流式(flow)语法表示对象
key: {key1: value1, key2: value2}
使用一个短横线加一个空格代表一个数组项
#(1)表示server为[node1,node2,node3]
server:
- node1
- node2
- node3
#(2)表示[[python,java]]
-
- python
- java
#(3)表示companies属性是一个数组,每一个数组元素又是由id,name,price三个属性构成
note:
-
id: 1
name: book1
price: 20
-
id: 2
name: book2
price: 50
#上面数组也可以使用流式(flow)的方式表示:
note: [{id: 1,name: book1,price: 20},{id: 2,name: book2,price: 50}]
常量结构,包括:整数,浮点数,字符串,NULL,日期,布尔,时间
boolean:
- TRUE #true,True都可以
- FALSE #false,False都可以
float:
- 3.14
- 6.8523015e+5 #可以使用科学计数法
int:
- 123
- 0b1010_0111_0100_1010_1110 #二进制表示
null:
Name: 'node'
parent: ~ #使用~表示null
string:
- 测试
- 'Hello world' #可以使用双引号或者单引号包裹特殊字符
- line1
line2 #字符串可以拆成多行,每一行会被转化成一个空格
date:
- 2020-04-02 #日期必须使用ISO 8601格式,即yyyy-MM-dd
datetime:
- 2020-04-02T15:02:31+08:00 #时间使用ISO 8601格式,时间和日期之间使用T连接,最后使用+代表时区
# (1)--- YAML可以在同一个文件中,使用---表示一个文档的开始;也常常使用---来分割不同的内容,比如记录日志
---
Time: 2020-04-02T15:02:31+08:00
User: ed
Warning:
This is an error message for the log file
---
Time: 2020-04-02T15:05:21+08:00
User: ed
Warning:
A slightly different error message.
#(2)... 和---配合使用,在一个配置文件中代表一个文件的结束,下面例子相当于在一个yaml文件中连续写了两个yaml配置项
---
time: 20:03:20
player: tom
action: run
...
---
time: 20:03:47
player: Lily
action: run
...
#(3)!! YAML中使用!!做类型强行转换,例如把数字和布尔类型强转为字符串
string:
- !!str 54321
- !!str true
#将数组解析为set,简单理解,转化的内容就是:[{aaa=58}, {bbb=65}, {ccc=63}],重复的ccc去掉
--- !!set
- bbb: 65
- ccc: 63
- ccc: 63
- aaa: 58
#(4)>在字符串中折叠换行,| 保留换行符
context: >
this is
a book
stats: |
today is
sunday
#结果是:
context=this is a book #换行符转化成了空格;每行的文本前一定要有一个空格
stats= today is
sunday
#(5)引用
#重复的内容在YAML中可以使用&来完成锚点定义,使用*来完成锚点引用
hr:
- aa
- &SS bb
rbi:
- *SS
- cc
#结果为:
{rbi=[bb, cc], hr=[aa, bb]}
#(6)合并
test:
- &SMALL { x: 1, y: 2 }
- &BIG { r: 10 }
exp2:
<< : [ *SMALL, *BIG ]
other: haha
exp3:
<< : [ *SMALL, *BIG ]
r: 100
#exp2中,<<: [*SMALL, *BIG] 意思是联合引用{x: 1,y: 2}和{r: 10},并且合并到exp2中,那么合并的结果为:exp2={other=haha, x=1, y=2, r=10}
#exp3中,引入了*SMALL, *BIG,还使用了r: 100覆盖了引入的r: 10,所以exp3值为:exp3={r=100, y=2, x=1}
- Hosts:运行指定任务的目标主机
- remote_user:在远程主机上执行任务的用户
sudo_user
- tasks:任务列表
模块,模块参数;
格式:(1)action:module arguments
(2)module:arguments
注意:shell和command模块后面直接跟命令,而非key=value类的参数列表;
1)某任务的状态在运行后为changed时,可通过"notify"通知给相应的handlers;
2)任务可以通过"tags"打标签,而后可在ansible-palybook命令上使用-t指定进行调用;
---
- hosts: abc #可以是一个主机组、主机、多个主机,中间以冒号分隔,也可以用all参数表示所有主机
remote_user: root #表示执行的用户账号
become: yes #2.6版本以后的参数,之前是sudo,意思为切换用户运行
become_user: mysql #指定sudo用户为mysql
become 和become_user 作为指定远程主机sudo切换用
1、Play的主体部分是task列表,task列表中的各任务按次序逐个在hosts中指定的主机上执行,即在所有主机上完成第一个任务后再开始第二个任务。
2、在运行playbook时(从上到下执行),如果一个host执行task失败,整个tasks都会回滚,请修正playbook 中的错误,然后重新执行即可。
3、每一个task必须有一个名称name,这样在运行playbook时,从其输出的任务执行信息中可以很好的辨别出是属于哪一个task的。
如果没有定义name,‘action’的值将会用作输出信息中标记特定的task。
4、定义一个task,常见的格式:”module: options” 例如:yum: name=httpd
5、ansible的自带模块中,command模块和shell模块无需使用key=value格式
# ansible-playbook first.yml --syntax-check #检查yaml文件的语法是否正确
# ansible-playbook first.yml --list-task #检查tasks任务
# ansible-playbook first.yml --list-hosts #检查生效的主机
# ansible-playbook first.yml --start-at-task='Copy Nginx.conf' #指定从某个task开始运行
# ansible-playbook first.yml -k #用来交互输入ssh密码
# ansible-playbook first.yml -K #用来交互输入sudo密码
# ansible-playbook first.yml -u #指定用户
执行方式:ansible-playbook playbook.yml [options]
-u REMOTE_USER, --user=REMOTE_USER
# ssh连接的用户名
-k, --ask-pass
#ssh登录认证密码
-s, --sudo
#sudo 到root用户相当于Linux系统下的sudo命令
-U SUDO_USER, --sudo-user=SUDO_USER
#sudo到对应的用户
-K, --ask-sudo-pass
#用户的密码(—sudo时使用)
-T TIMEOUT, --timeout=TIMEOUT
# ssh连接超时,默认10秒
-C, --check
# 指定该参数后,执行playbook文件不会真正去执行,而是模拟执行一遍,然后输出本次执行会对远程主机造成的修改
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
# 设置额外的变量如:key=value形式或者 YAML or JSON,以空格分隔变量,或用多个-e
-f FORKS, --forks=FORKS
# 进程并发处理,默认5
-i INVENTORY, --inventory-file=INVENTORY
# 指定 hosts 文件路径,默认 default=/etc/ansible/hosts
-l SUBSET, --limit=SUBSET
# 指定一个pattern,对-hosts:匹配到的主机再过滤一次
--list-hosts
# 只打印有哪些主机会执行这个playbook文件,不是实际执行该playbook
--list-tasks
# 列出该playbook中会被执行的task
--private-key=PRIVATE_KEY_FILE
# 私钥路径
--step
# 同一时间只执行一个task,每个task 执行前都会提示确认一遍
--syntax-check
# 只检测playbook文件语法是否有问题,不会执行该playbook
-t TAGS, --tags=TAGS
#当play和task的tag为该参数指定的值时才执行,多个tag以逗号分隔
--skip-tags=SKIP_TAGS
# 当play和task的tag不匹配该参数指定的值时,才执行
-v, --verbose
#输出更详细的执行过程信息,-vvv可得到所有执行过程信息。
#只检测可能会发生的改变,但不真正执行操作
ansible-playbook --check
#列出运行任务的主机
ansible-playbook --list-hosts
[root@localhost playbooks]# cat first.yaml
- hosts: all
remote_user: root
tasks:
- name: install redis
yum: name=redis state=latest
- name: start redis
service: name=redis state=started enabled=true
#语法检测
[root@localhost playbooks]# ansible-playbook --syntax-check first.yaml
playbook: first.yaml
#列出运行任务的主机
[root@localhost playbooks]# ansible-playbook --list-hosts first.yaml
playbook: first.yaml
play #1 (all): all TAGS: []
pattern: [u'all']
hosts (1):
192.168.75.128
#列出任务和主机
[root@localhost playbooks]# ansible-playbook --list-hosts --list-tasks first.yaml
playbook: first.yaml
play #1 (all): all TAGS: []
pattern: [u'all']
hosts (1):
192.168.75.128
tasks:
install redis TAGS: []
start redis TAGS: []
#执行playbook文件不会真正去执行,而是模拟执行一遍,然后输出本次执行会对远程主机造成的修改
[root@localhost playbooks]# ansible-playbook -C first.yaml
#开始运行YAML文件,按任务逐个执行
[root@localhost playbooks]# ansible-playbook first.yaml
PLAY [all] **************************************************************************
TASK [Gathering Facts] **************************************************************
ok: [192.168.75.128]
TASK [install redis] ****************************************************************
changed: [192.168.75.128]
TASK [start redis] ******************************************************************
changed: [192.168.75.128]
PLAY RECAP **************************************************************************
192.168.75.128 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
#查看备机已启动
[root@localhost ~]# ps -ef | grep redis
redis 73031 1 0 03:17 ? 00:00:08 /usr/bin/redis-server 127.0.0.1:6379
root 74017 73983 0 04:36 pts/0 00:00:00 grep --color=autoredis
处理远程服务器的redis相关配置
#将远程主机的配置文件复制到本地
[root@localhost playbooks]# ansible 192.168.75.128 -m fetch -a "src=/etc/redis.conf dest=./"
#修改配置文件redis.conf内容
[root@localhost playbooks]# ls
192.168.75.128 file1.yml first.yaml
[root@localhost playbooks]# mv 192.168.75.128/etc/redis.conf ./
[root@localhost playbooks]# rm -rf 192.168.75.128
#更改redis.conf
bind 0.0.0.0
requirepass changecan
#更改yaml,将已修改配置文件传到远程主机
[root@localhost playbooks]# cat first.yaml
- hosts: all
remote_user: root
tasks:
- name: install redis
yum: name=redis state=latest
- name: copy config file
copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis
- name: start redis
service: name=redis state=started enabled=true
[root@localhost playbooks]# ansible-playbook --syntax-check first.yaml
[root@localhost playbooks]# ansible-playbook -C first.yaml
[root@localhost playbooks]# ansible-playbook first.yaml #结果显示:只执行了传配置文件这一项
#当redis.conf内容复制发生改变,则执行重启
[root@localhost playbooks]# cat second.yaml
- hosts: all
remote_user: root
tasks:
- name: install redis
yum: name=redis state=latest
- name: copy config file
copy: src=/root/playbooks/redis.conf dest=/etc/redis.conf owner=redis
notify: restart redis
tags: configfile
- name: start redis
service: name=redis state=started enabled=true
handlers:
- name: restart redis
service: name=redis state=restarted
#更改redis.conf再测试执行,会触发restart重启redis操作。若redis.conf内容不变,则不会触发重启
[root@localhost playbooks]# ansible-playbook second.yaml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.75.128]
TASK [install redis] ***********************************************************
ok: [192.168.75.128]
TASK [copy config file] ********************************************************
changed: [192.168.75.128]
TASK [start redis] *************************************************************
ok: [192.168.75.128]
RUNNING HANDLER [restart redis] ************************************************
changed: [192.168.75.128]
PLAY RECAP *********************************************************************
192.168.75.128 : ok=5 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
#只执行指定标签tags:名为configfile标记的任务
[root@localhost playbooks]# ansible-playbook -t configfile second.yaml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.75.128]
TASK [copy config file] ********************************************************
ok: [192.168.75.128]
PLAY RECAP *********************************************************************
192.168.75.128 : ok=2 changed=0 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(1)facts:可直接调用
注意:可使用setup模块直接获取目标主机的facters;
ansible-playbook -m setup
(2)用户自定义变量:
(a)ansible-playbook命令的命令行中的自定义变量;
-e VARS, --extra-vars=VARS
(b)在playbook中定义变量的方法:
vars:
- var1: value1
- var2: value2
变量引用:{{ variable }}
(3)通过roles传递变量;
(4)Host Inventory主机清单
(a)用户自定义变量
(i)向不同的主机传递不同的变量;
IP/HOSTNAME variable=value var2=value2
(ii)向组中的主机传递相同的变量;
[groupname:vars]
variable=value
(b)invertory参数
用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
注意:可使用setup模块直接获取目标主机的facters;
ansible-playbook -m setup
#例如:调用ansible_env变量获取远程主机信息
[root@localhost playbooks]# cat third.yaml
- hosts: 192.168.75.128
remote_user: root
tasks:
- name: copy file
copy: content={{ ansible_env }} dest=/tmp/ansible.env
[root@localhost playbooks]# ansible-playbook --syntax-check third.yaml
[root@localhost playbooks]# ansible-playbook third.yaml
[root@128 ~]# cat /tmp/ansible.env
{"LANG": "en_US.UTF-8", "TERM": "xterm", "SHELL": "/bin/bash", "XDG_RUNTIME_DIR": "/run/user/0", "MAIL": "/var/mail/root", "SHLVL": "2", "SSH_TTY": "/dev/pts/1", "SSH_CLIENT": "192.168.75.129 40590 22", "LESSOPEN": "||/usr/bin/lesspipe.sh %s", "PWD": "/root", "SELINUX_USE_CURRENT_RANGE": "", "LOGNAME": "root", "USER": "root", "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", "HOME": "/root", "SELINUX_LEVEL_REQUESTED": "", "XDG_SESSION_ID": "177", "SELINUX_ROLE_REQUESTED": "", "_": "/usr/bin/python", "SSH_CONNECTION": "192.168.75.129 40590 192.168.75.128 22"}
(a)ansible-playbook命令的命令行中的自定义变量;
-e VARS, --extra-vars=VARS
(b)在playbook中定义变量的方法:
vars:
- var1: value1
- var2: value2
变量引用:{{ variable }}
#安装包使用变量表示
[root@localhost playbooks]# cat forth.yaml
- hosts: all
remote_user: root
tasks:
- name: install {{ pkgname }}
yum: name={{ pkgname }} state=latest
#安装nginx
[root@localhost playbooks]# ansible-playbook -e pkgname=nginx forth.yaml
PLAY [all] *********************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.75.128]
TASK [install nginx] ***********************************************************
changed: [192.168.75.128]
PLAY RECAP *********************************************************************
192.168.75.128 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
(a)用户自定义变量
(i)向不同的主机传递不同的变量;
IP/HOSTNAME variable=value var2=value2
(ii)向组中的主机传递相同的变量;
[groupname:vars]
variable=value
(b)invertory参数
用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
(i)向不同的主机传递不同的变量
#测试:添加用户changecan
[root@localhost playbooks]# cat users.yaml
- hosts: all
remote_user: root
tasks:
- name: add user
user: name=changecan system=no state=present
- name: set password
shell: echo changecan | passwd --stdin changecan
[root@localhost playbooks]# ansible-playbook users.yaml
#测试用户添加成功
[root@localhost playbooks]# ssh -l changecan 192.168.75.128
[email protected]'s password:
[changecan@128 ~]$
#更改主机清单的配置
[root@localhost playbooks]# cat /etc/ansible/hosts
[websrvs]
192.168.75.128 ansible_ssh_user=changecan ansible_ssh_pass=changecan
#测试主机清单普通用户使用权限
[root@localhost playbooks]# ansible websrvs --list-hosts
hosts (1):
192.168.75.128
[root@localhost playbooks]# ansible websrvs -m ping
[root@localhost playbooks]# ansible websrvs -m command -a "whoami"
192.168.75.128 | CHANGED | rc=0 >>
changecan
(ii)向组中的主机传递相同的变量
[root@localhost playbooks]# cat /etc/ansible/hosts
[websrvs]
192.168.75.128
[websrvs:vars]
http_port=8080
[root@localhost playbooks]# cat vars.yaml
- hosts: websrvs
remote_user: root
vars:
- pbvar: playbook variable testing
tasks:
- name: command line variable
copy: content={{ cmdvar }} dest=/tmp/cmd.var
- name: playbook variables
copy: content={{ pbvar }} dest=/tmp/pb.var
- name: host iventory variables
copy: content={{ http_port }} dest=/tmp/hi.var
[root@localhost playbooks]# ansible-playbook -e cmdvar="command" vars.yaml
PLAY [websrvs] *****************************************************************
TASK [Gathering Facts] *********************************************************
ok: [192.168.75.128]
TASK [command line variable] ***************************************************
changed: [192.168.75.128]
TASK [playbook variables] ******************************************************
changed: [192.168.75.128]
TASK [host iventory variables] *************************************************
changed: [192.168.75.128]
PLAY RECAP *********************************************************************
192.168.75.128 : ok=4 changed=3 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
[root@128 ~]# cat /tmp/cmd.var
command[root@128 ~]# cat /tmp/pb.var
playbook variable testing[root@128 ~]# cat /tmp/hi.var
8080
基于模板方式生成一个文件复制到远程主机
*src=
*dest=
owner=
group=
mode=
字面量:
字符串:使用单引号或双引号;
数字:整数,浮点数;
列表:[item1, item2, ...]
元组:(item1 item2, ...)
字典:{key1:value1, key2:value2, ...}
布尔型:true/false
算数运算:
+, -, *, /, //, %, **
比较操作:
==, !=, >, >=,<, <=
逻辑运算:
and, or, not
通过已修改的配置文件bind {{ ansible_eno16777736.ipv4.address }}去获取远程主机ip地址进行参数传递
[root@localhost playbooks]# cat /root/playbooks/redis.conf.j2 | grep -v "^$" | grep -v "^#"
bind {{ ansible_eno16777736.ipv4.address }}
protected-mode yes
port 6379
tcp-backlog 511
timeout 0
tcp-keepalive 300
daemonize no
supervised no
pidfile /var/run/redis_6379.pid
loglevel notice
logfile /var/log/redis/redis.log
databases 16
save 900 1
save 300 10
save 60 10000
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir /var/lib/redis
slave-serve-stale-data yes
slave-read-only yes
repl-diskless-sync no
repl-diskless-sync-delay 5
repl-disable-tcp-nodelay no
slave-priority 100
requirepass changecan
appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
lua-time-limit 5000
slowlog-log-slower-than 10000
slowlog-max-len 128
latency-monitor-threshold 0
notify-keyspace-events ""
hash-max-ziplist-entries 512
hash-max-ziplist-value 64
list-max-ziplist-size -2
list-compress-depth 0
set-max-intset-entries 512
zset-max-ziplist-entries 128
zset-max-ziplist-value 64
hll-sparse-max-bytes 3000
activerehashing yes
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit slave 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
hz 10
aof-rewrite-incremental-fsync yes
[root@localhost playbooks]# cat template.yaml
- hosts: 192.168.75.128
remote_user: root
tasks:
- name: install config file
template: src=/root/playbooks/redis.conf.j2 dest=/tmp/redis.conf
[root@localhost playbooks]# ansible-playbook template.yaml
执行yaml后,查看远程主机的IP地址正常传递到配置文件了
修改httpd配置,将主机清单/etc/ansible/hosts里面的变量传递到配置文件,使得远程主机httpd增加监听端口8080
[root@localhost ~]# cat /etc/ansible/hosts
[websrvs]
192.168.75.128
[websrvs:vars]
http_port=8080
[root@localhost playbooks]# cat mylisten.conf
Listen {{ http_port }}
[root@localhost playbooks]# cat httpd.yaml
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=latest
- name: install config file
template: src=/root/playbooks/mylisten.conf dest=/etc/httpd/conf.d/mylisten.conf
- name: start httpd
service: name=httpd state=started
[root@localhost playbooks]# ansible-playbook httpd.yaml
#从setup模块中取远程主机参数:
CPU内核数:"ansible_processor_cores": 2,
CPU颗数:"ansible_processor_count": 2,
#模板配置文件:files/nginx.conf.j2
worker_processes {{ ansible_processor_vcpus }};
listen {{ http_port }};
#yaml文件
- hosts: websrvs
remote_user: root
tasks:
- name: install nginx
yum: name=nginx state=present
- name: install conf file
template: src=files/nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: instconf
- name: start nginx service
service: name=nginx state=started
handlers:
- name: restart nginx
service: name=nginx state=restarted
when语句:在task中使用,jinja2的语法格式
例如:当操作系统为redhat安装httpd,当为Debian则安装apache2
- hosts: websrvs
remote_user: root
tasks:
- name: install httpd
yum: name=httpd state=latest
when: ansible_os_family == "Redhat"
- name: install apache2
apt: name=apache2 state=latest
when: ansible_os_family == "Debian"
对迭代项的引用,固定变量名为"item".
而后,要在task中使用with_items给定要迭代的元素列表
列表方法:字符串、字典
(下面例子:yum一次性安装多个模块的问题)
- hosts: websrvs
remote_user: root
tasks:
- name: install {{ item }} package
yum: name={{ item }} state=latest
with_items:
- nginx
- tomcat
- mariadb-server
- redis
#新版本的ansible-playbook已经不支持在yum安装多个模块里使用的方式。
#这么写在老版本还OK,但是在2.8以后,还这么写就会有错误:
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via
squash_actions is deprecated. Instead of using a loop to supply multiple items
and specifying `name: "{{ item }}"`, please use `name: ['nginx', 'tomcat',
'mariadb-server', 'redis']` and remove the loop. This feature will be removed
in version 2.11. Deprecation warnings can be disabled by setting
deprecation_warnings=False in ansible.cfg.
#[弃用警告]:只在通过squash_actions使用循环时调用“yum”一次是不赞成的。而不是如果使用循环提供多个项目并指定' name: ['nginx', 'tomcat', 'mariadb-server', 'redis']',请使用' name: "{{ item }}"' '并删除循环。这个特性将在2.11版本中删除。弃用的警告可以通过在ansible.cfg中设置deprecation_warnings=False来禁用。
#【更改】上面的报错可以通过变量来传递(把item该为packages,并通过变量赋值来传递参数):
- hosts: websrvs
remote_user: root
vars:
packages:
- nginx
- tomcat
- mariadb-server
- redis
tasks:
- name: install "{{ packages }}" package
yum: name={{ packages }} state=latest
with_items: "{{ packages }}"
roles默认存放路径:
#在/etc/ansible/ansible.cfg里面进行配置
roles_path = /etc/ansible/roles
角色集合:
roles/
mysql/
httpd/
nginx/
memcached/
每个角色,以特定的层级目录结构进行组织:
mysql/
files/: 存放copy或script模块等调用的文件;
templates/: template模块查找所需要的模板文件的目录;
tasks/: 至少应该包含一个名为main.yaml的文件,其他的文件需要在此文件中通过include进行包含;
handlers/: 至少应该包含一个名为main.yaml的文件,其他的文件需要在此文件中通过include进行包含;
vars/: 至少应该包含一个名为main.yaml的文件,其他的文件需要在此文件中通过include进行包含;
meta/: 至少应该包含一个名为main.yaml的文件,定义当前角色的特殊设定及其依赖关系,其他的文件需要在此文件中通过include进行包含;
default/: 设定默认变量时使用此目录中的main.yaml文件。
安装nginx并启动服务,并修改配置文件后重启服务,配置默认index.html
[root@localhost ~]# mkdir -pv /etc/ansible/roles/nginx/{files,templates,tasks,vars,handlers,meta,default}
[root@localhost ~]# cat /etc/ansible/roles/nginx/tasks/main.yaml
- name: install nginx
yum: name=nginx state=latest
when: ansible_os_family == "RedHat"
- name: install conf
template: src=vhost1.conf.j2 dest=/etc/nginx/conf.d/vhost1.conf
tags: conf
notify: restart nginx
- name: install site home diretory
file: path={{ ngxroot }} state=directory
- name: install index page
copy: src=index.html dest={{ ngxroot }}/
- name: start nginx
service: name=nginx state=started
[root@localhost ~]# cat /etc/ansible/roles/nginx/templates/vhost1.conf.j2
server {
listen 8080;
server_name {{ ansible_fqdn }};
location / {
root "/ngxdata/vhost1";
}
}
[root@localhost ~]# cat /etc/ansible/roles/nginx/handlers/main.yaml
- name: restart nginx
service: name=nginx state=restarted
[root@localhost ~]# cat /etc/ansible/roles/nginx/vars/main.yaml
ngxroot: /ngxdata/vhost1
[root@localhost ~]# cat /etc/ansible/roles/nginx/files/index.html
Vhost1
[root@localhost ~]# cat nginx.yaml
- hosts: websrvs
remote_user: root
roles:
- nginx
[root@localhost ~]# ansible-playbook --syntax-check nginx.yaml
[root@localhost ~]# ansible-playbook -C nginx.yaml
[root@localhost ~]# ansible-playbook nginx.yaml