一、安装Ansible

#pip安装
$ yum install python-pip
$ pip install ansible

#yum安装
$ yum install –y epel-release 
$ yum install –y ansible 

#check_ansible
$ ansible -V

二、配置文件

[defaults]                                                   #默认配置inventory = /etc/ansible/hosts #被控制端的IP或者DNS列表
library        = /usr/share/my_modules/                      #默认搜索模块的位置
module_utils   = /usr/share/my_module_utils/                 #自定义模块
remote_tmp     = ~/.ansible/tmp                              #ansible远程主机脚本临时存放目录
local_tmp      = ~/.ansible/tmp                              #ansible管理节点脚本临时存放目录
plugin_filters_cfg = /etc/ansible/plugin_filters.yml         #
forks          = 5                                           #并行线程数
poll_interval  = 15                                          #回频率或轮询间隔时间
sudo_user      = root                                        #sudo远程执行的用户名
ask_sudo_pass = True                                         #使用sudo是否需要密码
ask_pass      = True                                         #是否需要输入密码
transport      = smart                                       #ansible远程传输模式
remote_port    = 22                                          #远程ssh端口
module_lang    = C                                           #模块与系统之间通讯的语言
module_set_locale = False                                    #

gathering = implicit                                         #facts信息收集开关定义
gather_subset = all                                          #指定收集哪些事实变量
gather_timeout = 10                                          #收集事实变量超时时间
inject_facts_as_vars = True                                  #
roles_path    = /etc/ansible/roles                           #ansible角色使用的默认路径
host_key_checking = False                                    #是否检查远程主机的密钥
stdout_callback = skippy                                     #
callback_whitelist = timer, mail                             #回调白名单设置,可以开启ansible时间计算
task_includes_static = False                                 #
handler_includes_static = False                              #
error_on_missing_handler = True                              #
sudo_exe = sudo                                              #sudo远程执行命令
sudo_flags = -H -S -n                                        #传递sudo之外的参数
timeout = 10                                                 #ssh超时登陆时间
remote_user = root                                           #远程登陆用户名
log_path = /var/log/ansible.log                              #日志文件路径
module_name = command                                        #默认执行的模块
executable = /bin/sh                                         #执行shell环境,用户的shell模块
hash_behaviour = replace                                     #ansible主机变量重复处理方式
private_role_vars = yes                                      #默认情况下,角色中的变量将在全局变量范围中可见。 为了防止这种情况,可以启用以下选项,只有tasks的任务和handlers得任务可以看到角色变量
jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n            #开启jinja2模块
private_key_file = /path/to/file                             #私钥文件存储路径
vault_password_file = /path/to/vault_password_file           #指定vault密码文件路径
ansible_managed = Ansible managed                            #定义的一个Jinja2变量,可以插入到Ansible配置模版系统生成的文件中
display_skipped_hosts = True                                 #显示跳过任何任务状态
display_args_to_stdout = False                               #
error_on_undefined_vars = False                              #如果所引用的变量名称错误的话, 将会导致ansible在执行步骤上失败
system_warnings = True                                       #禁止运行ansible潜在问题警告
deprecation_warnings = True                                  #playbook输出禁用不建议使用警告
command_warnings = False                                     #command模块警告

action_plugins     = /usr/share/ansible/plugins/action       #用来激活一些事件,例如执行一个模块,一个模版,等等
become_plugins     = /usr/share/ansible/plugins/become
cache_plugins      = /usr/share/ansible/plugins/cache
callback_plugins   = /usr/share/ansible/plugins/callback     # 这是一个以开发者为中心的特性,可以实现对Ansible的底层拓展,并且拓展模块可以位于任何位置
connection_plugins = /usr/share/ansible/plugins/connection   #连接插件允许拓展ansible拓展通讯信道,用来传输命令或者文件
lookup_plugins     = /usr/share/ansible/plugins/lookup
inventory_plugins  = /usr/share/ansible/plugins/inventory
vars_plugins       = /usr/share/ansible/plugins/vars
filter_plugins     = /usr/share/ansible/plugins/filter       #过滤器是一种特殊的函数,用来拓展模版系统 
test_plugins       = /usr/share/ansible/plugins/test
terminal_plugins   = /usr/share/ansible/plugins/terminal
strategy_plugins   = /usr/share/ansible/plugins/strategy

