ansible 常用模块

1 command 模块

默认模块,不指定 -m 参数时,使用的就是 command 模块;

但 "<", ">", "|", and "&" 操作都不可以,当然,也不支持管道;

缺点:不支持管道,没法批量执行命令;

示例:

ansible 192.168.2.20 -m command -a 'ifconfig'  //联系某一台主机执行ifconfig命令
ansible all -m command -a 'ifconfig'  //联系主机清单里所有的主机执行ifconfig命令
ansible all -a  'ifconfig'  //command模块是默认的,所以可以省略
ansible websrvs -m command -a 'uptime'  # 主机清单中 websrvs 组执行命令 uptime

 

2 shell 模块

在远程命令通过/bin/sh 来执行;所以,在终端输入的各种命令方式,都可以使用。

示例:

ansible websrvs -m shell -a 'echo $HOSTNAME'    # 如果是 command 模块:这里的echo命令是在当前 shell中运行显示出来了,而不是在远程管理主机上

对 shell 模块的使用可以分成两块:

1) 如果待执行的语句少,可以直接写在一句话中: 

示例:

ansible websrvs -m shell -a 'source ~/.bash_profile && df -h'

  

2) 如果在远程待执行的语句比较多,可写成一个脚本,通过 copy 模块传到远端,然后再执行;但这样就又涉及到两次 ansible 调用;对于这种需求,ansible 已经为我们考虑到了,script 模块就是干这事的;

 

3 script 模块

可以将本地脚本复制到远程主机并运行之。 

ansible websrvs -m script -a '/tmp/test.sh'    # 本地的脚本在远程主机上运行,本地不需要给执行权限

 

4 user 模块

远程主机用户管理

-a 'name= uid= state={present|absent} system='  //name:指明创建的用户的名字

 示例:

给websrvs中主机添加用户hacluster
    # ansible websrvs -m user -a 'name=hacluster state=present'

给websrvs中的主机删除用户hacluster
    # ansible websrvs -m user -a 'name=hacluster state=absent'

 

5 group 模块

-a 'name= gid= state= system='

 示例:

ansible websrvs -m group -a 'name=mysql state=present system=yes'     # 创建 mysql 系统组

  

 6 cron 模块

-a 'name= minute= hour= day= month= weekday= job= user= state='

 示例:

ansible all -m cron -a 'name="sync time from ntpserver" minute="*/10" job="/sbin/ntpdate 192.168.2.50 &> /dev/null"'  //所有主机每10分钟同步一下时间
ansible websrvs -a 'crontab -l'    // 查看周期性任务
ansible websrvs -m cron -a 'name="sync time" state=absent'   // 删除时,只要指明name就可以

 

7 copy 模块

实现主控端向目标主机拷贝文件,类似 scp 功能

-a 'dest= src= mode= owner= group='  //src:定义本地源文件路径 dest:定义远程目标文件路径 content= : 取代src=,表示直接用此处指定的信息生成为目标文件内容

 示例:

ansible websrvs -m copy -a 'src="/etc/fstab" dest="/tmp/" mode=644 owner=mysql group=mysql'

  

 8 file 模块

设定文件属性

-a 'path= mode= owner= group= state={directory|link|present|absent} src='  //path:指定文件路径,可以使用name或dest来替换;src:指明源文件;path:指名符号链接文件路径

 示例:

ansible all -m file -a 'path=/tmp/testdir state=directory'  //远程主机上创建目录
ansible all -m file -a 'path=/tmp/fstab.symlink state=link src=/tmp/fstab.tmp force=yes'  
    //远程主机上创建符号链接文件;如果源文件不存在可以使用force=yes或true来强制创建,只是源文件不存在

  

9 ping 模块

ping 模块检查网络连通性

 示例:

使用 ping 检查 websrvs 组 或者 ansible 节点的连通性。
ansible websrvs -m ping

 

10 yum 模块

软件包管理

-a 'name= state={present|absent|latest}'  //name:指明要安装的程序包,可以带上版本号

示例:

ansible websrvs -m yum -a 'name=nginx state=latest'  //websrvs中的主机安装nginx
ansible websrvs -m yum -a 'name=nginx state=absent'  //卸载nginx

  

