ansible模块说明

 Ansible
时间:

Ansible 的模块工作原理

Ansible对远程服务器的操作实际是通过模块完成的。

  1. 将模块拷贝到远程服务器
  2. 执行模块定义的操作,完成对服务器的修改
  3. 在远程服务器中删除模块

Ansible中的模块是幂等的。也就是说,多次执行相同的操作,只有第一次会起作用。这也是在编写自定义Ansible模块时需要注意的地方。

模块列表与帮助信息

Ansible的模块非常多,如果以模块的功能进行分类,可以分为:

  • 云模块
  • 命令模块
  • 数据库模块
  • 文件模块
  • 资产模块
  • 消息模块
  • 监控模块
  • 网络模块
  • 通知模块
  • 包管理模块
  • 源码控制模块
  • 系统模块
  • 单元模块
  • web设施模块
  • windows模块等

模块参考文档

#获取模块帮助信息
ansible-doc -l
#获取指定模块帮助信息
ansible-doc [modules]
  1. 远程命令模块

command,raw,script和shell模块都可以实现在远程服务器上执行Linux命令。

  • command模块包含的其他重要选项:

    • chdir: 在执行指令之前,先切换到该指定的目录,类似与Linux下的cd
    • executable: 切换shell来执行命令。
  • raw模块相当于管道

    • raw模块相当于使用SSH直接执行Linux命令,不会进入到Ansible的模块子系统中。
  • shell模块

    • 可以执行远程服务器上的shell脚本文件
  • script模块

    • 可以在远程服务器上执行主控节点中的脚本文件,其功能相当于scp+shell的组合
  1. file模块

file模块主要用于对远程服务器上的文件(包括链接和目录)进行操作,包括修改文件的权限,修改文件所有者,创建文件,删除文件等。

  • path: 指定文件/目录的路径;
  • recurse: 递归设置文件属性,只对目录有效;
  • group: 定义文件/目录的组;
  • mode: 定义文件/目录的权限;
  • owner: 定义文件/目录的所有者;
  • src: 要被链接的源文件路径,只应用于state为link的情况;
  • dest: 被链接到的路径,只应用于state为link的情况;
  • force: 在两种情况下会强制创建软链接,一种是源文件不存在但之后会建立的情况;另一种是目标软链接已存在,需要先取消之前的软链接,然后创建新的软链接,默认取值为no;
  • state: 该选项有多个取值,包括directory, file, link,hard, touch, absent. 各个取值的含义如下:取值为directory时,如果目录不存在,创建目录;取值为file时,即使文件不存在也不会被创建;取值为link时,创建软链接;取值为hard时,创建硬链接,取值为touch时,如果文件不存在,创建一个新文件,如果文件或目录已存在,更新其最后访问时间和修改时间;取值为absent时,删除目录,文件或链接。
#创建一个目录
ansible test -m file  -a "path=/tmp/dd state=directory mode=0755"
#修改文件的权限
ansible test -m file -a "path=/tmp/dd sate=touch mode="u=rw, g=r, o=r""
#创建一个软链接
ansible test -m file -a "src=/tmp/dd dest=/tmp/ddl owner=lmxgroup=lmx  state=link"
#修改一个文件所有者
ansible test -m file -a "path=/tmp/dd owner=root group=root mode=0644" -become
  1. copy

copy模块用来将主控节点的文件或目录拷贝到远程服务器上,类似于Linux下的scp命令。但是,copy模块比scp命令更强大,在拷贝文件到远程服务器的同时,也可以设置文件在远程服务器的权限和所有者。

  • src: 要复制到远程主机的文件地址,可以是绝对路径,也可以是相对路径如果路径是一个目录,将递归复制。在这种情况下,如果路径使用”/“结尾,则只复制目录里的内容,如果没有使用”/“来结尾,则将包含目录在内整个内容全部复制,类似于rsync;
  • dest: 文件复制的目的地,必须是一个绝对路径,如果源文件是一个目录,那么,dest指向的也必须是一个目录;
  • force: 默认取值为yes,表示目标主机包含该文件,但内容不同时会强制覆盖,如果该选项设置为no,则只有当目标主机的目标位置不存在于该文件时,才会进行复制;
  • backup: 默认取值为no,如果为取值为yes,那么,在覆盖之前将原文件进行备份;
  • directory_mode: 递归设定目录权限,默认为系统默认权限;
  • others: 所有file模块里的选项都可以在这里使用。
  1. user/group

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

  • name: 需要操作的用户名(或群组名);
  • comment: 用户的详细描述;
  • createhome: 创建用户时,是否创建家目录,默认为yes;
  • home: 指定用户的家目录,需要与createhome选项配合使用;
  • groups: 指定用户的属组
  • uid: 设置用户的uid
  • gid: 设置群组的gid
  • password: 设置用户的密码
  • state: 是创建用户(或群组)还是删除用户(或群组),取值包括present和absent;
  • expires: 用户的过期时间;
  • shell:指定用户的shell环境
  1. apt

