初探ansible

Ansible

基于ssh的自动化运维工具

ansible 配置文件详解 

ansible.cfg 文件

文件默认放置在/etc/ansible下,ansible读取配置文件的顺序是: 当前命令执行目录-> 用户家目录的.ansible.cfg -> /etc/ansible.cfg

defaults
[defaults]

# some basic default values...

#inventory      = /etc/ansible/hosts # 定义Inventory
#library        = /usr/share/my_modules/ # 定义lib库的存放目录
#module_utils   = /usr/share/my_module_utils/ 
#remote_tmp     = ~/.ansible/tmp # 定义临时远程文件存放目录
#local_tmp      = ~/.ansible/tmp # 定于临时文件本地存放目录
#plugin_filters_cfg = /etc/ansible/plugin_filters.yml 
#forks          = 5 #默认开启的并发数
#poll_interval  = 15 #默认轮询的时间间隔
#sudo_user      = root # 默认dudo用户
#ask_sudo_pass = True # 是否需要sudo密码
#ask_pass      = True # 是否需要密码
#transport      = smart 
#remote_port    = 22 # 远程默认端口
#module_lang    = C 
#module_set_locale = False

# plays will gather facts by default, which contain information about
# the remote system.
#
# smart - gather by default, but don't regather if already gathered
# implicit - gather by default, turn off with gather_facts: False
# explicit - do not gather by default, must say gather_facts: True
#gathering = implicit

# This only affects the gathering done by a play's gather_facts directive,
# by default gathering retrieves all facts subsets
# all - gather all subsets
# network - gather min and network facts
# hardware - gather hardware facts (longest facts to retrieve)
# virtual - gather min and virtual facts
# facter - import facts from facter
# ohai - import facts from ohai
# You can combine them using comma (ex: network,virtual)
# You can negate them using ! (ex: !hardware,!facter,!ohai)
# A minimal set of facts is always gathered.
#gather_subset = all

# some hardware related facts are collected
# with a maximum timeout of 10 seconds. This
# option lets you increase or decrease that
# timeout to something more suitable for the
# environment.
# gather_timeout = 10

# Ansible facts are available inside the ansible_facts.* dictionary
# namespace. This setting maintains the behaviour which was the default prior
# to 2.5, duplicating these variables into the main namespace, each with a
# prefix of 'ansible_'.
# This variable is set to True by default for backwards compatibility. It
# will be changed to a default of 'False' in a future release.
# ansible_facts.
# inject_facts_as_vars = True

# additional paths to search for roles in, colon separated
#roles_path    = /etc/ansible/roles # 默认下载roles存放目录

# uncomment this to disable SSH key host checking
#host_key_checking = False # 首次连接是否需要key认证

# change the default callback, you can only have one 'stdout' type  enabled at a time.
#stdout_callback = skippy 


## Ansible ships with some plugins that require whitelisting,
## this is done to avoid running all of a type by default.
## These setting lists those that you want enabled for your system.
## Custom plugins should not need this unless plugin author specifies it.

# enable callback plugins, they can output to stdout but cannot be 'stdout' type.
#callback_whitelist = timer, mail

# Determine whether includes in tasks and handlers are "static" by
# default. As of 2.0, includes are dynamic by default. Setting these
# values to True will make includes behave more like they did in the
# 1.x versions.
#task_includes_static = False
#handler_includes_static = False

# Controls if a missing handler for a notification event is an error or a warning
#error_on_missing_handler = True

# change this for alternative sudo implementations
#sudo_exe = sudo

# What flags to pass to sudo
# WARNING: leaving out the defaults might create unexpected behaviours
#sudo_flags = -H -S -n

# SSH timeout
#timeout = 10 #默认SSH 超时时间

# default user to use for playbooks if user is not specified
# (/usr/bin/ansible will use current user as default)
#remote_user = root 

# logging is off by default unless this path is defined
# if so defined, consider logrotate
#log_path = /var/log/ansible.log

# default module name for /usr/bin/ansible
#module_name = command # 默认执行的模块

# use this shell for commands executed under sudo
# you may need to change this to bin/bash in rare instances
# if sudo is constrained
#executable = /bin/sh 

# if inventory variables overlap, does the higher precedence one win
# or are hash values merged together?  The default is 'replace' but
# this can also be set to 'merge'.
#hash_behaviour = replace

# by default, variables from roles will be visible in the global variable
# scope. To prevent this, the following option can be enabled, and only
# tasks and handlers within the role will see the variables there
#private_role_vars = yes

# list any Jinja2 extensions to enable here:
#jinja2_extensions = jinja2.ext.do,jinja2.ext.i18n

# if set, always use this private key file for authentication, same as
# if passing --private-key to ansible or ansible-playbook
#private_key_file = /path/to/file

# If set, configures the path to the Vault password file as an alternative to
# specifying --vault-password-file on the command line.
#vault_password_file = /path/to/vault_password_file

# format of string {{ ansible_managed }} available within Jinja2
# templates indicates to users editing templates files will be replaced.
# replacing {file}, {host} and {uid} and strftime codes with proper values.
#ansible_managed = Ansible managed: {file} modified on %Y-%m-%d %H:%M:%S by {uid} on {host}
# {file}, {host}, {uid}, and the timestamp can all interfere with idempotence
# in some situations so the default is a static string:
#ansible_managed = Ansible managed

# by default, ansible-playbook will display "Skipping [host]" if it determines a task
# should not be run on a host.  Set this to "False" if you don't want to see these "Skipping"
# messages. NOTE: the task header will still be shown regardless of whether or not the
# task is skipped.
#display_skipped_hosts = True

# by default, if a task in a playbook does not include a name: field then
# ansible-playbook will construct a header that includes the task's action but
# not the task's args.  This is a security feature because ansible cannot know
# if the *module* considers an argument to be no_log at the time that the
# header is printed.  If your environment doesn't have a problem securing
# stdout from ansible-playbook (or you have manually specified no_log in your
# playbook on all of the tasks where you have secret information) then you can
# safely set this to True to get more informative messages.
#display_args_to_stdout = False

# by default (as of 1.3), Ansible will raise errors when attempting to dereference
# Jinja2 variables that are not set in templates or action lines. Uncomment this line
# to revert the behavior to pre-1.3.
#error_on_undefined_vars = False

# by default (as of 1.6), Ansible may display warnings based on the configuration of the
# system running ansible itself. This may include warnings about 3rd party packages or
# other conditions that should be resolved if possible.
# to disable these warnings, set the following value to False:
#system_warnings = True

# by default (as of 1.4), Ansible may display deprecation warnings for language
# features that should no longer be used and will be removed in future versions.
# to disable these warnings, set the following value to False:
#deprecation_warnings = True

