ansible系列之二:常用模块介绍

模块简介

可以从ansible-doc -l | grep module_name来找出想要的模块。再使用ansible-doc -s module_name来查看此模块的用法。官方将模块按功能分类为:云模块、命令模块、数据库模块、文件模块、资产模块、消息模块、监控模块、网络模块、通知模块、包管理模块、源码控制模块、系统模块、单元模块、web设施模块、windows模块 ,列表和说明:https://docs.ansible.com/ansible/latest/modules_by_category.html

关于模块的使用方法,需要注意的是”state”。很多模块都会有该选项,且其值几乎都包含有”present”和”absent”,表示肯定和否定的意思。

ansible绝大多数模块都天然具有幂等特性,只有极少数模块如shell和command模块不具备幂等性。所谓的幂等性是指多次执行同一个操作不会影响最终结果。例如,ansible的yum模块安装rpm包时,如果待安装的包已经安装过了,则再次或多次执行安装操作都不会真正的执行下去。再例如,copy模块拷贝文件时,如果目标主机上已经有了完全相同的文件,则多次执行copy模块不会真正的拷贝。ansible具有幂等性的模块在执行时,都会自动判断是否要执行。

常用模块

ping模块

测试主机是否是通的,用法很简单,不涉及参数:

1
2
3
4
5
6
7
8
9
10
[root@localhost ~]# ansible 192.168.1.61 -m ping
192.168.1.61 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@localhost ~]# ansible 192.168.1.61 -m ping -o
192.168.1.61 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}

setup模块