apt模块用来Debian/Ubuntu系统中安装软件,删除软件。

  • name: 软件包名;
  • state: 软件包的状态,可以取值为latest,absent,present和build-dep, 默认为present;
  • autoremove: 默认取值为no, 如果取值为yes,将会移除不需要额软件包;
  • force: 强制安装或删除软件包;
  • update_cache: 作用与apt-get update 相同;
  • deb: deb文件的路径

7.get_url

从互联网下载数据到本地,作用类似于Linux下的curl命令。get_url模块比curl命令更加灵活,可以控制下载以后的数据所有者,权限以及检查数据的checksum等。

  • url: 必须选项,文件下载地址;
  • dest: 必须选择, 文件保存的绝对路径;
  • mode: 文件的权限mode;
  • others: 所有file模块里的选项都可以在这里使用;
  • checksum: 文件的校验码;
  • headers: 传递给下载服务器的HTTP Headers;
  • backup: 如果本地已经存在同名文件,备份文件;
  • timeout: 下载的超时时间.
  1. unarchive

unarchive模块用于解压文件,其作用类似于Linux下的tar命令。默认情况下,unarchive的作用是将控制节点的压缩包拷贝到远程服务器,然后解压。

  • remote_src: 该选项可以取值yes或no,用来表示解压的文件存在远程服务器中,还是存在控制节点所在的服务器中。默认取值为no,表示在解压文件之前,先将控制节点上的文件复制到远程主机中,然后在进行解压;
  • src: 指定压缩文件的路径,该选项的取值取决于remote_src的取值,如果remote_src取值为yes,则src指定1的是远程服务器中的压缩包的地址,如果remote_src取值为no,则src指向的是控制节点中的路径。
  • dest: 该选项指定的是远程服务器上的绝对路径,表示压缩文件解压路径。
  • list_files: 默认情况下该选项取值为no,如果该选项取值为yes,也会解压文件并且在ansible的返回值中列出压缩包里的文件;
  • exclude: 解压文件时排除exclude选项的文件或目录列表;
  • keep_newer: 默认取值为False,如果该选项取值为True,那么,当目标地址中存在同名的文件,并且文件比压缩包中的文件更新时,不进行覆盖。
  • owner: 文件或目录解压后的所有者
  • grop: 文件或目录解压后所属的群组;
  • mode: 文件或目录解压以后的权限。
  1. git

git模块非常好理解,就是在远程服务器执行git相关的操作。该模块一般应用于需要源码安装软件时,从github源码托管下载到本地。

  • repo: 远程git库的地址,可以是一个git协议,ssh协议或http协议的git库地址;
  • dest: 必须选项,git库clone到本地服务器以后保存的绝对路径;
  • version: 克隆远程git库的版本,取值可以为HEAD,分支的名称,tag名称,也可以是一个commit的hash值。
  • force: 默认取值为no,当该选项取值为yes时,如果本地的git库有修改,将会抛弃本地修改;
  • acceptt_hostkey: 当该选项取值为yes时,如果git库的服务器不在know_hosts中,则添加到know_hosts中,key_file指定克隆远程git库地址时使用的私钥。
  1. stat

stat模块用于获取远程服务器上的文件信息,其作用类似于Linux下的stat命令。stat模块可以获取atime,ctime,mtime,checksum,size,uid,gid等信息。

  • path: 指定文件或目录的路径。
  1. cron

cron是管理Linux下计划任务的模块

  • backup: 取值为yes或no,默认为no,表示修改之前先做备份;
  • state: 取值为present或absent,用来确定该任务计划是创建还是删除;
  • name: 该任务的描述;
  • job: 添加或删除任务,主要取决于state的取值;
  • user: 操作哪一个用户的crontab;
  • cron_file: 如果指定该选项,则用该文件替换远程主机上cron.d目录下的用户任务计划;
  • month weekday day minute hour: 取值与crontab类似,例如,对于minute的取值范围0~59,也可以选择”“ 表示每分钟运行, 或者 “/5” 表示每5分钟运行。
  1. service

