glcui 发表于 2018-7-29 09:44:45

自动化运维工具Ansible实战(六)playbook常用的模块

  (一)简述
  playbook的模块与在ansible命令行下使用的模块有一些不同。这主要是因为在playbook中会使用到一些facts变量和一些通过setup模块从远程主机上获取到的变量。有些模块没法在命令行下运行,就是因为它们需要这些变量。而且即使那些可以在命令行下工作的模块也可以通过playbook的模块获取一些更高级的功能。
  (二)常用的模块
  1,template模块
  在实际应用中,我们的配置文件有些地方可能会根据远程主机的配置的不同而有稍许的不同,template可以使用变量来接收远程主机上setup收集到的facts信息,针对不同配置的主机,定制配置文件。用法大致与copy模块相同。
  常见的参数如下:
backup:如果原目标文件存在,则先备份目标文件  
dest:目标文件路径
  
force:是否强制覆盖,默认为yes
  
group:目标文件属组
  
mode:目标文件的权限
  
owner:目标文件属主
  
src:源模板文件路径
  
validate:在复制之前通过命令验证目标文件,如果验证通过则复制
  
官方简单示例:
  
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode=0644
  
- template: src=/mytemplates/foo.j2 dest=/etc/file.conf owner=bin group=wheel mode="u=rw,g=r,o=r"
  
- template: src=/mine/sudoers dest=/etc/sudoers validate='visudo -cf %s'
  通过以下的例子来讲解template模块与copy模块的区别。
  有一个配置文件named.conf需要通过playbook的template模块来分发到主机组web1中,
下面是named.conf的简单配置:  
# cat named.conf
  
options {
  
listen-on port 53 {
  
127.0.0.1;
  
192.168.180.5;
  
};
  
listen-on-v6 port 53 { ::1; };
  
directory "/var/named";
  
dump-file "/var/named/data/cache_dump.db";
  
statistics-file "/var/named/data/named_stats.txt";
  
memstatistics-file "/var/named/data/named_mem_stats.txt";
  
};
  
zone "." IN {
  
type hint;
  
file "named.ca";
  
};
  
include "/etc/named.rfc1912.zones";
  
include "/etc/named.root.key";
  
zone "internal.example.com" IN {
  
type slave;
  
file "slaves/internal.example.com";
  
masters { 192.168.180.4; };
  
};
  
{ {group_names } }
  下面开始编写templated.yml的配置
# vim templated.yml  
- name: copy configure file to server web1 group
  
hosts: web1
  
tasks:
  
      - template: src=/etc/ansible/named.conf dest=/etc/named.conf
  
      - copy: src=/etc/ansible/named.conf dest=/etc/named2.conf
  执行结果如下:
# ansible-playbook templated.yml  
PLAY ********************************
  
TASK *******************************************************************
  
ok:
  
ok:
  
TASK ****************************************************************
  
ok:
  
ok:
  
TASK ********************************************************************
  
changed:
  
changed:
  
PLAY RECAP *********************************************************************
  
Server5                  : ok=3    changed=1    unreachable=0    failed=0
  
Server6                  : ok=3    changed=1    unreachable=0    failed=0
  去server5和server6上查看刚才拷贝的文件,发现name2.conf通过copy的没有任何改变,通过template模块拷贝的name.conf会有变量的更改。下面的是server5的name.conf
# cat /etc/named.conf  
options {
  
listen-on port 53 {
  
127.0.0.1;
  
192.168.180.5;
  
};
  
listen-on-v6 port 53 { ::1; };
  
directory "/var/named";
  
dump-file "/var/named/data/cache_dump.db";
  
statistics-file "/var/named/data/named_stats.txt";
  
memstatistics-file "/var/named/data/named_mem_stats.txt";
  
};
  
zone "." IN {
  
type hint;
  
file "named.ca";
  
};
  
include "/etc/named.rfc1912.zones";
  
include "/etc/named.root.key";
  
zone "internal.example.com" IN {
  
type slave;
  
file "slaves/internal.example.com";
  
masters { 192.168.180.4; };
  
};
  