setup模块,主要用于获取主机信息,在playbooks里经常会用到的一个参数gather_facts就与该模块相关。setup模块下经常使用的一个参数是filter参数,具体使用示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//获取系统版本信息
[root@localhost ~]# ansible localhost -m setup -a "filter=ansible_distribution*"
localhost | SUCCESS => {
"ansible_facts": {
"ansible_distribution": "CentOS",
"ansible_distribution_file_parsed": true,
"ansible_distribution_file_path": "/etc/redhat-release",
"ansible_distribution_file_variety": "RedHat",
"ansible_distribution_major_version": "7",
"ansible_distribution_release": "Core",
"ansible_distribution_version": "7.7",
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false
}

//查看主机内存信息
[root@node1 ~]# ansible home -m setup -a 'filter=ansible_*_mb'
home | SUCCESS => {
"ansible_facts": {
"ansible_memfree_mb": 1305,
"ansible_memory_mb": {
"nocache": {
"free": 1891,
"used": 121
},
"real": {
"free": 1305,
"total": 2012,
"used": 707
},
"swap": {
"cached": 0,
"free": 4999,
"total": 4999,
"used": 0
}
},
"ansible_memtotal_mb": 2012,
"ansible_swapfree_mb": 4999,
"ansible_swaptotal_mb": 4999
},
"changed": false
}

//将所有主机的信息输入到/tmp/setup目录下
[root@node1 ~]# ansible home -m setup --tree /tmp/setup
//会生成文件到/tmp/setup目录下,保存格式为字典格式
[root@node1 ~]# ll /tmp/setup/home
-rw-r--r-- 1 root root 8604 Jan 1 01:20 /tmp/setup/home

command与shell模块

ansible默认的模块是command,可以执行一些shell命令。但command不能解析变量(如$HOME)和某些操作符("<", ">", "|", ";"以及"&"),所以明确要使用这些不可解析的操作符时,使用shell模块来代替command。

shell和command的用法基本一样,实际上shell模块执行命令的方式是在远程使用/bin/sh来执行的,如/bin/sh ping

除了以上2个模块之后,还有2个命令模块,

  • raw模块:用法和shell 模块一样,其也可以执行任意命令,就像在本机执行一样;
  • script模块:其是将管理端的shell 在被管理主机上执行,其原理是先将shell 复制到远程主机,再在远程主机上执行,原理类似于raw模块。

注:raw模块和comand、shell 模块不同的是其没有chdir、creates、removes参数,chdir参数的作用就是先切到chdir指定的目录后,再执行后面的命令,这在后面很多模块里都会有该参数 。

command模块包含如下选项:

1
2
3
4
5
creates		一个文件名,当该文件存在,则该命令不执行 
free_form 要执行的linux指令
chdir 在执行指令之前,先切换到该指定的目录
removes 一个文件名,当该文件不存在,则该选项不执行
executable 切换shell来执行指令,该执行路径必须是一个绝对路径

使用chdir的示例

1
2
3
4
5
[root@localhost ~]# ansible 192.168.1.61 -m shell -a 'chdir=/tmp/ warn=false touch test1.file'
192.168.1.61 | CHANGED | rc=0 >>
[root@localhost ~]# ansible 192.168.1.61 -m raw -a 'chdir=/tmp/ touch test3.file'
192.168.1.61 | CHANGED | rc=0 >>
Shared connection to 192.168.1.61 closed.

以上2个命令都成功运行了,但是第一条命令是创建在/tmp,而raw命令是创建在家目录下。说明raw是没有chdir参数的。

1
2
3
4
5
6
7
[root@localhost ~]# ansible 192.168.1.61 -m shell -a 'ls -l /tmp/test*'
192.168.1.61 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0 Jan 3 21:43 /tmp/test1.file

[root@localhost ~]# ansible 192.168.1.61 -m shell -a 'ls -l /root/test*'
192.168.1.61 | CHANGED | rc=0 >>
-rw-r--r--. 1 root root 0 Jan 3 21:41 /root/test3.file

creates与removes示例

如下示例

1
2
3
4
5
6
7
8
9
#当/tmp/server.txt文件存在时,则不执行uptime指令
[root@localhost ~]# ansible 192.168.1.61 -a 'creates=/tmp/server.txt uptime'
192.168.1.61 | CHANGED | rc=0 >>
21:48:19 up 33 days, 11:43, 3 users, load average: 0.00, 0.01, 0.05

#当/tmp/server.txt文件不存在时,则不执行uptime指令
[root@localhost ~]# ansible 192.168.1.61 -a 'reomves=/tmp/server.txt uptime'
192.168.1.61 | FAILED | rc=2 >>
[Errno 2] No such file or directory

script模块示例

要执行的脚本文件script.sh内容如下:

1
2
3
#/bin/bash
ifconfig
df -hT

执行ansible指令:

1
ansible 10.212.52.252 -m script -a 'script.sh' |egrep '>>|stdout'

file 模块

file模块主要用于在远程主机上进行文件操作,可用于创建/删除目录和文件,file模块可以递归创建目录,但是不能在不存在的目录中创建文件,只能先创建目录,再在此目录中创建文件。

file模块包含如下选项:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
force:     需要在两种情况下强制创建软链接,一种是源文件不存在但之后会建立的情况下;另一种是目标软链接已存在,需要先取消之前的软链,然后创建新的软链,有两个选项:yes|no 
group: 定义文件/目录的属组
mode: 定义文件/目录的权限
owner: 定义文件/目录的属主
path: 必选项,定义文件/目录的路径
recurse: 递归的设置文件的属性,只对目录有效
src: 要被链接的源文件的路径,只应用于state=link的情况
dest: 被链接到的路径,只应用于state=link的情况
state:
directory: 如果目录不存在,创建目录
file: 即使文件不存在,也不会被创建
link: 创建软链接
hard: 创建硬链接
touch: 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent: 删除目录、文件或者取消链接文件

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#创建一个软链接
[root@node1 ~]# ansible home -m file -a 'src=/etc/fstab dest=/tmp/fstab state=link'
home | SUCCESS => {
"changed": true,
"dest": "/tmp/fstab",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"size": 10,
"src": "/etc/fstab",
"state": "link",
"uid": 0
}

#删除刚刚创建的软链接
[root@node1 ~]# ansible home -m file -a 'path=/tmp/fstab state=absent'
home | SUCCESS => {
"changed": true,
"path": "/tmp/fstab",
"state": "absent"
}

#创建一个权限为644的/tmp/test的文件
[root@node1 ~]# ansible home -m file -a 'path=/tmp/test state=touch owner=root group=root mode=644'
home | SUCCESS => {
"changed": true,
"dest": "/tmp/test",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"size": 0,
"state": "file",
"uid": 0
}
[root@node1 ~]# ansible home -m shell -a 'ls -l /tmp/test'
home | SUCCESS | rc=0 >>
-rw-r--r-- 1 root root 0 Jan 3 22:45 /tmp/test

copy模块

其作用是复制本地文件到远程主机上。ansible copy会检查文件md5查看是否需要拷贝,相同则不会拷贝,否则会拷贝。

copy模块包含如下选项:

1
2
3
4
5
6
7
backup:    在覆盖之前将原文件备份,备份文件包含时间信息。有两个选项:yes|no,默认为no。
content: 用于替代"src",可以直接设定指定文件的值
dest: 必选项。要将源文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么该路径也必须是个目录
directory_mode:递归的设定目录的权限,默认为系统默认权限
force: 如果目标主机包含该文件,但内容不同,如果设置为yes,则强制覆盖,如果为no,则只有当目标主机的目标位置不存在该文件时,才复制。默认为yes
others: 所有的file模块里的选项都可以在这里使用
src: 要复制到远程主机的文件在本地的地址,可以是绝对路径,也可以是相对路径。如果路径是一个目录,它将递归复制。在这种情况下,如果路径使用"/"来结尾,则只复制目录里的内容,如果没有使用"/"来结尾,则包含目录在内的整个内容全部复制,类似于rsync。

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#可以使用content直接写内容到远程主机上,默认不会备份。
#1、目的文件不存在,会自动创建,2、目的文件存在,则直接覆盖原有内容
[root@node1 ~]# ansible home -m copy -a 'content="abc-123" dest=/root/t123.txt'
home | SUCCESS => {
"changed": true,
"checksum": "a00eada80f974d9446d54719567f67349cdc2d34",
"dest": "/root/t123.txt",
"gid": 0,
"group": "root",
"md5sum": "6351623c8cef86fefabfa7da046fc619",
"mode": "0644",
"owner": "root",
"size": 7,
"src": "/root/.ansible/tmp/ansible-tmp-1483207025.79-265061349853078/source",
"state": "file",
"uid": 0
}
#会对比2个文件的md5,如果一样就不会进行复制。如果不一样,如果 有指定了backup=yes,则会备份
[root@node1 ~]# echo "abc-456" >>t.txt
[root@node1 ~]# ansible home -m copy -a 'src='t.txt' dest=/root/t123.txt backup=yes'
home | SUCCESS => {
"backup_file": "/root/t123.txt.27939.2017-01-03@22:59:42~",
"changed": true,
"checksum": "84c96db6cee38bb5d964fa10b41cf87a81e2a119",
"dest": "/root/t123.txt",
"gid": 0,
"group": "root",
"md5sum": "babcdc4712bc30be673c37954576a859",
"mode": "0644",
"owner": "root",
"size": 16,
"src": "/root/.ansible/tmp/ansible-tmp-1483207236.16-123550976713698/source",
"state": "file",
"uid": 0
}
[root@node1 ~]# ansible home -m shell -a 'ls -l /root/t123.txt*'
home | SUCCESS | rc=0 >>
-rw-r--r-- 1 root root 16 Jan 3 22:59 /root/t123.txt
-rw-r--r-- 1 root root 8 Jan 3 22:57 /root/t123.txt.27939.2017-01-03@22:59:42~

template模块

与copy模块类似,但ansible会渲染里面的变量。在实际应用中,我们的配置文件有些地方可能会根据远程主机的配置的不同而有稍许的不同,template可以使用变量来接收远程主机上setup收集到的facts信息,针对不同配置的主机,定制配置文件。用法大致与copy模块相同。

例如centos6与centos7所使用的yum源不一样,可以使用template来简化操作。可以将以下内容保存为repo.j2文件:

1
2
3
4
5
[epel]
name=epel
baseurl=http://mirrors.aliyun.com/epel/{{ ansible_distribution_major_version }}Server/x86_64/
enable=1
gpgcheck=0

然后在task复制就可以了。

1
2
3
---
- tasks:
- template: src=repo.j2 dest=/etc/yum.repos.d/epel.repo

这样就实现了一个文件适合2个系统的需求了。

service与systemd模块

用于管理服务
该模块包含如下选项:

1
2
3
4
5
6
7
arguments: 给命令行提供一些选项 
enabled: 是否开机启动 yes|no
name: 必选项,服务名称
pattern: 定义一个模式,如果通过status指令来查看服务的状态时,没有响应,就会通过ps指令在进程中根据该模式进行查找,如果匹配到,则认为该服务依然在运行
runlevel: 运行级别
sleep: 如果执行了restarted,在则stop和start之间沉睡几秒钟
state: 对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)