strategy = free
# free 每个host按照task执行,不与其他host相关联,也就是说host会一直把自己的tasks执行完,再继续下一个host的,此种执行方式,会发现每次执行task时,显示的 却不一定是当前task的进程。
# debug 类似pdb.strace() 如果有错误会直接进入调试模式
# linear 线性的执行策略,所有hosts逐一task执行,每次并发5个,同步执行。

bin_ansible_callbacks = False                                 #用来控制callback插件是否在运行 /usr/bin/ansible 的时候被加载. 这个模块将用于命令行的日志系统,发出通知等特性
nocows = 1                                                    #默认ansible可以调用一些cowsay的特性   开启/禁用:0/1
cow_selection = default
cow_selection = random
nocolor = 1                                                   #输出带上颜色区别, 开启/关闭:0/1
fact_caching = memory                                         #fact值默认存储在内存中,可以设置存储在redis中,用于持久化存储
fact_caching_connection=/tmp                                  #缓存位置
retry_files_enabled = False                                   #当playbook失败得情况下,一个重试文件将会创建,默认为开启此功能
retry_files_save_path = ~/.ansible-retry                      #重试文件的路径,默认为当前目录下.ansible-retry
squash_actions = apk,apt,dnf,homebrew,pacman,pkgng,yum,zypper #Ansible可以优化在循环时使用列表参数调用模块的操作。 而不是每个with_项调用模块一次,该模块会一次调用所有项目一次。该参数记录哪些action是这样操作得。
no_log = False                                                #任务数据的日志记录,默认情况下关闭
no_target_syslog = False                                      #防止任务的日志记录,但只在目标上,数据仍然记录在主/控制器上
allow_world_readable_tmpfiles = False                         #
var_compression_level = 9                                     #控制发送到工作进程的变量的压缩级别。 默认值为0,不使用压缩。 此值必须是从0到9的整数。
module_compression = 'ZIP_DEFLATED'                           #指定压缩方法,默认使用zlib压缩,可以通过ansible_module_compression来为每个主机设置
max_diff_size = 1048576                                       #控制--diff文件上的截止点(以字节为单位),设置0则为无限制(可能对内存有影响)
merge_multiple_cli_flags = True                               #
show_custom_stats = True                                      #
inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
network_group_modules=eos, nxos, ios, iosxr, junos, vyos
allow_unsafe_lookups = False
any_errors_fatal = False



[inventory]
enable_plugins = host_list, virtualbox, yaml, constructed
ignore_extensions = .pyc, .pyo, .swp, .bak, ~, .rpm, .md, .txt, ~, .orig, .ini, .cfg, .retry
ignore_patterns=
unparsed_is_failed=False


[privilege_escalation]                                      #sudo提权后使用的配置
become=True                                                 #是否启用
become_method=sudo                                          #启用方式
become_user=root                                            #启用后的用户
become_ask_pass=False                                       #是否验证密码


[paramiko_connection]                                        #不经常使用
record_host_keys=False                                       #不记录新主机的key以提升效率
pty=False                                                    #禁用sudo功能
look_for_keys = False
host_key_auto_add = True