11 service 模块

远程主机系统服务管理。

-a 'name= state={started|stopped|restarted} enabled='  //enabled:是否开机自启动,取值为true或false

 示例:

ansible websrvs -m service -a 'name=nginx state=started enabled=yes'

  

12 setup 模块

收集远程主机的facts

每个被管理节点在接收并运行管理命令之前,会将自己主机的相关信息,如操作系统版本、IP 地址等报告给远程的 ansible 主机

示例:

ansible websrvs -m setup  //获取远程主机的所支持的所有facts

  

13 stat 模块

获取远程文件信息

-a 'path='

示例:

ansible websrvs -m stat -a 'path=/etc/hosts'

  

14 get_url 模块

块实现远程主机下载指定 url 到本地,支持 sha256sum 文件校验。

-a "url= dest= mode= force=yes"  
  // 如果 force=yes,当下载文件时,如果所下的内容和原目录下的文件内容不一样,则替换原文件,如果一样,就不下载了。
  // 如果 force=no,则仅在目标不存在时才下载文件。 一般来说,只有小型本地文件才应该为“是”。 在 0.6 之前,该模块表现为默认为“是”。

示例:

下载 epel-release-latest-7.noarch.rpm 到主机清单中的/tmp/目录下:
ansible websrvs -m get_url -a "url=https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm dest=/tmp/ mode=440 force=yes"

  

15 sysctl 模块

远程主机 sysctl 配置。

示例:

开启路由转发功能:
ansible websrvs -m sysctl -a 'name=net.ipv4.ip_forward value=1 reload=yes'

  

playbook 应用

示例一:websrvs主机创建nginx用户和nginx组,dbsrvs主机复制文件

- hosts: websrvs
  remote_user: root
  tasks:
  - name: create nginx group
    group: name=nginx system=yes gid=208
  - name: reate nginx user
    user: name=nginx uid=208 group=208 system=yes

- hosts: dbsrvs
  remote_user: root
  tasks:
  - name: copy file to dbsrvs
    copy: src=/etc/inittab dest=/tmp/inittab.ans
# ansible-playbook nginx.yaml

 

示例二:安装 httpd 服务,并且将本地的配置文件复制到远程主机,然后运行 httpd 服务;当配置文件修改时使用 handlers

- hosts: websrvs
  remote_user: root
  tasks:
  - name: install httpd service
    yum: name=httpd state=latest
  - name: install configuration file for httpd
    copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify:
        - restart httpd
  - name: start httpd service
    service: name=httpd state=started enabled=true
  handlers:
  - name: restart httpd
    service: name=httpd state=restarted
# ansible-playboot httpd.yaml

修改配置文件后再次执行上面命令,会触发 handlers 里面的模块运行。

 

示例三:变量测试,以上面例子为例

- hosts: websrvs
  remote_user: root
  vars:    // 添加两个变量
  - package: httpd
  - service: httpd
  tasks:
  - name: install httpd service
    yum: name={{ package }} state=latest    # 变量替换使用 {{}}
  - name: install configuration file for httpd
    copy: src=/etc/httpd/conf/httpd.conf dest=/etc/httpd/conf/httpd.conf
    notify:
        - restart httpd
  - name: start httpd service
    service: name={{ service }} state=started enabled=true
  handlers:
  - name: restart httpd
    service: name={{ service }} state=restarted

有些变量我们可以不用定义,直接使用的,比如ansible facts中的变量:

# ansible node1 -m setup  //找一个facts,比如ansible_all_ipv4_addresses
- hosts: websrvs
  remote_user: root
  tasks:
  - name: copy file
    copy: content={{ ansible_all_ipv4_addresses }} dest=/tmp/vars.ans  //直接调用,无需定义

我们还可以使用Inventory中的主机变量:

在hosts文件中添加主机变量:

[websrvs]
192.168.2.20 testvar="2.20"  //各添加了 testvar 变量
192.168.2.40 testvar="2.40"

下面我们来调用:

- hosts: websrvs
  remote_user: root
  tasks:
  - name: copy file
    copy: content={{ ansible_all_ipv4_addresses }},{{ testvar }} dest=/tmp/vars.ans  // 调用testvar变量,虽然变量名都是同一个,但内容在各主机都不一样

  

示例四:不基于密钥认证的方式联系远程主机

我们如果不使用基于密钥的方式连接各主机,可以在hosts文件中定义账号密码的方式实现:

[websrvs]
192.168.2.20 ansible_ssh_user=root ansible_ssh_pass=ckh  //账号和密码

 

示例五:条件测试 when

- hosts: all
  remote_user: root
  vars:
    - username: user10
  tasks:
    - name: create {{ username }} user
      user: name={{ username }}
      when: ansible_fqdn == "node1.ckh.com"  //当 facts 是 node1.ckh.com 时,才会添加用户

  

示例六:迭代

重复同类task时使用

调用:item

定义循环列表:with_items

with_items:
 -  apache
 -  php
 -  mysql-server

注意:with_items中的列表值也可以是字典,但引用时要使用item.KEY:

with_items:
  - {name: apache, conf: conffiles/httpd.conf}
  - {name: php, conf: conffiles/php.ini}
  - {name: mysql-server,conf: conffiles/my.cnf}

 

示例七:Templates 应用

首先,我们将本地配置文件修改成一个模板:

比如我们修改 httpd.conf 配置文件中的这几项:
Listen {{ http_port }}
maxClients {{ maxClients }}
ServerName {{ ansible_fqdn }}

将上面修改的文件作为模板,就放在/root/templates/httpd.conf.j2

yaml文件中修改:

- hosts: websrvs
  remote_user: root
  vars:
  - package: httpd
  - service: httpd
  tasks:
  - name: install httpd service
    yum: name={{ package }} state=latest
  - name: install configuration file for httpd
    template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf    // 指定模板的位置
    notify:
        - restart httpd
  - name: start httpd service
    service: name={{ service }} state=started enabled=true
  handlers:
  - name: restart httpd
    service: name={{ service }} state=restarted

然后在/etc/ansible/hosts中给主机定义变量:

[websrvs]
192.168.2.11 http_port=80
192.168.2.12 http_port=8080
192.168.2.13 http_port=8090

还有一个变量 ServerName 是 facts 中的 ansible_fqdn,所以模板中直接调用就可以。

 

示例八:Tags 示例

在palybook可以为某个或某些任务定义一个标签,在执行此 playbook 时,通过为 ansible-playbook 命令使用 --tags 选项能实现仅运行指定的 tasks 而非所有的

- hosts: websrvs
  remote_user: root
  vars:
  - package: httpd
  - service: httpd
  tasks:
  - name: install httpd service
    yum: name={{ package }} state=latest
  - name: install configuration file for httpd
    template: src=/root/httpd.conf dest=/etc/httpd/conf/httpd.conf
    tags:    // 增加 tags
      - conf    
    notify:
        - restart httpd
  - name: start httpd service
    service: name={{ service }} state=started enabled=true
  handlers:
  - name: restart httpd
    service: name={{ service }} state=restarted
# ansible-playbook httpd.yaml --tags="conf"    // 执行命令的时候加上 --tags

Tags 还有特殊 tags:always

 

示例九:roles不同角色执行不同任务 

roles注意点:
  (1) 目录名同角色名
  (2) 目录结构有固定格式:
    files:静态文件
    templates:Jinjia2 模板文件
    tasks:至少有 main.yml 文件,定义各 tasks
    handlers:至少有一个 main.yml 文件,定义各 handlers
       vars:至少有一个 mail.yml 文件,定义变量
       meta:定义依赖关系等信息
  (3)
    site.yml 中定义 playbook,额外也可以有其他的 yml 文件

创建 roles 所需目录:

# mkdir ansible_playbooks
# mkdir ansible_playbooks/roles/{websrvs,dbsrvs}/{tasks,files,templates,meta,handlers,vars} -pv  // 这里 定义两个 role

tasks/main.yml

- name: install httpd package
  yum: name=httpd
- name: install configuration file
  copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf
  tags:
  - conf
  notify:  //这边定义了一个通知,调用处理器handlers
  - restart httpd
