ansible的常用命令与playbook
ansible-doc 命令
ansible-doc
命令常用于获取模块信息及其使用帮助
ansible-dochttps://lab.yigenet.cn/wp-admin/显示模块帮助的指令 格式:ansible-doc [参数] [模块] 常用参数 -l 列出可用模块 -s 显示指定模块的playbook片段
一、ansible 常用模块
命令格式: ansible [主机] [-m 模块] [-a args]
1、ping模块
红帽9开启ssh允许root登录 [root@ansible ~]# vim /etc/ssh/sshd_config 加入 PermitRootLogin yes
此模块用于进行主机连通性测试
[root@server01 ansible]# ansible all -m ping 192.168.100.100 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
2.command模块
功能: 在远程主机执行命令,此模块为默认模块,但是不能识别特殊字符
常用参数
chdir 执行命令前先进入到指定目录 cmd 运行命令指定 creates 如果文件存在将不运行 removes 如果文件存在在将运行 free_form 在远程主机中执行的命令,此参数不需要加
[root@server01 ansible]# ansible all -m command -a "chdir=/mnt pwd" 192.168.100.100 | CHANGED | rc=0 >> /mnt [root@server01 ansible]# ansible all -m command -a "creates=/mnt pwd" 192.168.100.100 | SUCCESS | rc=0 >> skipped, since /mnt existsDid not run command since '/mnt' exists [root@server01 ansible]# ansible all -m command -a "removes=/mnt pwd" 192.168.100.100 | CHANGED | rc=0 >> /root
3.shell模块
功能:
shell模块和command功能类似,但可以识别特殊字符
[root@server01 ansible]# ansible all -m shell -a "ps ax | grep $$" 192.168.100.100 | CHANGED | rc=0 >> 8961 pts/1 S+ 0:00 /bin/sh -c ps ax | grep 35502 8963 pts/1 S+ 0:00 grep 35502 [root@server01 ansible]#
4.script模块
功能: 在ansible主机中写好的脚本可以在受控主机中执行
实例:
[root@server01 ansible]# vim test.sh #!/bin/bash touch /opt/linux{1..4} [root@server01 ansible]# ansible all -m script -a "test.sh" 192.168.100.100 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.100.100 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.100.100 closed." ], "stdout": "", "stdout_lines": [] } [root@server01 ansible]# ansible all -a "ls /opt" 192.168.100.100 | CHANGED | rc=0 >> linux1 linux2 linux3 linux4
5.copy模块
功能:从ansible主机复制文件到受控主机
常用参数:
src 源文件 dest 目的地文件 owner 指定目的地文件所有人 group mode 指定目的地文件权限 backup=yes 当受控主机中存在文件时备份原文件 content 指定文本内容直接在受控主机中生成文件
案例: ansible all -m copy -a 'dest=/home/linux content="hello world"' 在/mnt/中创建linux文件,内容为hello westos
[root@server01 ansible]# ansible all -m copy -a 'dest=/home/linux content="hello world"' 192.168.100.100 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, [root@server01 ansible]# ansible all -a "cat /home/linux" 192.168.100.100 | CHANGED | rc=0 >> hello world
ansible all -m copy -a 'src=inventory dest=/home/file owner=westos group=devops mode=777 backup=yes' 将当期目录下的inventory文件复制到可控主机的/mnt/file中,并指定devops组,权限为777
[root@server01 ansible]# ansible all -m copy -a 'src=inventory dest=/home/user1/file owner=user1 group=user1 mode=777 backup=yes' 192.168.100.100 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, [root@server01 ansible]# ansible all -a "ls -l /home/user1" 192.168.100.100 | CHANGED | rc=0 >> total 4 -rwxrwxrwx. 1 user1 user1 66 Jan 24 15:42 file [root@server01 ansible]# ansible all -a "cat /home/user1/file" 192.168.100.100 | CHANGED | rc=0 >> 192.168.100.100 ansible_user=root ansible_password=ChinaSkill23! [root@server01 ansible]#
6.fetch模块
功能 :从受控主机把文件复制到ansible主机,但不支持目录
常用参数:
src 受控主机的源文件 dest 本机目录 flat 基本名称功能
实例: ansible all -m fetch –a ‘src=/home/linux dest=/tmp/ 将被控主机/mnt/中的linux文件复制到当前主机的/tmp/中 [root@server01 ansible]# ansible all -m fetch -a 'src=/home/linux dest=/tmp/' 192.168.100.100 | CHANGED => { "changed": true, "checksum": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", "dest": "/tmp/192.168.100.100/home/linux", "md5sum": "5eb63bbbe01eeed093cb22bb8f5acdc3", "remote_checksum": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", "remote_md5sum": null } [root@server01 ansible]# ls /tmp/192.168.100.100/home/ linux
ansible all -m fetch -a 'src=/home/linux dest=/tmp/hello flat=yes' 将被控主机中/home/中的linux文件复制到当前主机/tmp/目录中并命名为hello
[root@server01 ansible]# ansible all -m fetch -a 'src=/home/linux dest=/tmp/hello flat=yes' 192.168.100.100 | CHANGED => { "changed": true, "checksum": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", "dest": "/tmp/hello", "md5sum": "5eb63bbbe01eeed093cb22bb8f5acdc3", "remote_checksum": "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed", "remote_md5sum": null } [root@server01 ansible]# cat /tmp/hello hello world
7.file模块
功能:设置文件的属性
常用参数:
path 指定文件名称 state 指定操作状态 ouch 建立 absent 删除 directory 递归 link 建立链接 mode 设定权限 owner 设定文件用户 group 设定文件组 src 源文件 dest 目标文件 recurse=yes 递归更改 ansible all -m file -a 'path=/mnt/test.sh state=absent' 删除文件 ansible all -m file -a 'path=/mnt/westos state=directory' 建立目录 ansible all -m file -a 'src=/mnt/file dest=/mnt/westos state=link' 建立软连接 ansible all -m file -a 'src=/mnt/file dest=/mnt/westos1 state=hard' 建立硬链接 ansible all -m file -a 'path=/mnt/file state=touch owner=lee group=westos mode=777' 更改所有人所有组和权限
ansible all -m file -a 'path=/opt/linuxfile state=touch' 在被控主机/opt/中建立linuxfile文件 [root@server01 ansible]# ansible all -m file -a 'path=/opt/linuxfile state=touch' 192.168.100.100 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, [root@server01 ansible]# ansible all -a 'ls /opt' 192.168.100.100 | CHANGED | rc=0 >> linux1 linux2 linux3 linux4 linuxfile
ansible all -m file -a 'path=/opt/linux mode=777' 更改被控主机中/opt/中linuxfile文件权限为777 [root@server01 ansible]# ansible all -m file -a 'path=/opt/linuxfile mode=777' 192.168.100.100 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0777", "owner": "root", "path": "/opt/linuxfile", "secontext": "unconfined_u:object_r:usr_t:s0", "size": 0, "state": "file", "uid": 0 }
8.unarchive模块
功能:解压缩 常用参数:
Copy 默认为yes 从ansible主机复制文件到受控主机 设定为no 从受控主机中寻找src源文件 remote_src 功能同copy且相反 设定为yes 表示包在受控主机 设定为no表示包在ansible主机 src 包路径,可以使ansible主机也可以使受控主机 dest 受控主机目录 mode 加压后文件权限
案例: ansible all -m unarchive -a 'copy=no src=/mnt/etc.tar.gz dest=/mnt mode=777’ 解压/mnt/etc.tar.ge到/opt中 [root@ansible ansible]# ansible all -a "tar -czf /mnt/xxx.tar.gz /etc/passwd /etc/fstab /home" 192.168.100.128 | CHANGED | rc=0 >> tar: 从成员名中删除开头的“/” tar: 从硬连接目标中删除开头的“/” 192.168.100.129 | CHANGED | rc=0 >> tar: 从成员名中删除开头的“/” tar: 从硬连接目标中删除开头的“/” [root@ansible ansible]# [root@ansible ansible]# ansible all -m unarchive -a 'copy=no src=/mnt/xxx.tar.gz dest=/opt mode=777' 192.168.100.128 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, [root@ansible ansible]# ansible all -a 'ls /opt' 192.168.100.129 | CHANGED | rc=0 >> etc home 192.168.100.128 | CHANGED | rc=0 >> etc home
9.cron模块
作用:计划任务 常用参数:
minute 分钟 hour 小时 day 天 month 月 weekday 周 name 任务名称 job 任务脚本或命令 disabled yes禁用计划任务 no启动计划任务 state=absent 删除计划任务
案例: ansible all -m cron -a 'job="rm -rf /opt/*" name=clear minute=*/5' 删除被控主机中/opt/下的所有内容,每五分钟执行一次 [root@ansible ansible]# ansible all -m cron -a 'job="rm -rf /opt/*" name=clear minute=*/5' 192.168.100.128 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, [root@ansible ansible]# ansible all -a "crontab -l" 192.168.100.128 | CHANGED | rc=0 >> #Ansible: clear */5 * * * * rm -rf /opt/* 192.168.100.129 | CHANGED | rc=0 >> #Ansible: clear */5 * * * * rm -rf /opt/*
ansible all –m cron –a ‘job=”rm –rf /opt/*” name=clear minute=*/5 state=absent’ 删除该定时任务 [root@ansible ansible]# ansible all -m cron -a 'job="rm -rf /opt/*" name=clear minute=*/5 state=absent' 192.168.100.129 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, [root@ansible ansible]# ansible all -a "crontab -l" 192.168.100.129 | CHANGED | rc=0 >> 192.168.100.128 | CHANGED | rc=0 >>
10.yum_repository模块
作用:配置系统软件仓库源文 常用参数:
name 指定仓库名称 baseurl 指定源路径 description 指定仓库描述 file 指定仓库文件名称 enabled 仓库是否启用 gpgcheck 仓库是否检测 gpgkey state 默认值 present 建立 absent 删除
实例: ansible all -m yum_repository -a 'name="BaseOS" description="BaseOS" baseurl=file:///mnt/cdrom gpgcheck=no enabled=yes'
11.dnf模块
作用:管理系统中的dnf仓库及管理软件 常用参数:
name 指定包 state 指定动作 present 安装 latest 更新 absent 删除 list 列出指定信息
实例: ansible all -m dnf -a 'name="httpd,vsftpd,lftpr" state=present' 安装软件 [root@ansible ansible]# ansible all -m dnf -a 'name=httpd state=present' 192.168.100.128 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" },
ansible all -m dnf -a 'name="httpd,vsftpd,lftpr" state=absent autoremove=yes' 卸载软件 [root@ansible ansible]# ansible all -m dnf -a 'name="httpd,vsftpd,lftpr" state=absent autoremove=yes‘ 192.168.100.128 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" },
12.service模块
作用:管理系统服务状态 常用参数:
name 指定服务名称 state 指定对服务的动作 started stoped restarted reloaded enabled 设定服务开机是否启动 yes开启启动 o开机不启动
实例 ansible all -m service -a ‘name=httpd state=started enabled=yes’ 开启http ansible all -m service -a ‘name=httpd state=restarted enabled=yes’ 重启httpd [root@ansible ansible]# ansible all -m service -a 'name=httpd state=started enabled=yes' 192.168.100.129 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, [root@ansible ansible]# ansible all -m shell -a "systemctl status httpd | grep active" 192.168.100.128 | CHANGED | rc=0 >> Active: active (running) since Sat 2024-01-27 16:25:55 CST; 2min 15s ago 192.168.100.129 | CHANGED | rc=0 >> Active: active (running) since Sat 2024-01-27 16:25:55 CST; 2min 15s ago
13.user模块
作用 模块可以帮助我们管理远程主机上的用户,比如创建用户、修改用户、删除用户、为用户创建密钥对等操作
常用参数
name 必须参数,用于指定要操作的用户名称。 group 指定用户所在的基本组。 gourps 指定用户所在的附加组。 append 指定添加附加组默认值为 uid 指定用户的 uid 号。 comment 指定用户的注释信息。 state 用于指定用户是否存在于远程主机 present 建立 absent 删除 remove 当删除用户是删除用户家目录,默认值为no password 此参数用于指定用户的密码。但密码为明文,
实例 ansible westos -m user -a 'name=lee state=present uid=6666' 建立用户lee,并指定用户id为6666 [root@ansible ansible]# ansible all -m user -a 'name=lee state=present uid=6666' 192.168.100.129 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, [root@ansible ansible]# ansible all -a "id lee" 192.168.100.128 | CHANGED | rc=0 >> 用户id=6666(lee) 组id=6666(lee) 组=6666(lee) 192.168.100.129 | CHANGED | rc=0 >> 用户id=6666(lee) 组id=6666(lee) 组=6666(lee)
ansible all -m user -a 'name=lee remove=yes state=absent' 删除用户并且删除用户家目录 [root@ansible ansible]# ansible all -m user -a 'name=lee remove=yes state=absent' 192.168.100.128 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "force": false, "name": "lee", "remove": true, "state": "absent" }
14.group模块
作用:group 模块可以帮助我们管理远程主机上的组。
常用参数
name 用于指定要操作的组名称。 state 用于指定组的状态 present 建立 absent 删除 gid 用于指定组的gid。
实例 ansible all -m group -a 'name=westoslinux gid=8888' 指定westoslinux的组id为8888 [root@ansible ansible]# ansible all -m group -a 'name=westoslinux gid=8888' 192.168.100.128 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "gid": 8888, "name": "westoslinux", "state": "present", "system": false } 192.168.100.129 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python3" }, "changed": true, "gid": 8888, "name": "westoslinux", "state": "present", "system": false }
二. 实施playbook
2.1 Ansible Playbook与临时命令
临时命令可以作为一次性命令对一组目标主机运行一项简单的任务。不过,若要真正发挥Ansible的力量,需要了解如何使用playbook以便轻松重复的方式对一组目标主机执行多项复杂的任务。
play是针对清单中选定的主机运行的一组有序任务。playbook是一个文本文件,其中包含由一个或多个按特定顺序运行的play组成的列表。
Play可以将一系列冗长而复杂的手动管理任务转变为可轻松重复的例程,并且具有可预测的成功成果。在playbook中,可以将play内的任务序列保存为人类可读并可立即运行的形式。根据任务的编写方式,任务本身记录了部署应用或基础架构所需的步骤。
2.2 格式化Ansible Playbook
前面我们学习了临时命令模块,下面以一条命令做为案例来讲解下其在playbook中是如何编写的。
ansible 172.16.103.129 -m user -a 'name=runtime uid=4000 state=present'
这个任务可以将其编写为一个单任务的play并保存在playbook中。生成的playbook如下方所示:
---
- name: Configure important user consistently
hosts: 172.16.103.129
task:
- name: runtime exists with UID 4000
user:
name: runtime
uid: 4000
state: present
Playbook是以YAML格式编写的文本文件,通常使用扩展名yml保存。Playbook使用空格字符缩进来表示其数据结构。YAML对用于缩进的空格数量没有严格的要求,但有两个基本的规则:
-
处于层次结构中同一级别的数据元素(例如同一列表中的项目)必须具有相同的缩进量。
-
如果项目属于其他项目的子项,其缩进量必须大于父项
只有空格字符可用于缩进,不允许使用tab键。约定俗成的缩进量一般是一级2个空格。
Playbook开头的一行由三个破折号(---)组成,这是文档开始标记。其末尾可能使用三个圆点(...)作为文档结束标记,尽管在实践中这通常会省略。
在这两个标记之间,会以一个play列表的形式来定义playbook。YAML列表中的项目以一个破折号加空格开头。例如,YAML列表可能显示如下:
- apple
- orange
- grape
Play本身是一个键值对集合。同一play中的键应当使用相同的缩进量。以下示例显示了具有三个键的YAML代码片段。前两个键具有简单的值。第三个将含有三个项目的列表作为值。
- name: just an example
hosts: webservers
tasks:
- first
- second
- third
作为play中的一部分,tasks属性按顺序实际列出要在受管主机上运行的任务。列表中各项任务本身是一个键值对集合。
还以上面创建用户的play为例,play中唯一任务有两个键:
-
name是记录任务用途的可选标签。最好命名所有的任务,从而帮助记录自动流程中的每一步用途。
-
user是要为这个任务运行的模块。其参数作为一组键值对传递,它们是模块的子项(name、uid和state)。
下面再来看一个含有多项任务的tasks属性案例:
tasks:
- name: web server is enabled
service:
name: httpd
enabled: true
- name: NTP server is enabled
service:
name: chronyd
enabled: true
- name: Postfix is enabled
service:
name: postfix
enabled: true
playbook中play和任务列出的顺序很重要,因为Ansible会按照相同的顺序运行它们。
2.3 运行playbook
absible-playbook命令可用于运行playbook。该命令在控制节点上执行,要运行的playbook的名称则作为参数传递。
ansible-playbook site.yml
在运行playbook时,将生成输出来显示所执行的play和任务。输出中也会报告执行的每一项任务的结果。
以下示例中显示了一个简单的playbook的内容,后面是运行它的结果。
[root@localhost ~]# mkdir playdemo
[root@localhost ~]# cd playdemo/
[root@localhost playdemo]# vim webserver.yml
---
- name: play to setup web server
hosts: webservers
tasks:
- name: latest httpd version installed
yum:
name: httpd
state: latest
- name: service is enabled
service:
name: httpd
enabled: true
[root@localhost playdemo]# ansible-playbook webserver.yml
PLAY [play to setup web server] *****************************************************
TASK [Gathering Facts] **************************************************************
ok: [172.16.103.129]
ok: [172.16.103.130]
TASK [latest httpd version installed] ***********************************************
ok: [172.16.103.129]
ok: [172.16.103.130]
TASK [service is enabled] ***********************************************************
changed: [172.16.103.129]
changed: [172.16.103.130]
PLAY RECAP **************************************************************************
172.16.103.129 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
172.16.103.130 : ok=3 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
请注意,在playbook运行时,屏幕中会显示每个play和任务的name键的值。(Gathering Facts任务是一项特别的任务,setup模块通常在play启动时自动运行这项任务。)对于含有多个play和任务的playbook,设置name属性后可以更加轻松地监控playbook执行的进展。
通常而言,Ansible Playbook中的任务是幂等的,而且能够安全地多次运行playbook。如果目标受管主机已处于正确的状态,则不应进行任何更改。如果再次运行这个playbook,所有任务都会以状态OK传递,且不报告任何更改。
2.4 提高输出的详细程度
ansible-playbook命令提供的默认输出不提供详细的任务执行信息。ansible-playbook -v命令提供了额外的信息,总共有四个级别。
配置Playbook执行的输出详细程序
选项 | 描述 |
---|---|
-v | 显示任务结果 |
-vv | 任务结果和任务配置都会显示 |
-vvv | 包含关于与受管主机连接的信息 |
-vvvv | 增加了连接插件相关的额外详细程序选项,包括受管主机上用于执行脚本的用户以及所执行的脚本 |
2.5 语法验证
在执行playbook之前,最好要进行验证,确保其内容的语法正确无误。ansible-playbook命令提供了一个--syntax-check选项,可用于验证playbook的语法。
下例演示了一个playbook成功通过语法验证:
[root@localhost playdemo]# ansible-playbook --syntax-check webserver.yml
playbook: webserver.yml
语法验证失败时,将报告语法错误。输出中包含语法问题在playbook中的大致位置。
下例演示了一个playbook语法验证失败的情况:
[root@localhost playdemo]# ansible-playbook --syntax-check webserver.yml
Syntax Error while loading YAML.
did not find expected '-' indicator
The error appears to be in '/root/playdemo/webserver.yml': line 3, column 1, but may
be elsewhere in the file depending on the exact syntax problem.
The offending line appears to be:
- name: play to setup web server
hosts: webservers
^ here
2.6 执行空运行
可以使用-C选项对playbook执行空运行。这会使Ansible报告在执行该playbook时将会发生什么更改,但不会对受管主机进行任何实际的更改。
下例演示了一个playbook的空运行,它包含单项任务,可确保在受管主机上安装了最新版本的httpd软件包。注意该空运行报告此任务会对受管主机产生的更改。
ansible-playbook -C webserver.yml
3. 实施多个play
3.1 缩写多个play
Playbook是一个YAML文件,含有由一个或多个play组成的列表。记住一个play按顺序列出了要对清单中的选定主机执行的任务。因此,如果一个playbook中有多个play,每个play可以将其任务应用到单独的一组主机。
在编排可能涉及对不同主机执行不同任务的复杂部署时,这会大有帮助。我们可以这样进行编写:对一组主机运行一个play,完成后再对另一组主机运行另一个play。
缩写包含多个play的playbook非常简单。Playbook中的各个play编写为playbook中的顶级列表项。各个play是含有常用play关键字的列表项。
以下示例显示了含有两个play的简单playbook。第一个play针对172.16.103.129运行,第二个play则针对172.16.103.131运行。
---
# This is a simple playbook with two plays
- name: first play
hosts: 172.16.103.129
tasks:
- name: first task
yum:
name: httpd
status: present
- name: second task
service:
name: httpd
enabled: true
- name: second play
hosts: 172.16.103.131
tasks:
- name: first task
service:
name: mariadb
enabled: true
3.2 play中的远程用户和特权升级
Play可以将不同的远程用户或特权升级设置用于play,取代配置文件中指定的默认设置。这些在play本身中与hosts或tasks关键字相同的级别上设置。
3.2.1 用户属性
playbook中的任务通常通过与受管主机的网络连接来执行。与临时命令相同,用于任务执行的用户帐户取决于Ansible配置文件/etc/ansible/ansible.cfg中的不同关键字。运行任务的用户可以通过remote_user关键字来定义。不过,如果启用了特权升级,become_user等其他关键字也会发生作用。
如果用于任务执行的Ansible配置中定义的远程用户不合适,可以通过在play中使用remote_user关键字覆盖。
remote_user: remoteuser
3.2.2 特权升级属性
Ansible也提供额外的关键字,从而在playbook内定义特权升级参数。become布尔值关键字可用于启用或禁用特权升级,无论它在Ansible配置文件中的定义为何。它可取yes或true值来启用特权升级,或者取no或false值来禁用它。
become: true
如果启用了特权升级,则可以使用become_method关键字来定义特定play期间要使用的特权升级方法。
以下示例中指定sudo用于特权升级:
become_method: sudo
此外,启用了特权升级时,become_user关键字可定义特定play上下文内要用于特权升级的用户帐户。
become_user: privileged_user
以下示例演示了如何在play中使用这些关键字:
- name: /etc/hosts is up to date
hosts: 172.16.103.129
remote_user: automation
become: yes
tasks:
- name: 172.16.103.129 in /etc/hosts
lineinfile:
path: /etc/hosts
line: '172.16.103.129 web1.example.com'
state: present
3.3 查找用于任务的模块
3.3.1 模块文档
Ansible随附打包的大量模块为管理员提供了许多用于常见管理任务的工具。前面我们介绍了Ansible官方网站的帮助文档链接https://docs.ansible.com/。通过模块索引,可以很轻松的找到对应的模块。例如,适用于用户和服务管理的模块可以在Systems Modules下找到,而适合数据库管理的模块则可在Database Modules下找到。
对于每一个模块,Ansible官网提供了其功能摘要,以及关于如何通过模块的选项来调用各项具体功能的说明。文档还提供了实用的示例,演示各个模块的用法,以及任务中关键字的设置方法。
前面我们用到过ansible-doc -l命令。这将显示模块名称列表以及其功能的概要。
ansible-doc -l
使用ansible-doc [module name]命令来显示模块的详细文档。与Ansible官网一样,该命令提供模块功能的概要、其不同选项的详细信息,以及示例。
ansible-doc yum # 显示yum模块的帮助文档
ansible-doc命令还提供-s选项,它会生成示例输出,可以充当如何在playbook在使用特定模块的示范。此输出可以作为起步模板,包含在实施该模块以执行任务的playbook中。输出中包含的注释,提醒管理员各个选项的用法。下例演示了yum模块的这种输出:
ansible-doc -s yum
使用ansible-doc命令可以查找和了解如何使用模块。尽管command、shell和raw模块的用法可能看似简单,但在可能时,应尽量避免在playbook中使用它们因为它们可以取胜任意命令,因此使用这些模块时很容易写出非幂等的playbook。
例如,以下使用shell模块的任务为非幂等。每次运行play时,它都会重写/etc/resolv.conf,即使它已经包含了行nameserver 172.16.103.2。
- name: Non-idepotent approach with shell module
shell: echo "nameserver 172.16.103.2" > /etc/resolv.conf
可以通过多种方式编写以幂等方式使用shell模块的任务,而且有时候进行这些更改并使用shell是最佳的做法。但更快的方案或许是使用ansible-doc发现copy模块,再使用它获得所需的效果。
在以下示例中,如果/etc/resolv.conf文件已包含正确的内容,则不会重写该文件:
- name: Idempotent approach with copy module
copy:
dest: /etc/resolv.conf
content: "nameserver 172.16.103.2\n"
copy模块可以测试来了解是否达到了需要的状态,如果已达到,则不进行任何更改。shell模块容许非常大的灵活性,但需要格外小心,从而确保它以幂等方式运行。
幂等的playbook可以重复运行,确保系统处于特定的状态,而不会破坏状态已经正确的系统。