# (as of 1.8), Ansible can optionally warn when usage of the shell and
# command module appear to be simplified by using a default Ansible module
# instead.  These warnings can be silenced by adjusting the following
# setting or adding warn=yes or warn=no to the end of the command line
# parameter string.  This will for example suggest using the git module
# instead of shelling out to the git command.
# command_warnings = False


# set plugin path directories here, separate with colons
# 默认插件存放的路径
#action_plugins     = /usr/share/ansible/plugins/action 
#cache_plugins      = /usr/share/ansible/plugins/cache
#callback_plugins   = /usr/share/ansible/plugins/callback
#connection_plugins = /usr/share/ansible/plugins/connection
#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


# by default, ansible will use the 'linear' strategy but you may want to try
# another one
#strategy = free

# by default callbacks are not loaded for /bin/ansible, enable this if you
# want, for example, a notification or logging callback to also apply to
# /bin/ansible runs
#bin_ansible_callbacks = False


# don't like cows?  that's unfortunate.
# set to 1 if you don't want cowsay support or export ANSIBLE_NOCOWS=1
#nocows = 1

# set which cowsay stencil you'd like to use by default. When set to 'random',
# a random stencil will be selected for each task. The selection will be filtered
# against the `cow_whitelist` option below.
#cow_selection = default
#cow_selection = random

# when using the 'random' option for cowsay, stencils will be restricted to this list.
# it should be formatted as a comma-separated list with no spaces between names.
# NOTE: line continuations here are for formatting purposes only, as the INI parser
#       in python does not support them.
#cow_whitelist=bud-frogs,bunny,cheese,daemon,default,dragon,elephant-in-snake,elephant,eyes,\
#              hellokitty,kitty,luke-koala,meow,milk,moofasa,moose,ren,sheep,small,stegosaurus,\
#              stimpy,supermilker,three-eyes,turkey,turtle,tux,udder,vader-koala,vader,www

# don't like colors either?
# set to 1 if you don't want colors, or export ANSIBLE_NOCOLOR=1
#nocolor = 1

# if set to a persistent type (not 'memory', for example 'redis') fact values
# from previous runs in Ansible will be stored.  This may be useful when
# wanting to use, for example, IP information from one group of servers
# without having to talk to them in the same playbook run to get their
# current IP information.
#fact_caching = memory 

#This option tells Ansible where to cache facts. The value is plugin dependent.
#For the jsonfile plugin, it should be a path to a local directory.
#For the redis plugin, the value is a host:port:database triplet: fact_caching_connection = localhost:6379:0

#fact_caching_connection=/tmp # getfact缓存的主机信息存放方式



# retry files
# When a playbook fails by default a .retry file will be created in ~/
# You can disable this feature by setting retry_files_enabled to False
# and you can change the location of the files by setting retry_files_save_path

#retry_files_enabled = False
#retry_files_save_path = ~/.ansible-retry #错误重启文件存放目录

# squash actions
# Ansible can optimise actions that call modules with list parameters
# when looping. Instead of calling the module once per with_ item, the
# module is called once with all items at once. Currently this only works
# under limited circumstances, and only with parameters named 'name'.
#squash_actions = apk,apt,dnf,homebrew,pacman,pkgng,yum,zypper

# prevents logging of task data, off by default
#no_log = False

# prevents logging of tasks, but only on the targets, data is still logged on the master/controller
#no_target_syslog = False

# controls whether Ansible will raise an error or warning if a task has no
# choice but to create world readable temporary files to execute a module on
# the remote machine.  This option is False by default for security.  Users may
# turn this on to have behaviour more like Ansible prior to 2.1.x.  See
# https://docs.ansible.com/ansible/become.html#becoming-an-unprivileged-user
# for more secure ways to fix this than enabling this option.
#allow_world_readable_tmpfiles = False

# controls the compression level of variables sent to
# worker processes. At the default of 0, no compression
# is used. This value must be an integer from 0 to 9.
#var_compression_level = 9

# controls what compression method is used for new-style ansible modules when
# they are sent to the remote system.  The compression types depend on having
# support compiled into both the controller's python and the client's python.
# The names should match with the python Zipfile compression types:
# * ZIP_STORED (no compression. available everywhere)
# * ZIP_DEFLATED (uses zlib, the default)
# These values may be set per host via the ansible_module_compression inventory
# variable
#module_compression = 'ZIP_DEFLATED'

# This controls the cutoff point (in bytes) on --diff for files
# set to 0 for unlimited (RAM may suffer!).
#max_diff_size = 1048576

# This controls how ansible handles multiple --tags and --skip-tags arguments
# on the CLI.  If this is True then multiple arguments are merged together.  If
# it is False, then the last specified argument is used and the others are ignored.
# This option will be removed in 2.8.
#merge_multiple_cli_flags = True

# Controls showing custom stats at the end, off by default
#show_custom_stats = True

# Controls which files to ignore when using a directory as inventory with
# possibly multiple sources (both static and dynamic)
#inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo

# This family of modules use an alternative execution path optimized for network appliances
# only update this setting if you know how this works, otherwise it can break module execution
#network_group_modules=eos, nxos, ios, iosxr, junos, vyos

# When enabled, this option allows lookups (via variables like {{lookup('foo')}} or when used as
# a loop with `with_foo`) to return data that is not marked "unsafe". This means the data may contain
# jinja2 templating language which will be run through the templating engine.
# ENABLING THIS COULD BE A SECURITY RISK
#allow_unsafe_lookups = False

# set default errors for all plays
#any_errors_fatal = False
privilege_escalation
[privilege_escalation]
#become=True #是否sudo
#become_method=sudo #sudo方式
#become_user=root #sudo后的用户
#become_ask_pass=False #sudo后是否验证密码
paramiko_connection
[paramiko_connection]

# uncomment this line to cause the paramiko connection plugin to not record new host
# keys encountered.  Increases performance on new host additions.  Setting works independently of the
# host key checking setting above.
#record_host_keys=False #不记录新主机的key提升效率

# by default, Ansible requests a pseudo-terminal for commands executed under sudo. Uncomment this
# line to disable this behaviour.
#pty=False #禁用sudo功能

# paramiko will default to looking for SSH keys initially when trying to
# authenticate to remote devices.  This is a problem for some network devices
# that close the connection after a key failure.  Uncomment this line to
# disable the Paramiko look for keys function
#look_for_keys = False

# When using persistent connections with Paramiko, the connection runs in a
# background process.  If the host doesn't already have a valid SSH key, by
# default Ansible will prompt to add the host key.  This will cause connections
# running in background processes to fail.  Uncomment this line to have
# Paramiko automatically add host keys.
#host_key_auto_add = True
ssh_connection
[ssh_connection]

# ssh arguments to use
# Leaving off ControlPersist will result in poor performance, so use
# paramiko on older platforms rather than removing it, -C controls compression use
#ssh_args = -C -o ControlMaster=auto -o ControlPersist=60s