使用示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@localhost ~]# ansible 192.168.1.61 -m systemd -a 'name=sshd state=started' |head -n 7
192.168.1.61 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"name": "sshd",
"state": "started",

[root@localhost ~]# ansible 192.168.1.61 -m systemd -a 'name=sshd enabled=no'
192.168.1.61 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"enabled": false,
"name": "sshd",

主要看changed,如果是false表示未进行操作或者修改。

ansible test -m service -a "name=httpd state=started enabled=yes"
asnible test -m service -a "name=foo pattern=/usr/bin/foo state=started"
ansible test -m service -a "name=network state=restarted args=eth0"

cron模块

用于管理计划任务,包含如下选项:

1
2
3
4
5
6
7
8
9
10
11
12
backup:    对远程主机上的原任务计划内容修改之前做备份 
cron_file: 如果指定该选项,则用该文件替换远程主机上的cron.d目录下的用户的任务计划
day: 日(1-31,*,*/2,……)
hour: 小时(0-23,*,*/2,……)
minute: 分钟(0-59,*,*/2,……)
month: 月(1-12,*,*/2,……)
weekday: 周(0-7,*,……)
job: 要执行的任务,依赖于state=present
name: 该任务的描述
special_time:指定什么时候执行,参数:reboot,yearly,annually,monthly,weekly,daily,hourly
state: 确认该任务计划是创建还是删除
user: 以哪个用户的身份执行

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#创建一个crontab
[root@node1 ~]# ansible node2 -m cron -a 'backup="True" name="test" minute="0" hour="5,2" job="ls-alh > /dev/null"'
192.168.1.122 | SUCCESS => {
"backup_file": "/tmp/crontabSH6Xo7",
"changed": true,
"envs": [],
"jobs": [
"test"
]
}