{ {group_names }}
  2,set_fact模块
  set_fact模块可以自定义facts,这些自定义的facts可以通过template或者变量的方式在playbook中使用。如果你想要获取一个进程使用的内存的百分比,则必须通过set_fact来进行计算之后得出其值,并将其值在playbook中引用。

  #####下面是一个配置mysql innodb buffer># vim set_fact.yml  

  
- name: Configure MySQL
  
hosts: web1
  
tasks:
  
    - name: install MySql
  
      yum: name=mysql-server state=installed
  

  
    - name: Calculate InnoDB buffer pool size
  
      set_fact: innodb_buffer_pool_size_mb="{{ ansible_memtotal_mb / 2 }}"
  

  
    - name: Configure MySQL
  
      template: src=/etc/ansible/my.conf dest=/etc/my.cnf owner=root group=root mode=0644
  
      notify: restart mysql
  

  
    - name: Start MySQL
  
      service: name=mysqld state=started enabled=yes
  
handlers:
  
    - name: restart mysql
  
      service: name=mysqld state=restarted
  ####配置mysql的配置文件my.cnf
# vim /etc/ansible/my.conf  
# {{ ansible_managed }}
  

  
datadir=/var/lib/mysql
  
socket=/var/lib/mysql/mysql.sock
  
# Disabling symbolic-links is recommended to prevent assorted
  
security risks
  
symbolic-links=0
  
# Configure the buffer pool
  
innodb_buffer_pool_size = {{ innodb_buffer_pool_size_mb|int }}M
  

  
log-error=/var/log/mysqld.log
  
pid-file=/var/run/mysqld/mysqld.pid
#######查看执行结果  
# ansible-playbook set_fact.yml
  
PLAY *********************************************************
  
TASK *******************************************************************
  
ok:
  
ok:
  
TASK ***********************************************************
  
ok:
  
ok:
  
TASK ***************************************
  
ok:
  
ok:
  
TASK *********************************************************
  
ok:
  
ok:
  
TASK *************************************************************
  
fatal: : FAILED! => {"changed": false, "failed": true, "msg": "MySQL Daemon failed to start.\nStarting mysqld:\r\n"}
  
fatal: : FAILED! => {"changed": false, "failed": true, "msg": "MySQL Daemon failed to start.\nStarting mysqld:\r\n"}
  
      to retry, use: --limit @/etc/ansible/set_fact.retry
  
PLAY RECAP *********************************************************************
  
Server5                  : ok=4    changed=0    unreachable=0    failed=1
  
Server6                  : ok=4    changed=0    unreachable=0    failed=1
  在server5和server6服务器上查看该配置
# vim my.cnf  
# Ansible managed
  

  
datadir=/var/lib/mysql
  
socket=/var/lib/mysql/mysql.sock
  
# Disabling symbolic-links is recommended to prevent assorted
  
security risks
  
symbolic-links=0
  
# Configure the buffer pool
  
innodb_buffer_pool_size = 934M
  

  
log-error=/var/log/mysqld.log
  
pid-file=/var/run/mysqld/mysqld.pid
  3,pause模块
  pause模块是在playbook执行的过程中暂停一定时间或者提示用户进行某些操作
常用参数:  
minutes:暂停多少分钟
  
seconds:暂停多少秒
  
prompt:打印一串信息提示用户操作
  简单的实例:
# vim pause.yml  
- name: wait on user input
  
   pause: prompt="Warning! Detected slight issue. ENTER to continue CTRL-C a to quit"
  
- name: timed wait
  
pause: seconds=30
  4,wait_for模块
  在playbook的执行过程中,等待某些操作完成以后再进行后续操作
常用参数:  
connect_timeout:在下一个任务执行之前等待连接的超时时间
  
delay:等待一个端口或者文件或者连接到指定的状态时,默认超时时间为300秒,在这等待的300s的时间里,wait_for模块会一直轮询指定的对象是否到达指定的状态,delay即为多长时间轮询一次状态。
  
host:wait_for模块等待的主机的地址,默认为127.0.0.1
  