[ssh_connection]
ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s    #ssh连接时得参数
control_path_dir =                                           #保存ControlPath套接字的位置
control_path =                                               
pipelining = False                                           #SSH pipelining 是一个加速 Ansible 执行速度的简单方法。ssh pipelining 默认是关闭,之所以默认关闭是为了兼容不同的 sudo 配置,主要是 requiretty 选项。如果不使用 sudo,建议开启。打开此选项可以减少 ansible 执行没有传输时 ssh 在被控机器上执行任务的连接数。不过,如果使用 sudo,必须关闭 requiretty 选项。
scp_if_ssh = smart                                            #该项为True时,如果连接类型是ssh,使ansible使用scp,为False是,ansible使用sftp。默认为sftp
transfer_method = smart                                       
sftp_batch_mode = False                                       #该项为False时,sftp不会使用批处理模式传输文件。 这可能导致一些类型的文件传输失败而不可捕获,但应该只有在您的sftp版本在批处理模式上有问题时才应禁用
usetty = True                                                 
retries = 3                                                    


[persistent_connection]
connect_timeout = 30
command_timeout = 30


[accelerate]                                                   #ansible的加速连接配置
accelerate_port = 5099                                         #加速连接端口
accelerate_timeout = 30                                        #命令执行超时时间
accelerate_connect_timeout = 5.0                               #连接超时时间
accelerate_daemon_timeout = 30                                 #上一个活动连接
accelerate_multi_key = yes                                                   


[selinux]
special_context_filesystems=nfs,vboxsf,fuse,ramfs,9p,vfat
libvirt_lxc_noseclabel = yes


[colors]
highlight = white
verbose = blue
warn = bright purple
error = red
debug = dark gray
deprecate = purple
skip = cyan
unreachable = red
ok = green
changed = yellow
diff_add = green
diff_remove = red
diff_lines = cyan


[diff]
always = no
context = 3

三、Ansible常用命令

1、command模块

command模块可以帮助我们在远程主机上执行命令!

注意:使用command模块在远程主机中执行命令时,不会经过远程主机的shell处理,在使用command模块时,如果需要执行的命令中含有重定向、管道符等操作时,这些符号也会失效,比如<, >, |, ; 和 & 这些符号,如果你需要这些功能,可以参考后面介绍的shell模块,还有一点需要注意,如果远程节点是windows操作系统,则需要使用win_command模块。此处我们介绍一些command模块的常用参数,你可以先对这些参数有一个大概了解,然后再看小示例:

free_form参数 :必须参数,指定需要远程执行的命令,需要说明一点,free_form参数与其他参数并不相同,在之前的模块示例中,如果想要使用一个参数,那么则需要为这个参数赋值,举个例子,之前的示例模块中,大多都有path参数,当我们需要指定要操作的文件时,通常需要对path参数赋值,比如,path=/testdir/test,表示我们想要操作/testdir/test文件,但是free_form参数则不同,free_form并不是一个”实际存在”的参数名,比如,当我们想要在远程主机上执行ls命令时,我们并不需要写成free_form=ls ,这样写反而是错误的,因为并没有任何参数的名字是free_form,当我们想要在远程主机中执行ls命令时,直接写成ls即可,这就是free_form参数的含义,因为command模块的作用是执行命令,所以,任何一个可以在远程主机上执行的命令都可以被称为free_form,如果你还是不明白,看下面的小示例就行了;

chdir参数 : 此参数的作用就是指定一个目录,在执行对应的命令之前,会先进入到chdir参数指定的目录中;

creates参数 :看到creates,你可能会从字面上理解这个参数,但是使用这个参数并不会帮助我们创建文件,它的作用是当指定的文件存在时,就不执行对应命令,比如,如果/testdir/test文件存在,就不执行我们指定的命令;

removes参数 :与creates参数的作用正好相反,它的作用是当指定的文件不存在时,就不执行对应命令,比如,如果/testdir/tests文件不存在,就不执行我们指定的命令,此参数并不会帮助我们删除文件 

##示例命令
#使用如下命令,表示在test主机上执行ls命令,因为我使用的是root用户,所以默认情况下,ls的结果是test主机中root用户家目录中的文件列表;

$ ansible test -m command -a "ls"

#chdir参数表示执行命令之前,会先进入到指定的目录中,所以如下命令表示查看test主机上/testdir目录中的文件列表;

$ ansible test -m command -a "chdir=/testdir ls"