[root@node1 ~]# ansible node2 -m shell -a 'cat /var/spool/cron/root'
192.168.1.122 | SUCCESS | rc=0 >>
#Ansible: test
0 5,2 * * * ls -alh > /dev/null
# 删除任务
[root@node1 ~]# ansible node2 -m cron -a 'name="test" state=absent'
192.168.1.122 | SUCCESS => {
"changed": true,
"envs": [],
"jobs": []
}

ansbile cron在新建一个模块时,在创建任务的上面,会加上”#Ansible: name”这个主题。

yum模块

使用yum包管理器来管理软件包,name需要配合state来使用,如果state指定为present/installed/latest将安装包,其中latest是安装最新包,默认为present。如果指定为absent/removed则用于卸载包。其选项有:

1
2
3
4
5
6
config_file:   yum的配置文件 
disable_gpg_check: 关闭gpg_check
disablerepo: 不启用某个源
enablerepo: 启用某个源
name: 要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
state: 状态(present,absent,latest)

示例如下:

1
2
3
ansible test -m yum -a 'name=httpd state=latest'
ansible test -m yum -a 'name="@Development tools" state=present'
ansible test -m yum -a 'name=http://nginx.org/packages/centos/6/noarch/RPMS/nginx-release-centos-6-0.el6.ngx.noarch.rpm state=present'

如果目标主机有安装了包,则changed返回false

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@node1 ~]# ansible node2 -m yum -a "name=screen state=latest"
192.168.1.122 | SUCCESS => {
"changed": true,
"msg": "",
"rc": 0,
"results": [
"Loaded plugins: fastestmirror, security\nLoading mirror speeds from cached hostfile\n * base: mirrors.btte.net\n * extras: mirrors.btte.net\n * updates: mirrors.aliyun.com\nSetting up Install Process\nResolving Dependencies\n-->Running transaction check\n---> Package screen.x86_64 0:4.0.3-19.el6 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package Arch Version Repository Size\n================================================================================\nInstalling:\n screen x86_64 4.0.3-19.el6 base 494 k\n\nTransaction Summary\n================================================================================\nInstall 1 Package(s)\n\nTotal download size: 494 k\nInstalled size: 795 k\nDownloading Packages:\nRunning rpm_check_debug\nRunning Transaction Test\nTransaction Test Succeeded\nRunning Transaction\n\r Installing : screen-4.0.3-19.el6.x86_64 1/1 \n\r Verifying : screen-4.0.3-19.el6.x86_64 1/1 \n\nInstalled:\n screen.x86_64 0:4.0.3-19.el6 \n\nComplete!\n"
]
}
[root@node1 ~]# ansible node2 -m yum -a "name=screen state=latest"
192.168.1.122 | SUCCESS => {
"changed": false,
"msg": "",
"rc": 0,
"results": [
"All packages providing screen are up to date",
""
]
}

yum_repository模块

用于配置yum源。可以实现非常完整的yum仓库配置。但是一般只需简单的添加yum源即可。

