yum install ansible
/etc/ansible/hosts      # 主机清单
/etc/ansible/roles      # 角色
/etc/ansible/ansible.cfg  # 主配置文件
/usr/bin/ansible       # ansible 主程序命令,是一个软连接
/usr/bin/ansible-doc    # 查看配置文档,模块功能查看工具
/usr/bin/ansible-galaxy  # 下载优秀的代码或roles模块的官网
/usr/bin/ansible-playbook # 定制自动化任务
/usr/bin/ansible-vault   # 加密
/usr/bin/ansible-console  # 交互式执行工具

ansible 配置文件/etc/ansible/ansible.cfg (一般保持默认) 
[defaults] 
#inventory        = /etc/ansible/hosts    # 主机列表配置文件 
#library         = /usr/share/my_modules/  # 库文件存放目录  
#remote_tmp       = $HOME/.ansible/tmp    # 临时py命令文件存放在远程主机目录 
#local_tmp       = $HOME/.ansible/tmp     # 本机的临时命令执行目录 
#forks          = 5        # 默认并发数 
#sudo_user        = root     # 默认sudo 用户 
#ask_sudo_pass     = True     # 每次执行ansible命令是否询问ssh密码 
#ask_pass        = True           
#remote_port      = 22 
#host_key_checking   = False  # 检查对应服务器的host_key,建议取消注释:如果取消此注释将禁用key的检查
#log_path=/var/log/ansible.log  # 日志文件
-----------------------------------------------------------
#host_key_checking = False  # 检查对应服务器的host_key,建议取消注释
#log_path = /var/log/ansible.log 建议启用
记录ansible的操作
不需要重启,立即生效,不是以服务方式运行的

Ansible系列命令    
ansible ansible-doc  ansible-playbook    ansible-vault    
ansible-console   ansible-galaxy   ansible-pull  
ansible-doc: 显示模块帮助  
ansible-doc [options] [module...]  
-a 显示所有模块的文档   
-l, --list 列出可用模块    
-s, --snippet 显示指定模块的playbook片段 
示例: 
ansible-doc –l  列出所有模块 
ansible-doc ping  查看指定模块帮助用法 
ansible-doc –s  ping 查看指定模块帮助用法

ansible通过ssh实现配置管理、应用部署、任务执行等功能,建议配置ansible端能基于密钥认证的方式联系各被管理节点
ansible <host-pattern> [-m module_name] [-a args]  
--version             显示版本         
-m module             指定模块,默认为command  
-v                  详细过程 –vv  -vvv更详细  
--list-hosts           显示主机列表,可简写 -list          
-k, --ask-pass          提示输入ssh连接密码,默认Key验证  
-K, --ask-become-pass     提示输入sudo时的口令          
-C, --check            检查,并不执行          
-T, --timeout=TIMEOUT     执行命令的超时时间,默认10s  
-u, --user=REMOTE_USER    执行远程执行的用户  
-b, --become           代替旧版的sudo 切换


ansible的Host-pattern 
ansible的Host-pattern匹配主机的列表 
All:表示所有Inventory中的所有主机  
ansible all –m ping 
*:通配符  
ansible  "*"  -m ping   
ansible  192.168.1.* -m ping  
ansible  "*srvs"  -m ping 
或关系  
ansible "websrvs:appsrvs"  -m ping  
ansible "192.168.1.10:192.168.1.20"  -m ping
逻辑与:
ansible "websrvs:&dbsrvs" –m ping  # 在websrvs组并且在dbsrvs组中的主机
逻辑非:
ansible 'websrvs:!dbsrvs' –m ping  # 在websrvs组,但不在dbsrvs组中的主机  注意:此处为单引号 
综合逻辑:
ansible 'websrvs:dbsrvs:&appsrvs:!ftpsrvs' –m ping
正则表达式:
ansible "websrvs:&dbsrvs" –m ping
ansible "~(web|db).*\.magedu\.com" –m ping


ansible命令执行过程
1. 加载自己的配置文件 默认/etc/ansible/ansible.cfg
2. 加载自己对应的模块文件,如command
3.通过ansible将模块或命令生成对应的临时py文件,并将该文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/XXX.PY文件 
4. 给文件+x执行
5. 执行并返回结果
6. 删除临时py文件,sleep 0退出

执行状态: 
绿色:执行成功并且不需要做改变的操作 
黄色:执行成功并且对目标主机做变更 
红色:执行失败

ansible sdservs -u liu -k -m command -a 'ls /root' -b -K
sudo 以liu的身份去看root的家目录
反之则会要求:第一次必须用ssh连
ssh 172.20.0.1
ssh 172.20.45.65
  172.20.45.66
  172.20.45.67

vim /etc/ansible/hosts
[webservs]
172.20.45.65
172.20.45.66

[dbservs]
172.20.45.66
172.20.45.67