如下命令表示/testdir/test文件如果存在于远程主机中,则不执行对应命令,如果不存在,才执行echo test命令;

$ ansible test -m command -a "creates=/testdir/test echo test"

如下命令表示/testdir/test文件如果不存在于远程主机中,则不执行对应命令,如果存在,才执行echo test命令;

$ ansible test -m command -a "removes=/testdir/test echo test"

2、shell模块

shell模块可以帮助我们在远程主机上执行命令,与command模块不同的是,shell模块在远程主机中执行命令时,会经过远程主机上的/bin/sh程序处理。

学习此模块之前,请先参考本文中的command模块。

此处我们介绍一些shell模块的常用参数:

free_form参数 :必须参数,指定需要远程执行的命令,但是并没有具体的一个参数名叫free_form,具体解释参考command模块;

chdir参数 : 此参数的作用就是指定一个目录,在执行对应的命令之前,会先进入到chdir参数指定的目录中;

creates参数 :使用此参数指定一个文件,当指定的文件存在时,就不执行对应命令,可参考command模块中的解释;

removes参数 :使用此参数指定一个文件,当指定的文件不存在时,就不执行对应命令,可参考command模块中的解释;

executable参数:默认情况下,shell模块会调用远程主机中的/bin/sh去执行对应的命令,通常情况下,远程主机中的默认shell都是bash,如果你想要使用其他类型的shell执行命令,则可以使用此参数指定某种类型的shell去执行对应的命令,指定shell文件时,需要使用绝对路径。

shell模块中chdir、creates、removes参数的作用与command模块中的作用都是相同的,此处不再举例

##示例命令
#使用shell模块可以在远程服务器上执行命令,它支持管道与重定向等符号。

$ ansible test -m shell -a "chdir=/testdir echo test > test"

#如果你想要执行的命令需要csh解析,那么可以指定使用csh在远程主机上执行对应的命令,比如在如下示例中,我们使用csh的语法定义了一个数字类型的变量TestNum,然后将TestNum变量的值重定向到了/testdir/TestNumFile,在bash中,@符号不能用于定义变量,所以,可以使用executable指定需要的shell类型。

$ ansible test -m shell -a 'executable=/bin/csh @ TestNum=666 ; echo $TestNum > /testdir/TestNumFile'

3、script模块

script模块可以帮助我们在远程主机上执行ansible主机上的脚本,也就是说,脚本一直存在于ansible主机本地,不需要手动拷贝到远程主机后再执行。

学习此模块之前,请先参考本文中的command模块。

此处我们介绍一些script模块的常用参数,你可以先对这些参数有一个大概了解,然后再看小示例:

free_form参数 :必须参数,指定需要执行的脚本,脚本位于ansible主机本地,并没有具体的一个参数名叫free_form,具体解释参考command模块;

chdir参数 : 此参数的作用就是指定一个远程主机中的目录,在执行对应的脚本之前,会先进入到chdir参数指定的目录中;

creates参数 :使用此参数指定一个远程主机中的文件,当指定的文件存在时,就不执行对应脚本,可参考command模块中的解释;

removes参数 :使用此参数指定一个远程主机中的文件,当指定的文件不存在时,就不执行对应脚本,可参考command模块中的解释;

##示例命令

#如下命令表示ansible主机中的/testdir/atest.sh脚本将在test主机中执行,执行此脚本之前,会先进入到test主机中的/opt目录

$ ansible test -m script -a "chdir=/opt /testdir/atest.sh"

#如下命令表示,如果test主机中的/opt/testfile文件已经存在,ansible主机中的/testdir/atest.sh脚本将不会在test主机中执行,反之则执行。

$ ansible test -m script -a "creates=/opt/testfile /testdir/atest.sh"


#如下命令表示,如果test主机中的/opt/testfile文件不存在,ansible主机中的/testdir/atest.sh脚本将不会在test主机中执行,反之则执行。

$ ansible test -m script -a "removes=/opt/testfile /testdir/atest.sh"