ansible使用

ansible.cfg配置文件说明

ansible_ssh_port=22                  #远程主机登陆端口
ansible_ssh_user=root                #远程主机登陆用户名
ansible_ssh_pass=*******              #远程主机登陆用户名的密码
ansible_ssh_private_key_file=/etc/ansible/hosts   #指定管理主机群列表文件
host_key_checking=False              #跳过第一次连接检测询问是否登陆的提示(YES/NO)
hostfile = /etc/ansible/hosts   #指定文件

常用命令

列出当前的核心模块		ansible-doc -l 
查看此模块用法		ansible-doc -s 模块名 
启动并发线程数,减少压力		ansible 组名 -f 
测试通信			ansible all -m ping
在组里的机器去创建用户		ansible 组名 –m user –a 'name=名字'
给组里的所有机器安装这个软件			ansible 组名 –m yum –a 'name=安装包名字 state=present'
卸载组里所有机器的这个安装包			ansible 组名 –m yum –a 'name=安装包名字 state=absent'
重启组里所有机器的这个安装包			ansible 组名 –m service –a 'name=服务名字 state=restarted'
拷贝当前文件到组里的机器			ansible 组名 –m copy –a 'src=/root/psu.py dest=/tmp'
拷贝当前文件到组里的机器的任意一台		ansible 组里机器的ip –m copy –a 'src=/root/psu.py dest=/tmp'
直接执行命令		ansible 组名 –m command  -a 'ls -ltr'
检测剧本是否有语法错误			ansible-playbook --syntax-check 文件名.yml  
检查生效的主机  		ansible-playbook a.yml --list-hosts 
检查tasks任务   		ansible-playbook a.yml --list-task 
指定从某个task开始运行    	ansible-playbook a.yml --start-at-task=‘Copy Nginx.conf’ 
模拟执行剧本		ansible-playbook  -C  文件名.yml

playbook格式

原文链接:playbook文件详解
https://blog.51cto.com/13689359/2333338
https://www.jianshu.com/p/171578692c94 详细

注意:一定要对齐格式,不允许用TAB

  1. playbook书写规则

playbook语法有如下特性:
1.以 — (三个减号)开始,必须顶行写;
2.次行开始写Playbook的内容,但是一般要求写明该playbook的功能;
3.严格缩进,并且不能用Tab键缩进;
4.缩进级别必须是一致的,同样的缩进代表同样的级别,程序判别配置的级别是通过缩进结合换行来实现的;
5.K/V的值可同行写,也可换行写。同行使用 :分隔,换行写需要以 - 分隔;

  1. 举例
---
- hosts: site 				#主机
  remote_user: root		#远程主机用户
  vars:					#定义变量
  - file: ziyuan.sh        	# 变量名:变量
 
  tasks:					#任务
        - name: file to dest			#任务名
          copy: src=/etc/ansible/script/{{file}} dest=/usr/local/src/{{file}} mode=755
        - name: run				#任务名
          shell: /bin/bash /usr/local/src/{{file}}

playbook常用参数

gather_facts

1.这个参数是用来收集客户端主机信息的。例:主机名、内核版本、网卡接口、IP 地址、操作系统版本、环境变量、CPU 核数、可用内存、可用磁盘 等等……。
2.如果gather_facts: no或false,在playbook中setup参数是收集不到以上信息的,只有在gather_facts:yes 或者是true,才能收集到

ignore_erros

在有些情况下,一些必须运行的命令或脚本会报一些错误,而这些错误并不一定真的说明有问题,但是经常会给接下来要运行的任务造成困扰,甚至直接导致playbook运行中断。
这时候,我们可以在相关任务中添加ignore_errors: true来屏蔽当前任务的报错信息。ansible也将视该任务运行成功,不再报错,这样就不会对接下来要运行的任务造成额外困扰。但是要注意的是,我们不应过度依赖ignore_errors,因为它会隐藏所有的报错信息,而应该把精力集中在寻找报错的原因上面,这样才能从根本上解决问题

strategy

Strategies 控制task的执行方式, 在2.0中增加了"free" Strategies, 可以允许每个host尽快的执行完一个play. 默认是Strategies是linear, 表示任何host必须等待所有的host完成一个task后才能开始执行下一个task
Strategies 还有一个debug模式, debug模式在2.1中才能使用.

ansible变量

cat test.sh
#!/bin/bash
echo $1
引用anisble内部的变量

ansible 192.168.3.51 -m script -a ‘test.sh {{inventory_hostname}}’
ansible localhost -m shell -a “echo {{inventory_hostname}}”

引用自定义变量

ansible 192.168.3.51 -m script -a ‘test.sh {{test}}’ -e ‘test=“12”’
ansible localhost -m shell -a “echo {{say_hi}}” -e ‘say_hi=“hello world”’

引用playbook文件中的变量