# The base directory for the ControlPath sockets.
# This is the "%(directory)s" in the control_path option
#
# Example:
# control_path_dir = /tmp/.ansible/cp
#control_path_dir = ~/.ansible/cp

# The path to use for the ControlPath sockets. This defaults to a hashed string of the hostname,
# port and username (empty string in the config). The hash mitigates a common problem users
# found with long hostames and the conventional %(directory)s/ansible-ssh-%%h-%%p-%%r format.
# In those cases, a "too long for Unix domain socket" ssh error would occur.
#
# Example:
# control_path = %(directory)s/%%h-%%r
#control_path =

# Enabling pipelining reduces the number of SSH operations required to
# execute a module on the remote server. This can result in a significant
# performance improvement when enabled, however when using "sudo:" you must
# first disable 'requiretty' in /etc/sudoers
#
# By default, this option is disabled to preserve compatibility with
# sudoers configurations that have requiretty (the default on many distros).
#
#pipelining = False #管道加速功能,需要配置requiretty使用

# Control the mechanism for transferring files (old)
#   * smart = try sftp and then try scp [default]
#   * True = use scp only
#   * False = use sftp only
#scp_if_ssh = smart

# Control the mechanism for transferring files (new)
# If set, this will override the scp_if_ssh option
#   * sftp  = use sftp to transfer files
#   * scp   = use scp to transfer files
#   * piped = use 'dd' over SSH to transfer files
#   * smart = try sftp, scp, and piped, in that order [default]
#transfer_method = smart

# if False, sftp will not use batch mode to transfer files. This may cause some
# types of file transfer failures impossible to catch however, and should
# only be disabled if your sftp version has problems with batch mode
#sftp_batch_mode = False

# The -tt argument is passed to ssh when pipelining is not enabled because sudo 
# requires a tty by default. 
#use_tty = True

# Number of times to retry an SSH connection to a host, in case of UNREACHABLE.
# For each retry attempt, there is an exponential backoff,
# so after the first attempt there is 1s wait, then 2s, 4s etc. up to 30s (max).
#retries = 3
accelerate
[accelerate]
#accelerate_port = 5099 # 加速连接端口
#accelerate_timeout = 30 #命令执行超时
#accelerate_connect_timeout = 5.0 #连接超时

# The daemon timeout is measured in minutes. This time is measured
# from the last activity to the accelerate daemon.
#accelerate_daemon_timeout = 30 #上一个活动连接的时间

# If set to yes, accelerate_multi_key will allow multiple
# private keys to be uploaded to it, though each user must
# have access to the system via SSH to add a new key. The default
# is "no".
#accelerate_multi_key = yes 
selinux
[selinux]
# file systems that require special treatment when dealing with security context
# the default behaviour that copies the existing context or uses the user default
# needs to be changed to use the file system dependent context.
#special_context_filesystems=nfs,vboxsf,fuse,ramfs,9p

# Set this to yes to allow libvirt_lxc connections to work without SELinux.
#libvirt_lxc_noseclabel = yes
colors
[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

基于ssh key 验证

产生ssh公钥
# ssh-keygen -t rsa -C "test.ansible"
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):    
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
02:ec:bd:bb:8c:d0:fb:fc:4a:d7:25:00:dc:62:e2:de test.ansible
The key's randomart image is:
+--[ RSA 2048]----+
|     ...         |
|   .. +..        |
|   .oo ..        |
|   ..o   .       |
|   ...o S . .    |
|   .. Eo . o     |
|  . . o . .      |
|   . * o         |
|    o.B+.        |
+-----------------+
# 
copy ssh key公钥
# ssh-copy-id -i /root/.ssh/id_rsa.pub root@47.96.×.×
The authenticity of host '47.96.×.× (47.96.×.×)' can't be established.
ECDSA key fingerprint is 21:d2:86:df:11:58:b2:88:4b:2d:b2:dc:81:e1:35:a6.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@47.96.×.×'s password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@47.96.×.×'"
and check to make sure that only the key(s) you wanted were added.

#

ansible 基本命令使用

语法
# ansible --help | head -n 1
Usage: ansible <host-pattern> [options]
# 
<host-pattern>

是Inventory中定义的主机或者主机组,可以为,ip hostname group等

[options]
-m NAME , --module-name=NAME: 指定执行使用的模块
-u USERNAME, --user=USERNAME: 指定远程主机以USERNAME运行命令
-s , --sudo: 相当于linux系统下的sudo命令
-U SUDO_USERNAME , --sudo-user=SUDO_USERNAME: 使用sudo,相当于linux下的sudo命令
案例
1.查看全部主机的hostname
# date +"%F_%H_%M_%S" ; ansible all -m command -a "hostname" ;  date +"%F_%H_%M_%S"
2019-02-14_14_10_06
118.24.×.× | CHANGED | rc=0 >>
VM_16_16_centos

121.196.×.× | CHANGED | rc=0 >>
iZbp17twzbvh62ydqkggc2Z

47.111.×.× | CHANGED | rc=0 >>
iZbp14gjvbmzrz8z1jyorvZ

47.96.×.× | CHANGED | rc=0 >>
iZbp1hvlnilb22bvkdnk4mZ

47.105.×.× | CHANGED | rc=0 >>
iZm5edwptyaf0mwcw02muhZ

47.96.×.× | CHANGED | rc=0 >>
iZbp1eafj0lnxqoiww6l3bZ

116.62.×.× | CHANGED | rc=0 >>
iZbp1fzb5xamtnab0jhofuZ

47.244.×.× | CHANGED | rc=0 >>
iZj6cb5ign9dl1h9l412g5Z

2019-02-14_14_10_15
# 
2.查看group1,group2的磁盘空间
# ansible group1,group2 -m command -a "df -h"
121.196.×.× | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  1.7G   36G   5% /
devtmpfs        486M     0  486M   0% /dev
tmpfs           496M     0  496M   0% /dev/shm
tmpfs           496M  432K  496M   1% /run
tmpfs           496M     0  496M   0% /sys/fs/cgroup
tmpfs           100M     0  100M   0% /run/user/0

47.111.×.× | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  1.7G   36G   5% /
devtmpfs        486M     0  486M   0% /dev
tmpfs           496M     0  496M   0% /dev/shm
tmpfs           496M  432K  496M   1% /run
tmpfs           496M     0  496M   0% /sys/fs/cgroup
tmpfs           100M     0  100M   0% /run/user/0

47.96.×.× | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  1.7G   36G   5% /
devtmpfs        486M     0  486M   0% /dev
tmpfs           496M     0  496M   0% /dev/shm
tmpfs           496M  432K  496M   1% /run
tmpfs           496M     0  496M   0% /sys/fs/cgroup
tmpfs           100M     0  100M   0% /run/user/0

