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