port:wait_for模块待待的主机的端口
  
path:文件路径,只有当这个文件存在时,下一任务才开始执行,即等待该文件创建完成
  
state:等待的状态,即等待的文件或端口或者连接状态达到指定的状态时,下一个任务开始执行。当等的对象为端口时,状态有started,stoped,即端口已经监听或者端口已经关闭;当等待的对象为文件时,状态有present或者started,absent,即文件已创建或者删除;当等待的对象为一个连接时,状态有drained,即连接已建立。默认为started
  
timeout:wait_for的等待的超时时间,默认为300秒
#####示例  
# cat /etc/ansible/wait_for.yml
  
- name: create task
  
hosts: 192.168.180.2
  
tasks:
  

  
      - wait_for: port=8080 state=started   #等待8080端口已正常监听,才开始下一个任务,直到超时
  
      - wait_for: port=8081 delay=10    #等待8000端口正常监听,每隔10s检查一次,直至等待超时
  
      - wait_for: host=0.0.0.0 port=8000 delay=10 state=drained    #等待8000端口直至有连接建立
  
      - wait_for: host=0.0.0.0 port=8000 state=drained exclude_hosts=10.2.1.2,10.2.1.3    #等待8000端口有连接建立,如果连接来自10.2.1.2或者10.2.1.3,则忽略。
  
      - wait_for: path=/tmp/foo    #等待/tmp/foo文件已创建
  
      - wait_for: path=/tmp/foo search_regex=completed    #等待/tmp/foo文件已创建,而且该文件中需要包含completed字符串
  
      - wait_for: path=/var/lock/file.lock state=absent    #等待/var/lock/file.lock被删除
  
      - wait_for: path=/proc/3466/status state=absent      #等待指定的进程被销毁
  
      - local_action: wait_for port=22 host="{{ ansible_ssh_host | default(inventory_hostname) }}" search_regex=OpenSSH delay=10    #等待openssh启动,10s检查一次
  执行过程为:
# ansible-playbook wait_for.yml  
PLAY *************************************************************
  
TASK *******************************************************************
  
ok:
  
TASK ****************************************************************
  
ok:
  
TASK ****************************************************************
  
ok:
  
TASK ****************************************************************
  
ok:
  
TASK ****************************************************************
  
ok:
  
TASK ****************************************************************
  
ok:
  
TASK ****************************************************************
  
ok:
  
TASK ****************************************************************
  
ok:
  
TASK ****************************************************************
  
ok:
  
TASK ****************************************************************
  
ok:
  
PLAY RECAP *********************************************************************
  
192.168.180.2            : ok=10   changed=0    unreachable=0    failed=0
  5,assemble模块
  用于组装文件,即将多个零散的文件,合并一个大文件
常用参数:  
src:原文件(即零散文件)的路径
  
dest:合并后的大文件路径
  
group:合并后的大文件的属组
  
owner:合并后的大文件的属主
  
mode:合并后的大文件的权限
  
validate:与template的validate相同,指定命令验证文件
  
ignore_hidden:组装时,是否忽略隐藏文件,默认为no,该参数在2.0版本中新增
  示例:
# vim assemble.yml  
- hosts: web1
  
tasks:
  
    - name: Make a Directory in /opt
  
      file: path=/opt/sshkeys state=directory owner=root group=root mode=0700
  
    - name: Copy SSH keys over
  
      copy: src=playbook/{{ item }}.pub dest=/opt/sshkeys/{{ item }}.pub owner=root group=root mode=0600
  
      with_items:
  
      - dan
  
      - kate
  
      - mal
  
    - name: Make the root users SSH config directory
  
      file: path=/root/.ssh state=directory owner=root group=root mode=0700
  
    - name: Build the authorized_keys file
  
      assemble: src=/opt/static/ dest=/root/.ssh/authorized_keys owner=root group=root mode=0700   #将/opt/sshkeys目录里所
  
有的文件合并到/root/.ssh/authorized_keys一个文件中
  ######执行过程
# ansible-playbook assemble.yml  
PLAY ********************************************************************
  