ansible localhost -m shell -a “echo {{say_hi}}” -e @test.yaml

cat test.yaml
---
say_hi: hello world

setup模块

执行命令 : ansible all -m setup|more #获取所有hosts中所有绑定过的主机信息
       ansible localhost -m setup|more #获取本地主机的系统参数

1.参数
ansible_all_ipv4_addresses  # 所有的ipv4地址
ansible_all_ipv6_addresses  # 所有的ipv6的地址
ansible_bios_version          # 主板bios的版本
ansible_architecture          # 架构信息
ansible_date_time             # 系统的时间
ansible_default_ipv4          # IPv4默认地址
	address                #ip地址
	alias                  #网卡名称
	broadcast             #广播地址
	gateway                # 网关
	macaddress            #mac地址
	netmask               #子网掩码
	network               #网段
ansible_distribution                       #系统的版本
ansible_distribution_file_variety          # 系统的基于对象
ansible_distribution_major_version         # 系统的主版本 7或6
ansible_distribution_version               #系统的版本
ansible_domain              #系统的域
ansible_dns                 #系统的dns
ansible_env                 #系统的环境变量
ansible_hostname            #系统的主机名
ansible_fqdn                #系统的完整主机名
ansible_machine             #系统的架构
ansible_memory_mb           #系统的内存信息
ansible_os_family           #系统的家族
ansible_pkg_mgr             #系统的包管理工具
ansible_processor_cores     #cpu的核数
ansible_processor_count     #每颗cpu上的颗数
ansible_processor_vcpus     #cpu的总核数=cpu的颗数*每颗cpu上的核数
ansible_python              #系统的python版本  
可以通过ansible 10.0.0.132 -m setup -a "filter=‘*关键字*‘" 类似的命令进行搜索.
补充 : grep "^\(.*\):.*\1$" /etc/passwd    \1表示前边分组中的信息,前后一致
   grep -E "^(.*):.*\1$" /etc/passwd    -E表示扩展匹配
2.playbook使用
例1:获取主机信息
---
- name: facts
  hosts: test
  gather_facts: true           ###默认是开启的
  remote_user: root
  tasks:
		- debug: var=ansible_distribution   ###更多参数请看setup模块
例2: setup和when使用
---
- name: facts
  hosts: test
  gather_facts: true           ###默认是开启的
  remote_user: root
  tasks:
		- debug:
				msg: "红帽系统"
		  when: ansible_distribution == "RedHat"     ###当是ansible_distribution值是RedHat就输出红帽系统

copy模块

1.选项解释

backup : 在覆盖之前源文件备份,备份文件包含时间信息,有两个选项 yes | no
content :用于替代"src" ,可以直接指定文件的值
dest:必选项,要将文件复制到的远程主机的绝对路径,如果源文件是一个目录,那么路径必须是个目录
directory_mode:递归的设置目录的权限,默认为系统默认权限
force:如果目标主机包含该文件,但内容不同,如果设置成yes,则强制覆盖,如果no,则只有当目标主机的目标位置不存在该文件时,才复制,默认yes

others:所有的file模块里的必选项都可以在这里使用
src:要复制到远程的主机文件在本地的地址,可以是绝对路径,也可以是相对路径,如果路径是一个目录,将递归复制,在这种情况下,如果路径使用/结尾,则复制路径里的内容,如果没有/ 则复制包含目录在内的整个内容全部复制,类似于rsync
flat:当flat 为 yes 时,有两种情况: 见例2
1.dest 是以"/" 结尾,那么文件直接保存在 dest 的目录下
2.dest 不是以 “/” 结尾,则dest 被看做文件,相当于文件会重命名再保存

2.基本使用
copy文件或者目录
ansible -i ansiblepy.py test22 -m copy -a "src=/root/ansibletest dest=/root/"
如果想在在目录下创建文件并写入内容,那么dest 参数对应的值必须是一个文件,而不能是一个路径。 
ansible -i ansiblepy.py test22 -m copy -a 'content="aaa\nbbb\n" dest=/testdir/testfile1'

##force
将 ansible 主机中 /testdir/copytest 文件复制到远程主机的 /testdir 目录中时,如果远程主机中已经存在 /testdir/copytest 文件,并且文件内容与 ansible 主机中的 copytest 文件的内容不一致,则不执行拷贝操作,远程主机中的
/testdir/copytest 文件内容不会被改变。
ansible -i ansiblepy.py test22 -m copy -a 'src=/root/testdir/ttt dest=/root/testdir/ force=no'

##backup
将 ansible 主机中 /testdir/copytest 文件复制到远程主机的 /testdir 目录中时,如果远程主机中已经存在 /testdir/copytest 文件,并且文件内容与 ansible 主机中的 /testdir/copytest 文件的内容不一致,会执行拷贝操作,但是
在执行拷贝操作之前,会将远程主机中的原文件重命名,以作备份,然后再进行拷贝操作
ansible -i ansiblepy.py test22 -m copy -a 'src=/root/testdir/ttt dest=/root/testdir/ backup=yes'