1
2
3
4
5
6
7
8
9
baseurl      # 地址
mirrorlist # 设置mirrorlist地址
description # 描述信息
enabled # 是否启用该仓库,默认为yes
file # 保存此仓库的文件,不设置该项的话则默认以name选项中的名称命名,将自动以".repo"后缀结尾。
gpgcheck # 是否要进行gpgcheck
name= # 仓库的名称,要保证名称的唯一性
reposdir # 保存.repo文件的目录,默认/etc/yum.repos.d/
state # repo文件的状态,present/absent,默认present。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[root@localhost yaml]# ansible 192.168.1.61 -m yum_repository -a 'name=aliyun_epel description="epel repo" baseurl=http://mirrors.aliyun.com/epel/7/$basearch/ gpgcheck=no enabled=yes'
192.168.1.61 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"repo": "aliyun_epel",
"state": "present"
}
[root@localhost yaml]# ansible 192.168.1.61 -m shell -a "cat /etc/yum.repos.d/aliyun_epel.repo"
192.168.1.61 | CHANGED | rc=0 >>
[aliyun_epel]
baseurl = http://mirrors.aliyun.com/epel/7/$basearch/
enabled = 1
gpgcheck = 0
name = epel repo

user模块与group模块

user模块是请求的是useradd, userdel, usermod三个指令,goup模块请求的是groupadd, groupdel, groupmod 三个指令。

1、user模块

1
2
3
4
5
6
7
8
9
10
home:		指定用户的家目录,需要与createhome配合使用
groups: 指定用户的属组
uid: 指定用的uid
password: 指定用户的密码
name: 指定用户名
createhome: 是否创建家目录 yes|no
system: 是否为系统用户
remove: 当state=absent时,remove=yes则表示连同家目录一起删除,等价于userdel -r
state: 是创建还是删除 present(默认), absent
shell: 指定用户的shell环境

使用示例:

1
2
3
4
5
user: name=johnd comment="John Doe" uid=1040 group=admin
user: name=james shell=/bin/bash groups=admins,developers append=yes
user: name=johnd state=absent remove=yes
user: name=james18 shell=/bin/zsh groups=developers expires=1422403387
user: name=test generate_ssh_key=yes ssh_key_bits=2048 ssh_key_file=.ssh/id_rsa #生成密钥时,只会生成公钥文件和私钥文件,和直接使用ssh-keygen指令效果相同,不会生成authorized_keys文件。

注:指定password参数时,不能使用明文密码,因为后面这一串密码会被直接传送到被管理主机的/etc/shadow文件中,所以需要先将密码字符串进行加密处理。然后将得到的字符串放到password中即可。

1
2
echo "123456" | openssl passwd -1 -salt $(< /dev/urandom tr -dc '[:alnum:]' | head -c 32) -stdin
$1$4P4PlFuE$ur9ObJiT5iHNrb9QnjaIB0

使用上面的密码创建用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@node1 ~]# ansible node2 -m user -a 'password="$1$RK0XivXG$Bju.cNS4InMrnFRH.ykDS1" name="fdm" createhome="yes"'
192.168.1.122 | SUCCESS => {
"changed": true,
"comment": "",
"createhome": true,
"group": 502,
"home": "/home/fdm",
"name": "fdm",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 501
}

密码保存在/etc/shadow
[root@node1 ~]# ansible node2 -m shell -a 'cat /etc/shadow |grep fdm'
192.168.1.122 | SUCCESS | rc=0 >>
fdm:$1$RK0XivXG$Bju.cNS4InMrnFRH.ykDS1:17166:0:99999:7:::

测试可以正常登陆
[root@node1 ~]# ssh fdm@192.168.1.122
fdm@192.168.1.122's password:
[fdm@node2 ~]$ exit
logout
Connection to 192.168.1.122 closed.

删除用户,连同家目录一起删除

1
2
3
4
5
6
7
8
9
10
11
[root@node1 ~]# ansible node2 -m user -a 'name="fdm" state="absent" remove="yes"'
192.168.1.122 | SUCCESS => {
"changed": true,
"force": false,
"name": "fdm",
"remove": true,
"state": "absent"
}
[root@node1 ~]# ansible node2 -m shell -a 'ls -la /home/fdm'
192.168.1.122 | FAILED | rc=2 >>
ls: cannot access /home/fdm: No such file or directory

不同的发行版默认使用的加密方式可能会有区别,具体可以查看/etc/login.defs文件确认,centos 6.5版本使用的是SHA512加密算法。