service模块的作用类似于Linux下的service命令,用来启动,停止,重启服务。

  • name: 服务的名称,该选项为必选
  • state: 可以取值为started, stopped, restarted 和 reloaded。其中,started和stoped是幂等的,也就是说,如果服务已经启动了执行stared不会执行任何操作;
  • sleep: 重启的过程中,先停止服务然后sleep几秒再启动;
  • pattern: 定义一个模式,Ansible首先通过status命令查看服务的状态,以此判断服务是否运行,如果通过status查看服务状态时没有响应,Ansible会尝试匹配ps命令的输出,当匹配到相应模式时,认为服务已经启动,否则认为服务没有启动;
  • enabled: 取值为yes或no,用来设置服务是否开机启动。
  1. sysctl

该模块的作用与Linux下的sysctl命令相似,用于控制Linux的内核参数。

  • name: 需要设置的参数;
  • value: 需要设置的值;
  • sysctl_file: sysctl.conf文件的绝对路径,默认路径是/etc/sysctl.conf;
  • reload: 该选项可以取值为yes或no,默认为yes,用于表示设置完成以后是否需要执行sysctl -p操作。
  1. mount

在远程服务器上挂在磁盘,当进行挂盘操作时,如果挂载点指定的路径不存在,将创建该路径。

  • name: 挂载点的路径;
  • state: 可以1取值为present, absent, mounted, unmounted, 其中, mountted与unmounted用来处理磁盘的挂载和卸载,并且会正确配置fstab文件,preset与absent只会设置fstab文件,,不会操作磁盘;
  • fstype: 指定文件系统类型,当state取值为present或mounted时,该选项为必填选项;
  • src: 挂载的设备
  1. synchronize

synchronizze模块是对rsync命令的封装,以便对常见的rsync任务进行处理既然synchronize模块是对rsync命令的封装,那么,我们也可以使用command模块调用rsync命令执行相应的操作。rsync是一个比较复杂的命令,相对来说,使用synchrronize简单一些。

  • src: 需要同步到远程服务器的文件或目录;
  • dest: 远程服务器保存的路径;
  • archive: 默认为yes, 表示在文件同步过程中是否启用压缩;
  • delete: 默认为no,当取值为yes时,表示删除dest中存在而src中不存在的文件。

线性更新服务器

Ansible为了提高部署的效率,默认使用了并发的方式对远程服务器进行更新。我们可以使用—forks参数控制并发的进程数,默认并发进程数为5.

  • serial选项
- name: test play
  hosts: webservers
  #一次只更新一台
  serial: 1
  #一次更新30%
  serial: "30%"
  #先更新1台然后更新5台,在更新10台,直至webservers组中所有服务器都更新完毕
  serial:
  - 1
  - 5
  - 10

任务委派功能

playbook中的每个play都指明了要对那些服务器执行那些操作。典型的用法是, Ansible在定义好的一组服务器上执行相同的操作。大部分情况下,这也是我们想要的功能。但是,在某些特殊情况下,对服务器进行批量操作的过程中需要对其中一台服务器进行特殊处理。此时,需要使用ANsible的任务委派功能。

例如: 在部署之前将一台服务器从负载均衡集群中删除;或在对一台服务器做改变前去掉相应dns记录。

-name take out of load balancer pool
command: /usr/bin/take_out_of_pool {{ inventory_hostname }}
delegate_to: 127.0.1

控制服务器执行操作

Ansible默认只对远程服务器执行操作,如果要在Ansible的控制服务器(Ansible进程所在服务器)上执行操作,可以使用delegate_to功能将任务委派到本地执行。除此之外,Ansible还提供了local_action选项明确指定在控制服务器执行操作。

tasks:
    - name: take out of load balancer pool
      local_action: command /usr/bin/take_out_of_pool {{ inventory_hostname }}

保证任务仅执行一次

考虑这样一个需求:有多台应用服务器运行在负载均衡后面,现在需要进行数据库迁移,应该如何实现,这个任务特殊之处在于,只需要在一台应用服务器上执行这个迁移操作,在任何一台应用服务器上执行迁移都可以这个时候,我们可以使用索引1和切片的方式访问组中的服务器,因此,可以像下面这样指定该组中的第一台服务器执行数据库迁移操作:

- command: /opt/application/migrate_db.py
  when: inventory_hostname = webservers[0]