[appservs]
172.20.45.65
172.20.45.66172.20.45.67
 
ansible 172.20.45.46 -m ping -k 输口令
基于key验证:
ssh-keygen
ssh-copy-id 172.20.45.65
ssh-copy-id 172.20.45.66
ssh-copy-id 172.20.45.67
-----------------------------------------------------------
1、Command:在远程主机执行命令,默认模块,可忽略-m选项
ansible all -a 'removes=/etc/fs cat /etc/fstab'  # 如果文件不存在,就不执行后面的
ansible all -a 'creates=/etc/fs cat /etc/fstab'  # 如果文件不存在,就执行后面的
ansible all -a 'useradd test1'  # 创建test1测试用户
ansible all -a 'getent passwd test1'  # 查看用户是否创建成功
2、Shell:和command相似,用shell执行命令
ansible all -m shell -a 'echo redhat|passwd --stdin test1'  # 更改用户密码
3、Script:运行脚本  
vim f1.sh
#!/bin/bash
hostname
snsible websrvs  -m script -a f1.sh
ansible all -a 'chdir=/boot ls'  # 切换目录,执行ls命令
ansible 172.20.45.65 -a 'chdir=/data ./f1.sh'  #通过它执行的脚本必须带#!/bin/bash机制
4、Copy:从服务器复制文件到客户端
ansible all -m copy -a 'src=/root/ansible/selinux dest=/etc/selinux/config backup=yes'  # 复制文件到远程主机,如果文件存在,则覆盖且备份
ansible all -a 'cat /etc/sysconfig/selinux'  # 查看远程主机的文件
ansible all -a 'getenforce'  # 查看远程主机的selinux是否禁用
ansible all -m copy -a 'src=/etc/shadow dest=/data/ mode=000 owner=liu'  # 复制文件到远程主机,并更改权限和所有者
ansible all -a 'ls -l /data/'  # 在远程主机执行ls -l命令
ansible all -m copy -a 'content="hello\thanks\n" dest=/data/f2' # 在远程主机创建非空文件
ansible all -a 'cat /data/f2' # 查看在远程主机上创建的文件
ansible all -m shell -a 'tar Jcf log.tar.xz /var/log/*.log'  # 远程主机文件打包压缩,这样就可以把多个文件拷贝到当前主机
5、Fetch:从客户端取文件至服务器端,copy相反,目录可先tar
ansible all -m fetch -a 'src=/root/log.tar.xz dest=/data/' # 拷贝远程主机的单个文件
tar tvf log.tar.xz # 预览打包文件
6、File:设置文件属性 
ansible all -m file -a 'name=/data/f3 state=touch'  # 在远程主机创建文件
ansible all -m file -a 'name=/data/f3 state=absent'  # 删除远程主机的文件
ansible all -m file -a 'name=/data/dir1 state=directory'  # 在远程主机创建目录
ansible all -m file -a 'name=/data/dir1 state=absent'  # 删除远程主机的目录
ansible all -m file -a 'src=/etc/fstab dest=/data/fstab.link state=link'  # 在远程主机创建软连接
ansible all -m file -a 'dest=/data/fstab.link state=absent'  # 删除远程主机的软连接
ansible all -m file -a 'dest=/data/  state=absent'
ansible all -m shell -a 'rm -f /data/*'
centos7主机名存放位置
cat /etc/hostname
cat /etc/hosts
centos6主机名存放位置
cat /etc/sysconfig/network 
7、Hostname:管理主机名
ansible 172.20.45.65 -m hostname -a 'name=nod1' # 更改主机名,立即生效,并同时保存
8、Cron:计划任务
ansible all -m cron -a 'minute=* job="/usr/bin/wall FBI warning" name=warning'  # 在远程主机创建计划任务
ansible all -m cron -a 'disabled=true job="/usr/bin/wall FBI warning" name=warning'  # 在远程主机禁用计划任务
ansible all -m cron -a 'disabled=false job="/usr/bin/wall FBI warning" name=warning'  # 在远程主机启用计划任务
ansible all -m cron -a 'disabled=yes job="/usr/bin/wall FBI warning" name=warning'  # 在远程主机禁用计划任务
ansible all -m cron -a 'disabled=no job="/usr/bin/wall FBI warning" name=warning'  # 在远程主机启用计划任务
ansible all -m cron -a 'job="/usr/bin/wall FBI warning" name=warning state=absent'  # 彻底删除远程主机上的计划任务
9、Yum:管理包
ansible all -m yum -a 'name=httpd state=latest'  # 安装httpd服务
ansible all -m yum -a 'name=vsftpd state=latest'  # 安装vsftpd服务
ansible all -m yum -a 'list=installed'  # 查看所有装好的包
ansible all -m yum -a 'name=vsftpd state=absent/removed'  # 卸载远程主机上的安装包
ansible all -m shell -a 'rpm -q vsftpd'  # 查看rpm包按是否安装
ansible all -m yum -a 'name=vsftpd,memcached,httpd'  # 同时安装多个rpm包
ansible all -m yum -a 'name=vsftpd,memcached,httpd state=absent'  # 同时卸载多个rpm包
ansible all -m copy -a 'src=/misc/cd/vsftpd-3.0.2-22.el7.x86_64.rpm dest=/data/'  # 把单个安装包推送到远程主机
ansible all -m yum -a 'name=/data/vsftpd-3.0.2-22.el7.x86_64.rpm disable_gpg_check=yes'  # 在远程主机上安装单个安装包,并且忽略key的检查
ansible all -m yum -a 'name=dstat update_cache=yes'  # 在远程主机安装包,并且更新缓存  dstat 监控
10、Service:管理服务 
ansible all -m service -a 'name=vsftpd state=started enabled=yes/true'  # 在远程主机启用vsftpd服务,并设为开机自启
ansible all -m service -a 'name=vsftpd state=restarted'  # 重启服务
ansible all -m service -a 'name=vsftpd state=stopped'  # 停用服务
ansible all -m service -a 'name=vsftpd state=stopped enabled=no/false'  # 开机不启动
11、User:管理用户
ansible all -m user -a 'name=nginx shell=/sbin/nologin system=yes home=/var/nginx groups=root,bin uid=80 comment="nginx service"'  # 在远程主机创建账号,并指定相应的属性
ansible all -a 'getent passwd nginx'  # 查看创建的用户
ansible all -m user -a 'name=nginx state=absent remove=yes'  # 删除远程主机上的用户账号,并删除相应的家目录以及相应的文件
12、Group:管理组 
ansible all -m group -a 'name=nginx system=yes gid=80'  # 在远程主机上创建组,并指定相应的属性
ansible all -a 'getent group nginx' # 查看远程主机上创建的组
ansible all -m group -a 'name=nginx state=absent'  # 删除远程主机上创建的账号
ansible-galaxy install geerlingguy.nginx
ansible-galaxy list geerlingguy.nginx  # 查看安装的版本信息
连接 https://galaxy.ansible.com 下载相应的roles
列出所有已安装的galaxy  ansible-galaxy list
安装galaxy  ansible-galaxy install geerlingguy.redis 
删除galaxy  ansible-galaxy remove geerlingguy.redis
----------------------------------------------------------- 
playbook:
cd /root/ansible
vim hello.yml
---
- hosts: webservs
  remote_user: root

  tasks:
    - name: hello
      command: hostname