47.105.×.× | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  1.8G   36G   5% /
devtmpfs        486M     0  486M   0% /dev
tmpfs           496M     0  496M   0% /dev/shm
tmpfs           496M  432K  496M   1% /run
tmpfs           496M     0  496M   0% /sys/fs/cgroup
tmpfs           100M     0  100M   0% /run/user/0# 
3.查看47.105.×.×的内存使用情况
# ansible 47.105.×.× -m shell -a "free -h"
47.105.×.× | CHANGED | rc=0 >>
              total        used        free      shared  buff/cache   available
Mem:           991M         65M        743M        432K        181M        778M
Swap:            0B          0B          0B

# 

ansible AD-Hoc命令集

ansible 命令用法
Usage: ansible <host-pattern> [options]
可用选项如下:
-v 输出更为详细的执行过此 -vvv 可得到执行过程的所有信息
-i PATH ,指定inventory信息,默认/etc/ansible/host
-f NUM, --forks=NUM ,并发线程数,默认5个
-m NAME,指定执行使用的模块
-a 模块参数
-k 认证密码
-K 认证sudo密码
-o 标准输出至一行
-t DIRECTORY 输出信息至DIRECTORY目录下,结果文件以远程主机命名
ansible 命令执行流程
# ansible 116.62.×.× -m command -a "df -h" -vvv
ansible 2.7.7
  config file = /etc/ansible/ansible.cfg
  configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/lib/python2.7/site-packages/ansible
  executable location = /usr/bin/ansible
  python version = 2.7.5 (default, Nov  6 2016, 00:28:07) [GCC 4.8.5 20150623 (Red Hat 4.8.5-11)]
Using /etc/ansible/ansible.cfg as config file
/etc/ansible/hosts did not meet host_list requirements, check plugin documentation if this is unexpected
/etc/ansible/hosts did not meet script requirements, check plugin documentation if this is unexpected
Parsed /etc/ansible/hosts inventory source with ini plugin
META: ran handlers
<116.62.×.×> ESTABLISH SSH CONNECTION FOR USER: None
<116.62.×.×> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e870a09818 116.62.×.× '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<116.62.×.×> (0, '/root\n', '')
<116.62.×.×> ESTABLISH SSH CONNECTION FOR USER: None
<116.62.×.×> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e870a09818 116.62.×.× '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp/ansible-tmp-1550125721.57-130973814602143 `" && echo ansible-tmp-1550125721.57-130973814602143="` echo /root/.ansible/tmp/ansible-tmp-1550125721.57-130973814602143 `" ) && sleep 0'"'"''
<116.62.×.×> (0, 'ansible-tmp-1550125721.57-130973814602143=/root/.ansible/tmp/ansible-tmp-1550125721.57-130973814602143\n', '')
Using module file /usr/lib/python2.7/site-packages/ansible/modules/commands/command.py
<116.62.×.×> PUT /root/.ansible/tmp/ansible-local-18588u6H5KJ/tmps8P40y TO /root/.ansible/tmp/ansible-tmp-1550125721.57-130973814602143/AnsiballZ_command.py
<116.62.×.×> SSH: EXEC sftp -b - -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e870a09818 '[116.62.×.×]'
<116.62.×.×> (0, 'sftp> put /root/.ansible/tmp/ansible-local-18588u6H5KJ/tmps8P40y /root/.ansible/tmp/ansible-tmp-1550125721.57-130973814602143/AnsiballZ_command.py\n', '')
<116.62.×.×> ESTABLISH SSH CONNECTION FOR USER: None
<116.62.×.×> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e870a09818 116.62.×.× '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1550125721.57-130973814602143/ /root/.ansible/tmp/ansible-tmp-1550125721.57-130973814602143/AnsiballZ_command.py && sleep 0'"'"''
<116.62.×.×> (0, '', '')
<116.62.×.×> ESTABLISH SSH CONNECTION FOR USER: None
<116.62.×.×> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e870a09818 -tt 116.62.×.× '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1550125721.57-130973814602143/AnsiballZ_command.py && sleep 0'"'"''
<116.62.×.×> (0, '\r\n{"changed": true, "end": "2019-02-14 14:28:43.648606", "stdout": "Filesystem      Size  Used Avail Use% Mounted on\\n/dev/vda1        40G  1.8G   36G   5% /\\ndevtmpfs        486M     0  486M   0% /dev\\ntmpfs           496M     0  496M   0% /dev/shm\\ntmpfs           496M  436K  496M   1% /run\\ntmpfs           496M     0  496M   0% /sys/fs/cgroup\\ntmpfs           100M     0  100M   0% /run/user/0", "cmd": ["df", "-h"], "rc": 0, "start": "2019-02-14 14:28:43.623024", "stderr": "", "delta": "0:00:00.025582", "invocation": {"module_args": {"warn": true, "executable": null, "_uses_shell": false, "_raw_params": "df -h", "removes": null, "argv": null, "creates": null, "chdir": null, "stdin": null}}}\r\n', 'Shared connection to 116.62.×.× closed.\r\n')
<116.62.×.×> ESTABLISH SSH CONNECTION FOR USER: None
<116.62.×.×> SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o ConnectTimeout=10 -o ControlPath=/root/.ansible/cp/e870a09818 116.62.×.× '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1550125721.57-130973814602143/ > /dev/null 2>&1 && sleep 0'"'"''
<116.62.×.×> (0, '', '')
116.62.×.× | CHANGED | rc=0 >>
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        40G  1.8G   36G   5% /
devtmpfs        486M     0  486M   0% /dev
tmpfs           496M     0  496M   0% /dev/shm
tmpfs           496M  436K  496M   1% /run
tmpfs           496M     0  496M   0% /sys/fs/cgroup
tmpfs           100M     0  100M   0% /run/user/0

META: ran handlers
META: ran handlers
# 

ansible执行逻辑:

现在宿主机生成py文件(在ansible目录下的tmp下),连接至远程主机,将py文件copy至远程主机$HOME/.ansible/tmp/ansible-tmp-数字/ 目录下
远端执行命令
将命令返回至宿主机

ansible 常用模块

ping
[root@VM_16_16_centos ~]# ansible group3 -m ping 
47.96.×.× | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
116.62.×.× | SUCCESS => {
    "changed": false, 
    "ping": "pong"
}
[root@VM_16_16_centos ~]# 
command (默认模块)
[root@VM_16_16_centos ~]# ansible group5 -m command -a "date"
118.24.×.× | CHANGED | rc=0 >>
Fri Feb 15 08:49:37 CST 2019