##owner属主
拷贝文件时,指定文件的属主,需要注意,远程主机上必须存在对应的用户。
ansible -i ansiblepy.py test11 -m copy -a 'src=/root/testdir/ttt dest=/root/ owner=root'
 
##mode权限
拷贝文件时,指定文件的权限。
ansible -i ansiblepy.py test22 -m copy -a 'src=/root/testdir/ttt dest=/root/ owner=root backup=yes mode=777'
3.在playbook使用
例1:传文件
---
- name: scan
  host: test
  gather_facts: true  ##允许收集客户端信息,默认开启
  remote_user: root
  vars:
		host_ip: "{{inventory_hostname}}"
  tasks:
		- copy:
				src=/opt/Ubuntu/vmware-file/redhat.txt dest=/usr/local/src/ force=yes
				src=/opt/Ubuntu/vmware-file/ubuntu.txt dest=/usr/local/src/ force=yes mode=755
例2:flat参数使用
保存到本地时,直接使用远程的文件名,不需要remote_host 创建新的目录
cat fetched.yml
hosts: centos7
remote_user: root
tasks:
name : fetched file from centos7 into local
fetch:
src: /tmp/fstab_from_centos6
dest: /tmp/
flat: yes

增加 flat 参数,当flat 为 yes 时,有两种情况:
(1)dest 是以"/" 结尾,怎文件直接保存在 dest 的目录下,所以现在的结果是:
fstab_from_centos6 保存在本地主机的 /tmp/fstab_from_centos6
(2) dest 不是以 “/” 结尾,则dest 被看做文件,相当于 fstab_from_centos6 会重命名再保存。例如:
cat fetched.yml
hosts: centos7
remote_user: root
tasks:
name : fetched file from centos7 into local
fetch:
src: /tmp/fstab_from_centos6
dest: /tmp/centos
flat: yes

fstab_from_centos6 被保存为 /tmp/cnetos
复制本地(或远程)文件 到远程主机

handlers和notify模块

1.解释

在需要被监控的任务(tasks)中定义一个notify,只有当这个任务被执行时,才会触发notify对应的handlers去执行相应操作

注意:
handlers只有在其所在的任务被执行时,才会被运行;
handlers只会在Play的末尾运行一次;如果想在一个Playbook的中间运行handlers,则需要使用meta模块来实现,例如:- meta: flush_handlers。
如果一个Play在运行到调用handlers的语句之前失败了,那么这个handlers将不会被执行。我们可以使用mega模块的–force-handlers选项来强制执行handlers,即使在handlers所在Play中途运行失败也能执行。

2.playbook使用
例1:监控某一个任务是否运行成功
---
- name: scan
  host: test
  gather_facts: true  ##收集客户端信息的
  remote_user: root
  vars:
		host_ip: "{{inventory_hostname}}"
  tasks:
		- copy:
				src=/opt/Ubuntu/vmware-file/redhat.txt dest=/usr/local/src/ force=yes
				src=/opt/Ubuntu/vmware-file/ubuntu.txt dest=/usr/local/src/ force=yes mode=755
		  when: ansible_distribution == "RedHat"				###当收集到系统是红帽就运行cpoy
		  notify: echo				###监控当前copy这个任务,如果允许成功,就允许handlers内的任务
  handlers:
		- name: echo
		  debug:
				msg: "脚本已运行"
例2:notify执行多个监控任务

见目录:不同的系统传不同的文件(批量传多个文件)

tags模块

标签的不同写法
语法一:
tags:
 - testtag
 - t1
 
语法二:
tags: tag1,t1
 
语法三:
tags: ['tagtest','t2'] 
查看playbook中的所有标签
ansible-playbook --list-tags testhttpd.yml
执行指定任务

如果在playbook中有多条任务,现在只想执行某个任务,可以在任务中定义tags,在执行操作时指定-t即可单独执行此任务.
示例 :

---
- hosts: web
  tasks:
  - name: install
    yum: name=redis
  - name: copyfile
    copy: dest=/etc/redis.conf src=/etc/redis.conf
    tags: copyfile   #在copyfile任务中定义tags(后边名字什么的无所谓)
  - name: start
    service: name=redis state=started 
 
 ansible-playbook -t copyfile p2.yml    #操作时通过-t指定copyfile单独执行
---
- hosts: test70
  remote_user: root
  tasks:
  - name: task1
    file:
      path: /testdir/t1
      state: touch
    tags: t1
  - name: task2
    file: path=/testdir/t2
          state=touch
    tags: t2
  - name: task3
    file: path=/testdir/t3
          state=touch
    tags: t3