ansible-playbook hello.yml

加密playbook
ansible-vault encrypt hello.yml
New Vault password: 
Confirm New Vault password: 
Encryption successful
cat hello.yml
$ANSIBLE_VAULT;1.1;AES256
35393465386162323131383635623862643064386565663263643435353933353038323231356437
3436326563336463663530313763633137323031373634300a633037363630646431396166313964
38366565636232313730623466653237383538316663653861346564346663363233326465303961
3966323330326439380a323962373635396364393935643962336434376533623830343661376264
62376464663232353233346237346335363836343132333135313639333834363965346166636533
32313565396266386637666630303933623061383139336362616134356262303864303931653936
39333832303364396536663666613766646330663836326561383161636130636130666631643664
31306239633161636263343731643062336262306631366438303335396662363364306531643764
35616337356531646437663261353834353762313932663962376266393461663165
ansible-vault view hello.yml  # 查看加密的playbook
ansible-vault edit hello.yml  # 编辑加密的playbook
ansible-vault rekey hello.yml  # 更改playbook的加密口令
ansible-vault create new.yml  # 创建新文
解密playbook
ansible-vault decrypt hello.yml

ansible-console # 交互式的工具

vim file.yml
---
-hosts: all
 remote_user: root

 tasks: 
   - name: create new file
     file: name=/data/newfile state=touch
   - name: create new user
     user: name=test2 state=present system=yes shell=/sbin/nologin
   - name: installl package
     yum: name=httpd
   - name: copy index.html
     copy: src=/var/www/html/index.html dest=/var/www/html
   - name: start service
     service: name=httpd state=started enabled=yes
# 一个模块对应一个name,哪怕是相同的模块,name也得分开写
ansible-playbook -C file.yml  # 检查一遍是否写错,干跑一次,不做任何操作
ansible all -m shell -a 'ss -tln|grep :80' # 查看httpd服务是否开启
curl 172.20.45.65 # 浏览器访问

如果命令或脚本的退出码不为零,可以使用如下方式替代  
tasks:    
  - name: run this command and ignore the result      
    shell: /usr/bin/somecommand || /bin/true 
