ansible实用模块

简介

ansible是基于 paramiko 开发的,并且基于模块化工作,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。ansible不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的。同时此文章记录在项目使用playbook编写中用到的模块,以便后续作为知识库,也为正在接触ansible的同学们提供一个入学指南,此文章定时更新。

ansible 帮助使用
bash 复制代码
# 查找相应的模块
$ ansible-doc -l module

# 查看ping模块使用方式
$ ansible-doc ping
ansible如何执行一个模块?

使用ansible的-vvv或-vvvv分析执行过程。以下是一个启动远程10.20.43.25上ping模块的执行过程分析。

复制代码
# 读取相应的配置文件和主机清单,然后开始执行对应的处理程序。
Using /etc/ansible/ansible.cfg as config file
META: ran handlers

# 建立连接,获取被控节点当前用户的家目录,用于存放稍后的临时任务文件,此处返回值为/root。
<10.20.43.25> ESTABLISH SSH CONNECTION FOR USER: None
<10.20.43.25> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e558b2d4c4 10.20.43.25 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<10.20.43.25> (0, '/root\n', '')

# 再次建立连接,在远端创建临时任务文件的目录,临时目录由配置文件中的remote_tmp指令控制。

<10.20.43.25> ESTABLISH SSH CONNECTION FOR USER: None
<10.20.43.25> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e558b2d4c4 10.20.43.25 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1659340813.87-20445-27992807493154 `" && echo ansible-tmp-1659340813.87-20445-27992807493154="` echo /root/.ansible/tmp/ansible-tmp-1659340813.87-20445-27992807493154 `" ) && sleep 0'"'"''
<10.20.43.25> (0, 'ansible-tmp-1659340813.87-20445-27992807493154=/root/.ansible/tmp/ansible-tmp-1659340813.87-20445-27992807493154\n', '')

# 尝试去发现被控端的python 解释器。
<10.20.43.25> Attempting python interpreter discovery
<10.20.43.25> ESTABLISH SSH CONNECTION FOR USER: None
<10.20.43.25> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e558b2d4c4 10.20.43.25 '/bin/sh -c '"'"'echo PLATFORM; uname; echo FOUND; command -v '"'"'"'"'"'"'"'"'/usr/bin/python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.6'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.5'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python2.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python2.6'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/libexec/platform-python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/bin/python3'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python'"'"'"'"'"'"'"'"'; echo ENDFOUND && sleep 0'"'"''
<10.20.43.25> (0, 'PLATFORM\nLinux\nFOUND\n/usr/bin/python\n/usr/bin/python2.7\n/usr/libexec/platform-python\n/usr/bin/python\nENDFOUND\n', '')


# 将执行的模块的py文件拷贝到被控端的临时文件中,并使用sftp将任务文件传输到被控端节点上。
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/ping.py
<10.20.43.25> PUT /root/.ansible/tmp/ansible-local-204372QA8oB/tmpgYdA9A TO /root/.ansible/tmp/ansible-tmp-1659340813.87-20445-27992807493154/AnsiballZ_ping.py
<10.20.43.25> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e558b2d4c4 '[10.20.43.25]'
[WARNING]: sftp transfer mechanism failed on [10.20.43.25]. Use ANSIBLE_DEBUG=1 to see detailed information
<10.20.43.25> SSH: EXEC scp -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e558b2d4c4 /root/.ansible/tmp/ansible-local-204372QA8oB/tmpgYdA9A '[10.20.43.25]:/root/.ansible/tmp/ansible-tmp-1659340813.87-20445-27992807493154/AnsiballZ_ping.py'

# 建立连接,设置远程任务文件其所有者有可执行权限。
<10.20.43.25> ESTABLISH SSH CONNECTION FOR USER: None
<10.20.43.25> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e558b2d4c4 10.20.43.25 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1659340813.87-20445-27992807493154/ /root/.ansible/tmp/ansible-tmp-1659340813.87-20445-27992807493154/AnsiballZ_ping.py && sleep 0'"'"''
<10.20.43.25> (0, '', '')

# 建立连接,执行任务,执行完任务立即删除临时任务文件,并返回收集到的信息或者结果给到控制端。至此ping模块任务结束,关闭共享连接。
<10.20.43.25> ESTABLISH SSH CONNECTION FOR USER: None
<10.20.43.25> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e558b2d4c4 -tt 10.20.43.25 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1659340813.87-20445-27992807493154/AnsiballZ_ping.py && sleep 0'"'"''
<10.20.43.25> (0, '\r\n{"invocation": {"module_args": {"data": "pong"}}, "ping": "pong"}\r\n', 'Shared connection to 10.20.43.25 closed.\r\n')
<10.20.43.25> ESTABLISH SSH CONNECTION FOR USER: None
<10.20.43.25> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e558b2d4c4 10.20.43.25 '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1659340813.87-20445-27992807493154/ > /dev/null 2>&1 && sleep 0'"'"''
<10.20.43.25> (0, '', '')
include_vars模块

当从其它项目的变量文件引入当前项目时,我们可以采用include_vars加载。

yaml 复制代码
- hosts: all
  gather_facts: false
  vars:
    iaas_globals_yml: /etc/iaas/globals.yml
  tasks:
    - name: "include {{ iaas_globals_yml }} file"
      include_vars:
        file: "{{ iaas_globals_yml }}"
      tags:
        - always
group_by模块

创建一个临时的主机组,以便后续执行playbook按照这个组执行所有的主机。

yaml 复制代码
---
- hosts: all
  gather_facts: false
  tasks:
  - name: 定义一个名为new_hosts_group的主机组
    group_by:
      key: new_hosts_group

  - name: 输出执行节点主机组变量信息,发现动态加的new_hosts_group组生效
    debug: msg=new_hosts_group组{{ hostvars[inventory_hostname]['groups']['new_hosts_group'] }}
    connection: local
    run_once: true

  - name: 查看新定义的主机组
    debug: msg="{{ inventory_hostname }} 属于主机组new_hosts_group"
    when:
      - inventory_hostname in groups['new_hosts_group']
add_host模块

在playbook中,需要动态把主机加到主机组,可以通过在playbook的执行器内存中添加一个主机(如果组不存在则自动创建)。

yaml 复制代码
---
- hosts: all
  gather_facts: false
  tasks:
  - name: 在playbook的内存中创建一个主机(如果组不存在则自动创建)
    add_host:
      name: "{{ item }}"
      groups: new_hosts_group
    changed_when: false
    with_items: "{{ groups['nfs'] }}"

  - name: 从新建立的new_hosts_group组的主机执行ping
    ping:
    when: inventory_hostname in groups['new_hosts_group']
block 和 delegate_to

在playbook中,需要把多个play进行执行一次,才能进行执行下一个play,可以采用block。如另有只需要在本地主机执行的话,可以采用delegate_to。

yaml 复制代码
- hosts: all
  gather_facts: no
  tasks:
  - block:
    - name: 从ansible变量中定义一个文本数据,拷贝到result文件
      copy:
        content: |
          hostip={{ inventory_hostname }}
        dest: "{{ playbook_dir }}/result"
    - name: 从远端服务器拷贝文件到执行端
      fetch:
        src: /root/install
        dest: /tmp
    delegate_to: localhost
git模块

在playbook中,很多时候需要对git repo项目进行拉取操作,而进行项目的变更。

yaml 复制代码
---                                                                                                           
- hosts: localhost
  vars:
    base_dir:  /root/system_env
    gitlab_url: http://172.17.2.183:11080/edge
    system_name: guangzhou_edge
    system_tag_name: guangzhou_edgeV1
    system_dir: "{{ base_dir }}/{{ system_name }}"
    ssh_key: /root/.ssh/id_rsa
  gather_facts: false
  tasks:
    - name: 尝试在/root/system_env/guangzhou_edge目录下克隆或者更新http://172.17.2.183:11080/edge/guangzhou_edge.git项目。
      git:
        repo: "{{ gitlab_url }}/{{ system_name }}.git"
        dest: "{{ system_dir }}"
        key_file: "{{ ssh_key }}"
        update: true

    - name: 尝试在/root/system_env/guangzhou_edgeV1目录下检出guangzhou_edgeV1项目,但不更新。
      git:
        repo: "{{ gitlab_url }}/{{ system_name }}.git"
        dest: "{{ base_dir }}/{{ system_tag_name}}"
        version: "{{ system_tag_name }}"
        clone: false
        update: false
      register: checkout_res

    - name: 当不能检出项目时,/root/system_env/guangzhou_edge/ 复制为 /root/system_env/guangzhou_edgeV1
      copy:
        src: "{{ system_dir }}/"
        dest: "{{ base_dir }}/{{ system_tag_name}}"
      when: not checkout_res.before == checkout_res.after

    - name: 再次尝试检出/root/system_env/guangzhou_edgeV1项目,项目guangzhou_edgeV1 并更新
      git:
        repo: "{{ gitlab_url }}/{{ system_name }}.git"
        dest: "{{ base_dir }}/{{ system_tag_name}}"
        version: "{{ system_tag_name }}"
        force: true
lineinfile模块

在playbook中,很多时候需要对项目的文件内容进行修改操作,但要确保每次修改具有幂等性,我们可以采用lineinfile。

yaml 复制代码
---
- hosts: all
  gather_facts: false
  vars:
    system_name: edge
  tasks:
  - block:
    - name: 添加hostvars变量的内容到lineinfile.txt1文件,文件不存在则创建(幂等)
      lineinfile:
        path: "{{ playbook_dir }}/lineinfile.txt"
        line: "{{ hostvars }}"
        create: yes

    - name: 修改lineinfile.txt文件的内容,在文件的头部增加一行(不具有幂等性)。
      lineinfile:
        path: "{{ playbook_dir }}/lineinfile.txt"
        line: "{{ item }}"
        insertbefore: "BOF"
      when: system_name == "edge" or system_name == "iaas"
      with_items:
        - "localhost ansible_python_interpreter=/usr/bin/python\n"
    - name: 正则匹配Listen开头的内容,如果有或者没有Listen开头的内容,都在#Listen后面增加或者修改为Listen 8080(幂等)
      lineinfile:
        path: "{{ playbook_dir }}/lineinfile.txt"
        regexp: '^Listen '
        insertafter: '^#Listen '
        line: Listen 8080
    run_once: true
    delegate_to: localhost
相关推荐
风清再凯7 小时前
自动化工具ansible,以及playbook剧本
运维·自动化·ansible
IT乌鸦坐飞机7 小时前
ansible部署数据库服务随机启动并创建用户和设置用户有完全权限
数据库·ansible·centos7
遇见火星13 天前
如何使用Ansible一键部署MinIO集群?
ansible
粥周粥13 天前
ANSIBLE
ansible
码农101号13 天前
Linux中ansible模块补充和playbook讲解
linux·运维·ansible
码农101号13 天前
Linux的Ansible软件基础使用讲解和ssh远程连接
ansible
烟雨书信15 天前
ANSIBLE运维自动化管理端部署
运维·自动化·ansible
碎碎-li15 天前
ANSIBLE(运维自动化)
运维·自动化·ansible
@donshu@18 天前
Linux运维-ansible-python开发-获取inventroy信息
linux·运维·ansible
Kendra91921 天前
Ansible
ansible