2、group示例

ansible all -m group -a 'name=somegroup state=present'

synchronize模块

synchronize模块用于实现rsync的简单版常用功能,它无法实现完整版的rsync,毕竟rsync功能太多太细致。如果要使用rsync,还是应该使用command或shell模块来调用rsync命令。其参数如下:

1
2
3
4
5
6
7
8
9
10
11
archive:    归档,相当于同时开启recursive(递归)、links、perms、times、owner、group、-D选项都为yes,默认该项为开启
checksum: 跳过检测sum值,默认关闭
compress: 是否开启压缩
copy_links:复制链接文件,默认为no ,注意后面还有一个links参数
delete: 删除不存在的文件,默认no
dest: 目录路径
dest_port: 默认目录主机上的端口 ,默认是22,走的ssh协议
dirs: 传速目录不进行递归,默认为no,即进行目录递归
rsync_opts:rsync参数部分
set_remote_user: 主要用于/etc/ansible/hosts中定义或默认使用的用户与rsync使用的用户不同的情况
mode: push或pull 模块,push模的话,一般用于从本机向远程主机上传文件,pull 模式用于从远程主机上取文件

使用示例:

1
2
3
4
src=some/relative/path dest=/some/absolute/path rsync_path="sudo rsync"
src=some/relative/path dest=/some/absolute/path archive=no links=yes
src=some/relative/path dest=/some/absolute/path checksum=yes times=no
src=/tmp/helloworld dest=/var/www/helloword rsync_opts=--no-motd,--exclude=.git mode=pull

filesystem模块

在块设备上创建文件系统。选项:

1
2
3
4
dev:   目标块设备
force: 在一个已有文件系统 的设备上强制创建
fstype:文件系统的类型
opts: 传递给mkfs命令的选项

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#先创建块设备
[root@node1 ~]# ansible node2 -m command -a 'dd if=/dev/zero of=/diskimg bs=1M count=10'
192.168.1.122 | SUCCESS | rc=0 >>
10+0 records in
10+0 records out
10485760 bytes (10 MB) copied, 0.0377583 s, 278 MB/s

[root@node1 ~]# ansible node2 -m command -a 'ls -lh /diskimg'
192.168.1.122 | SUCCESS | rc=0 >>
-rw-r--r-- 1 root root 10M Jan 1 05:41 /diskimg

#关联loop
[root@node1 ~]# ansible node2 -m command -a 'losetup /dev/loop0 /diskimg'
192.168.1.122 | SUCCESS | rc=0 >>

#格式化
[root@node1 ~]# ansible node2 -m filesystem -a 'dev=/diskimg fstype=ext4 opts=-F'
192.168.1.122 | SUCCESS => {
"changed": true
}

mount模块

配置挂载点,选项:

1
2
3
4
5
6
7
8
9
fstype:必选项,挂载文件的类型 
name: 必选项,挂载点
opts: 传递给mount命令的参数
src: 必选项,要挂载的文件
state: 必选项
present: 只处理fstab中的配置
absent: 删除挂载点
mounted: 自动创建挂载点并挂载之
umounted: 卸载

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#挂载刚刚格式化成功的diskimg
[root@node1 ~]# ansible node2 -m mount -a 'name=/cache1 fstype=ext4 src=/diskimg state=mounted'
192.168.1.122 | FAILED! => {
"changed": false,
"failed": true,
"msg": "Error mounting /cache1: mount: /diskimg is not a block device (maybe try `-o loop'?)\n"
}

[root@node1 ~]# ansible node2 -m mount -a 'name=/cache1 fstype=ext4 src=/dev/loop0 state=mounted'
192.168.1.122 | SUCCESS => {
"changed": true,
"dump": "0",
"fstab": "/etc/fstab",
"fstype": "ext4",
"name": "/cache1",
"opts": "defaults",
"passno": "0",
"src": "/dev/loop0"
}
[root@node1 ~]# ansible node2 -m command -a 'df -h'
192.168.1.122 | SUCCESS | rc=0 >>
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 20G 2.2G 17G 12% /
tmpfs 495M 0 495M 0% /dev/shm
/dev/sda1 485M 34M 426M 8% /boot
/dev/sda5 2.0G 36M 1.9G 2% /tmp
/dev/loop0 9.7M 1.1M 8.1M 12% /cache1
[root@node1 ~]# ansible node2 -m raw -a 'cat /etc/fstab |grep cache'
192.168.1.122 | SUCCESS | rc=0 >>
/dev/loop0 /cache1 ext4 defaults 0 0