ansible-playbook --tags=t2 touch.yml    #操作时通过-t指定t2单独执行
跳过指定任务
---
- hosts: test70
  remote_user: root
  tasks:
  - name: task1
    file:
      path: /testdir/t1
      state: touch
    tags: t1
  - name: task2
    file: path=/testdir/t2
          state=touch
    tags: t2
  - name: task3
    file: path=/testdir/t3
          state=touch
tags: t3

ansible-playbook --skip-tags='t2' testtag.yml      ###加上--skip-tags表示跳过t2
一个标签执行多个任务
---
- hosts: test70
  remote_user: root
  tasks:
  - name: install httpd package
    tags: httpd,package
    yum:
      name=httpd
      state=latest
 
  - name: start up httpd service
    tags: httpd,service
    service:
      name: httpd
      state: started

每个任务都有多个标签,而且上例中两个任务都有一个共同的标签,就是httpd标签,所以,当我们执行:
'ansible-playbook --tags=httpd testhttpd.yml',上述两个任务都会执行
同时执行多个标签
---
- hosts: test70
  remote_user: root
  tags: httpd		###将标签写在开始表示整个文档都会继承这一个标签,不管是否指定自己的标签都可以继承和使用这个标签
  tasks:
  - name: install httpd package
    tags: ['package']
    yum:
      name=httpd
      state=latest
 
  - name: start up httpd service
    tags:
      - service
    service:
      name: httpd
      state: started

ansible-playbook --tags package,service testhttpd.yml     执行多个任务标签
特殊标签

always
never(2.5版本中新加入的特殊tag)
tagged
untagged
all

当我们把任务的tags的值指定为always时,那么这个任务就总是会被执行,除非你使用’–skip-tags’选项明确指定不执行对应的任务,这样说可能不容易理解,不如看个小示例,示例如下

---
- hosts: test70
  remote_user: root
  tasks:
  - name: task1
    file:
      path: /testdir/t1
      state: touch
    tags:
      - t1
  - name: task2
    file: path=/testdir/t2
          state=touch
    tags: ['t2']
  - name: task3
    file: path=/testdir/t3
          state=touch
    tags: t3,always

上例中,task3的标签有两个,t3和always,那么我们来执行一下这个playbook,假设,我只想运行上述playbook中标签为t1的任务
在执行上述playbook时,我只指定了’t1’,正常情况下应该只执行’t1’对应的任务,也就是应该只执行task1,但是实际上执行了task1和task3,这是因为task3的标签的值包含always关键字,所以即使task3对应的标签没有被调用,task3也会执行,这就是always的作用。

如果你不想执行标签中包含always的任务,你可以使用’–skip-tags’选项明确指定跳过它们,仍然以上例的playbook为例,假设我们就是不想执行task3,我们可以执行如下命令

ansible-playbook --skip-tags always testtag.yml
但是需要注意,如果上述play中有多个任务都有always标签,那么上述命令将会跳过所有包含always标签的任务,如果上例中的
play中的多个任务都有always标签,则可以使用如下命令只跳过task3,其他带有always标签的任务不会跳过,前提是task3有除了
always以外的自定义标签。

ansible-playbook --skip-tags t3 testtag.yml 
在2.5版本的ansible中,引入了新的特殊标签 'never',从字面上理解,never的作用应该与always正好相反,由于我当前使用的
ansible版本为2.4(还没有引入never标签),所以当指定任务的标签为never时,貌似被ansible当做了自定义标签,所以如果你
安装了2.5版本的ansible,可以尝试一下never标签的作用,由于还没有实际使用过2.5版本,所以此处暂时不进行示例。

剩余的三个特殊标签分别为 tagged、untagged、all
这三个特殊标签并非像always一样,always作为标签值存在,而这三个特殊标签则是在调用标签时使用,示例如下

ansible-playbook --tags tagged testtag.yml
上述命令表示只执行有标签的任务,没有任何标签的任务不会被执行。

ansible-playbook --skip-tags tagged testtag.yml
上述命令表示跳过包含标签的任务,即使对应的任务包含always标签,也会被跳过。

ansible-playbook --tags untagged testtag.yml
上述命令表示只执行没有标签的任务,但是如果某些任务包含always标签,那么这些任务也会被执行。
ansible-playbook --skip-tags untagged testtag.yml

when模块判断

1.解释

就和if判断语句一样,当when后的判断条件成立,就和之前当前任务

2.playbook使用
例1:与或判断
---
- hosts: load-node,img
  remote_user: root
  tasks:
  - name: "touch flag file"
    command: "touch /tmp/this_is_{{ ansible_distribution }}_system" 
    when: (ansible_distribution == "CentOS" and ansible_distribution_major_version == '6') or
          (ansible_distribution == "Debian" and ansible_distribution_major_version == '7')
