ansible特性:
模块化,调用特定的模块,完成特定的任务;
基于Python语言实现,由Paramiko、PyYAML和Jinja2三个关键模块;
部署简单,agentless;
主从模式
支持自定义模块
支持Playbook
幂等性:
安装:
epel,ansible
配置文件:/etc/ansible/ansible.cfg
主机清单:/etc/ansible/hosts
主程序:
ansible
ansible-playbook
ansible-doc
ansible的简单使用格式:
ansible HOST-PATTERN -m MOD_NAME -a MOD_ARGS
ansible常用模块:
获取模块列表:
ansible-doc -l
command模块:在远程主机运行命令;
shell模块:在远程主机在shell进程下运行命令,支持shell特性,如管道等;
copy模块:Copies files to remote locations
用法:
(1)src= dest=
(2)content= dest=
owner,group,mode
cron模块:Manage cron.d and crontab entries.
minute=
day=
month=
weekday=
hour=
job=
*name=
state=
present:创建
absent:删除
fetch模块:Fetches a file from remote nodes
file模块:Sets attributes of files
用法
(1)创建链接文件:*path= src= state=link
(2)修改属性:path= owner= mode= group=
(3)创建目录:path= state=directory
hostname模块:Manager Hostname
name=
pip模块:Manages Python library dependencies.
yum模块:Manages packages with the `yum' package manager
name=:程序包名称,可以带版本号;
state=
present,latest
absent
service模块:管理服务
*name=
state=
started
stopped
restarted
enabled=
runlevel=
user模块:管理用户账号
*name=
state=
system=
uid=
shell=
group=
groups=
comment=
home=
setup模块:用来获取facts
本次Ansible测试的环境:
Ansible主机:192.168.150.137
两台Centos7:192.168.150.138/192.168.150.139
一台Centos6:192.168.150.133
测试前准备:
网络均能ping通
root@localhost yum.repos.d]# ping 192.168.150.138
PING 192.168.150.138 (192.168.150.138) 56(84) bytes of data.
64 bytes from 192.168.150.138: icmp_seq=1 ttl=64 time=0.650 ms
^C
— 192.168.150.138 ping statistics —
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.650/0.650/0.650/0.000 ms
[root@localhost yum.repos.d]# ping 192.168.150.139
PING 192.168.150.139 (192.168.150.139) 56(84) bytes of data.
64 bytes from 192.168.150.139: icmp_seq=1 ttl=64 time=1.01 ms
^C
— 192.168.150.139 ping statistics —
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 1.010/1.010/1.010/0.000 ms
[root@localhost yum.repos.d]# ping 192.168.150.133
PING 192.168.150.133 (192.168.150.133) 56(84) bytes of data.
64 bytes from 192.168.150.133: icmp_seq=1 ttl=64 time=0.716 ms
^C
— 192.168.150.133 ping statistics —
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.716/0.716/0.716/0.000 ms
ansible主机安装:yum -y install ansible 配置好epel源
编辑ansible中的hosts文件进行分组
~]# cd /etc/ansible/
ansible]# ls
ansible.cfg hosts roles
ansible]# cp hosts{,.bak}
ansible]# vim hosts
ansible]# cat 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
# – A hostname/ip can be a member of multiple groups
[websrvs]
192.168.150.138
192.168.150.139
[dbsrvs]
192.168.150.138
192.168.150.133
由于ansible是通过ssh进行管理,对被管理的三台主机进行ssh公钥认证
~]# ssh-keygen -t rsa -P ''
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
9c:fb:5b:bb:06:d9:d5:71:62:12:dc:65:55:7d:90:1f root@localhost.localdomain
The key's randomart image is:
+–[ RSA 2048]—-+
| ..o.+O|
| o =E+|
| o +=|
| . . . o|
| S o . |
| .o . |
| . .. |
| . … |
| ooo. |
+—————–+
~]# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.150.138
The authenticity of host '192.168.150.138 (192.168.150.138)' can't be established.
ECDSA key fingerprint is 2a:e3:03:52:8c:84:02:59:a2:26:a3:b2:f6:74:6c:3c.
Are you sure you want to continue connecting (yes/no)? yes
ady installed
ll the new keys
root@192.168.150.138's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.150.138'"
and check to make sure that only the key(s) you wanted were added.
~]# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.150.139
The authenticity of host '192.168.150.139 (192.168.150.139)' can't be established.
ECDSA key fingerprint is 2a:e3:03:52:8c:84:02:59:a2:26:a3:b2:f6:74:6c:3c.
Are you sure you want to continue connecting (yes/no)? yes
ady installed
ll the new keys
root@192.168.150.139's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.150.139'"
and check to make sure that only the key(s) you wanted were added.
~]# ssh-copy-id -i .ssh/id_rsa.pub root@192.168.150.133
The authenticity of host '192.168.150.133 (192.168.150.133)' can't be established.
RSA key fingerprint is d7:5f:1a:ba:53:c3:c7:0e:68:32:bf:76:92:64:ca:a0.
Are you sure you want to continue connecting (yes/no)? yes
ady installed
ll the new keys
root@192.168.150.133's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh 'root@192.168.150.133'"
and check to make sure that only the key(s) you wanted were added.
Ansible常用模块测试:
ping模块
~]# ansible all -m ping
192.168.150.139 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.150.138 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.150.133 | SUCCESS => {
"changed": false,
"ping": "pong"
}
显示说明文档的简要信息
ansible]# ansible-doc -s ping
– name: Try to connect to host, verify a usable python and return `pong' on success.
action: ping
yum模块
ansible]# ansible-doc -s yum
– name: Manages packages with the `yum' package manager
action: yum
conf_file # The remote yum configuration file to use for the transaction.
disable_gpg_check # Whether to disable the GPG checking of signatures of packages being
installed. Has an effect only if state
is `present' or `latest'.
disablerepo # `Repoid' of repositories to disable for the install/update operation.
These repos will not persist beyond the
transaction. When specifying multiple
repos, separate them with a ",".
enablerepo # `Repoid' of repositories to enable for the install/update operation.
These repos will not persist beyond the
transaction. When specifying multiple
repos, separate them with a ",".
exclude # Package name(s) to exclude when state=present, or latest
list # Various (non-idempotent) commands for usage with `/usr/bin/ansible'
and `not' playbooks. See examples.
name= # Package name, or package specifier with version, like `name-1.0'. When
using state=latest, this can be '*'
which means run: yum -y update. You can
also pass a url or a local path to a
rpm file (using state=present). To
operate on several packages this can
accept a comma separated list of
packages or (as of 2.0) a list of
packages.
state # Whether to install (`present' or `installed', `latest'), or remove
(`absent' or `removed') a package.
update_cache # Force updating the cache. Has an effect only if state is `present' or
`latest'.
validate_certs # This only applies if using a https url as the source of the rpm. e.g.
for localinstall. If set to `no', the
SSL certificates will not be validated.
This should only set to `no' used on
personally controlled sites using self-
signed certificates as it avoids
verifying the source site. Prior to 2.1
the code worked as if this was set to
`yes'.
~]# ansible all -m yum -a "name=httpd state=absent"
192.168.150.133 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
httpd.x86_64 0:2.2.15-55.el6.centos.2 \n\nComplete!\n"
]
}
192.168.150.139 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
od_ssl.x86_64 1:2.4.6-40.el7.centos.4 php.x86_64 0:5.4.16-36.3.el7_2 \n\n完毕!\n"
]
}
192.168.150.138 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
sl.x86_64 1:2.4.6-40.el7.centos.4 \n\n完毕!\n"
]
}
~]# ansible all -m yum -a "name=httpd state=latest"
192.168.150.133 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
5-55.el6.centos.2 \n\nComplete!\n"
]
}
192.168.150.139 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
\n\n完毕!\n"
]
}
192.168.150.138 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
\n\n完毕!\n"
]
}
command模块
ansible]# ansible-doc -s command 此模块是默认选项,在ansible不见任何模块是默认即使用comman模块
– name: Executes a command on a remote node
action: command
chdir # cd into this directory before running the command
creates # a filename or (since 2.0) glob pattern, when it already exists, this
step will *not* be run.
executable # change the shell used to execute the command. Should be an absolute
path to the executable.
free_form= # the command module takes a free form command to run. There is no
parameter actually named 'free form'.
See the examples!
removes # a filename or (since 2.0) glob pattern, when it does not exist, this
step will *not* be run.
warn # if command warnings are on in ansible.cfg, do not warn about this
particular line if set to no/false.
ansible]# ansible websrvs -m command -a 'ls /var'
192.168.150.139 | SUCCESS | rc=0 >>
adm
cache
crash
db
empty
games
gopher
kerberos
lib
local
lock
log
nis
opt
preserve
run
spool
tmp
www
yp
192.168.150.138 | SUCCESS | rc=0 >>
adm
cache
crash
db
empty
games
gopher
kerberos
lib
local
lock
log
nis
opt
preserve
run
spool
tmp
www
yp
[root@localhost ansible]# ansible websrvs -a 'ls /var'
192.168.150.138 | SUCCESS | rc=0 >>
adm
cache
crash
db
empty
games
gopher
kerberos
lib
local
lock
log
nis
opt
preserve
run
spool
tmp
www
yp
192.168.150.139 | SUCCESS | rc=0 >>
adm
cache
crash
db
empty
games
gopher
kerberos
lib
local
lock
log
nis
opt
preserve
run
spool
tmp
www
yp
ansible]# ansible websrvs -a 'useradd user1'
192.168.150.138 | SUCCESS | rc=0 >>
192.168.150.139 | SUCCESS | rc=0 >>
ansible]# ansible websrvs -a 'echo void | passwd –stdin user1' command的参数不支持管道,需通过shell模块来支持
192.168.150.139 | SUCCESS | rc=0 >>
void | passwd –stdin user1
192.168.150.138 | SUCCESS | rc=0 >>
void | passwd –stdin user1
shell模块
ansible]# ansible-doc -s shell
– name: Execute commands in nodes.
action: shell
chdir # cd into this directory before running the command
creates # a filename, when it already exists, this step will *not* be run.
executable # change the shell used to execute the command. Should be an absolute
path to the executable.
free_form= # The shell module takes a free form command to run, as a string.
There's not an actual option named
"free form". See the examples!
removes # a filename, when it does not exist, this step will *not* be run.
warn # if command warnings are on in ansible.cfg, do not warn about this
particular line if set to no/false.
ansible]# ansible websrvs -m shell -a 'echo void | passwd –stdin user1'
192.168.150.138 | SUCCESS | rc=0 >>
更改用户 user1 的密码 。
passwd:所有的身份验证令牌已经成功更新。
192.168.150.139 | SUCCESS | rc=0 >>
更改用户 user1 的密码 。
passwd:所有的身份验证令牌已经成功更新。
copy模块
ansible]# ansible-doc -s copy
– name: Copies files to remote locations.
action: copy
backup # Create a backup file including the timestamp information so you can
get the original file back if you
somehow clobbered it incorrectly.
content # When used instead of 'src', sets the contents of a file directly to
the specified value. This is for simple
values, for anything complex or with
formatting please switch to the
template module.
dest= # Remote absolute path where the file should be copied to. If src is a
directory, this must be a directory
too.
directory_mode # When doing a recursive copy set the mode for the directories. If this
is not set we will use the system
defaults. The mode is only set on
directories which are newly created,
and will not affect those that already
existed.
follow # This flag indicates that filesystem links, if they exist, should be
followed.
force # the default is `yes', which will replace the remote file when contents
are different than the source. If `no',
the file will only be transferred if
the destination does not exist.
group # name of the group that should own the file/directory, as would be fed
to `chown'
mode # mode the file or directory should be. For those used to
`/usr/bin/chmod' remember that modes
are actually octal numbers (like 0644).
Leaving off the leading zero will
likely have unexpected results. As of
version 1.8, the mode may be specified
as a symbolic mode (for example,
`u+rwx' or `u=rw,g=r,o=r').
owner # name of the user that should own the file/directory, as would be fed
to `chown'
remote_src # If False, it will search for src at originating/master machine, if
True it will go to the remote/target
machine for the src. Default is False.
Currently remote_src does not support
recursive copying.
selevel # level part of the SELinux file context. This is the MLS/MCS attribute,
sometimes known as the `range'.
`_default' feature works as for
`seuser'.
serole # role part of SELinux file context, `_default' feature works as for
`seuser'.
setype # type part of SELinux file context, `_default' feature works as for
`seuser'.
seuser # user part of SELinux file context. Will default to system policy, if
applicable. If set to `_default', it
will use the `user' portion of the
policy if available
src # Local path to a file to copy to the remote server; can be absolute or
relative. If path is a directory, it is
copied recursively. In this case, if
path ends with "/", only inside
contents of that directory are copied
to destination. Otherwise, if it does
not end with "/", the directory itself
with all contents is copied. This
behavior is similar to Rsync.
unsafe_writes # Normally this module uses atomic operations to prevent data corruption
or inconsistent reads from the target
files, sometimes systems are configured
or just broken in ways that prevent
this. One example are docker mounted
files, they cannot be updated
atomically and can only be done in an
unsafe manner. This boolean option
allows ansible to fall back to unsafe
methods of updating files for those
cases in which you do not have any
other choice. Be aware that this is
subject to race conditions and can lead
to data corruption.
validate # The validation command to run before copying into place. The path to
the file to validate is passed in via
'%s' which must be present as in the
example below. The command is passed
securely so shell features like
expansion and pipes won't work.
a、将文件拷贝至各被管理主机
ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab"
192.168.150.139 | SUCCESS => {
"changed": true,
"checksum": "efcce184759db569346abcbb55686bbd3a7a387b",
"dest": "/tmp/fstab",
"gid": 0,
"group": "root",
"md5sum": "b5b57afea153639c2f0082a3ea764192",
"mode": "0644",
"owner": "root",
"size": 465,
"src": "/root/.ansible/tmp/ansible-tmp-1478674427.63-215984605850567/source",
"state": "file",
"uid": 0
}
192.168.150.138 | SUCCESS => {
"changed": true,
"checksum": "efcce184759db569346abcbb55686bbd3a7a387b",
"dest": "/tmp/fstab",
"gid": 0,
"group": "root",
"md5sum": "b5b57afea153639c2f0082a3ea764192",
"mode": "0644",
"owner": "root",
"size": 465,
"src": "/root/.ansible/tmp/ansible-tmp-1478674427.6-49164059723033/source",
"state": "file",
"uid": 0
}
192.168.150.133 | SUCCESS => {
"changed": true,
"checksum": "efcce184759db569346abcbb55686bbd3a7a387b",
"dest": "/tmp/fstab",
"gid": 0,
"group": "root",
"md5sum": "b5b57afea153639c2f0082a3ea764192",
"mode": "0644",
"owner": "root",
"size": 465,
"src": "/root/.ansible/tmp/ansible-tmp-1478674427.6-185161529910096/source",
"state": "file",
"uid": 0
}
被管理主机状态
~]# ls /tmp/
fstab httpd.crt systemd-private-b03b2a0b72a54248954ee1d2328a6818-httpd.service-CbpdoM
b、将内容传递至被管理主机文件中
~]# ansible all -m copy -a "content='hello ansible' dest=/tmp/testfile"
192.168.150.133 | SUCCESS => {
"changed": true,
"checksum": "7b320b1dc0c867516cf00728df488daa3532bc1f",
"dest": "/tmp/testfile",
"gid": 0,
"group": "root",
"md5sum": "37bc018071eae9a0e879c31b2f9aa554",
"mode": "0644",
"owner": "root",
"size": 13,
"src": "/root/.ansible/tmp/ansible-tmp-1478674619.82-143184915917329/source",
"state": "file",
"uid": 0
}
192.168.150.138 | SUCCESS => {
"changed": true,
"checksum": "7b320b1dc0c867516cf00728df488daa3532bc1f",
"dest": "/tmp/testfile",
"gid": 0,
"group": "root",
"md5sum": "37bc018071eae9a0e879c31b2f9aa554",
"mode": "0644",
"owner": "root",
"size": 13,
"src": "/root/.ansible/tmp/ansible-tmp-1478674619.81-251006283956641/source",
"state": "file",
"uid": 0
}
192.168.150.139 | SUCCESS => {
"changed": true,
"checksum": "7b320b1dc0c867516cf00728df488daa3532bc1f",
"dest": "/tmp/testfile",
"gid": 0,
"group": "root",
"md5sum": "37bc018071eae9a0e879c31b2f9aa554",
"mode": "0644",
"owner": "root",
"size": 13,
"src": "/root/.ansible/tmp/ansible-tmp-1478674619.86-136685496450394/source",
"state": "file",
"uid": 0
}
被管理主机状态
~]# cd /tmp/
tmp]# ls
fstab httpd.crt systemd-private-b03b2a0b72a54248954ee1d2328a6818-httpd.service-CbpdoM testfile
tmp]# cat testfile
hello ansible[root@localhost tmp]#
c、拷贝是带权限指定
~]# ansible all -m copy -a "content='hello ansible\n' mode=600 dest=/tmp/testfile"
192.168.150.138 | SUCCESS => {
"changed": true,
"checksum": "df800445bb74b4abb144b3f9bf03f90aa9618f4c",
"dest": "/tmp/testfile",
"gid": 0,
"group": "root",
"md5sum": "f61d358bbdd6a9bd2e93322023a4e29d",
"mode": "0600",
"owner": "root",
"size": 14,
"src": "/root/.ansible/tmp/ansible-tmp-1478674782.24-143392146139391/source",
"state": "file",
"uid": 0
}
192.168.150.139 | SUCCESS => {
"changed": true,
"checksum": "df800445bb74b4abb144b3f9bf03f90aa9618f4c",
"dest": "/tmp/testfile",
"gid": 0,
"group": "root",
"md5sum": "f61d358bbdd6a9bd2e93322023a4e29d",
"mode": "0600",
"owner": "root",
"size": 14,
"src": "/root/.ansible/tmp/ansible-tmp-1478674782.24-68939485219113/source",
"state": "file",
"uid": 0
}
192.168.150.133 | SUCCESS => {
"changed": true,
"checksum": "df800445bb74b4abb144b3f9bf03f90aa9618f4c",
"dest": "/tmp/testfile",
"gid": 0,
"group": "root",
"md5sum": "f61d358bbdd6a9bd2e93322023a4e29d",
"mode": "0600",
"owner": "root",
"size": 14,
"src": "/root/.ansible/tmp/ansible-tmp-1478674782.23-6367200716688/source",
"state": "file",
"uid": 0
}
被管理主机状态
tmp]# ll
总用量 8
-rw-r–r– 1 root root 465 12月 8 19:29 fstab
-rw-r–r– 1 root root 0 12月 1 01:45 httpd.crt
ce-CbpdoM
-rw——- 1 root root 14 12月 8 19:35 testfile
cron模块:
~]# ansible-doc -s cron
– name: Manage cron.d and crontab entries.
action: cron
backup # If set, create a backup of the crontab before it is modified. The
location of the backup is returned in
the `backup_file' variable by this
module.
cron_file # If specified, uses this file instead of an individual user's crontab.
If this is a relative path, it is
interpreted with respect to
/etc/cron.d. (If it is absolute, it
will typically be /etc/crontab). To use
the `cron_file' parameter you must
specify the `user' as well.
day # Day of the month the job should run ( 1-31, *, */2, etc )
disabled # If the job should be disabled (commented out) in the crontab. Only has
effect if state=present
env # If set, manages a crontab's environment variable. New variables are
added on top of crontab. "name" and
"value" parameters are the name and the
value of environment variable.
hour # Hour when the job should run ( 0-23, *, */2, etc )
insertafter # Used with `state=present' and `env'. If specified, the environment
variable will be inserted after the
declaration of specified environment
variable.
insertbefore # Used with `state=present' and `env'. If specified, the environment
variable will be inserted before the
declaration of specified environment
variable.
job # The command to execute or, if env is set, the value of environment
variable. Required if state=present.
minute # Minute when the job should run ( 0-59, *, */2, etc )
month # Month of the year the job should run ( 1-12, *, */2, etc )
name # Description of a crontab entry or, if env is set, the name of
environment variable. Required if
state=absent. Note that if name is not
set and state=present, then a new
crontab entry will always be created,
regardless of existing ones.
reboot # If the job should be run at reboot. This option is deprecated. Users
should use special_time.
special_time # Special time specification nickname.
state # Whether to ensure the job or environment variable is present or
absent.
user # The specific user whose crontab should be modified.
weekday # Day of the week that the job should run ( 0-6 for Sunday-Saturday, *,
etc )
a、给三台被管理主机统一添加对时脚本cron
~]# ansible all -m cron -a "minute=*/5 job='/sbin/ntpdate 10.53.1.9 &>/dev/null' name=Synctime"
192.168.150.133 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"Synctime"
]
}
192.168.150.138 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"Synctime"
]
}
192.168.150.139 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": [
"Synctime"
]
}
执行后被管理主机状态
~]# crontab -l
#Ansible: Synctime
*/5 * * * * /sbin/ntpdate 10.53.1.9 &>/dev/null
b、删除cron
~]# ansible all -m cron -a "state=absent name=Synctime"
192.168.150.138 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
192.168.150.133 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
192.168.150.139 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}
被管理主机状态,已被删除
]# crontab -l
file模块
~]# ansible-doc -s file
– name: Sets attributes of files
action: file
follow # This flag indicates that filesystem links, if they exist, should be
followed.
force # force the creation of the symlinks in two cases: the source file does
not exist (but will appear later); the
destination exists and is a file (so, we
need to unlink the "path" file and create
symlink to the "src" file in place of
it).
group # name of the group that should own the file/directory, as would be fed to
`chown'
mode # mode the file or directory should be. For those used to `/usr/bin/chmod'
remember that modes are actually octal
numbers (like 0644). Leaving off the
leading zero will likely have unexpected
results. As of version 1.8, the mode may
be specified as a symbolic mode (for
example, `u+rwx' or `u=rw,g=r,o=r').
owner # name of the user that should own the file/directory, as would be fed to
`chown'
path= # path to the file being managed. Aliases: `dest', `name'
recurse # recursively set the specified file attributes (applies only to
state=directory)
selevel # level part of the SELinux file context. This is the MLS/MCS attribute,
sometimes known as the `range'.
`_default' feature works as for `seuser'.
serole # role part of SELinux file context, `_default' feature works as for
`seuser'.
setype # type part of SELinux file context, `_default' feature works as for
`seuser'.
seuser # user part of SELinux file context. Will default to system policy, if
applicable. If set to `_default', it will
use the `user' portion of the policy if
available
src # path of the file to link to (applies only to `state=link'). Will accept
absolute, relative and nonexisting paths.
Relative paths are not expanded.
state # If `directory', all immediate subdirectories will be created if they do
not exist, since 1.7 they will be created
with the supplied permissions. If `file',
the file will NOT be created if it does
not exist, see the [copy] or [template]
module if you want that behavior. If
`link', the symbolic link will be created
or changed. Use `hard' for hardlinks. If
`absent', directories will be recursively
deleted, and files or symlinks will be
unlinked. Note that [file] will not fail
if the `path' does not exist as the state
did not change. If `touch' (new in 1.4),
an empty file will be created if the
`path' does not exist, while an existing
file or directory will receive updated
file access and modification times
(similar to the way `touch` works from
the command line).
unsafe_writes # Normally this module uses atomic operations to prevent data corruption
or inconsistent reads from the target
files, sometimes systems are configured
or just broken in ways that prevent this.
One example are docker mounted files,
they cannot be updated atomically and can
only be done in an unsafe manner. This
boolean option allows ansible to fall
back to unsafe methods of updating files
for those cases in which you do not have
any other choice. Be aware that this is
subject to race conditions and can lead
to data corruption.
a、创建连接件文件
~]# ansible all -m file -a "src=/tmp/fstab path=/tmp/fstab.link state=link"
192.168.150.133 | SUCCESS => {
"changed": true,
"dest": "/tmp/fstab.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 10,
"src": "/tmp/fstab",
"state": "link",
"uid": 0
}
192.168.150.139 | SUCCESS => {
"changed": true,
"dest": "/tmp/fstab.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 10,
"src": "/tmp/fstab",
"state": "link",
"uid": 0
}
192.168.150.138 | SUCCESS => {
"changed": true,
"dest": "/tmp/fstab.link",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 10,
"src": "/tmp/fstab",
"state": "link",
"uid": 0
}
被管理主机状态
tmp]# ll
总用量 8
-rw-r–r– 1 root root 465 12月 8 19:29 fstab
lrwxrwxrwx 1 root root 10 12月 8 19:48 fstab.link -> /tmp/fstab
-rw-r–r– 1 root root 0 12月 1 01:45 httpd.crt
-CbpdoM
-rw——- 1 root root 14 12月 8 19:35 testfile
b、创建目录
~]# ansible all -m file -a "path=/tmp/tmpdir state=directory"
192.168.150.133 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/tmpdir",
"size": 4096,
"state": "directory",
"uid": 0
}
192.168.150.138 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/tmpdir",
"size": 6,
"state": "directory",
"uid": 0
}
192.168.150.139 | SUCCESS => {
"changed": true,
"gid": 0,
"group": "root",
"mode": "0755",
"owner": "root",
"path": "/tmp/tmpdir",
"size": 6,
"state": "directory",
"uid": 0
}
被管理主机状态
tmp]# ll
总用量 8
-rw-r–r– 1 root root 465 12月 8 19:29 fstab
lrwxrwxrwx 1 root root 10 12月 8 19:48 fstab.link -> /tmp/fstab
-rw-r–r– 1 root root 0 12月 1 01:45 httpd.crt
-CbpdoM
-rw——- 1 root root 14 12月 8 19:35 testfile
drwxr-xr-x 2 root root 6 12月 8 19:50 tmpdir
hostname模块
~]# ansible-doc -s hostname
– name: Manage hostname
action: hostname
name= # Name of the host
service模块
~]# ansible-doc -s service
– name: Manage services.
action: service
arguments # Additional arguments provided on the command line
enabled # Whether the service should start on boot. *At least one of state and
enabled are required.*
name= # Name of the service.
pattern # If the service does not respond to the status command, name a substring
to look for as would be found in the
output of the `ps' command as a stand-in
for a status result. If the string is
found, the service will be assumed to be
running.
runlevel # For OpenRC init scripts (ex: Gentoo) only. The runlevel that this
service belongs to.
sleep # If the service is being `restarted' then sleep this many seconds between
the stop and start command. This helps to
workaround badly behaving init scripts
that exit immediately after signaling a
process to stop.
state # `started'/`stopped' are idempotent actions that will not run commands
unless necessary. `restarted' will
always bounce the service. `reloaded'
开启被管理主机httpd服务
~]# ansible all -m shell -a "ss -tnl | grep :80"
192.168.150.139 | FAILED | rc=1 >>
192.168.150.138 | FAILED | rc=1 >>
192.168.150.133 | FAILED | rc=1 >>
~]# ansible all -m service -a "name=httpd state=started"
192.168.150.138 | SUCCESS => {
"changed": true,
"name": "httpd",
"state": "started",
"status": {
"ActiveEnterTimestampMonotonic": "0",
"ActiveExitTimestampMonotonic": "0",
"ActiveState": "inactive",
ystemd-journald.socket",
"AllowIsolate": "no",
"AssertResult": "no",
"AssertTimestampMonotonic": "0",
"Before": "shutdown.target",
"BlockIOAccounting": "no",
"BlockIOWeight": "18446744073709551615",
"CPUAccounting": "no",
"CPUQuotaPerSecUSec": "infinity",
"CPUSchedulingPolicy": "0",
"CPUSchedulingPriority": "0",
"CPUSchedulingResetOnFork": "no",
"CPUShares": "18446744073709551615",
"CanIsolate": "no",
"CanReload": "yes",
"CanStart": "yes",
"CanStop": "yes",
"CapabilityBoundingSet": "18446744073709551615",
"ConditionResult": "no",
"ConditionTimestampMonotonic": "0",
"Conflicts": "shutdown.target",
"ControlPID": "0",
"DefaultDependencies": "yes",
"Delegate": "no",
"Description": "The Apache HTTP Server",
"DevicePolicy": "auto",
"Documentation": "man:httpd(8) man:apachectl(8)",
"EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)",
"ExecMainCode": "0",
"ExecMainExitTimestampMonotonic": "0",
"ExecMainPID": "0",
"ExecMainStartTimestampMonotonic": "0",
"ExecMainStatus": "0",
rors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
rors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
ime=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
"FailureAction": "none",
"FileDescriptorStoreMax": "0",
"FragmentPath": "/usr/lib/systemd/system/httpd.service",
"GuessMainPID": "yes",
"IOScheduling": "0",
"Id": "httpd.service",
"IgnoreOnIsolate": "no",
"IgnoreOnSnapshot": "no",
"IgnoreSIGPIPE": "yes",
"InactiveEnterTimestampMonotonic": "0",
"InactiveExitTimestampMonotonic": "0",
"JobTimeoutAction": "none",
"JobTimeoutUSec": "0",
"KillMode": "control-group",
"KillSignal": "18",
"LimitAS": "18446744073709551615",
"LimitCORE": "18446744073709551615",
"LimitCPU": "18446744073709551615",
"LimitDATA": "18446744073709551615",
"LimitFSIZE": "18446744073709551615",
"LimitLOCKS": "18446744073709551615",
"LimitMEMLOCK": "65536",
"LimitMSGQUEUE": "819200",
"LimitNICE": "0",
"LimitNOFILE": "4096",
"LimitNPROC": "3829",
"LimitRSS": "18446744073709551615",
"LimitRTPRIO": "0",
"LimitRTTIME": "18446744073709551615",
"LimitSIGPENDING": "3829",
"LimitSTACK": "18446744073709551615",
"LoadState": "loaded",
"MainPID": "0",
"MemoryAccounting": "no",
"MemoryCurrent": "18446744073709551615",
"MemoryLimit": "18446744073709551615",
"MountFlags": "0",
"Names": "httpd.service",
"NeedDaemonReload": "no",
"Nice": "0",
"NoNewPrivileges": "no",
"NonBlocking": "no",
"NotifyAccess": "main",
"OOMScoreAdjust": "0",
"OnFailureJobMode": "replace",
"PermissionsStartOnly": "no",
"PrivateDevices": "no",
"PrivateNetwork": "no",
"PrivateTmp": "yes",
"ProtectHome": "no",
"ProtectSystem": "no",
"RefuseManualStart": "no",
"RefuseManualStop": "no",
"RemainAfterExit": "no",
"Requires": "basic.target -.mount",
"RequiresMountsFor": "/tmp /var/tmp",
"Restart": "no",
"RestartUSec": "100ms",
"Result": "success",
"RootDirectoryStartOnly": "no",
"RuntimeDirectoryMode": "0755",
"SameProcessGroup": "no",
"SecureBits": "0",
"SendSIGHUP": "no",
"SendSIGKILL": "yes",
"Slice": "system.slice",
"StandardError": "inherit",
"StandardInput": "null",
"StandardOutput": "journal",
"StartLimitAction": "none",
"StartLimitBurst": "5",
"StartLimitInterval": "10000000",
"StartupBlockIOWeight": "18446744073709551615",
"StartupCPUShares": "18446744073709551615",
"StatusErrno": "0",
"StopWhenUnneeded": "no",
"SubState": "dead",
"SyslogLevelPrefix": "yes",
"SyslogPriority": "30",
"SystemCallErrorNumber": "0",
"TTYReset": "no",
"TTYVHangup": "no",
"TTYVTDisallocate": "no",
"TimeoutStartUSec": "1min 30s",
"TimeoutStopUSec": "1min 30s",
"TimerSlackNSec": "50000",
"Transient": "no",
"Type": "notify",
"UMask": "0022",
"UnitFilePreset": "disabled",
"UnitFileState": "disabled",
"Wants": "system.slice",
"WatchdogTimestampMonotonic": "0",
"WatchdogUSec": "0"
}
}
192.168.150.139 | SUCCESS => {
"changed": true,
"name": "httpd",
"state": "started",
"status": {
"ActiveEnterTimestampMonotonic": "0",
"ActiveExitTimestampMonotonic": "0",
"ActiveState": "inactive",
arget remote-fs.target",
"AllowIsolate": "no",
"AssertResult": "no",
"AssertTimestampMonotonic": "0",
"Before": "shutdown.target",
"BlockIOAccounting": "no",
"BlockIOWeight": "18446744073709551615",
"CPUAccounting": "no",
"CPUQuotaPerSecUSec": "infinity",
"CPUSchedulingPolicy": "0",
"CPUSchedulingPriority": "0",
"CPUSchedulingResetOnFork": "no",
"CPUShares": "18446744073709551615",
"CanIsolate": "no",
"CanReload": "yes",
"CanStart": "yes",
"CanStop": "yes",
"CapabilityBoundingSet": "18446744073709551615",
"ConditionResult": "no",
"ConditionTimestampMonotonic": "0",
"Conflicts": "shutdown.target",
"ControlPID": "0",
"DefaultDependencies": "yes",
"Delegate": "no",
"Description": "The Apache HTTP Server",
"DevicePolicy": "auto",
"Documentation": "man:httpd(8) man:apachectl(8)",
"EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)",
"ExecMainCode": "0",
"ExecMainExitTimestampMonotonic": "0",
"ExecMainPID": "0",
"ExecMainStartTimestampMonotonic": "0",
"ExecMainStatus": "0",
rors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
rors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
ime=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }",
"FailureAction": "none",
"FileDescriptorStoreMax": "0",
"FragmentPath": "/usr/lib/systemd/system/httpd.service",
"GuessMainPID": "yes",
"IOScheduling": "0",
"Id": "httpd.service",
"IgnoreOnIsolate": "no",
"IgnoreOnSnapshot": "no",
"IgnoreSIGPIPE": "yes",
"InactiveEnterTimestampMonotonic": "0",
"InactiveExitTimestampMonotonic": "0",
"JobTimeoutAction": "none",
"JobTimeoutUSec": "0",
"KillMode": "control-group",
"KillSignal": "18",
"LimitAS": "18446744073709551615",
"LimitCORE": "18446744073709551615",
"LimitCPU": "18446744073709551615",
"LimitDATA": "18446744073709551615",
"LimitFSIZE": "18446744073709551615",
"LimitLOCKS": "18446744073709551615",
"LimitMEMLOCK": "65536",
"LimitMSGQUEUE": "819200",
"LimitNICE": "0",
"LimitNOFILE": "4096",
"LimitNPROC": "3829",
"LimitRSS": "18446744073709551615",
"LimitRTPRIO": "0",
"LimitRTTIME": "18446744073709551615",
"LimitSIGPENDING": "3829",
"LimitSTACK": "18446744073709551615",
"LoadState": "loaded",
"MainPID": "0",
"MemoryAccounting": "no",
"MemoryCurrent": "18446744073709551615",
"MemoryLimit": "18446744073709551615",
"MountFlags": "0",
"Names": "httpd.service",
"NeedDaemonReload": "no",
"Nice": "0",
"NoNewPrivileges": "no",
"NonBlocking": "no",
"NotifyAccess": "main",
"OOMScoreAdjust": "0",
"OnFailureJobMode": "replace",
"PermissionsStartOnly": "no",
"PrivateDevices": "no",
"PrivateNetwork": "no",
"PrivateTmp": "yes",
"ProtectHome": "no",
"ProtectSystem": "no",
"RefuseManualStart": "no",
"RefuseManualStop": "no",
"RemainAfterExit": "no",
"Requires": "-.mount basic.target",
"RequiresMountsFor": "/tmp /var/tmp",
"Restart": "no",
"RestartUSec": "100ms",
"Result": "success",
"RootDirectoryStartOnly": "no",
"RuntimeDirectoryMode": "0755",
"SameProcessGroup": "no",
"SecureBits": "0",
"SendSIGHUP": "no",
"SendSIGKILL": "yes",
"Slice": "system.slice",
"StandardError": "inherit",
"StandardInput": "null",
"StandardOutput": "journal",
"StartLimitAction": "none",
"StartLimitBurst": "5",
"StartLimitInterval": "10000000",
"StartupBlockIOWeight": "18446744073709551615",
"StartupCPUShares": "18446744073709551615",
"StatusErrno": "0",
"StopWhenUnneeded": "no",
"SubState": "dead",
"SyslogLevelPrefix": "yes",
"SyslogPriority": "30",
"SystemCallErrorNumber": "0",
"TTYReset": "no",
"TTYVHangup": "no",
"TTYVTDisallocate": "no",
"TimeoutStartUSec": "1min 30s",
"TimeoutStopUSec": "1min 30s",
"TimerSlackNSec": "50000",
"Transient": "no",
"Type": "notify",
"UMask": "0022",
"UnitFilePreset": "disabled",
"UnitFileState": "disabled",
"Wants": "system.slice",
"WatchdogTimestampMonotonic": "0",
"WatchdogUSec": "0"
}
}
192.168.150.133 | SUCCESS => {
"changed": true,
"name": "httpd",
"state": "started"
}
~]# ansible all -m shell -a "ss -tnl | grep :80"
192.168.150.133 | SUCCESS | rc=0 >>
LISTEN 0 128 :::80 :::*
192.168.150.138 | SUCCESS | rc=0 >>
LISTEN 0 128 :::80 :::*
192.168.150.139 | SUCCESS | rc=0 >>
LISTEN 0 128 :::80 :::*
user模块
~]# ansible-doc -s user
– name: Manage user accounts
action: user
append # If `yes', will only add groups, not set them to just the list in
`groups'.
comment # Optionally sets the description (aka `GECOS') of user account.
createhome # Unless set to `no', a home directory will be made for the user when the
account is created or if the home
directory does not exist.
expires # An expiry time for the user in epoch, it will be ignored on platforms
that do not support this. Currently
supported on Linux and FreeBSD.
force # When used with `state=absent', behavior is as with `userdel –force'.
generate_ssh_key # Whether to generate a SSH key for the user in question. This will *not*
overwrite an existing SSH key.
group # Optionally sets the user's primary group (takes a group name).
groups # Puts the user in this comma-delimited list of groups. When set to the
empty string ('groups='), the user is
removed from all groups except the
primary group.
home # Optionally set the user's home directory.
login_class # Optionally sets the user's login class for FreeBSD, OpenBSD and NetBSD
systems.
创建一系统账号
~]# ansible all -m user -a "name=user2 system=yes state=present uid=306"
192.168.150.133 | SUCCESS => {
"append": false,
"changed": true,
"comment": "",
"group": 510,
"home": "/home/user2",
"move_home": false,
"name": "user2",
"shell": "/bin/bash",
"state": "present",
"uid": 306
}
192.168.150.139 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 306,
"home": "/home/user2",
"name": "user2",
"shell": "/bin/bash",
"state": "present",
"system": true,
"uid": 306
}
192.168.150.138 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 306,
"home": "/home/user2",
"name": "user2",
"shell": "/bin/bash",
"state": "present",
"system": true,
"uid": 306
}
setup模块
~]# ansible-doc -s setup
– name: Gathers facts about remote hosts
action: setup
fact_path # path used for local ansible facts (*.fact) – files in this dir will be
run (if executable) and their results be
added to ansible_local facts if a file is
not executable it is read. Check notes
for Windows options. (from 2.1 on)
File/results format can be json or ini-
format
filter # if supplied, only return facts that match this shell-style (fnmatch)
wildcard.
gather_subset # if supplied, restrict the additional facts collected to the given
subset. Possible values: all, hardware,
network, virtual, ohai, and facter Can
specify a list of values to specify a
larger subset. Values can also be used
with an initial `!' to specify that that
specific subset should not be collected.
For instance: !hardware, !network,
!virtual, !ohai, !facter. Note that a
few facts are always collected. Use the
filter parameter if you do not want to
display those.
gather_timeout # Set the default timeout in seconds for individual fact gathering
~]# ansible 192.168.150.138 -m setup setup模块可以提供templates中的变量
playbook
YAML:playbook语法格式
packages:
-httpd
-php
-php-mysql
version:0.1
[1,2,3,4]
{1:mon,2:[red,blue,yellow]}
playbook的核心元素:
Hosts:
tasks: 任务
variables: 变量
templates: 模板,包含了模板语法的文本文件;
handlers: 处理器,由特定条件触发的任务;
roles: 角色
playbook的基础组件:
Hosts:运行指定任务的目标主机;
remote_user:在远程主机上执行任务的用户;
sudo_user:
tasks:任务列表
模块,模块参数;
格式:
(1)action:module arguments
(2)module:arguments
注意:shell和command模块后面直接跟命令,而非key=value类的参数列表;
(1)某任务的状态在运行后为changed时,可通过“notify”通知给相应的handlers;
(2)任务可以通过"tags"打标签,而后可在ansible-playbook命令上使用-t指定进行调用;
运行playbook的方式:
(1)测试
ansible-playbook –check
只检测可能会发生的改变,但不真正执行操作;
ansible-playbook –list-hosts
列出运行任务的主机;
(2)运行
handlers:
任务,在特定条件下触发;
接收到其他任务的通知时被触发;
variables:
(1)facts:可直接调用;
(2)ansible-playbook命令的命令行中的自定义变量:
-e VARS,–extra-vars=VARS
(3)通过role传递变量;
(4)Host Inventory
(a)向不同的主机传递不同变量;
IP/HOSTNAME variable=value var2=values2
(b)向组中的主机传递相同的变量
[groupname:vars]
variable=value
注意:inventory参数:
用于定义ansible远程连接目标主机时使用的参数,而非传递给playbook的变量;
ansible_ssh_host
ansible_ssh_port
ansible_ssh_user
ansible_ssh_pass
ansible_sudo_pass
…
实验:
创建一个yaml文件小试牛刀
~]# vim first.yaml
– hosts: all
remote_user: root
tasks:
– name: create a user user3
user: name=user3 system=true uid=307
– name: create a user user4
user: name=user4 system=true uid=308
~]# ansible-playbook –check first.yaml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
ok: [192.168.150.133]
TASK [create a user user3] *****************************************************
changed: [192.168.150.133]
changed: [192.168.150.138]
changed: [192.168.150.139]
TASK [create a user user4] *****************************************************
changed: [192.168.150.133]
changed: [192.168.150.138]
changed: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.133 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
~]# ansible-playbook –list-hosts first.yaml 查看host清单
playbook: first.yaml
play #1 (all): all TAGS: []
pattern: [u'all']
hosts (3):
192.168.150.138
192.168.150.139
192.168.150.133
playbook之httpd的测试:
yum安装httpd;修改配置文件,监听端口为8080;开启httpd服务;重启httpd服务
创建一个playbook的工作目录
~]# mkdir working
[root@localhost ~]# cd working/
working]# ls
working]# mkdir files
本地安装httpd,主要用于使用httpd的配置文件
working]# rpm -q httpd
未安装软件包 httpd
working]# yum -y install httpd
working]# cp /etc/httpd/conf/httpd.conf files/
working]# vim files/httpd.conf 修改httpd的监听端口为8080
创建web.yaml文件
working]# ls
files
working]# vim web.yaml
– hosts: websrvs
remote_user: root
tasks:
– name: install httpd package 安装httpd的包
yum: name=httpd state=present
– name: install configure file 将本地配置文件拷贝至被管理主机
copy: src=files/httpd.conf dest=/etc/httpd/conf/
– name: start httpd service 开启httpd服务
service: name=httpd state=started
yaml文件的检测
working]# ansible-playbook –check web.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
由于被管理主机已经安装了httpd,所有此处的状态为OK
TASK [install httpd package] ***************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [install configure file] **************************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
TASK [start httpd service] *****************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=4 changed=1 unreachable=0 failed=0
192.168.150.139 : ok=4 changed=1 unreachable=0 failed=0
为了实验效果,此处使用yum模块删除httpd,不然会影响后面的start和配置文件修改等步骤
working]# ansible all -m yum -a "name=httpd state=absent"
192.168.150.133 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
nComplete!\n"
]
}
192.168.150.139 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
\n删除:\n httpd.x86_64 0:2.4.6-40.el7.centos.4 \n\n完毕!\n"
]
}
192.168.150.138 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
\n删除:\n httpd.x86_64 0:2.4.6-40.el7.centos.4 \n\n完毕!\n"
]
}
删除完成后install任务和配置文件的任务均是change状态
working]# ansible-playbook –check web.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [install httpd package] ***************************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
TASK [install configure file] **************************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
TASK [start httpd service] *****************************************************
ested service \"'httpd'\": "}
ested service \"'httpd'\": "}
to retry, use: –limit @/root/working/web.retry
PLAY RECAP *********************************************************************
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=1
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=1
执行web.yaml的playbook
orking]# ansible-playbook web.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [install httpd package] ***************************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
TASK [install configure file] **************************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
TASK [start httpd service] *****************************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=4 changed=3 unreachable=0 failed=0
192.168.150.139 : ok=4 changed=3 unreachable=0 failed=0
查看状态,被管理主机均被安装了httpd,开启后以8080端口监听
working]# ansible websrvs -m shell -a "ss -tnl | grep :8080"
192.168.150.138 | SUCCESS | rc=0 >>
LISTEN 0 128 :::8080 :::*
192.168.150.139 | SUCCESS | rc=0 >>
LISTEN 0 128 :::8080 :::*
yaml文件中使用shell模块,执行后并不会显示出执行结果
working]# cat web.yaml
– hosts: websrvs
remote_user: root
tasks:
– name: install httpd package
yum: name=httpd state=present
– name: install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
– name: start httpd service
service: name=httpd state=started
– name: execute ss command
shell: ss -tnl | grep :80
[root@localhost working]# ansible-playbook –check web.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [install httpd package] ***************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [install configure file] **************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [start httpd service] *****************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [execute ss command] ******************************************************
skipping: [192.168.150.139]
skipping: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=4 changed=0 unreachable=0 failed=0
192.168.150.139 : ok=4 changed=0 unreachable=0 failed=0
[root@localhost working]# ansible-playbook web.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [install httpd package] ***************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [install configure file] **************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [start httpd service] *****************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [execute ss command] ******************************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=5 changed=1 unreachable=0 failed=0
192.168.150.139 : ok=5 changed=1 unreachable=0 failed=0
web2-yaml进行优化,添加了handler模块
working]# cat web-2.yaml
– hosts: websrvs
remote_user: root
tasks:
– name: install httpd package
yum: name=httpd state=present
– name: install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
notify: restart httpd 添加了触发,如果配置文档有改变的话,会去触发name为restart httpd的handlers
– name: start httpd service
service: name=httpd state=started
handlers:
– name: restart httpd
service: name=httpd state=restarted
working]# ansible-playbook –check web-2.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [install httpd package] ***************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [install configure file] **************************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
TASK [start httpd service] *****************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
RUNNING HANDLER [restart httpd] ************************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=5 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=5 changed=2 unreachable=0 failed=0
working]# vim files/httpd.conf 此时我编辑下本地的配置文件,将8080修改至808
working]# ansible-playbook –check web-2.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [install httpd package] ***************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [install configure file] **************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [start httpd service] *****************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=4 changed=0 unreachable=0 failed=0
192.168.150.139 : ok=4 changed=0 unreachable=0 failed=0
working]# ansible websrvs -m shell -a "ss -tnl | grep :8080"
192.168.150.138 | FAILED | rc=1 >>
192.168.150.139 | FAILED | rc=1 >>
working]# ansible websrvs -m shell -a "ss -tnl | grep :80"
192.168.150.139 | SUCCESS | rc=0 >>
LISTEN 0 128 :::808 :::*
192.168.150.138 | SUCCESS | rc=0 >>
LISTEN 0 128 :::808 :::*
web3-yaml版本更新
添加了tags模块,在使用ansible-playbook时使用-t 选项指定所运行的tag
working]# cat web-3.yaml
– hosts: websrvs
remote_user: root
tasks:
– name: install httpd package
yum: name=httpd state=present
tags: insthttpd 添加安装httpd的tag
– name: install configure file
copy: src=files/httpd.conf dest=/etc/httpd/conf/
tags: instconf 添加了修改配置文件的tag
notify: restart httpd
– name: start httpd service
service: name=httpd state=started
tags: starthttpd 添加了开启httpd的tag
handlers:
– name: restart httpd
service: name=httpd state=restarted
working]# ansible-playbook -t insthttpd –check web-3.yaml 此处只运行了install httpd package的task
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [install httpd package] ***************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=2 changed=0 unreachable=0 failed=0
192.168.150.139 : ok=2 changed=0 unreachable=0 failed=0
修改下配置文件,测试下instconf的tag下的task
working]# vim files/httpd.conf 将端口修改为80
working]# ansible-playbook -t instconf web-3.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [install configure file] ************************************************** 只是运行了此task
changed: [192.168.150.139]
changed: [192.168.150.138]
RUNNING HANDLER [restart httpd] ************************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
=working]# ansible websrvs -m shell -a "ss -tnl | grep :80"
192.168.150.139 | SUCCESS | rc=0 >>
LISTEN 0 128 :::80 :::*
192.168.150.138 | SUCCESS | rc=0 >>
LISTEN 0 128 :::80 :::*
playbook之variables
变量:
ansible facts
ansible-playbook -e "var=value"
host variable:host iventory
group variable
[groupname:vars]
var=value
roles
调用:{{ variable }}
在playbook中定义变量的方式:
vars:
– var1: value1
– var2: value2
a、ansible-playbook -e "var=value"
working]# cat forth.yaml
– hosts: websrvs
remote_user: root
tasks:
– name: install {{ pkname }}
yum: name={{ pkname }} state=present
working]# ansible-playbook -e pkname=memcached forth.yaml 在执行时通过-e进行变量赋值
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [install memcached] *******************************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=2 changed=1 unreachable=0 failed=0
192.168.150.139 : ok=2 changed=1 unreachable=0 failed=0
b、host variable:host iventory
使用hostname模块进行测试,通过hosts中的变量指定进行hostname更改
nsible]# ansible-doc -s hostname
– name: Manage hostname
action: hostname
name= # Name of the host
在hosts文件中添加变量指定及赋值
working]# cd /etc/ansible/
ansible]# vim hosts
ansible]# cat 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
# – A hostname/ip can be a member of multiple groups
[websrvs]
192.168.150.138 hanme=www1 hname变量指定及赋值
192.168.150.139 hname=www2
[dbsrvs]
192.168.150.138
192.168.150.133
yaml编写
ansible]# vim hostname.yaml
– hosts: websrvs
remote_user: root
tasks:
– name: set hostname
hostname: name={{ hname }} 此处调用了hname变量
ansible]# ansible-playbook –check hostname.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [set hostname] ************************************************************
skipping: [192.168.150.138]
skipping: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=1 changed=0 unreachable=0 failed=0
192.168.150.139 : ok=1 changed=0 unreachable=0 failed=0
ansible]# ansible-playbook hostname.yaml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [set hostname] ************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=2 changed=0 unreachable=0 failed=0
192.168.150.139 : ok=2 changed=0 unreachable=0 failed=0
ansible]# vim 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
# – A hostname/ip can be a member of multiple groups
[websrvs]
192.168.150.138 hname=www1
192.168.150.139 hname=www2
[websrvs:vars] 在hosts中给http_port指定变量及赋值,可供调用
http_port=8080
[dbsrvs]
192.168.150.138
192.168.150.133
当使用-e执行ansible-playbook时,会使用-e指定的变量值来取代yml中定义的变量
~]# cd working/
working]# ls
1 forth.yaml nginx.retry users.yaml web-3.yaml web.yaml
files iter.yaml nginx.yaml web-2.yaml web.retry
working]# vim myuser.yml
working]# cat myuser.yml
– hosts: all
remote_user: root
vars:
– username: testuser1
– groupname: testgroup1
tasks:
– name: create group
group: name={{ groupname }} state=present
– name: create user
user: name={{ username }} state=present
working]# ansible-playbook –check myuser.yml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
ok: [192.168.150.133]
TASK [create group] ************************************************************
changed: [192.168.150.139]
changed: [192.168.150.133]
changed: [192.168.150.138]
TASK [create user] *************************************************************
changed: [192.168.150.139]
changed: [192.168.150.133]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.133 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
working]# ansible-playbook -e "groupname=mygrp1" -e "username=myuser1" myuser.yml 此时会使用-e选项指定的变量值
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
ok: [192.168.150.133]
TASK [create group] ************************************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
changed: [192.168.150.133]
TASK [create user] *************************************************************
changed: [192.168.150.139]
changed: [192.168.150.133]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.133 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
nginx]# tail /etc/group
user4:x:308:
memcached:x:305:
nginx:x:304:
group11:x:1002:
group12:x:1003:
group13:x:1004:
testgroup1:x:1005:
testuser1:x:1006:
mygrp1:x:1007:
myuser1:x:1008:
playbook之nginx的测试:
nginx安装、配置
模板:templates
文本文件,嵌套有脚本(使用模板编程语言编写)
jinja2:
字面量:
字符串:使用单引号或双引号;
数字:整数,浮点数;
列表:[item1,item2,…]
元组:(item1,item2,…)
字典:{key1:value1,key2:value2,…}
布尔型:true/false
算数运算:
+,-,*,/,//,%,**
比较操作:
==,!=,>,>=,<,<=
逻辑运算符:
and,or,not
yum源的统一部署方法:
本地编辑epel的yum源
working]# vim files/epel.repo
[epel]
name=Fedora EPEL
baseurl=http://mirrors.aliyun.com/epel/$releasever/$basearch 此处使用变量进行指定本机的版本号及架构
enabled=1
gpgcheck=0
将仓库通过ansible的copy模块,拷贝至被管理主机
working]# ansible all -m copy -a "src=files/epel.repo dest=/etc/yum.repos.d"
192.168.150.139 | SUCCESS => {
"changed": false,
"checksum": "d23380d4e6429df809ec9990951d68c430fed96f",
"dest": "/etc/yum.repos.d/epel.repo",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/yum.repos.d/epel.repo",
"size": 106,
"state": "file",
"uid": 0
}
192.168.150.138 | SUCCESS => {
"changed": false,
"checksum": "d23380d4e6429df809ec9990951d68c430fed96f",
"dest": "/etc/yum.repos.d/epel.repo",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"path": "/etc/yum.repos.d/epel.repo",
"size": 106,
"state": "file",
"uid": 0
}
192.168.150.133 | SUCCESS => {
"changed": true,
"checksum": "d23380d4e6429df809ec9990951d68c430fed96f",
"dest": "/etc/yum.repos.d/epel.repo",
"gid": 0,
"group": "root",
"md5sum": "494d30aa39c457eda24955cf4dc58963",
"mode": "0644",
"owner": "root",
"size": 106,
"src": "/root/.ansible/tmp/ansible-tmp-1478688854.86-29806914220334/source",
"state": "file",
"uid": 0
}
nginx的统一安装
working]# ansible all -m yum -a "name=nginx state=present"
192.168.150.138 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
\n\nComplete!\n"
]
}
192.168.150.133 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
ete!\n"
]
}
192.168.150.139 | SUCCESS => {
"changed": true,
r mirror.\n",
"rc": 0,
"results": [
x86_64 1:1.10.2-1.el7 \n\nComplete!\n"
]
}
nginx配置选项的设置
拷贝配置文件至工作目录
working]# ls /etc/nginx/
conf.d fastcgi_params mime.types scgi_params win-utf
default.d fastcgi_params.default mime.types.default scgi_params.default
fastcgi.conf koi-utf nginx.conf uwsgi_params
fastcgi.conf.default koi-win nginx.conf.default uwsgi_params.default
working]# cp /etc/nginx/nginx.conf files/
working]# mv files/nginx.conf files/nginx.conf.j2 一般模板文件的后缀已j2结尾
working]# vim files/nginx.conf.j2 修改启动进程数进行试验worker_processes {{ ansible_processor_vcpus+1 }} listen {{ http_port }};调用hosts中定义的http_port
此处的变量引用了ansible facts,通过ansible的setup模块可以查看facts(ansible all -m setup)
同时修改hosts文件,同步调用hosts中的变量
working]# vim /etc/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
# – A hostname/ip can be a member of multiple groups
[websrvs]
192.168.150.138 http_port=8080
192.168.150.139 http_port=8080
[dbsrvs]
192.168.150.138
192.168.150.133
编辑nginx.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 此处的配置文件使用的是template模板组件
notify: restart nginx
tags: instconf
– name: start nginx service
service: name=nginx state=started
handlers:
– name: restart nginx
service: name=nginx state=restarted
playbook之条件测试when:
条件测试:
when语句:在task中使用,jinja2的语法格式
task:
– name: install conf file to centos7
template: src=file/nginx.conf.c7.j2
when: ansible_distribution_major_version == "7"
– name: install conf file to cento6
template:src=file/nginx.conf.c6.j2
when: ansible_distribution_major_version == "6"
将centos6主机的配置文件拷贝至ansible主机,通过模板话后,进行条件判断部署
working]# scp root@192.168.150.133:/etc/nginx/nginx.conf files/nginx.conf.c6.j2
nginx.conf 100% 1137 1.1KB/s 00:00
working]# vim nginx.yaml
– hosts: all
remote_user: root
tasks:
– name: install nginx
yum: name=nginx state=present
– name: install conf file to centos7
template: src=files/nginx.conf.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "7"
notify: restart nginx
tags: instconf
– name: install conf file to centos6
template: src=files/nginx.conf.c6.j2 dest=/etc/nginx/nginx.conf
when: ansible_distribution_major_version == "6" 进行when的条件判断,变量使用facts中选项,判定操作系统是centos6还是centos7
notify: restart nginx
tags: instconf
– name: start nginx service
service: name=nginx state=started
handlers:
– name: restart nginx
service: name=nginx state=restarted
working]# ansible-playbook –check nginx.yaml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
ok: [192.168.150.133]
TASK [install nginx] ***********************************************************
ok: [192.168.150.139]
ok: [192.168.150.133]
ok: [192.168.150.138]
TASK [install conf file to centos7] ********************************************
skipping: [192.168.150.133]
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [install conf file to centos6] ********************************************
skipping: [192.168.150.138]
skipping: [192.168.150.139]
changed: [192.168.150.133]
TASK [start nginx service] *****************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
changed: [192.168.150.133]
RUNNING HANDLER [restart nginx] ************************************************
changed: [192.168.150.133]
PLAY RECAP *********************************************************************
192.168.150.133 : ok=5 changed=3 unreachable=0 failed=0
192.168.150.138 : ok=4 changed=0 unreachable=0 failed=0
192.168.150.139 : ok=4 changed=0 unreachable=0 failed=0
working]# ansible-playbook nginx.yaml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
ok: [192.168.150.133]
TASK [install nginx] ***********************************************************
ok: [192.168.150.139]
ok: [192.168.150.133]
ok: [192.168.150.138]
TASK [install conf file to centos7] ********************************************
skipping: [192.168.150.133]
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [install conf file to centos6] ********************************************
skipping: [192.168.150.138]
skipping: [192.168.150.139]
ok: [192.168.150.133]
TASK [start nginx service] *****************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
changed: [192.168.150.133]
PLAY RECAP *********************************************************************
192.168.150.133 : ok=4 changed=1 unreachable=0 failed=0
192.168.150.138 : ok=4 changed=0 unreachable=0 failed=0
192.168.150.139 : ok=4 changed=0 unreachable=0 failed=0
playbook之循环:
循环:迭代,需要重复执行的任务;
对迭代项的引用,固定变量名为"item"
而后,要在task中使用with_items给定要迭代的元素列表;
列表方法:
字符串
字典
– name: install some packages
yum: name={{ item }} state=present
with_items:
– nginx
– memcached
– php-fpm
– name: add some groups
group: name={{ item }} state=present
with_items:
– group11
– group12
– group13
– name: add some users
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
– { name: 'user11',group: 'group11'}
– { name: 'user12',group: 'group12'}
– { name: 'user13',group: 'group13'}
通过循环迭代的方式进行多个安装包的安装
working]# vim iter.yaml
– hosts: all
remote_user: root
tasks:
– name: install some packages
yum: name={{ item }} state=present
with_items:
– nginx
– memcached
– php-fpm
working]# ansible-playbook –check iter.yaml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
ok: [192.168.150.133]
TASK [install some packages] ***************************************************
changed: [192.168.150.138] => (item=[u'nginx', u'memcached', u'php-fpm'])
changed: [192.168.150.139] => (item=[u'nginx', u'memcached', u'php-fpm'])
changed: [192.168.150.133] => (item=[u'nginx', u'memcached', u'php-fpm'])
PLAY RECAP *********************************************************************
192.168.150.133 : ok=2 changed=1 unreachable=0 failed=0
192.168.150.138 : ok=2 changed=1 unreachable=0 failed=0
192.168.150.139 : ok=2 changed=1 unreachable=0 failed=0
working]# ansible-playbook iter.yaml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
ok: [192.168.150.133]
TASK [install some packages] ***************************************************
changed: [192.168.150.139] => (item=[u'nginx', u'memcached', u'php-fpm'])
changed: [192.168.150.133] => (item=[u'nginx', u'memcached', u'php-fpm'])
changed: [192.168.150.138] => (item=[u'nginx', u'memcached', u'php-fpm'])
PLAY RECAP *********************************************************************
192.168.150.133 : ok=2 changed=1 unreachable=0 failed=0
192.168.150.138 : ok=2 changed=1 unreachable=0 failed=0
192.168.150.139 : ok=2 changed=1 unreachable=0 failed=0
通过迭代方式进行用户和组的添加
working]# cat users.yaml
– hosts: all
remote_user: root
tasks:
– name: add some groups 此处是循环
group: name={{ item }} state=present
with_items:
– group11
– group12
– group13
– name: add some users 此处使用的是迭代
user: name={{ item.name }} group={{ item.group }} state=present
with_items:
– { name: 'user11',group: 'group11' }
– { name: 'user12',group: 'group12' }
– { name: 'user13',group: 'group13' }
working]# ansible-playbook –check users.yaml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
ok: [192.168.150.133]
TASK [add some groups] *********************************************************
changed: [192.168.150.133] => (item=group11)
changed: [192.168.150.139] => (item=group11)
changed: [192.168.150.138] => (item=group11)
changed: [192.168.150.133] => (item=group12)
changed: [192.168.150.138] => (item=group12)
changed: [192.168.150.139] => (item=group12)
changed: [192.168.150.133] => (item=group13)
changed: [192.168.150.139] => (item=group13)
changed: [192.168.150.138] => (item=group13)
TASK [add some users] **********************************************************
changed: [192.168.150.139] => (item={u'group': u'group11', u'name': u'user11'})
changed: [192.168.150.138] => (item={u'group': u'group11', u'name': u'user11'})
changed: [192.168.150.133] => (item={u'group': u'group11', u'name': u'user11'})
changed: [192.168.150.139] => (item={u'group': u'group12', u'name': u'user12'})
changed: [192.168.150.133] => (item={u'group': u'group12', u'name': u'user12'})
changed: [192.168.150.138] => (item={u'group': u'group12', u'name': u'user12'})
changed: [192.168.150.133] => (item={u'group': u'group13', u'name': u'user13'})
changed: [192.168.150.139] => (item={u'group': u'group13', u'name': u'user13'})
changed: [192.168.150.138] => (item={u'group': u'group13', u'name': u'user13'})
PLAY RECAP *********************************************************************
192.168.150.133 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
working]# ansible-playbook users.yaml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
ok: [192.168.150.133]
TASK [add some groups] *********************************************************
changed: [192.168.150.139] => (item=group11)
changed: [192.168.150.138] => (item=group11)
changed: [192.168.150.133] => (item=group11)
changed: [192.168.150.139] => (item=group12)
changed: [192.168.150.138] => (item=group12)
changed: [192.168.150.133] => (item=group12)
changed: [192.168.150.139] => (item=group13)
changed: [192.168.150.138] => (item=group13)
changed: [192.168.150.133] => (item=group13)
TASK [add some users] **********************************************************
changed: [192.168.150.139] => (item={u'group': u'group11', u'name': u'user11'})
changed: [192.168.150.138] => (item={u'group': u'group11', u'name': u'user11'})
changed: [192.168.150.133] => (item={u'group': u'group11', u'name': u'user11'})
changed: [192.168.150.139] => (item={u'group': u'group12', u'name': u'user12'})
changed: [192.168.150.138] => (item={u'group': u'group12', u'name': u'user12'})
changed: [192.168.150.133] => (item={u'group': u'group12', u'name': u'user12'})
changed: [192.168.150.139] => (item={u'group': u'group13', u'name': u'user13'})
changed: [192.168.150.138] => (item={u'group': u'group13', u'name': u'user13'})
changed: [192.168.150.133] => (item={u'group': u'group13', u'name': u'user13'})
PLAY RECAP *********************************************************************
192.168.150.133 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
角色(roles)
角色集合:
roles/
mysql/
httpd/
nginx/
memcached/
每个角色,以特定的层级目录结构进行组织;
mysql/
files/ :存放由copy或script模块等调用的文件;
templates/:template模块查找所需要模板文件的目录;
tasks/:至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过include进行包含;
handlers/:至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过include进行包含;
vars/:至少应该包含一个名为main.yml的文件;其他的文件需要在此文件中通过include进行包含;
meta/:至少应该包含一个名为main.yml的文件,定义当前角色的特殊设定及其依赖关系;其他的文件需要在此文件中通过include进行包含;
default/:设定默认变量时使用此目录中的main.yml文件;
在playbook调用角色方法1:
– hosts: websrvs
remote_user: root
roles:
– mysql
– memcached
– nginx
在playbook调用角色方法2:传递变量给角色
– hosts:
remote_user:
roles:
– { role: nginx,username: nginx}
创建一个角色并创建特定的层级目录结构
~]# ls /etc/ansible/
1 ansible.cfg hostname.retry hostname.yaml hosts hosts.bak roles
~]# mkdir /etc/ansible/roles/nginx/{files,tasks,templates,handlers,vars,default,meta} -pv
mkdir: 已创建目录 "/etc/ansible/roles/nginx"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/files"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/tasks"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/templates"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/handlers"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/vars"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/default"
mkdir: 已创建目录 "/etc/ansible/roles/nginx/meta"
~]# tree /etc/ansible/roles/nginx/
/etc/ansible/roles/nginx/
├── default
├── files
├── handlers
├── meta
├── tasks
├── templates
└── vars
7 directories, 0 files
创建task
~]# cd /etc/ansible/roles/nginx/
nginx]# vim tasks/main.yml
– name: install nginx package
yum: name=nginx state=present
– name: install conf file
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
– name: start nginx
service: name=nginx state=started enabled=true
创建template
nginx]# cp /root/working/files/nginx.conf.j2 templates/
创建工作目录,通过playbook调用roles
nginx]# cd
~]# mkdir ansible
~]# cd ansible/
ansible]# vim nginx.yml
– hosts: websrvs
remote_user: root
roles: 此处为playbook调用roles
– nginx
check和执行
ansible]# ansible-playbook –check nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install nginx package] *******************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
TASK [nginx : start nginx] *****************************************************
ested service \"'nginx'\": "}
ested service \"'nginx'\": "}
to retry, use: –limit @/root/ansible/nginx.retry
PLAY RECAP *********************************************************************
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=1
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=1
ansible]# ansible-playbook nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install nginx package] *******************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
TASK [nginx : start nginx] *****************************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=4 changed=3 unreachable=0 failed=0
192.168.150.139 : ok=4 changed=3 unreachable=0 failed=0
编辑task,添加handler
nginx]# vim tasks/main.yml
– name: install nginx package
yum: name=nginx state=present
– name: install conf file
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
– name: start nginx
service: name=nginx state=started enabled=true
nginx]# vim handlers/main.yml
– name: restart nginx
service: name=nginx state=restarted
ansible]# ansible-playbook –check nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [nginx : install nginx package] *******************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
TASK [nginx : start nginx] *****************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=5 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=5 changed=2 unreachable=0 failed=0
加tag
ansible]# vim /etc/ansible/roles/nginx/tasks/main.yml
– name: install nginx package
yum: name=nginx state=present
– name: install conf file
template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf
notify: restart nginx
tags: instconf
– name: start nginx
service: name=nginx state=started enabled=true
ansible]# ansible-playbook -t instconf –check nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
ansible]# ansible-playbook -t instconf nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
变量使用
变量声明
ansible]# vim /etc/ansible/roles/nginx/vars/main.yml
username: daemon
template中调用此变量
working]# vim /etc/ansible/roles/nginx/templates/nginx.conf.j2 修改nginx使用哪个用户开启服务 指定变量user {{ username }};
check并执行
ansible]# ansible-playbook –check nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
TASK [nginx : install nginx package] *******************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
TASK [nginx : start nginx] *****************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=5 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=5 changed=2 unreachable=0 failed=0
ansible]# ansible-playbook nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install nginx package] *******************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
TASK [nginx : start nginx] *****************************************************
ok: [192.168.150.138]
ok: [192.168.150.139]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=5 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=5 changed=2 unreachable=0 failed=0
被管理端状态
nginx]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
……
daemon 8134 0.0 0.3 122652 3072 ? S 17:50 0:00 nginx: worker process
daemon 8135 0.0 0.3 122652 3280 ? S 17:50 0:00 nginx: worker process
daemon 8136 0.0 0.3 122652 3280 ? S 17:50 0:00 nginx: worker process
root 8139 0.0 0.1 139492 1648 pts/0 R+ 17:50 0:00 ps aux
此时在执行时通过-e选项来进行变量指定,会直接调用此选项
ansible]# ansible-playbook -t instconf -e "username=adm" –check nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
ansible]# ansible-playbook -t instconf -e "username=adm" nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
后端状态
nginx]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
……
adm 8604 0.0 0.3 122652 3276 ? S 17:52 0:00 nginx: worker process
adm 8605 0.0 0.3 122652 3276 ? S 17:52 0:00 nginx: worker process
adm 8606 0.0 0.3 122652 3072 ? S 17:52 0:00 nginx: worker process
在roles通过k/v方式进行传递变量给角色
ansible]# vim nginx.yml
– hosts: websrvs
remote_user: root
roles:
– { role: nginx, username: nginx }
ansible]# ansible-playbook -t instconf –check nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.138]
changed: [192.168.150.139]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
ansible]# ansible-playbook -t instconf nginx.yml
PLAY [websrvs] *****************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.138]
TASK [nginx : install conf file] ***********************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.138 : ok=3 changed=2 unreachable=0 failed=0
192.168.150.139 : ok=3 changed=2 unreachable=0 failed=0
后端状态
nginx]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
……
nginx 8894 0.0 0.3 122652 3276 ? S 17:59 0:00 nginx: worker process
nginx 8895 0.0 0.3 122652 3276 ? S 17:59 0:00 nginx: worker process
nginx 8896 0.0 0.3 122652 3276 ? S 17:59 0:00 nginx: worker process
还可以基于条件测试实现角色调用
ansible]# vim nginx.yml
– hosts: all
remote_user: root
roles:
– { role: nginx, username: nginx, when: ansible_distribution_major_version == '7' } 当版本为centos7时调用此角色
ansible]# cat lnm.yml
– hosts: all
remote_user: root
roles:
– { role: nginx, when: ansible_distribution_major_version == '7' } 版本为7时调用nginx角色,当主机名称为memcached时调用memcached角色
– { role: memcached,when: ansible_hostname == 'memcached' }
创建memcached的角色
ansible]# mkdir -pv /etc/ansible/roles/memcached/tasks
mkdir: 已创建目录 "/etc/ansible/roles/memcached"
mkdir: 已创建目录 "/etc/ansible/roles/memcached/tasks"
ansible]# vim /etc/ansible/roles/memcached/tasks/main.yml
ansible]# cat /etc/ansible/roles/memcached/tasks/main.yml
– name: install package
yum: name=memcached state=present
– name: start memcached
service: name=memcached state=started enabled=true
ansible]# ansible-playbook lnm.yml
PLAY [all] *********************************************************************
TASK [setup] *******************************************************************
ok: [192.168.150.139]
ok: [192.168.150.133]
ok: [192.168.150.138]
TASK [nginx : install nginx package] *******************************************
skipping: [192.168.150.133]
changed: [192.168.150.138]
changed: [192.168.150.139]
TASK [nginx : install conf file] ***********************************************
skipping: [192.168.150.133]
changed: [192.168.150.139]
changed: [192.168.150.138]
TASK [nginx : start nginx] *****************************************************
skipping: [192.168.150.133]
changed: [192.168.150.138]
changed: [192.168.150.139]
TASK [memcached : install package] *********************************************
skipping: [192.168.150.133]
skipping: [192.168.150.139]
ok: [192.168.150.138]
TASK [memcached : start memcached] *********************************************
skipping: [192.168.150.133]
skipping: [192.168.150.139]
changed: [192.168.150.138]
RUNNING HANDLER [nginx : restart nginx] ****************************************
changed: [192.168.150.139]
changed: [192.168.150.138]
PLAY RECAP *********************************************************************
192.168.150.133 : ok=1 changed=0 unreachable=0 failed=0
192.168.150.138 : ok=7 changed=5 unreachable=0 failed=0
192.168.150.139 : ok=5 changed=4 unreachable=0 failed=0
原创文章,作者:N23-苏州-void,如若转载,请注明出处:http://www.178linux.com/63811
评论列表(1条)
赞,很详细的描述了ansible的用法~继续加油~