[root@VM_16_16_centos ~]# 
cron
创建新cron
[root@VM_16_16_centos ~]# ansible group5 -m cron -a 'minute="*" job="/usr/bin/echo hello" name="Hello"'
118.24.×.× | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": [
        "Hello"
    ]
}
[root@VM_16_16_centos ~]#
删除cron
[root@VM_16_16_centos ~]# ansible group5 -m cron -a 'minute="*" job="/usr/bin/echo hello" name="Hello" state="absent"'
118.24.×.× | CHANGED => {
    "changed": true, 
    "envs": [], 
    "jobs": []
}
[root@VM_16_16_centos ~]#
user
新建用户
[root@VM_16_16_centos ~]# ansible group5 -m user -a 'name="jack"'
118.24.×.× | CHANGED => {
    "changed": true, 
    "comment": "", 
    "create_home": true, 
    "group": 1000, 
    "home": "/home/jack", 
    "name": "jack", 
    "shell": "/bin/bash", 
    "state": "present", 
    "system": false, 
    "uid": 1000
}
[root@VM_16_16_centos ~]# 
删除用户
[root@VM_16_16_centos ~]# ansible group5 -m user -a 'name="jack" state="absent"'
118.24.×.× | CHANGED => {
    "changed": true, 
    "force": false, 
    "name": "jack", 
    "remove": false, 
    "state": "absent"
}
[root@VM_16_16_centos ~]# 
copy
[root@VM_16_16_centos ~]# ansible group5 -m copy -a 'src="/root/shell.sh" dest="/root/output" mode="777" owner="mysql" backup="yes"'
118.24.×.× | CHANGED => {
    "changed": true, 
    "checksum": "0c6e11149cb332837cd3c496c28982a5d070c8b5", 
    "dest": "/root/output/shell.sh", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "mysql", 
    "path": "/root/output/shell.sh", 
    "size": 24, 
    "state": "file", 
    "uid": 1000
}
[root@VM_16_16_centos ~]#
[root@VM_16_16_centos ~]# echo "123" >> shell.sh 
[root@VM_16_16_centos ~]# ansible group5 -m copy -a 'src="/root/shell.sh" dest="/root/output" mode="777" owner="mysql" backup="yes"'
118.24.×.× | CHANGED => {
    "backup_file": "/root/output/shell.sh.18807.2019-02-15@09:34:05~", 
    "changed": true, 
    "checksum": "5407d07a1693951861d84121a023c18aaf72633a", 
    "dest": "/root/output/shell.sh", 
    "gid": 0, 
    "group": "root", 
    "md5sum": "7a1d74fa7b6e9ee01a35b097f6401c38", 
    "mode": "0777", 
    "owner": "mysql", 
    "size": 28, 
    "src": "/root/.ansible/tmp/ansible-tmp-1550194444.02-2693174122698/source", 
    "state": "file", 
    "uid": 1000
}
[root@VM_16_16_centos ~]# ansible group5 -m shell -a 'ls -l /root/output | grep "shell"'
118.24.×.× | CHANGED | rc=0 >>
-rwxrwxrwx 1 mysql root    28 Feb 15 09:34 shell.sh
-rwxrwxrwx 1 mysql root    24 Feb 15 09:32 shell.sh.18807.2019-02-15@09:34:05~

[root@VM_16_16_centos ~]# 
file模块
赋予所有者权限
[root@VM_16_16_centos ~]# ansible group5 -m file -a 'path="/root/output/shell.sh" owner="root"'
118.24.×.× | CHANGED => {
    "changed": true, 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "path": "/root/output/shell.sh", 
    "size": 28, 
    "state": "file", 
    "uid": 0
}
[root@VM_16_16_centos ~]# 
创建连接文件
[root@VM_16_16_centos ~]# ansible group5 -m file -a 'src="/root/output/shell.sh" path="/root/shell.sh.link" state="link"'
118.24.×.× | CHANGED => {
    "changed": true, 
    "dest": "/root/shell.sh.link", 
    "gid": 0, 
    "group": "root", 
    "mode": "0777", 
    "owner": "root", 
    "size": 21, 
    "src": "/root/output/shell.sh", 
    "state": "link", 
    "uid": 0
}
[root@VM_16_16_centos ~]# ansible group5 -m shell -a 'ls -l /root | grep shell.sh.link'
118.24.×.× | CHANGED | rc=0 >>
lrwxrwxrwx 1 root root   21 Feb 15 09:41 shell.sh.link -> /root/output/shell.sh