例2:自定义变量判断
---
	- hosts: agentd
	  remote_user: root
  vars:
		host_ip:  "{{inventory_hostname}}"     '   ###中括号里的是ansible的内部变量
	  tasks:
			- name: zabbix-agent dir exist or not exist 			##判断zabbix安装目录在不在
			  shell: ls -ld /usr/local/zabbix-agent | wc -l
			  register: dir_num							##声明变量
			  ignore_erros: True
			  ##因为ls目录,目录不存在的情况,会报错,意思是报错也会继续执行下边的任务
			- debug: var=dir_num
			- name: send zabbix-4.0.4.tar.gz to agent				###发送zabbix包
			  copy: src=/etc/ansible/tar/zabbix_4.0.4.tar.gz dst=/usr/local/src/
			  ##dir_num.stdout 表示输出结果如果等于零,等于零就是没有zabbix_agent目录,就执行,发送tar包
			  when: dir_num.stdout == "0"     

ansible 实例

统计硬件信息

ansible hosts信息
[site]
192.168.101.[96:118]
[site:vars]
ansible_ssh_user='root'
ansible_ssh_pass=''

[mall]
192.168.101.[64:85]
[mall:vars]
ansible_ssh_user='root'
ansible_ssh_pass=''

方法一: ansible mall -m script -a ‘/etc/ansible/script/ziyuan.sh’
ansible mall:site -m script -a ‘/etc/ansible/script/ziyuan.sh’ 也可以

方法二: ansible-playbook [任务名] 文件名.yaml
系统名字,IP,cpu总数,内存总大小脚本

脚本

#!/bin/bash
hostname=$(hostname) && echo KaTeX parse error: Expected 'EOF', got '&' at position 10: hostname &̲& IP=(ifconfig eth0 | grep Mask | awk -F’:’ ‘{print $2}’ | awk ‘{print $1}’) && echo KaTeX parse error: Expected 'EOF', got '&' at position 4: IP &̲& CPU=(lscpu | grep “^CPU(s)” | awk ‘{print $2}’) && echo KaTeX parse error: Expected 'EOF', got '&' at position 5: CPU &̲& Mem=(cat /proc/meminfo | grep “^MemTotal” | awk ‘{print $2}’) && echo $(expr $Mem / 1024 / 1000)

playbook
---
- hosts: site 				#主机
  remote_user: root		#远程主机用户
  vars:					#定义变量
  - file: ziyuan.sh        	# 变量名:变量
 
  tasks:					#任务
        - name: file to dest			#任务名
          copy: src=/etc/ansible/script/{{file}} dest=/usr/local/src/{{file}} mode=755
        - name: run				#任务名
          shell: /bin/bash /usr/local/src/{{file}}

过滤出信息
sed -rn 's/("stdout": ")(.*)(",)/\2/gp' test.txt > mall.txt
sed -rn 's/(.*)(\\r\\n)(.*)(\\r\\n)(.*)(\\r\\n)(.*)(\\r\\n)/\1  \3  \5  \7/gp' mall.txt
想要排序找U盘里的脚本

批量修改密码

修改密码脚本
#!/bin/bash
echo "tRM8I4_>uvwCJXqA" | passwd --stdin root
ansible hosts信息
[site]
192.168.101.[96:118]
[site:vars]
ansible_ssh_user='root'
ansible_ssh_pass=''

[mall]
192.168.101.[64:85]
[mall:vars]
ansible_ssh_user='root'
ansible_ssh_pass=''
方法一:

ansible mall -m script -a ‘/etc/ansible/script/passwd.sh’
ansible mall:site -m script -a ‘/etc/ansible/script/passwd.sh’ 也可以

方法二:

ansible-playbook [任务名] 文件名.yaml

playbook
---
- hosts: site
  remote_user: root
  vars:
  - file: password.sh        
 
  tasks:
        - name: file to dest
          copy: src=/etc/ansible/script/{{file}} dest=/usr/local/src/{{file}} mode=755
        - name: run
          shell: /bin/bash /usr/local/src/{{file}}

批量修改主机名

添加主机hosts
[DLR]
192.168.101.154 host_name=DLRAPP_Web03
192.168.101.155 host_name=DLRAPP_Nginx01
192.168.101.156 host_name=DLRAPP_Nginx02
192.168.101.157 host_name=DLRAPP_DB01
192.168.101.158 host_name=DLRAPP_DB02
192.168.101.159 host_name=DLRAPP_DB03
192.168.101.160 host_name=DLRAPP_BI01
192.168.101.161 host_name=DLRAPP_BI02
192.168.101.162 host_name=DLRAPP_BI03
192.168.101.163 host_name=DLRAPP_Test01
[DLR:vars]
ansible_ssh_user='root'
ansible_ssh_pass='MKPEUi7rDb81OBKg'

ansile-playbook