TASK *******************************************************************
  
ok:
  
ok:
  
TASK ************************************************
  
ok:
  
ok:
  
TASK ******************************************************
  
failed: (item=mal) => {"failed": true, "item": "mal", "msg": "Unable to find 'playbook/mal.pub' in expected paths."}
  
failed: (item=kate) => {"failed": true, "item": "kate", "msg": "Unable to find 'playbook/kate.pub' in expected paths."}
  
failed: (item=dan) => {"failed": true, "item": "dan", "msg": "Unable to find 'playbook/dan.pub' in expected paths."}
  
failed: (item=kate) => {"failed": true, "item": "kate", "msg": "Unable to find 'playbook/kate.pub' in expected paths."}
  
failed: (item=dan) => {"failed": true, "item": "dan", "msg": "Unable to find 'playbook/dan.pub' in expected paths."}
  
failed: (item=mal) => {"failed": true, "item": "mal", "msg": "Unable to find 'playbook/mal.pub' in expected paths."}
  
      to retry, use: --limit @/etc/ansible/assemble.retry
  
PLAY RECAP *********************************************************************
  
Server5                  : ok=2    changed=0    unreachable=0    failed=1
  
Server6                  : ok=2    changed=0    unreachable=0    failed=1
  6,add_host模块
  在playbook执行的过程中,动态的添加主机到指定的主机组中
常用参数:  
groups:添加主机至指定的组
  
name:要添加的主机名或IP地址
  示例
# vim add_host.yml  
- name: add a host to group webservers
  
hosts: web1
  
tasks:
  
    - add_host name={{ ip_from_ec2 }} group=web1 foo=23    #添加主机到webservers组中,主机的变量foo的值为42
  7,group_by模块
  playbook执行的过程中,动态的创建主机组
  示例:
- name: Create operating system group  
hosts: all
  
tasks:
  
    - group_by: key=os_{{ ansible_distribution }}         #在playbook中设置一个新的主机组
  
- name: Run on CentOS hosts only
  
hosts: os_CentOS
  
tasks:
  
    - name: Install Apache
  
      yum: name=httpd state=latest
  
- name: Run on Ubuntu hosts only
  
hosts: os_Ubuntu
  
tasks:
  
    - name: Install Apache
  
      apt: pkg=apache2 state=latest
  执行过程:
root@Monitor ansible]# ansible-playbook group_by.yml  
PLAY *******************************************
  
TASK *******************************************************************
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
TASK ****************************************************************
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
PLAY ************************************************
  
TASK *******************************************************************
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
ok:
  
TASK **********************************************************
  
changed:
  
changed:
  
ok:
  
ok:
  
ok:
  
ok:
  
changed:
  8,debug模块
  调试模块,用于在调试中输出信息
常用参数:  
msg:调试输出的消息
  
var:将某个任务执行的输出作为变量传递给debug模块,debug会直接将其打印输出
  
verbosity:debug的级别
  示例:
# vim debug.yml  
# Example that prints the loopback address and gateway for each host- debug: msg="System {{ inventory_hostname }} has uuid
  
{{ ansible_product_uuid }}"
  
- debug: msg="System {{ inventory_hostname }} has gateway {{ ansible_default_ipv4.gateway }}"
  
      when: ansible_default_ipv4.gateway is defined
  
- shell: /usr/bin/uptime
  
      register: result
  
- debug: var=result verbosity=2    #直接将上一条指令的结果作为变量传递给var,由debug打印出result的值
  
- name: Display all variables/facts known for a host
  
      debug: var=hostvars verbosity=4
  9,fail模块
  用于终止当前playbook的执行,通常与条件语句组合使用,当满足条件时,终止当前play的运行。可以直接由failed_when取代。
选项只有一个:  
msg:终止前打印出信息
  示例:
# vim fail.yml  
- fail: msg="The system may not be provisioned according to the CMDB status."
  
when: cmdb_status != "to-be-staged"
  备注:以后会继续修改有不妥之处
页: [1]
查看完整版本: 自动化运维工具Ansible实战(六)playbook常用的模块