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