---
- hosts: DLR
  user: root
  gather_facts: true
  tasks:
  - name: hostname
    hostname: 'name={{ host_name }}' 		#定义上边的红色字体为变量
  - name:
    shell: sed -ri "s/(HOSTNAME=)(.*)/\1{{ host_name }}/g" /etc/sysconfig/network
  - name:
    shell: "hostname {{ host_name }}"

批量安装PHP扩展模块

脚本
vim install.sh
#!/bin/bash
value=$(php -m | grep mongo)
if [ -z $value ]
then
cd /usr/local/src/
wget http://pecl.php.net/get/mongo-1.6.16.tgz && tar -zxf mongo-1.6.16.tgz && cd /usr/local/src/mongo-1.6.16
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config && make && make install
echo "extension=mongo.so" >> /usr/local/php/etc/php.ini 
pkill php-fpm
sleep 10 
/usr/local/php/sbin/php-fpm
else
	echo "已经安装mongo模块"
fi
方法一:

ansible mall -m script -a ‘/etc/ansible/script/install.sh’
ansible mall:site -m script -a ‘/etc/ansible/script/install.sh’ 也可以

方法二:

ansible-playbook [任务名] 文件名.yaml

批量传文件

方法一:

ansible mall -m script -a ‘/etc/ansible/script/install.sh’
ansible mall:site -m script -a ‘/etc/ansible/script/install.sh’ 也可以

方法二:

ansible-playbook [任务名] 文件名.yaml

远程复制或者本地上传,加上force=yes,则会覆盖掉原来的文件,加上backup=yes,在覆盖的时候会把原来的文件做一个备份: ansible all -m copy -a “src=/root/test.txt dest=/root force=yes backup=yes”
ansible webserver -m copy -a “src=/usr/local/tomcat8/webapps/ROOT/scripts/shell-sh/test.sh dest=/usr/local/tomcat8/shell-sh/”

不同的系统传不同的文件(批量传多个文件)

对比过滤出的文件和文件内容,并将不同部分输出
两个文件:vmfile1 vmfile2
vmfile1内容是:过滤主机上原装的VMware文件 redhat.txt是红帽上的VMware文件 ubuntu.txt是Ubuntu上的VMware文件
vmfile2内容是:过滤主机上其他以VMware命名的文件
目标:将vmfile2中比vmfile1中不同的过滤出来(批量的)

---
- name: Ascan
  hosts: AIP
  strategy: free
  gather_facts: true
  remote_user: root
  vars:
      host_ip: "{{inventory_hostname}}"
  tasks:
       #当时Ubuntu系统客户端时删除这ubuntu.txt and scan.sh文件
       - name: delete agent ubuntu.txt and scan.sh
         file: path=/usr/local/src/{{ item }} state=absent
         when: ansible_distribution == "Ubuntu"
         with_items:
              - ubuntu.txt
              - scan.sh
       #当时RedHat系统客户端时删除这redhat.txt and scan.sh文件
       - name: delete agent redhat.txt and scan.sh
         file: path=/usr/local/src/{{ item }} state=absent
         when: ansible_distribution == "RedHat"
         with_items:
              - redhat.txt
              - scan.sh
       #删除之后发送新的文件
       - name: send ubuntu.txt to agent
         copy: src=/opt/Ubuntu/vmware-file/ubuntu.txt dest=/usr/local/src/ force=yes
         when: ansible_distribution == "Ubuntu"
         notify:
              - scansh
              - run
       - name: send redhat.txt to agent
         copy: src=/opt/Ubuntu/vmware-file/redhat.txt dest=/usr/local/src/ force=yes
         notify:
              - scansh
              - run
  handlers:
       - name: scansh
         copy: src=/opt/Ubuntu/vmware-file/scan.sh dest=/usr/local/src/ mode=755 force=yes
       - name: run
         shell:
               nohup bash /usr/local/src/scan.sh > /usr/local/src/scan.log &
scan.sh脚本
#!/bin/bash

#比较多余的VMware文件
##正常VMware文件
#判断是Redhat系统还是Ubuntu系统
version=`cat /proc/version | grep -i "red hat"`
if [[ $version =~ "Red Hat" ]]
then
	vmfile1=`cat /usr/local/src/redhat.txt`
else
	vmfile2=`cat /usr/local/src/ubuntu.txt`
fi

###过滤出来的VMware文件
vmfile2=`find / -name '*vmware*' | sort -r`

##声明diff_list变量为数组型
declare -a diff_list

t=0
flag=0

for file1 in ${vmfile2[@]}
do
	#echo "$file1 is vmfile2"
	for file2 in ${vmfile1[@]}
	do
		#echo "$file2 is vmfile2"
		if [[ "${file}" ==${file2}]]
		then
			flag=1
			#跳出当前for循环,执行下边if
			break
		fi
	#如果flag=0,就把file1给diff_list数组
	if [[ $flag -eq 0 ]]
	then
         #如果$file1中有包含以下字符串的就不输出
		if [[ $file1 == *vmware-vmis* || $file1 == *-sp  ]]
		then
			echo "" 2>&1 > /dev/null
		else
			diff_list[t]=$file1
		     echo ${diff_list[t]}
		     t=$((t+1))
		fi
	else
		flag=0
	fi