- name: start httpd
  service: name=httpd state=started

handlers/main.yml 

- name: restart httpd
  service: name=httpd state=restarted

vars/main.yml

httpd_port: 80
maxClient: 200

在 roles 目录之外创建一个 site.yml 

site.yml

- hosts: 192.168.2.20
  remote_user: root
  roles:
  - websrvs

- hosts: 192.168.2.40
  remote_user: root
  roles:
  - dbsrvs

- hosts: 192.168.2.80
  remote_user: root
  roles:
  - websrvs
  - dbsrvs
# ansible-playbook site.yml

  

示例十:使用 Playbook 批量部署多台 LAMP 环境

1. 在 ansible 服务器上安装 lamp 环境

yum install httpd php php-mysql mariadb-server -y

修改 httpd 配置文件:/etc/httpd/conf/httpd.conf

Listen 8080

添加测试页:index.php

<?php
    phpinfo();
?>

修改 mariadb 配置文件:/etc/my.cnf

datedir = /mydata/data
innodb_file_per_table = On
skip_name_resolve = On

执行 mysql 安全脚本:删除匿名用户,给root设置密码等。

启动 mariadb、httpd 并测试。

测试成功后进行 ansible 的配置。

2. ansible 定义 主机清单组

[websrvs]
192.168.2.11
192.168.2.12

3 创建 roles 相关的文件

mkdir /etc/ansible/lamp/roles/{prepare,httpd,mysql,php}/{tasks,files,handlers,templates,vars,meta,default} -pv

4 将上面搭建好的 lamp 环境的 httpd 和 mysql 的配置文件拷贝到对应目录下

cd /etc/ansible
cp /etc/httpd/conf/httpd.conf lamp/roles/httpd/files/
cp /etc/my.cnf lamp/roles/mysql/files/
cp /var/www/html/index.php lamp/roles/httpd/files/

5 写 prepare(前期准备)角色的 playbooks

vim lamp/roles/prepare/tasks/main.yml:

- name: delete yum config
  shell: rm -rf /etc/yum.repos.d/*
- name: provide yumrepo file
  shell: wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
- name: clean the yum repo
  shell: yum clean all
- name: clean the iptables
  shell: iptables -F

6 构建 httpd 的任务

/etc/ansible/lamp/roles/httpd/tasks/main.yml

- name: install httpd package
  yum: name=httpd state=latest
- name: provide test page
  copy: src=index.php dest=/var/www/html/index.php force=yes
- name: delete httpd.conf
  shell: rm -rf /etc/httpd/conf/httpd.conf
- name: install configuration file
  copy: src=httpd.conf dest=/etc/httpd/conf/httpd.conf force=yes
  notify:
    - restart httpd

/etc/ansible/lamp/roles/httpd/handlers/main.yml

- name: restart httpd
  service: name=httpd state=restarted

7 构建 mariadb 服务

/etc/ansible/lamp/roles/mysql/tasks/main.yml

- name: install mysql
  yum: name="mariadb-server" state="latest"
- name: create mysql group
  group: name=mysql state=present system=yes
- name: create mysql user
  user: name=mysql group=mysql state=present system=yes
- name: mkdir the directory
  shell: mkdir -p /mydata/data
- name: chage the owner
  shell: chown -R mysql.mysql /mydata
- name: delete my.cnf
  shell: rm -rf /etc/my.cnf
- name: install my.cnf
  copy: src=my.cnf dest=/etc/my.cnf force=yes
  notify:
  - restart mysql

/etc/ansible/lamp/roles/mysql/handlers/main.yml

- name: restart mysql
  service: name=mariadb state=restarted

数据文件这里就不复制了,就复制配置文件好了

8 构建 php 的任务

/etc/ansible/lamp/roles/php/tasks/main.yml

- name: install php
  yum: name=php state=latest
- name: install php-mysql
  yum: name=php-mysql state=latest

 

9 定义整个任务

/etc/ansible/lamp/site.yml

- name: LAMP build
  remote_user: root
  hosts: websrvs
  roles:
  - prepare
  - mysql
  - php
  - httpd