或者使用ignore_errors来忽略错误信息:  tasks:    
  - name: run this command and ignore the result      
    shell: /usr/bin/somecommand      
    ignore_errors: True

handlers和notify结合使用触发条件 

Handlers  
是task列表,这些task与前述的task并没有本质上的不同,用于当关注的资源发生变化时,才会采取一定的操作


Notify此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,
仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作

vim httpd.yml
---
- hosts: all
  remote_user: root

  task:
    - name: install httpd package
      yum: name=httpd
      tags: inshttpd  # 添加标签
    - name: copy conf file
      copy: src=files/httpd.conf dest=/etc/httpd/conf/ backup=yes
      notify:  # 触发条件
        - restart service
          Check Nginx process
    - name: start service
      service: name=httpd state=started enabled=yes
      tags: rshttpd  # 添加标签

  handlers:  # 当发生变化时,执行的操作,比如配置文件修改了,重启服务生效
  - name: restart service
    service: name=httpd state=restarted
  - name: Check Nginx process
    shell: killall -0 > nginx.log  # 探测以下此服务是否启动 $?

ansible-playbook httpd.yml
ansible-playbook -t rshttpd httpd.yml  # tags标签的用途: 可以挑选指定的标签执行
ansible-playbook -t inshttpd,rshttpd httpd.yml  # 执行两个标签
# 多个动作也可以共用一个标签


play-book中变量的使用
ansible all -m hostname -a 'name=host123'
172.20.45.65 | SUCCESS => {
    "ansible_facts": {
        "ansible_domain": "", 
        "ansible_fqdn": "host123", 
        "ansible_hostname": "host123", 
        "ansible_nodename": "host123"
    }, 
    "changed": true, 
    "name": "host123"
}
ansible all -m setup |less  # 当前电脑的系统信息
ansible all -m setup -a 'filter=ansible_hostname'  # 过滤
ansible all -m setup -a 'filter=ansible_all_ipv4_addresses'  # 过滤

变量使用:pkname
vim app.yml
---
- hosts: all
  remote_user: root
  
  tasks:
    - name: install packages
      yum: name={{ pkname }}
    - name: start service
      service: name={{ pkname }} state=started enabled=yes
ansible-playbook -e 'pkname=vsftpd' app.yml

多个变量赋值:
vim app1.yml
---
- hosts: all
  remote_user: root
  
  tasks:
    - name: install packages
      yum: name={{ pkname1 }}
    - name: install packages
      yum: name={{ pkname2 }}
ansible-playbook -e 'pkname1=vsftpd pkname2=memcached' app.yml  # 临时指定变量,装2个包

在playbook内部定义变量,vars:并且使用变量
vim app2.yml
---
- hosts: all
  remote_user: root
  vars:  # 内部定义变量
    - pkname1: httpd
      pkname2: vsftpd
  tasks:
    - name: install packages
      yum: name={{ pkname1 }}
    - name: install packages
      yum: name={{ pkname2 }}

在/etc/ansible/hosts中,针对主机进行变量定义
cat /etc/ansible/hosts 
[webservs]
172.20.45.65  http_port=81
172.20.45.66  http_port=82

[webservs:vars]  # 添加的通用变量
nodename=www
domainname=.magedu.com

[dbservs]
172.20.45.67
172.20.45.66

[appservs]
172.20.45.6[5:7]
-----------------------------------------------------------
设置不一样的主机名
vim hostname.yml
---
- hosts: webservs
  remote_user: root

  task:
    - name: set hostname
      hostname: name=www{{http_port}}.magedu.com
-----------------------------------------------------------
vim hostname1.yml
---
- hosts: webservs
  remote_user: root

  task:
    - name: set hostname
      hostname: name={{nodename}}{{http_port}}{{domainname}}

命令行的优先级,通通优先于配置文件
如果命令行里用-e定义了临时变量,那么优先于配置文件中定义的变量
普通变量的优先级,要高于公共(组)变量


Playbook中变量使用
变量名:仅能由字母、数字和下划线组成,且只能以字母开头
变量来源:

1、ansible setup facts 远程主机的所有变量都可直接调用
2、在/etc/ansible/hosts中定义
普通变量:主机组中主机单独定义,优先级高于公共变量
公共(组)变量:针对主机组中所有主机定义统一
3、通过命令行指定变量,优先级最高
ansible-playbook –e varname=value
4、在playbook中定义
 
vars: - var1: value1 - var2: value2 
5 在role中定义
 
Playbook中变量使用
变量命名
变量名仅能由字母、数字和下划线组成,且只能以字母开头
变量定义: key=value 
示例: http_port=80 

变量调用方式:
通过{{ variable_name }} 调用变量,且变量名前后必须有空格,有时用 “{{ variable_name }}”才生效 
ansible-playbook –e 选项指定   
ansible-playbook test.yml -e "hosts=www user=mageedu"