done

批量分发公钥

配置文件格式
密码不一样时:
[组名]
192.168.101.154 ansible_ssh_user='root' ansible_ssh_pass='111111'
192.168.101.155 ansible_ssh_user='root' ansible_ssh_pass='222222'
192.168.101.156 ansible_ssh_user='root' ansible_ssh_pass='333333'
192.168.101.157 ansible_ssh_user='root' ansible_ssh_pass='444444'
192.168.101.166 ansible_ssh_user='root' ansible_ssh_pass='555555'
192.168.101.172 ansible_ssh_user='root' ansible_ssh_pass='666666'

密码一样时:
[组名]
192.168.101.154
192.168.101.155
192.168.101.156
192.168.101.157
192.168.101.166
192.168.101.172
[组名:vars]
ansible_ssh_user='root'
ansible_ssh_pass='MKPEUi7rDb81OBKg'
方法一:
ansible 组名 -m blockinfile -a 'dest=/root/.ssh/authorized_keys  block="ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDJg3gXcUtKnGADy+sgvI+ExEOp2T+hlyiDE7L4MdREn8sDSGnvTS4t7/J2CzECLuoYYAmYAxvcyS3eutMnXGR54tnM4hm0/MFhNvYm/9xzzET82ZfEadShnLHZrgtNcn0SfEEUigk0x7snOupcQDB71Voi4JG0UVr+0iKpv0agLcEi5T+Nt9bXqeaW38T0LzW4FUc1JNLLSXIP2kV+K/9lGs+nNBVzDDy+xrJ5TKy+gyx/t/rrijrJ88U3DFs+auovQa8xcMiZ6N4ZVPEige1AWqkSkwaoy1urYHcm4bxd0eoEqF24a6rJUO3EqpsxfZPEf2DXVEj0W9H0J4+70PUUP8oRCcqLW364w+TzkVrE0vEEIBe646LiRqKh8A49PaiaygkQqsT/LBairZUKTs/EOY9WvUYXcbxVfO05vsjVTYvgMZtfah8hFVLnEAapdCsW6BvcNK6errew7o9oxjikKCszWr/8N0euC+J4/04P8E6m6VKcEw66OqfR4zYGYlM= 110356@100302001796"'
方法二:
authorized_keys.yml
---
- name: ssh-copy
blockinfile: path=/root/.ssh/authorized_keys block="{{ lookup('file', 'public_key') }}"

[root@master1 ansible]# cat roles/init/files/public_key 
#测试1
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAvRBWaTcJwmbhfluPnHoGZBf/HNnVx5lwmPnkKx8F7HxeMxuUd6Ju38ReGdY0l0qtiDlTQ6eNuZjakfuca1lw==
#测试2
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC2tVQjRc3Zrkkj6Vh4Vja4iV0fDq0WIUtN+L8PwA5u+ugwQ4U1kTn4P5olepq4oN/SstmuLn9BR6/PvCTjn1Y
方法三:
[root@master1 ansible]# vim roles/init/tasks/ssh.yaml
- hosts: caoguo
  remote_user: root

  tasks:
  - name: copy ssh key
    authorized_key:
      user: root
      key: "{{ lookup('file', '/root/.ssh/id_rsa.pub') }}"
方法四:
[root@localhost ansible]# vim roles/init/tasks/ssh.yaml 
- hosts: caoguo
  remote_user: root

  tasks:
  - name: mkdir /root/.ssh
    command: mkdir -p /root/.ssh

  - name: copy ssh key
    copy: src=/root/.ssh/id_rsa.pub dest=/root/.ssh owner=root group=root mode=0644

blockinfile模块

将内容写入到目标服务器文件中

dest后是目标服务器上的文件,必须存在 block后是公钥

文件中会多出两行
BEGIN ANSIBLE MANGED BLOCK
中间是block的内容
END ANSIBLE MANGED BLOCK

ansible 组名 -m blockinfile -a 'dest=/root/.ssh/文件名  block="内容"'

批量源码安装zabbix-agentd