其他用法:

1
2
3
4
5
6
7
name=/mnt/dvd src=/dev/sr0 fstype=iso9660 opts=ro state=present
name=/srv/disk src='LABEL=SOME_LABEL' state=present
name=/home src='UUID=b3e48f45-f933-4c8e-a700-22a159ec9077' opts=noatime state=present
ansible test -a 'dd if=/dev/zero of=/disk.img bs=4k count=1024'
ansible test -a 'losetup /dev/loop0 /disk.img'
ansible test -m filesystem 'fstype=ext4 force=yes opts=-F dev=/dev/loop0'
ansible test -m mount 'name=/mnt src=/dev/loop0 fstype=ext4 state=mounted opts=rw'

get_url 模块

该模块主要用于从http、ftp、https服务器上下载文件(类似于wget),主要有如下选项:

1
2
3
4
5
6
7
8
9
sha256sum: 下载完成后进行sha256 check;
timeout: 下载超时时间,默认10s
url: 下载的URL
url_password、url_username:主要用于需要用户名密码进行验证的情况
use_proxy: 使用代理,代理需事先在环境变更中定义
dest: 下载存放地址,必须为绝对路径。如果dest是一个目录,则使用url的base name作为文件名
group # 文件/目录的所属组
owner # 文件/目录的所有者
mode # 设置文件/目录的的权限,支持'0644'或'u+rwx'或'u=rw,g=r,o=r'等格式

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[root@node1 ~]# ansible node2 -m get_url -a 'url=https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo_top_ca79a146.png dest=/tmp'
192.168.1.122 | SUCCESS => {
"changed": true,
"checksum_dest": null,
"checksum_src": "91d38b20db1da51b7980e69086db0832016605a9",
"dest": "/tmp/logo_top_ca79a146.png",
"gid": 0,
"group": "root",
"md5sum": "d9f77d9db903dada8eac7910ca79a146",
"mode": "0644",
"msg": "OK (1636 bytes)",
"owner": "root",
"size": 1636,
"src": "/tmp/tmp9PcbSi",
"state": "file",
"uid": 0,
"url": "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo_top_ca79a146.png"
}

archive模块

用于在远端压缩文件。当然,前提是在远端主机上要有对应的压缩工具。支持zip/gz/tar/bz2。模块包含如下选项:

1
2
3
4
5
6
7
dest         # 目标归档文件名。除非path指定要压缩的是单文件,否则需要dest选项
format # 指定压缩格式,默认为gz格式
group # 文件/目录的所属组
owner # 文件/目录的所有者
mode # 设置文件/目录的的权限,支持'0644'或'u+rwx'或'u=rw,g=r,o=r'等格式
path= # 要压缩的文件,可以是绝对路径,也可以是glob统配的路径,还可以是文件列表
remove # 压缩后删除源文件

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 将目录/path/to/foo/压缩为/path/to/foo.tgz
- archive:
path: /path/to/foo
dest: /path/to/foo.tgz

# 压缩普通文件/path/to/foo为/path/to/foo.gz并删除源文件,由于压缩的是单文件,所以可以省略dest选项
- archive:
path: /path/to/foo
remove: True

# 将单文件/path/to/foo压缩为zip格式
- archive:
path: /path/to/foo
format: zip

# 将给定的文件列表压缩为bz2格式,压缩包路径为/path/file.tar.bz2
- archive:
path:
- /path/to/foo
- /path/wong/foo
dest: /path/file.tar.bz2
format: bz2

unarchive模块

默认复制ansible端的归档文件到被控主机,然后在被控主机上进行解包。如果设置选项remote_src=yes,则表示解包被控主机上的归档文件。

要求在被控主机上有对应的解包命令。unzip命令用于解压”.zip”文件,gtar(tar包提供)命令用于解压”.tar”、”.tar.gz”、”.tar.bz2”和”.tar.xz”。模块包含如下选项:

1
2
3
4
5
6
7
8
9
copy:      在解压文件之前,是否先将文件复制到远程主机,默认为yes。若为no,则要求目标主机上压缩包必须存在。
creates: 指定一个文件名,当该文件存在时,则解压指令不执行
dest: 远程主机上的一个路径,即文件解压的路径
grop: 解压后的目录或文件的属组
list_files:如果为yes,则会列出压缩包里的文件,默认为no,2.0版本新增的选项
mode: 解决后文件的权限
remote_src # 设置为yes表示远程主机上已有目标归档文件,即不再从本地复制归档文件到远端,直接在远端解包。默认为no
src: 如果remote_src=no,将复制本地归档文件到远端,可相对路径也可绝对路径。如果remote_src=yes, 将解包远程已存在的归档文件。如果remote_src=yes且src中包含了"://",将指挥远程主机从url中下载文件并解包
owner: 解压后文件或目录的属主

示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 复制ansible端的foo.tgz文件到远端并解包
- unarchive:
src: foo.tgz
dest: /var/lib/foo

# 直接解包远端已经存在的文件- unarchive:
src: /tmp/foo.zip
dest: /usr/local/bin
remote_src: True

# 从url上下载压缩包,然后进行解压
- unarchive:
src: https://example.com/example.zip
dest: /usr/local/bin
remote_src: True

debug模块

用于输出自定义的信息,类似于echo、print等输出命令。ansible中的debug主要用于输出变量值、表达式值,以及用于when条件判断时。使用方式非常简单。

1
2
3
msg        # 调试输出的消息
var # 指定待调试的变量。只能指定变量,不能指定自定义信息,且变量不能加大括号包围,而是直接的变量名。
verbosity # 控制debug运行的调试级别,有效值为一个数值N。(默认是0级,全部显示)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
[root@localhost yaml]# cat test.yaml
---
- hosts: localhost
tasks:
- name: exec date command
command: /bin/date
register: ret
notify:
- print out
#- name: copy fstab to /tmp
# copy: src=/etc/fstab dest=/tmp
handlers:
- name: print out
debug: var=ret

[root@localhost yaml]# ansible-playbook test.yaml

PLAY [localhost] ***********************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************
ok: [localhost]

TASK [exec date command] ****************************************************************************************************************
changed: [localhost]

RUNNING HANDLER [print out] ****************************************************************************************************************
ok: [localhost] => {
"ret": {
"changed": true,
"cmd": [
"/bin/date"
],
"delta": "0:00:00.188618",
"end": "2020-01-05 02:38:48.757133",
"failed": false,
"rc": 0,
"start": "2020-01-05 02:38:48.568515",
"stderr": "",
"stderr_lines": [],
"stdout": "Sun Jan 5 02:38:48 EST 2020",
"stdout_lines": [
"Sun Jan 5 02:38:48 EST 2020"
]
}
}

PLAY RECAP *******************************************************************************************************
localhost : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0

上述 var=ret 将所有的信息都输出来了,

wait_for模块

有些时候任务之间对状态、文件、端口等资源是有依赖关系的,只有满足了前提,任务才会继续。wait_for模块就是用于判断任务在满足什么条件的情况下会继续。主要用来判断端口是否开启、文件是否存在、文件中是否存在某些字符串。

1
2
3
4
5
6
7
8
9
delay          # 在检查操作进行之前等待的秒数
host # 等待这个主机处于启动状态,默认为127.0.0.1
port # 等待这个端口已经开放
path # 这个文件是否已经存在
search_regex # 在文件中进行正则匹配
state # 默认started。当检查的是一个端口时:started:保证端口是开放的 ,stopped:保证端口是关闭的;
# 当检查的是一个文件时:present/started:在检查到文件存在才会继续,absent:检查到文件被移除后才会继续
sleep # 两次检查之间sleep的秒数,默认1秒
timeout # 检查的等待超时时间(秒数,默认300)

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 连接上主机后10秒后才检查8000端口是否处于开放状态,300秒(默认值)内未开放则超时。
- wait_for:
port: 8000
delay: 10

# 直到/tmp/foo文件存在才会继续
- wait_for:
path: /tmp/foo

# 直到/tmp/foo文件中能匹配"completed"字符串才继续
- wait_for:
path: /tmp/foo
search_regex: completed

# 直到/var/lock/file.lock这个锁文件被移除了才继续
- wait_for:
path: /var/lock/file.lock
state: absent

# 直到/proc/3466/status文件被移除才继续,可用来判断进程是启动还是停止,pid文件是存在还是被移除等
- wait_for:
path: /proc/3466/status
state: absent
  • 本文作者: wumingx
  • 本文链接: https://www.wumingx.com/linux/ansible-module.html
  • 本文主题: ansible系列之二:常用模块介绍
  • 版权声明: 本站所有文章除特别声明外,转载请注明出处!如有侵权,请联系我删除。
0%