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.www58058.com/63811
贊,很詳細的描述了ansible的用法~繼續加油~