playbook
---
	- hosts: agentd
	  remote_user: root
  vars:
		host_ip:  "{{inventory_hostname}}"     '   ###中括号里的是ansible的内部变量
	  tasks:
			- name: PS
			  shell:  ps -ef | grep zabbix | grep -v grep | wc -l    ##判断zabbix进程在不在
			  register: zabbix_num      ##声明变量
			- debug: var=zabbix_num				##调试
			- name: zabbix-agent dir exist or not exist 			##判断zabbix安装目录在不在
			  shell: ls -ld /usr/local/zabbix-agent | wc -l
			  register: dir_num								##声明结果
			  ignore_erros: True 			##因为ls目录不存在会报错,所以需要,意思是报错也要执行
			- debug: var=dir_num
			- name: zabbix_agentd script exist or not exist			###判断zabbix_agentd脚本存在不存在
              shell: ls -l /usr/local/src/zabbix_agentd | wc -l		###查zabbix_agnetd脚本
			  register: script_num					##声明变量
			  ignore_errors: True						##因为ls脚本不存在会报错,所以需要,意思是报错也要执行
			- debug: var=script_num
			- name: send zabbix-4.0.4.tar.gz to agent				###发送zabbix包
			  copy: src=/etc/ansible/tar/zabbix_4.0.4.tar.gz dst=/usr/local/src/
			  when: dir_num.stdout == "0"     ##dir_num.stdout 表示输出结果如果等于零,等于零就是没有zabbix_agent目录,就执行,发送tar包
			- name: send zabbix_agentd start or stop script			###发送zabbix_agentd启停程序
			  copy: src=/etc/ansible/roles/init/tasks/zabbix_agentd dest=/usr/local/src/
			  when: script_num.stuout == "0"  ##script_num.stdout 表示输出结果如果等于零,等于零就是没有zabbix_agend,就执行,发送zabbix_agnetd
			- name: install zabbix_agentd
			  script: /etc/ansible/roles/init/tasks/install-zabbix.sh {{host_ip}} > /usr/local/src/zabbix.log   ###执行安装脚本,安装日志在zabbix.log
install-zabbix.sh
#!/bin/bash
srcdir=/usr/local/zabbix_agent
installdir=/usr/local/zabbix-agent
zabbix=zabbix-4.0.4
tar=zabbix-4.0.4.tar.gz

###grep zabbix pid  过滤zabbix进程
num=`ps -ef | grep zabbix_agentd | grep -v grep | wc -l`			###过滤zabbix进程数
pid=`ps -ef | grep zabbix_agentd | grep -v grep | awk '{print $2}'`	###过滤zabbix进程号
usernum=`awk -F':' '{print $1}' /etc/passwd | grep -w "zabbix" | wc -l`    ###过滤是否存在zabbix用户
date=`date +%F`
zabbix_server=192.168.3.51    ###zabbixserverIP

###stop zabbix-agentd 停zabbix_agentd服务
if [ $num -ne 0 ]
then
	kill -9 $pid
fi

###依赖包 install 
[ -d $installdir ] || yum -y install gcc gcc-c++ make pcre pcre-devel

###install zabbix_agentd 安装zabbix_agnetd端
cd $srcdir
[ -d $installdir ] || tar -zxf $tar && cd $zabbix && ./configure --prefix=$installdir --enable-agent && make && make install

###mkdir logdir and backup zabbix_agentd.conf    创建日志目录以及备份配置文件
cd $installdir
[ -d logs ] || mkdir logs
cd etc/
[ -f zabbix_agentd.conf-$date ] || cp zabbix_agentd.conf zabbix_agnetd.conf-$date

###config zabbix_agentd 修改配置文件
cat << eof > zabbix_agentd.conf
PidFile=$installdir/logs/zabbix_agentd.pid
LogFile=$installdir/logs/zabbix_agentd.log
ListenPort=10050
Server=$zabbix_server
ServerActive=$zabbix_sever:10051
Hostname=$1
Include=$installdir/etc/zabbix_agentd.conf.d/*.conf
UnsafeUserParameters=1
eof

###user add zabbix and dir auth  创建用户以及目录权限
if [ $usrnum -eq 0 ]
then
	useradd -M -s /sbin/nologin zabbix
fi
chown -R zabbix:zabbix $installdir

###service join boot  服务加入开机自启
\cp -f $srcdir/zabbix_agentd /etc/init.d/
if [ -f /etc/init.d/zabbix_agentd ]
then
	service=`chkconfig --list` | grep zabbix_agentd | wc -l`
	cd /etc/init.d/
	sed -ri "s|(BASEDIR=)(.*)|\1$installdir|g" /etc/init.d/zabbix_agentd
	sed -i "s|PIDFILE=.*|PIDFILE=$installdir\/logs\/zabbix_agentd.pid|g" /etc/init.d/zabbix_agentd
	chmod +x /etc/init.d/zabbix_agentd
	[ $service -eq 1 ] && chkconfig --del zabbix_agentd
	chkconfig --add zabbix_agentd
	chkconfig zabbix_agentd on
	chkconfig --list | grep zabbix_agentd
fi

###start zabbix 启动zabbix
$installdir/sbin/zabbix_agentd && echo "zabbix service running"

报错

提示ssh主机需要输入yes

Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host’s fingerprint to your known_hosts file to manage this host.
解决:
vi /etc/ansible/ansible.cfg
#uncomment this to disable SSH key host checking
host_key_checking = False

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值