通过索引的方式指定服务器,虽然能够满足这里的需求。但是,没有明确说明任务仅执行一次这个重点,其他人看到这段代码时,看到的是该组下的第一台服务器中执行迁移操作,,而不是任意一台服务器上执行一次数据迁移操作。为了让代码更加清晰明了,Ansible提供了run_once选项。

- command: /opt/application/migrate_db.py
  run_once: true

默认情况下,Ansible会选择在组中第一台服务器中执行run_once操作。因此,上面两种方式的实际效果是一样的,他们都会选择该组中的第一台服务器执行数据库迁移操作。如果要指定某一台服务器执行数据库迁移操作,可以结合delegate_to选项1实现

- command: /opt/application/migrate_db.py
  run_once: true
  deletegate_to: web01.example.org

高级循环结构

  • with_lines
    字典循环
    ```

users:
alice:
name: Alice Appleworth
telephone: 123-456-7890
bob:
name: Bob Bananarama
telephone: 987-654-3210

tasks:

- name: Print phone records
  debug:
    msg: "User {{ item.key }} is {{ item.value.name }} {{{ item.value.telephone }}}"
    with_dict:  "{{ user }}"

* with_fileglob
* with_first_found
* with_dict
* with_flattened
* with_indexed_items
* with_nested
列表循环
  • name: give users access to multiple databases
    mysql_user:
    name: “{{ item[0] }}”
    priv: “{{ item[1] }}.*:ALL”
    append_privs: yes
    password: “foo”
    with_nested:
     - ['alice', 'bob']
     - ['clientdb', 'employeedb', ''providerdb]
    
    ```
  • with_random_choice

随机选择某一项

- debug:
    msg: "{{ item }}"
    with_random_choice:
        - "go through the door"
        - "drink from the goblet"
        - "press the red button"
        - "do nothing"
  • with_sequence
    产生数字列表
    ```

    create some test users

  • user:
    name: “{{ item }}”
    state: present
    groups: “evens”
    with_sequence: start=0 end=32 format=testuser%02x
    ```
  • with_together
  • with_subelements

使用标签灵活控制Play的执行

使用Ansible部署服务器时,如果部署的任务比较复杂,那么,不可避免地导致任务列表变长。任务列表变长以后,错误处理就会比较麻烦。这时因为Ansible中的task是按顺序依次执行的。当我们重新指定修改过后的Playbook,Ansible会重新执行前面已经执行过task。如果中间某些步骤比较耗时(如下载一个很大的安装包),那么会显著增加复杂Playbook的调试时间。这个时候,我们希望跳过某些task仅执行Playbook中的部分task,或者明确指定运行Playbook中的部分task。在Ansible中,可以通过tags选项实现这个功能。

- name: install package
  yum: name={{ item }} state=installed
  with_items:
        - httpd
        - memcached
  tags:
        - packages
- name: uploading config file
  template: src=templates/src.j2 dest=/etc/foo.conf
  tags:
        - configuration
- name: be sure ntpd is running and enabled
  service: name=ntpd state=started enabled=yes
  tags: ntp

在这个例子中,我们使用tags为每个任务打上了一个标签。有了标签以后,可以使用ansible-playbook的—skip-tags选项与—tags选项指定需要执行1的task或者需要跳过的task。

#仅执行这个Playbook中前两个task
ansible-playbook example.yaml --tags "configuration,packages"
#忽略后一个task的功能
ansible-playbook example.yaml --skip-tags "ntp"

使用changed_when控制对changed字段的定义

当shell命令或模块运行时,它们往往会根据自己的判断报告是否对远程服务器进行了修改,然后通过返回值中的”changed”字段返回给我们。如果changed字段返回有误,则可以根据具体的场景修正changed字段的返回值。

tasks:
    - shell: /usr/bin/billybass --mode="take me to the river"
    register: bass_result
    changed_when: "bass_result.rc != 2"

使用failed_when控制对failed字段的定义

与changed字段类似,我们也可以通过自定义的方式判断命令是否执行成功。如果使用Ansible执行shell命令,默认情况下通过命令的返回码是否为0判断命令是否执行成功(这也是Linux命令的标准)。对于一些特殊的命令,无法通过返回码知道命令是否执行成功,那么,我们可以使用failed_when选项自定义命令执行失败的标准。

- name: this command prints FAILED when it fails
  command: /usr/bin/example-command -x -y -z
  register: command_result
  failed_when: "FAILED' in command_result.stderr"

0 评论