[root@VM_16_16_centos ~]# 
service模块
[root@VM_16_16_centos ~]# ansible group5 -m service -a 'name="nginx" state="started" enabled="yes"'
118.24.×.× | CHANGED => {
    "changed": true, 
    "enabled": true, 
    "name": "nginx", 
    "state": "started", 
    "status": {
        "ActiveEnterTimestampMonotonic": "0", 
        "ActiveExitTimestampMonotonic": "0", 
        "ActiveState": "inactive", 
        "After": "systemd-journald.socket basic.target -.mount network.target tmp.mount system.slice nss-lookup.target remote-fs.target", 
        "AllowIsolate": "no", 
        "AssertResult": "no", 
        "AssertTimestampMonotonic": "0", 
        "Before": "shutdown.target", 
        "BlockIOAccounting": "no", 
        "BlockIOWeight": "18446744073709551615", 
        "CPUAccounting": "no", 
        "CPUQuotaPerSecUSec": "infinity", 
        "CPUSchedulingPolicy": "0", 
        "CPUSchedulingPriority": "0", 
        "CPUSchedulingResetOnFork": "no", 
        "CPUShares": "18446744073709551615", 
        "CanIsolate": "no", 
        "CanReload": "yes", 
        "CanStart": "yes", 
        "CanStop": "yes", 
        "CapabilityBoundingSet": "18446744073709551615", 
        "ConditionResult": "no", 
        "ConditionTimestampMonotonic": "0", 
        "Conflicts": "shutdown.target", 
        "ControlPID": "0", 
        "DefaultDependencies": "yes", 
        "Delegate": "no", 
        "Description": "The nginx HTTP and reverse proxy server", 
        "DevicePolicy": "auto", 
        "ExecMainCode": "0", 
        "ExecMainExitTimestampMonotonic": "0", 
        "ExecMainPID": "0", 
        "ExecMainStartTimestampMonotonic": "0", 
        "ExecMainStatus": "0", 
        "ExecReload": "{ path=/bin/kill ; argv[]=/bin/kill -s HUP $MAINPID ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "ExecStart": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "ExecStartPre": "{ path=/usr/sbin/nginx ; argv[]=/usr/sbin/nginx -t ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", 
        "FailureAction": "none", 
        "FileDescriptorStoreMax": "0", 
        "FragmentPath": "/usr/lib/systemd/system/nginx.service", 
        "GuessMainPID": "yes", 
        "IOScheduling": "0", 
        "Id": "nginx.service", 
        "IgnoreOnIsolate": "no", 
        "IgnoreOnSnapshot": "no", 
        "IgnoreSIGPIPE": "yes", 
        "InactiveEnterTimestampMonotonic": "0", 
        "InactiveExitTimestampMonotonic": "0", 
        "JobTimeoutAction": "none", 
        "JobTimeoutUSec": "0", 
        "KillMode": "process", 
        "KillSignal": "3", 
        "LimitAS": "18446744073709551615", 
        "LimitCORE": "18446744073709551615", 
        "LimitCPU": "18446744073709551615", 
        "LimitDATA": "18446744073709551615", 
        "LimitFSIZE": "18446744073709551615", 
        "LimitLOCKS": "18446744073709551615", 
        "LimitMEMLOCK": "65536", 
        "LimitMSGQUEUE": "819200", 
        "LimitNICE": "0", 
        "LimitNOFILE": "1000000", 
        "LimitNPROC": "3894", 
        "LimitRSS": "18446744073709551615", 
        "LimitRTPRIO": "0", 
        "LimitRTTIME": "18446744073709551615", 
        "LimitSIGPENDING": "3894", 
        "LimitSTACK": "18446744073709551615", 
        "LoadState": "loaded", 
        "MainPID": "0", 
        "MemoryAccounting": "no", 
        "MemoryCurrent": "18446744073709551615", 
        "MemoryLimit": "18446744073709551615", 
        "MountFlags": "0", 
        "Names": "nginx.service", 
        "NeedDaemonReload": "no", 
        "Nice": "0", 
        "NoNewPrivileges": "no", 
        "NonBlocking": "no", 
        "NotifyAccess": "none", 
        "OOMScoreAdjust": "0", 
        "OnFailureJobMode": "replace", 
        "PIDFile": "/run/nginx.pid", 
        "PermissionsStartOnly": "no", 
        "PrivateDevices": "no", 
        "PrivateNetwork": "no", 
        "PrivateTmp": "yes", 
        "ProtectHome": "no", 
        "ProtectSystem": "no", 
        "RefuseManualStart": "no", 
        "RefuseManualStop": "no", 
        "RemainAfterExit": "no", 
        "Requires": "basic.target -.mount", 
        "RequiresMountsFor": "/var/tmp", 
        "Restart": "no", 
        "RestartUSec": "100ms", 
        "Result": "success", 
        "RootDirectoryStartOnly": "no", 
        "RuntimeDirectoryMode": "0755", 
        "SameProcessGroup": "no", 
        "SecureBits": "0", 
        "SendSIGHUP": "no", 
        "SendSIGKILL": "yes", 
        "Slice": "system.slice", 
        "StandardError": "inherit", 
        "StandardInput": "null", 
        "StandardOutput": "journal", 
        "StartLimitAction": "none", 
        "StartLimitBurst": "5", 
        "StartLimitInterval": "10000000", 
        "StartupBlockIOWeight": "18446744073709551615", 
        "StartupCPUShares": "18446744073709551615", 
        "StatusErrno": "0", 
        "StopWhenUnneeded": "no", 
        "SubState": "dead", 
        "SyslogLevelPrefix": "yes", 
        "SyslogPriority": "30", 
        "SystemCallErrorNumber": "0", 
        "TTYReset": "no", 
        "TTYVHangup": "no", 
        "TTYVTDisallocate": "no", 
        "TimeoutStartUSec": "1min 30s", 
        "TimeoutStopUSec": "5s", 
        "TimerSlackNSec": "50000", 
        "Transient": "no", 
        "Type": "forking", 
        "UMask": "0022", 
        "UnitFilePreset": "disabled", 
        "UnitFileState": "disabled", 
        "Wants": "system.slice", 
        "WatchdogTimestampMonotonic": "0", 
        "WatchdogUSec": "0"
    }
}
[root@VM_16_16_centos ~]# 
script模块
[root@VM_16_16_centos ~]# cat shell.sh
#!/bin/bash

systemctl stop nginx.service
[root@VM_16_16_centos ~]# ansible group5 -m script -a '/root/shell.sh'

118.24.×.× | CHANGED => {
    "changed": true, 
    "rc": 0, 
    "stderr": "Shared connection to 118.24.×.× closed.\r\n", 
    "stderr_lines": [
        "Shared connection to 118.24.×.× closed."
    ], 
    "stdout": "", 
    "stdout_lines": []
}
[root@VM_16_16_centos ~]# 
yum 模块
[root@VM_16_16_centos ~]# ansible group5 -m yum -a 'name="nginx"'
118.24.×.× | CHANGED => {
    "ansible_facts": {
        "pkg_mgr": "yum"
    }, 
    "changed": true, 
    "msg": "", 
    "rc": 0, 
    "results": [
        "Loaded plugins: fastestmirror, langpacks\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package nginx.x86_64 1:1.12.2-2.el7 will be installed\n--> Processing Dependency: nginx-all-modules = 1:1.12.2-2.el7 for package: 1:nginx-1.12.2-2.el7.x86_64\n--> Running transaction check\n---> Package nginx-all-modules.noarch 1:1.12.2-2.el7 will be installed\n--> Processing Dependency: nginx-mod-http-geoip = 1:1.12.2-2.el7 for package: 1:nginx-all-modules-1.12.2-2.el7.noarch\n--> Processing Dependency: nginx-mod-http-image-filter = 1:1.12.2-2.el7 for package: 1:nginx-all-modules-1.12.2-2.el7.noarch\n--> Processing Dependency: nginx-mod-http-perl = 1:1.12.2-2.el7 for package: 1:nginx-all-modules-1.12.2-2.el7.noarch\n--> Processing Dependency: nginx-mod-http-xslt-filter = 1:1.12.2-2.el7 for package: 1:nginx-all-modules-1.12.2-2.el7.noarch\n--> Processing Dependency: nginx-mod-mail = 1:1.12.2-2.el7 for package: 1:nginx-all-modules-1.12.2-2.el7.noarch\n--> Processing Dependency: nginx-mod-stream = 1:1.12.2-2.el7 for package: 1:nginx-all-modules-1.12.2-2.el7.noarch\n--> Running transaction check\n---> Package nginx-mod-http-geoip.x86_64 1:1.12.2-2.el7 will be installed\n---> Package nginx-mod-http-image-filter.x86_64 1:1.12.2-2.el7 will be installed\n---> Package nginx-mod-http-perl.x86_64 1:1.12.2-2.el7 will be installed\n---> Package nginx-mod-http-xslt-filter.x86_64 1:1.12.2-2.el7 will be installed\n---> Package nginx-mod-mail.x86_64 1:1.12.2-2.el7 will be installed\n---> Package nginx-mod-stream.x86_64 1:1.12.2-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package                         Arch       Version              Repository\n                                                                           Size\n================================================================================\nInstalling:\n nginx                           x86_64     1:1.12.2-2.el7       epel     530 k\nInstalling for dependencies:\n nginx-all-modules               noarch     1:1.12.2-2.el7       epel      16 k\n nginx-mod-http-geoip            x86_64     1:1.12.2-2.el7       epel      23 k\n nginx-mod-http-image-filter     x86_64     1:1.12.2-2.el7       epel      26 k\n nginx-mod-http-perl             x86_64     1:1.12.2-2.el7       epel      36 k\n nginx-mod-http-xslt-filter      x86_64     1:1.12.2-2.el7       epel      26 k\n nginx-mod-mail                  x86_64     1:1.12.2-2.el7       epel      54 k\n nginx-mod-stream                x86_64     1:1.12.2-2.el7       epel      76 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+7 Dependent packages)\n\nTotal download size: 788 k\nInstalled size: 1.9 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal                                              1.0 MB/s | 788 kB  00:00     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : 1:nginx-mod-http-geoip-1.12.2-2.el7.x86_64                   1/8 \n  Installing : 1:nginx-mod-mail-1.12.2-2.el7.x86_64                         2/8 \n  Installing : 1:nginx-mod-http-xslt-filter-1.12.2-2.el7.x86_64             3/8 \n  Installing : 1:nginx-mod-http-image-filter-1.12.2-2.el7.x86_64            4/8 \n  Installing : 1:nginx-mod-stream-1.12.2-2.el7.x86_64                       5/8 \n  Installing : 1:nginx-1.12.2-2.el7.x86_64                                  6/8 \n  Installing : 1:nginx-mod-http-perl-1.12.2-2.el7.x86_64                    7/8 \n  Installing : 1:nginx-all-modules-1.12.2-2.el7.noarch                      8/8 \n  Verifying  : 1:nginx-mod-http-perl-1.12.2-2.el7.x86_64                    1/8 \n  Verifying  : 1:nginx-mod-http-geoip-1.12.2-2.el7.x86_64                   2/8 \n  Verifying  : 1:nginx-1.12.2-2.el7.x86_64                                  3/8 \n  Verifying  : 1:nginx-mod-mail-1.12.2-2.el7.x86_64                         4/8 \n  Verifying  : 1:nginx-all-modules-1.12.2-2.el7.noarch                      5/8 \n  Verifying  : 1:nginx-mod-http-xslt-filter-1.12.2-2.el7.x86_64             6/8 \n  Verifying  : 1:nginx-mod-http-image-filter-1.12.2-2.el7.x86_64            7/8 \n  Verifying  : 1:nginx-mod-stream-1.12.2-2.el7.x86_64                       8/8 \n\nInstalled:\n  nginx.x86_64 1:1.12.2-2.el7                                                   \n\nDependency Installed:\n  nginx-all-modules.noarch 1:1.12.2-2.el7                                       \n  nginx-mod-http-geoip.x86_64 1:1.12.2-2.el7                                    \n  nginx-mod-http-image-filter.x86_64 1:1.12.2-2.el7                             \n  nginx-mod-http-perl.x86_64 1:1.12.2-2.el7                                     \n  nginx-mod-http-xslt-filter.x86_64 1:1.12.2-2.el7                              \n  nginx-mod-mail.x86_64 1:1.12.2-2.el7                                          \n  nginx-mod-stream.x86_64 1:1.12.2-2.el7                                        \n\nComplete!\n"
    ]
}
[root@VM_16_16_centos ~]# 

Playbook 快速入门

检查yaml语法
# ansible-playbook playbook.yaml --syntax-check 
在机器上预执行playbook,但是不会对实体机造成影响
# ansible-playbook playbook.yaml --check
查看playbook会影响的主机
# ansible-playbook playbook.yaml --list-host
第一个ansible-playbook

yaml

---
- hosts: all
  tasks:
    - name: 安装httpd
      yum: name=httpd

    - name: 启动httpd
      service: name=httpd state=started
检查语法
[root@VM_16_16_centos playbook]# ansible-playbook test1.yaml --syntax-check

playbook: test1.yaml
[root@VM_16_16_centos playbook]#
执行ansible-playbook
[root@VM_16_16_centos playbook]# ansible-playbook test1.yaml 

PLAY [all] *******************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [121.196.×.×]
ok: [47.105.×.×]
ok: [47.111.×.×]
ok: [47.96.×.×]
ok: [47.96.×.×]
ok: [118.24.×.×]
ok: [116.62.×.×]
ok: [47.244.×.×]

TASK [安装httpd] ***************************************************************************************************************************************************************************************************************************************************************
changed: [47.96.×.×]
changed: [47.105.×.×]
changed: [47.111.×.×]
changed: [121.196.×.×]
changed: [47.244.×.×]
changed: [118.24.×.×]
changed: [47.96.×.×]
changed: [116.62.×.×]

TASK [启动httpd] ***************************************************************************************************************************************************************************************************************************************************************
changed: [47.96.×.×]
changed: [47.111.×.×]
changed: [121.196.×.×]
changed: [47.105.×.×]
changed: [47.96.×.×]
changed: [118.24.×.×]
fatal: [116.62.×.×]: FAILED! => {"changed": false, "msg": "Unable to start service httpd: Job for httpd.service failed because the control process exited with error code. See \"systemctl status httpd.service\" and \"journalctl -xe\" for details.\n"}
fatal: [47.244.×.×]: FAILED! => {"changed": false, "msg": "httpd: apr_sockaddr_info_get() failed for iZj6cb5ign9dl1h9l412g5Z\nhttpd: Could not reliably determine the server's fully qualified domain name, using 127.0.0.1 for ServerName\n(98)Address already in use: make_sock: unable to listen for connections on address 0.0.0.0:80\nno listening sockets available, shutting down\nUnable to open logs\n"}
    to retry, use: --limit @/root/playbook/test1.retry

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************
116.62.×.×              : ok=2    changed=1    unreachable=0    failed=1   
118.24.×.×                : ok=3    changed=2    unreachable=0    failed=0   
121.196.×.×             : ok=3    changed=2    unreachable=0    failed=0   
47.105.×.×              : ok=3    changed=2    unreachable=0    failed=0   
47.111.×.×              : ok=3    changed=2    unreachable=0    failed=0   
47.244.×.×               : ok=2    changed=1    unreachable=0    failed=1   
47.96.×.×               : ok=3    changed=2    unreachable=0    failed=0   
47.96.×.×                 : ok=3    changed=2    unreachable=0    failed=0   

[root@VM_16_16_centos playbook]#
第二个ansible-playbook,使用变量item

yaml

---
- hosts: all
  tasks: 
    - name: 停掉httpd
      service: name=httpd state=stopped

    - name: 卸载httpd httpd-devel
      yum: name={{ item }} state=absent
      with_items:
        - httpd
        - httpd-devel
检查语法
[root@VM_16_16_centos playbook]# ansible-playbook ./test1.2.yaml --syntax-check 

playbook: ./test1.2.yaml
[root@VM_16_16_centos playbook]# 
执行ansible-playbook
[root@VM_16_16_centos playbook]# ansible-playbook ./test1.2.yaml 

PLAY [all] *******************************************************************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************************************************************************************************************************
ok: [47.111.×.×]
ok: [47.96.×.×]
ok: [121.196.×.×]
ok: [116.62.×.×]
ok: [118.24.×.×]
ok: [47.96.×.×]
ok: [47.105.×.×]
ok: [47.244.×.×]

TASK [停掉httpd] ***************************************************************************************************************************************************************************************************************************************************************
changed: [47.111.×.×]
changed: [121.196.×.×]
changed: [47.96.×.×]
changed: [116.62.×.×]
changed: [118.24.×.×]
changed: [47.244.×.×]
changed: [47.96.×.×]
changed: [47.105.×.×]

TASK [卸载httpd httpd-devel] ***************************************************************************************************************************************************************************************************************************************************
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['httpd', 'httpd-devel']` and remove the loop. This feature will
 be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['httpd', 'httpd-devel']` and remove the loop. This feature will
 be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['httpd', 'httpd-devel']` and remove the loop. This feature will
 be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['httpd', 'httpd-devel']` and remove the loop. This feature will
 be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['httpd', 'httpd-devel']` and remove the loop. This feature will
 be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [47.96.×.×] => (item=[u'httpd', u'httpd-devel'])
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['httpd', 'httpd-devel']` and remove the loop. This feature will
 be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [121.196.×.×] => (item=[u'httpd', u'httpd-devel'])
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['httpd', 'httpd-devel']` and remove the loop. This feature will
 be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [47.111.×.×] => (item=[u'httpd', u'httpd-devel'])
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying `name: "{{ item }}"`, please use `name: ['httpd', 'httpd-devel']` and remove the loop. This feature will
 be removed in version 2.11. Deprecation warnings can be disabled by setting deprecation_warnings=False in ansible.cfg.
changed: [116.62.×.×] => (item=[u'httpd', u'httpd-devel'])
changed: [118.24.×.×] => (item=[u'httpd', u'httpd-devel'])
changed: [47.96.×.×] => (item=[u'httpd', u'httpd-devel'])
changed: [47.244.×.×] => (item=[u'httpd', u'httpd-devel'])
changed: [47.105.×.×] => (item=[u'httpd', u'httpd-devel'])

PLAY RECAP *******************************************************************************************************************************************************************************************************************************************************************
116.62.×.×              : ok=3    changed=2    unreachable=0    failed=0   
118.24.×.×                : ok=3    changed=2    unreachable=0    failed=0   
121.196.×.×             : ok=3    changed=2    unreachable=0    failed=0   
47.105.×.×              : ok=3    changed=2    unreachable=0    failed=0   
47.111.×.×              : ok=3    changed=2    unreachable=0    failed=0   
47.244.×.×               : ok=3    changed=2    unreachable=0    failed=0   
47.96.×.×               : ok=3    changed=2    unreachable=0    failed=0   
47.96.×.×                 : ok=3    changed=2    unreachable=0    failed=0   

[root@VM_16_16_centos playbook]#
ansible-playbook 配置tomcat
---
- hosts: all
  tasks:
    - name: 创建新目录
      file: path={{ item }} state="directory"
      with_items:
        - "/root/soft"
        - "/usr/local/tomcat"

    - name: 下载tomcat
      command: wget -P /root/soft http://mirrors.hust.edu.cn/apache/tomcat/tomcat-9/v9.0.16/bin/apache-tomcat-9.0.16.tar.gz

    - name: 解压下载的文件
      unarchive: src=/root/soft/apache-tomcat-9.0.16.tar.gz dest=/usr/local/tomcat copy=no mode=0755

    - name: 安装openjdk
      yum: name={{ item }}
      with_items:
        - java-1.8.0-openjdk
        - java-1.8.0-openjdk-devel

    - name: 开启tomcat
      shell: nohup /usr/local/tomcat/apache-tomcat-9.0.16/bin/startup.sh &
ansible-playbook 配置nginx
---
- hosts: 121.196.×.×
  tasks:
    - name: 新建nginx下载目录
      file: path={{ item }} state="directory"
      with_items:
        - "/root/soft"

    - name: 下载nginx
      get_url: url=http://nginx.org/download/nginx-1.15.8.tar.gz dest=/root/soft

    - name: 安装必要包
      yum:
        name: "{{ packages }}"
      vars:
        packages:
        - gcc
        - openssl
        - openssl-devel

    - name: 解压nginx
      unarchive: src=/root/soft/nginx-1.15.8.tar.gz dest=/root/soft copy=no

    - name: 编译安装nginx
      shell: cd /root/soft/nginx-1.15.8 && ./configure --prefix=/usr/local/nginx --with-http_realip_module  --with-http_ssl_module && make && make install


    - name: 启动nginx
      shell: nohup /usr/local/nginx/sbin/nginx &
ansible-playbook 配置nginx
nginx.yaml
---
- hosts: all
  vars_files:
    vars.yaml
  tasks:
    - name: 新建nginx下载目录
      file: path={{ item }} state="directory"
      with_items:
        - "/root/soft"

    - name: 下载nginx
      get_url: url=http://nginx.org/download/nginx-1.15.8.tar.gz dest={{ down_load_dirs }}

    - name: 安装必要包
      yum:
        name: "{{ packages }}"
      vars:
        packages:
        - gcc
        - openssl
        - openssl-devel

    - name: 解压nginx
      unarchive: src=/root/soft/nginx-{{ nginx_version }}.tar.gz dest={{ down_load_dirs }} copy=no

    - name: 编译安装nginx
      shell: cd /root/soft/nginx-1.15.8 && ./configure --prefix={{ install_dirs }} --with-http_realip_module  --with-http_ssl_module && make && make install


    - name: 启动nginx
      shell: nohup /usr/local/nginx/sbin/nginx &
vars.yaml
---
# 软件包的下载路径
down_load_dirs: /root/soft

# nginx版本号
nginx_version: 1.15.8

# nginx安装目录
install_dirs: /usr/local/nginx

 

 

 

 

 

   

 

 

 

 
 

 

 

 

 

 

 

 

上一篇:35岁程序员面试腾讯、头条、华为,含面试题+答案


下一篇:Ubuntu下wxWidgets学生公寓管理编程,sqlite3的用法(mysql数据库),窗体,下面是部分添加和删除功能,其他功能可以联系我。。