返回总目录页

ansible使用详解

 

ansible执行,用户主机配置

免密同一个同一个用户执行命令

1

能免密登录的
[root@mcw1 ~]$ ansible 10.0.0.132 -m shell -a "hostname" 10.0.0.132 | CHANGED | rc=0 >> mcw2

[root@mcw1 ~]$ ssh 10.0.0.132  #132能免密登录
Last login: Mon Feb 7 18:57:12 2022 from 10.0.0.131
[root@mcw2 ~]#

 

不能免密登录的

[root@mcw1 ~]$ ssh 10.0.0.133
root@10.0.0.133's password:

[root@mcw1 ~]$ ansible 10.0.0.133 -m shell -a "hostname"
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.133
[WARNING]: No hosts matched, nothing to do

 

使用host文件执行命令

[root@mcw1 ~]$ cat mcw.txt
[mcw]
10.0.0.132  #免密
10.0.0.133  #不免密

[root@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "hostname"
10.0.0.133 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: root@10.0.0.133: Permission denied (publickey,password).",
"unreachable": true
}
10.0.0.132 | CHANGED | rc=0 >>
mcw2

 

2、指定用户密码执行命令

[root@mcw1 ~]$ cat mcw.txt 
[mcw]
10.0.0.132
10.0.0.133 ansible_ssh_user='root' ansible_ssh_pass='123456'
[root@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "hostname"
10.0.0.132 | CHANGED | rc=0 >>
mcw2
10.0.0.133 | CHANGED | rc=0 >>
mcw3

用户密码可以写在上面,这样分组里重复使用的时候不用写用户密码了

[root@mcw1 ~]$ cat mcw.txt
10.0.0.133 ansible_ssh_user='root' ansible_ssh_pass='123456'
[mcw]
10.0.0.132
10.0.0.133
[root@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "hostname"
10.0.0.133 | CHANGED | rc=0 >>
mcw3
10.0.0.132 | CHANGED | rc=0 >>
mcw2

3、使用普通用户执行命令


[machangwei@mcw1 ~]$ cat mcw.txt
10.0.0.132 ansible_ssh_user='root' ansible_ssh_pass='123456'
10.0.0.133
[mcw]
10.0.0.132 #root免密,machangwei不
10.0.0.133 #都不
[machangwei@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami"
The authenticity of host '10.0.0.133 (10.0.0.133)' can't be established.
ED25519 key fingerprint is SHA256:q2pX2MgVhzo7ed3GE0bd50R7jcFkd5FR68yaVAbSVG4.
This host key is known by the following other names/addresses:
~/.ssh/known_hosts:1: 10.0.0.132
Are you sure you want to continue connecting (yes/no/[fingerprint])? 10.0.0.132 | CHANGED | rc=0 >>
root



普通用户连接root执行命令还是需要添加ansible_sudo_pass,不然会提示yes信息

[machangwei@mcw1 ~]$ cat mcw.txt
10.0.0.132 ansible_ssh_user='root' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
10.0.0.133 ansible_ssh_user='machangwei' ansible_ssh_pass='123456'
[mcw]
10.0.0.132
10.0.0.133
[machangwei@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami"
10.0.0.133 | FAILED | rc=-1 >>
Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host.


10.0.0.132 | CHANGED | rc=0 >>
root

 

 

 

免密普通用户连接另一个普通用户执行命令

 

 

普通用户连接另一个普通用户sudo到root执行命令

报错了:
[xiaoma@mcw1 ~]$ cat mcw.txt 10.0.0.132 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456' 10.0.0.133 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456' [mcw] 10.0.0.132 10.0.0.133 [xiaoma@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami" 10.0.0.132 | FAILED | rc=-1 >> Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host. 10.0.0.133 | FAILED | rc=-1 >> Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host.


解决方法:打开这个参数

[root@mcw1 ~]$ vim /etc/ansible/ansible.cfg
[root@mcw1 ~]$ grep host_key_checking /etc/ansible/ansible.cfg
#host_key_checking = False
host_key_checking = False

然后再次执行,但是用户不是root,我们想通过普通用户sudo到root执行命令的

[xiaoma@mcw1 ~]$ cat mcw.txt
10.0.0.132 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
10.0.0.133 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
[mcw]
10.0.0.132
10.0.0.133
[xiaoma@mcw1 ~]$
[xiaoma@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami"
10.0.0.132 | CHANGED | rc=0 >>
machangwei


10.0.0.133 | CHANGED | rc=0 >>
machangwei


 

如下,需要开启这些参数,可参考:https://blog.csdn.net/weixin_46575696/article/details/109638397 

[root@mcw1 ~]$ grep -A 8 privilege_escalation /etc/ansible/ansible.cfg
[privilege_escalation]
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False
become=True
become_method=sudo
become_user=root
become_ask_pass=False

然后再次执行,就可以实现sudo到root执行命令

[xiaoma@mcw1 ~]$ cat mcw.txt
10.0.0.132 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
10.0.0.133 ansible_ssh_user='machangwei' ansible_ssh_pass='123456' ansible_sudo_pass='123456'
[mcw]
10.0.0.132
10.0.0.133
[xiaoma@mcw1 ~]$ ansible -i mcw.txt mcw -m shell -a "whoami"
10.0.0.132 | CHANGED | rc=0 >>
root


10.0.0.133 | CHANGED | rc=0 >>
root

 

 

 

ansible通过跳板机方式执行(主机A上用普通用户A连接主机B的另一个普通用户B,然后在主机B上用普通用户B连接主机C,在主机C上执行命令

1.1 首先生成ssh公钥秘钥对(如果没有,有就不用了):

ssh-keygen -t rsa
1
一路默认回车,系统会在~/.ssh下生成id_rsa、id_rsa.pub

1.2 然后将公钥发送到跳板机和目标机:

可以直接将公钥的内容拷贝到~/.ssh/authorized_keys中
chmod 600 ~/.ssh/authorized_keys
或者ssh-copy-id -p12345 user@IP(跳板机可以使用,目标机不能)

二、跳板机安装nc命令

执行nc -help确认命令是否成功安装(没有安装的可以百度安装,我这里是已经安装好了的)

三、测试ssh是否能通过跳板机连接到目标机

ssh -o "ProxyCommand ssh -p 12345 user@跳板机公网IP nc -w 1000 %h %p" -p22 user@目标主机ip

我这里环境如下,mcw1是ansible主机,mcw2是当做跳板机,mcw3是当做目标主机。现在mcw1上通过mcw2去连接mcw3测试成功

10.0.0.131 mcw1        10.0.0.132 mcw2           10.0.0.133 mcw3

[root@mcw1 ~]$ ssh -o "ProxyCommand ssh -p 22 root@10.0.0.132 nc  %h %p" -p22 root@10.0.0.133
Last login: Mon Feb  7 22:10:29 2022 from 10.0.0.132
[root@mcw3 ~]# 

加上-w参数这个值也是可以的

[root@mcw1 ~]$ ssh -o "ProxyCommand ssh -p 22 root@10.0.0.132 -w 14400  nc  %h %p" -p22 root@10.0.0.133
channel 0: open failed: administratively prohibited: open failed
Tunnel forwarding failed
Last login: Mon Feb  7 22:15:12 2022 from 10.0.0.132
[root@mcw3 ~]# 

 

四、测试添加到~/.ssh/config配置文件中

 

 mcw1是ansible主机,mcw2是当做跳板机,mcw3是当做目标主机。现在mcw1上通过mcw2去连接mcw3测试成功

[root@mcw1 ~]$ cat .ssh/config 
Host mcw2
    HostName 10.0.0.132
    Port 22
    BatchMode yes
    User root

Host mcw3
    HostName 10.0.0.133
    ServerAliveInterval 60
    TCPKeepAlive        yes
    IdentityFile ~/.ssh/id_rsa
    ProxyCommand ssh mcw2 'nc  %h %p'
    User root
    Port 22
[root@mcw1 ~]$ ssh mcw3
Last login: Tue Feb  8 00:44:54 2022 from 10.0.0.132
[root@mcw3 ~]# 

由于实际情况生产的服务器太多不能一个一个的config配置文件,所以config可以配置如下:

 我这里不太好模拟环境。因为这里本来就可以直接通过ip连接

[root@mcw1 ~]$ cat .ssh/config 
Host mcw2
    HostName 10.0.0.132
    Port 22
    BatchMode yes #这个选项对脚本文件和批处理任务十分有用
    User machangwei

Host 10.0.0.x
    ServerAliveInterval 60 #本地 ssh 每隔 60s 向 server 端 sshd 发送 keep-alive 包,如果发送 50 次,server 无回应断开连接。
     #ServerAliveCountMax 50  #前一个参数表示要保持TCP连接,后一个参数(ClientAliveCountMax)表示客户端的SSH连线闲置多长时间后自动终止连线的数值,单位为分钟。
    TCPKeepAlive        yes
    #ClientAliveCountMax 360
    #IdentityFile ~/.ssh/id_rsa
    ProxyCommand ssh mcw2 'nc  %h %p'
    User machangwei
    Port 22
[root@mcw1 ~]$ ssh 10.0.0.133
Last login: Tue Feb  8 01:03:44 2022 from 10.0.0.131
[root@mcw3 ~]# 

 安装

yum安装

[root@mcw01 ~]$ yum install -y ansible

 下载tar包安装

包下载地址:https://releases.ansible.com/ansible/

yum install -y ansible
yum remove ansible
yum install gcc gcc-c++ make glibc-devel kernel-headers
yum install pycrypto
wget https://pypi.python.org/packages/source/a/ansible/ansible-1.9.6.tar.gz
tar xf ansible-1.9.6.tar.gz
cd ansible-1.9.6/
python setup.py install

[root@mcw02 ~/ansible]$ ansible --version
ansible 1.9.6
  configured module search path = None
[root@mcw02 ~/ansible]$ 

安装后不知道它的配置和hosts在哪里,直接创建一个目录/etc/ansible/,然后创建hosts文件,它就能找到

[root@mcw02 ~/ansible]$ ls /etc/ansible/
hosts
[root@mcw02 ~/ansible]$

此时,可以直接写程序调用apii也是没问题的。安装时将包都装到python2的目录下了

 linux上使用tar包成功安装1,9,6版本的了,但是我pycharm中没有,这样不太好开发。pycharm命令行和setting里面都装失败了,那么就将linux上的包下载到本地

如下,当我setting里面按照ansible时,发现依赖包已经安装上了,但只是ansible包装不了。将包从linux上下载下来后,发现不能识别,就把里面两个文件弄到外面来就行,就能识别到了。如下,导入不报红线了。如此,可以方便开发了

 我们最好实现安装ansible,能直接迁移就用的那种。不会破坏主机内环境,单独一个目录下,像编译安装的那种。ansible我这里编译安装的,发现在其他目录生成文件了,包括命令文件,有时间试试迁移走能不能使用,这样就能确定生成哪些文件,我们能安装又能恢复到安装之前的环境。

 

 

 

安装后简单使用

配置免密。将控制主机的共有下发到被管节点,重命名为authorized_keys。添加主机清单

添加主机到默认hosts文件中

echo '10.0.0.12' >>/etc/ansible/hosts

没有设置免密
[root@mcw01 ~]$ ansible  10.0.0.12 -m 'ping'
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.12

将控制主机的共有下发到被管节点,重命名为authorized_keys
[root@mcw01 ~]$ ssh-copy-id -i /root/.ssh/id_rsa.pub  root@10.0.0.12
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/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@10.0.0.12's password: 

Number of key(s) added: 1

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

[root@mcw01 ~]$ 


再次执行报错
[root@mcw01 ~]$ ansible  10.0.0.12 -m ping
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.12
原因:
没有添加主机清单

[root@mcw01 ~]$ echo '10.0.0.12' >>/etc/ansible/hosts   #添加主机到hosts文件后就可以了
[root@mcw01 ~]$ ansible  10.0.0.12 -m ping
10.0.0.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[root@mcw01 ~]$ 

自定义hosts文件

[root@mcw01 ~/mcw]$ vim hosts
[root@mcw01 ~/mcw]$ cat hosts 
10.0.0.12
[web]
10.0.0.12
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.12 -m ping 
10.0.0.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[root@mcw01 ~/mcw]$ ansible -i hosts web -m ping 
10.0.0.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[root@mcw01 ~/mcw]$ 

 获取帮助信息

 ansible-doc -h

[root@mcw01 ~/mcw]$ ansible-doc -h
usage: ansible-doc [-h] [--version] [-v] [-M MODULE_PATH]
                   [--playbook-dir BASEDIR]
                   [-t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}]
                   [-j] [-F | -l | -s | --metadata-dump]
                   [plugin [plugin ...]]

plugin documentation tool

positional arguments:
  plugin                Plugin

optional arguments:
  --metadata-dump       **For internal testing only** Dump json metadata for
                        all plugins.
  --playbook-dir BASEDIR
                        Since this tool does not use playbooks, use this as a
                        substitute playbook directory.This sets the relative
                        path for many features including roles/ group_vars/
                        etc.
  --version             show program's version number, config file location,
                        configured module search path, module location,
                        executable location and exit
  -F, --list_files      Show plugin names and their source files without
                        summaries (implies --list)
  -M MODULE_PATH, --module-path MODULE_PATH
                        prepend colon-separated path(s) to module library (def
                        ault=~/.ansible/plugins/modules:/usr/share/ansible/plu
                        gins/modules)
  -h, --help            show this help message and exit
  -j, --json            Change output into json format.
  -l, --list            List available plugins
  -s, --snippet         Show playbook snippet for specified plugin(s)
  -t {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}, --type {become,cache,callback,cliconf,connection,httpapi,inventory,lookup,netconf,shell,module,strategy,vars}
                        Choose which plugin type (defaults to "module").
                        Available plugin types are : ('become', 'cache',
                        'callback', 'cliconf', 'connection', 'httpapi',
                        'inventory', 'lookup', 'netconf', 'shell', 'module',
                        'strategy', 'vars')
  -v, --verbose         verbose mode (-vvv for more, -vvvv to enable
                        connection debugging)

See man pages for Ansible CLI options or website for tutorials
https://docs.ansible.com
[root@mcw01 ~/mcw]$ 

列出ansible系统支持的模块  ansible-doc -l

[root@mcw01 ~/mcw]$ ansible-doc -l
fortios_router_community_list                                 Configure community lists in Fortinet's FortiOS and FortiGate                    
azure_rm_devtestlab_info                                      Get Azure DevTest Lab facts                                                      
ecs_taskdefinition                                            register a task definition in ecs                                                
avi_alertscriptconfig                                         Module for setup of AlertScriptConfig Avi RESTful Object                         
tower_receive                                                 Receive assets from Ansible Tower                                                
netapp_e_iscsi_target                                         NetApp E-Series manage iSCSI target configuration                                
azure_rm_acs                                                  Manage an Azure Container Service(ACS) instance                                  
fortios_log_syslogd2_filter                                   Filters for remote system server in Fortinet's FortiOS and FortiGate             
junos_rpc                                                     Runs an arbitrary RPC over NetConf on an Juniper JUNOS device                    
na_elementsw_vlan                                             NetApp Element Software Manage VLAN                                              
pn_ospf                                                       CLI command to add/remove ospf protocol to a vRouter                             
pn_snmp_vacm                                                  CLI command to create/modify/delete snmp-vacm                                    
cp_mgmt_service_sctp                                          Manages service-sctp objects on Check Point over Web Services API  
..........

ansible-doc -s 模块,列出模块的动作

[root@mcw01 ~]$ ansible-doc -s yum
- name: Manages packages with the `yum' package manager
  yum:
      allow_downgrade:       # Specify if the named package and version is allowed to downgrade a maybe already installed higher version of that
                               package. Note that setting allow_downgrade=True can make this module behave in a non-
                               idempotent way. The task could end up with a set of packages that does not match the
                               complete list of specified packages to install (because dependencies between the
                               downgraded package and others can cause changes to the packages which were in the
                               earlier transaction).
      autoremove:            # If `yes', removes all "leaf" packages from the system that were originally installed as dependencies of user-
                               installed packages but which are no longer required by any such package. Should be
                               used alone or when state is `absent' NOTE: This feature requires yum >= 3.4.3
                               (RHEL/CentOS 7+)
      bugfix:                # If set to `yes', and `state=latest' then only installs updates that have been marked bugfix related.
      conf_file:             # The remote yum configuration file to use for the transaction.
      disable_excludes:      # Disable the excludes defined in YUM config files. If set to `all', disables all excludes. If set to `main', disable
                               excludes defined in [main] in yum.conf. If set to `repoid', disable excludes defined
                               for given repo id.
      disable_gpg_check:     # Whether to disable the GPG checking of signatures of packages being installed. Has an effect only if state is
                               `present' or `latest'.
      disable_plugin:        # `Plugin' name to disable for the install/update operation. The disabled plugins will not persist beyond the
                               transaction.
      disablerepo:           # `Repoid' of repositories to disable for the install/update operation. These repos will not persist beyond the
                               transaction. When specifying multiple repos, separate them with a `","'. As of
                               Ansible 2.7, this can alternatively be a list instead of `","' separated string
      download_dir:          # Specifies an alternate directory to store packages. Has an effect only if `download_only' is specified.
      download_only:         # Only download the packages, do not install them.
      enable_plugin:         # `Plugin' name to enable for the install/update operation. The enabled plugin will not persist beyond the
                               transaction.
      enablerepo:            # `Repoid' of repositories to enable for the install/update operation. These repos will not persist beyond the
                               transaction. When specifying multiple repos, separate them with a `","'. As of
                               Ansible 2.7, this can alternatively be a list instead of `","' separated string
      exclude:               # Package name(s) to exclude when state=present, or latest
      install_weak_deps:     # Will also install all packages linked by a weak dependency relation. NOTE: This feature requires yum >= 4
                               (RHEL/CentOS 8+)
      installroot:           # Specifies an alternative installroot, relative to which all packages will be installed.
      list:                  # Package name to run the equivalent of yum list --show-duplicates <package> against. In addition to listing packages,
                               use can also list the following: `installed', `updates', `available' and `repos'.
                               This parameter is mutually exclusive with `name'.
      lock_timeout:          # Amount of time to wait for the yum lockfile to be freed.
      name:                  # A package name or package specifier with version, like `name-1.0'. If a previous version is specified, the task also
                               needs to turn `allow_downgrade' on. See the `allow_downgrade' documentation for
                               caveats with downgrading packages. When using state=latest, this can be `'*'' which
                               means run `yum -y update'. You can also pass a url or a local path to a rpm file
                               (using state=present). To operate on several packages this can accept a comma
                               separated string of packages or (as of 2.0) a list of packages.
      releasever:            # Specifies an alternative release from which all packages will be installed.
      security:              # If set to `yes', and `state=latest' then only installs updates that have been marked security related.
      skip_broken:           # Skip packages with broken dependencies(devsolve) and are causing problems.
      state:                 # Whether to install (`present' or `installed', `latest'), or remove (`absent' or `removed') a package. `present' and
                               `installed' will simply ensure that a desired package is installed. `latest' will
                               update the specified package if it's not of the latest available version. `absent'
                               and `removed' will remove the specified package. Default is `None', however in effect
                               the default action is `present' unless the `autoremove' option is enabled for this
                               module, then `absent' is inferred.
      update_cache:          # Force yum to check if cache is out of date and redownload if needed. Has an effect only if state is `present' or
                               `latest'.
      update_only:           # When using latest, only update installed packages. Do not install packages. Has an effect only if state is `latest'
      use_backend:           # This module supports `yum' (as it always has), this is known as `yum3'/`YUM3'/`yum-deprecated' by upstream yum
                               developers. As of Ansible 2.7+, this module also supports `YUM4', which is the "new
                               yum" and it has an `dnf' backend. By default, this module will select the backend
                               based on the `ansible_pkg_mgr' fact.
      validate_certs:        # This only applies if using a https url as the source of the rpm. e.g. for localinstall. If set to `no', the SSL
                               certificates will not be validated. This should only set to `no' used on personally
                               controlled sites using self-signed certificates as it avoids verifying the source
                               site. Prior to 2.1 the code worked as if this was set to `yes'.
(END)

ansible命令后加-v -vvv得到详细输出结果

[root@mcw01 ~/mcw]$ ansible web -i hosts -m ping 
10.0.0.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[root@mcw01 ~/mcw]$ 
[root@mcw01 ~/mcw]$ ansible web -i hosts -m ping -v
Using /etc/ansible/ansible.cfg as config file
10.0.0.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[root@mcw01 ~/mcw]$ ansible web -i hosts -m ping -vvv
ansible 2.9.27
  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, Aug  4 2017, 00:39:18) [GCC 4.8.5 20150623 (Red Hat 4.8.5-16)]
Using /etc/ansible/ansible.cfg as config file
host_list declined parsing /root/mcw/hosts as it did not pass its verify_file() method
script declined parsing /root/mcw/hosts as it did not pass its verify_file() method
auto declined parsing /root/mcw/hosts as it did not pass its verify_file() method
Parsed /root/mcw/hosts inventory source with ini plugin
Skipping callback 'actionable', as we already have a stdout callback.
Skipping callback 'counter_enabled', as we already have a stdout callback.
Skipping callback 'debug', as we already have a stdout callback.
Skipping callback 'dense', as we already have a stdout callback.
Skipping callback 'dense', as we already have a stdout callback.
Skipping callback 'full_skip', as we already have a stdout callback.
Skipping callback 'json', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'null', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
Skipping callback 'selective', as we already have a stdout callback.
Skipping callback 'skippy', as we already have a stdout callback.
Skipping callback 'stderr', as we already have a stdout callback.
Skipping callback 'unixy', as we already have a stdout callback.
Skipping callback 'yaml', as we already have a stdout callback.
META: ran handlers
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> 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/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'echo ~ && sleep 0'"'"''
<10.0.0.12> (0, '/root\n', '')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> 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/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'( umask 77 && mkdir -p "` echo /root/.ansible/tmp `"&& mkdir "` echo /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605 `" && echo ansible-tmp-1665935443.85-27907-45480909600605="` echo /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605 `" ) && sleep 0'"'"''
<10.0.0.12> (0, 'ansible-tmp-1665935443.85-27907-45480909600605=/root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605\n', '')
<10.0.0.12> Attempting python interpreter discovery
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> 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/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'echo PLATFORM; uname; echo FOUND; command -v '"'"'"'"'"'"'"'"'/usr/bin/python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.6'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python3.5'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python2.7'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python2.6'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/libexec/platform-python'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'/usr/bin/python3'"'"'"'"'"'"'"'"'; command -v '"'"'"'"'"'"'"'"'python'"'"'"'"'"'"'"'"'; echo ENDFOUND && sleep 0'"'"''
<10.0.0.12> (0, 'PLATFORM\nLinux\nFOUND\n/usr/bin/python\n/usr/bin/python2.7\n/usr/bin/python\nENDFOUND\n', '')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> 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/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'/usr/bin/python && sleep 0'"'"''
<10.0.0.12> (0, '{"osrelease_content": "NAME=\\"CentOS Linux\\"\\nVERSION=\\"7 (Core)\\"\\nID=\\"centos\\"\\nID_LIKE=\\"rhel fedora\\"\\nVERSION_ID=\\"7\\"\\nPRETTY_NAME=\\"CentOS Linux 7 (Core)\\"\\nANSI_COLOR=\\"0;31\\"\\nCPE_NAME=\\"cpe:/o:centos:centos:7\\"\\nHOME_URL=\\"https://www.centos.org/\\"\\nBUG_REPORT_URL=\\"https://bugs.centos.org/\\"\\n\\nCENTOS_MANTISBT_PROJECT=\\"CentOS-7\\"\\nCENTOS_MANTISBT_PROJECT_VERSION=\\"7\\"\\nREDHAT_SUPPORT_PRODUCT=\\"centos\\"\\nREDHAT_SUPPORT_PRODUCT_VERSION=\\"7\\"\\n\\n", "platform_dist_result": ["centos", "7.4.1708", "Core"]}\n', '')
Using module file /usr/lib/python2.7/site-packages/ansible/modules/system/ping.py
<10.0.0.12> PUT /root/.ansible/tmp/ansible-local-27892Bsbym2/tmpDle2Wk TO /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/AnsiballZ_ping.py
<10.0.0.12> 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/4121990a2e '[10.0.0.12]'
<10.0.0.12> (0, 'sftp> put /root/.ansible/tmp/ansible-local-27892Bsbym2/tmpDle2Wk /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/AnsiballZ_ping.py\n', '')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> 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/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'chmod u+x /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/ /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/AnsiballZ_ping.py && sleep 0'"'"''
<10.0.0.12> (0, '', '')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> 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/4121990a2e -tt 10.0.0.12 '/bin/sh -c '"'"'/usr/bin/python /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/AnsiballZ_ping.py && sleep 0'"'"''
<10.0.0.12> (0, '\r\n{"invocation": {"module_args": {"data": "pong"}}, "ping": "pong"}\r\n', 'Shared connection to 10.0.0.12 closed.\r\n')
<10.0.0.12> ESTABLISH SSH CONNECTION FOR USER: None
<10.0.0.12> 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/4121990a2e 10.0.0.12 '/bin/sh -c '"'"'rm -f -r /root/.ansible/tmp/ansible-tmp-1665935443.85-27907-45480909600605/ > /dev/null 2>&1 && sleep 0'"'"''
<10.0.0.12> (0, '', '')
10.0.0.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "invocation": {
        "module_args": {
            "data": "pong"
        }
    }, 
    "ping": "pong"
}
META: ran handlers
META: ran handlers
[root@mcw01 ~/mcw]$ 

 ansible inventory

 定义主机和主机组

 还没有免密的11和13

[root@mcw01 ~/mcw]$ cat hosts 
10.0.0.11
10.0.0.12
10.0.0.13
[web]
10.0.0.12
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.13 -m ping 
The authenticity of host '10.0.0.13 (10.0.0.13)' can't be established.
ECDSA key fingerprint is SHA256:1TxynA6n0UD3ZO0xutB2zsCTeq3wtp+O3L5p34As/4Q.
ECDSA key fingerprint is MD5:b0:3d:ab:dd:d7:93:68:ae:3d:b8:7a:35:c6:03:49:1d.
Are you sure you want to continue connecting (yes/no)? 10.0.0.11 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Permission denied (publickey,password).", 
    "unreachable": true
}
yes
10.0.0.13 | UNREACHABLE! => {
    "changed": false, 
    "msg": "Failed to connect to the host via ssh: Warning: Permanently added '10.0.0.13' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey,password).", 
    "unreachable": true
}
[root@mcw01 ~/mcw]$ 

没有免密的可以添加密码,加密码ansible_ssh_pass,免密的可以不用写密码。多个主机可以用冒号分割

[root@mcw01 ~/mcw]$ cat hosts 
10.0.0.11  ansible_ssh_pass='123456'
10.0.0.12
10.0.0.13  ansible_ssh_pass='123456'
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[ansible:chidren]
docker
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.13 -m ping 
[WARNING]:  * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]:  * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.13 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
10.0.0.11 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[root@mcw01 ~/mcw]$



[root@mcw01 ~/mcw]$ cat hosts 
10.0.0.11  ansible_ssh_pass='123456'
10.0.0.12  
10.0.0.13  ansible_ssh_pass='123456'
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[ansible:chidren]
docker
[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.12 -m ping 
[WARNING]:  * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]:  * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.12 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
10.0.0.11 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false, 
    "ping": "pong"
}
[root@mcw01 ~/mcw]$ 


[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.12:10.0.0.13 -m ping
[WARNING]: * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]: * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.13 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
10.0.0.11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
[root@mcw01 ~/mcw]$

-o单行输出

[root@mcw01 ~/mcw]$ ansible -i hosts 10.0.0.11:10.0.0.12:10.0.0.13 -m ping -o
[WARNING]:  * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]:  * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.13 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@mcw01 ~/mcw]$ 

一组主机组要添加密码等变量,需要在后面定义[主机组名称:vars]

[root@mcw01 ~/mcw]$ cat hosts 
10.0.0.11  ansible_ssh_pass='123456'
10.0.0.12  
10.0.0.13  ansible_ssh_pass='123456'
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[ansible:chidren]
docker
[root@mcw01 ~/mcw]$ ansible -i hosts docker -m ping -o
[WARNING]:  * Failed to parse /root/mcw/hosts with yaml plugin: YAML inventory has invalid structure, it should be a dictionary, got: <class
'ansible.parsing.yaml.objects.AnsibleUnicode'>
[WARNING]:  * Failed to parse /root/mcw/hosts with ini plugin: /root/mcw/hosts:8: Section [ansible:chidren] has unknown type: chidren
[WARNING]: Unable to parse /root/mcw/hosts as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
10.0.0.13 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@mcw01 ~/mcw]$

把[ansible:children] docker 去掉之后,就没有警告信息了。不过这个代表的是ansible这个主机组继承的docker主机组的数据,应该是这样的。从下面那小节可以看出

[root@mcw01 ~/mcw]$ cat hosts 
10.0.0.11  ansible_ssh_pass='123456'
10.0.0.12  
10.0.0.13  ansible_ssh_pass='123456'
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ ansible -i hosts docker -m ping -o
10.0.0.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.13 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
10.0.0.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@mcw01 ~/mcw]$ 

多个Inventory列表

inventory默认为/etc/ansible/hosts,可以修改为一个目录。

[root@mcw01 ~/mcw]$ tree inventory
inventory
├── docker
└── hosts

0 directories, 2 files
[root@mcw01 ~/mcw]$ 
[root@mcw01 ~/mcw]$ cat inventory/hosts 
10.0.0.11  ansible_ssh_pass='123456'
10.0.0.13  ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ cat inventory/docker 
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ 


注意这个参数不能放到最后,这个配置文件是分区的,放在defaults下面
[defaults]

# some basic default values...
inventory = /root/mcw/inventory/
#inventory      = /etc/ansible/hosts

[root@mcw01 ~/mcw]$ ansible 10.0.0.11:10.0.0.13 --list-hosts
  hosts (2):
    10.0.0.11
    10.0.0.13
[root@mcw01 ~/mcw]$ ansible docker --list-hosts
  hosts (3):
    10.0.0.11
    10.0.0.12
    10.0.0.13
[root@mcw01 ~/mcw]$ vim /root/mcw/inventory/docker 
[root@mcw01 ~/mcw]$ cat /root/mcw/inventory/docker
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_ssh_pass='123456'
[ansible:children]
docker
[root@mcw01 ~/mcw]$ ansible ansible --list-hosts
  hosts (3):
    10.0.0.11
    10.0.0.12
    10.0.0.13
[root@mcw01 ~/mcw]$ 

动态inventory,自定义inventory脚本

 程序:

[root@mcw01 ~/mcw]$ cat mcw.py 
#!/usr/bin/env python
#_*_ coding: utf-8 _*_
import argparse
import sys
import json
def lists():
    r={}
    h=['172.17.42.10'+str(i) for i in range(1,4)]
    hosts={'hosts':h}
    r['docker']=hosts
    return json.dumps(r,indent=4)
def hosts(name):
    r = {'ansible_ssh_pass':'123456'}
    cpis=dict(r.items())
    return json.dumps(cpis)
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-l','--list',help='hosts list',action='store_true')

    parser.add_argument('-H','--host',help='hosts vars')
    args=vars(parser.parse_args())

    if args['list']:
        print(lists())
    elif args['host']:
        print(hosts(args['host']))
    else:
        parser.print_help()
[root@mcw01 ~/mcw]$ 

执行结果:

[root@mcw01 ~/mcw]$ python mcw.py --list
{
    "docker": {
        "hosts": [
            "172.17.42.101", 
            "172.17.42.102", 
            "172.17.42.103"
        ]
    }
}
[root@mcw01 ~/mcw]$ 
 

[root@mcw01 ~/mcw]$ python mcw.py -H 172.17.42.102
{"ansible_ssh_pass": "123456"}
[root@mcw01 ~/mcw]$

 

 修改主机:

[root@mcw01 ~/mcw]$ cat mcw.py 
#!/usr/bin/env python
#_*_ coding: utf-8 _*_
import argparse
import sys
import json
def lists():
    r={}
    h=['10.0.0.1'+str(i) for i in range(1,4)]
    hosts={'hosts':h}
    r['docker']=hosts
    return json.dumps(r,indent=4)
def hosts(name):
    r = {'ansible_ssh_pass':'123456'}
    cpis=dict(r.items())
    return json.dumps(cpis)
if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('-l','--list',help='hosts list',action='store_true')

    parser.add_argument('-H','--host',help='hosts vars')
    args=vars(parser.parse_args())

    if args['list']:
        print(lists())
    elif args['host']:
        print(hosts(args['host']))
    else:
        parser.print_help()

调用的执行结果如下:

[root@mcw01 ~/mcw]$ python mcw.py --list
{
    "docker": {
        "hosts": [
            "10.0.0.11", 
            "10.0.0.12"
        ]
    }
}
[root@mcw01 ~/mcw]$ python mcw.py --list
{
    "docker": {
        "hosts": [
            "10.0.0.11", 
            "10.0.0.12"
        ]
    }
}
[root@mcw01 ~/mcw]$ vim mcw.py 
[root@mcw01 ~/mcw]$ python mcw.py --list
{
    "docker": {
        "hosts": [
            "10.0.0.11", 
            "10.0.0.12", 
            "10.0.0.13"
        ]
    }
}
[root@mcw01 ~/mcw]$ python mcw.py -H 10.0.0.13
{"ansible_ssh_pass": "123456"}
[root@mcw01 ~/mcw]$ 
[root@mcw01 ~/mcw]$ 
[root@mcw01 ~/mcw]$ ansible -i mcw.py  10.0.0.13 -m ping -o   #没有执行权限,会报错。不能解析脚本插件,这是作为脚本插件的,作为一个inventory源
[WARNING]:  * Failed to parse /root/mcw/mcw.py with script plugin: problem running /root/mcw/mcw.py --list ([Errno 13] Permission denied)
[WARNING]:  * Failed to parse /root/mcw/mcw.py with ini plugin: /root/mcw/mcw.py:3: Expected key=value host variable assignment, got: argparse
[WARNING]: Unable to parse /root/mcw/mcw.py as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.13
[root@mcw01 ~/mcw]$ ll mcw.py 
-rw-r--r-- 1 root root 715 Oct 17 21:51 mcw.py
[root@mcw01 ~/mcw]$ chmod +x mcw.py 
[root@mcw01 ~/mcw]$ ansible -i mcw.py  10.0.0.13 -m ping -o 
10.0.0.13 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@mcw01 ~/mcw]$ 

inventory内置参数

 

 指定ansible执行的python解释器

 Ansible Ad-Hoc 命令

ansible命令的常用选项

ansible命令的常用选项:

*-m MODULE_NAME:指定要执行的模块的名称,如果不指定-m选项,默认是COMMAND模块。
*-a MODULE_ARGS,:指定执行模块对应的参数选项。
-k:提示输入SSH登录的密码而不是基于密钥的验证
-K:用于输入执行su或sudo操作时需要的认证密码。
-b:表示提升权限操作。
–become-method:指定提升权限的方法,常用的有 sudo和su,默认是sudo。
–become-user:指定执行 sudo或su命令时要切换到哪个用户下,默认是root用户。
-B SECONDS:后台运行超时时间
-C:测试一下会改变什么内容,不会真正去执行,主要用来测试一些可能发生的变化
-f FORKS,:设置ansible并行的任务数。默认值是5
*-i INVENTORY: 指定主机清单文件的路径,默认为/etc/ansible/hosts。


ansible-playbook    -l 似乎剧本里面写了all ,-l后制定一个ip主机,那么只对这个ip主机做剧本里面的任务

执行命令

[root@mcw01 ~/mcw]$ ansible docker -m shell -a 'hostname' -o
10.0.0.13 | CHANGED | rc=0 | (stdout) mcw03
10.0.0.12 | CHANGED | rc=0 | (stdout) mcw02
10.0.0.11 | CHANGED | rc=0 | (stdout) mcw01
[root@mcw01 ~/mcw]$ 

添加并发参数,貌似默认就有5个并发

[root@mcw01 ~/mcw]$ ansible docker  -m shell -a 'sleep 10;hostname' -f 5 -o
10.0.0.13 | CHANGED | rc=0 | (stdout) mcw03
10.0.0.12 | CHANGED | rc=0 | (stdout) mcw02
10.0.0.11 | CHANGED | rc=0 | (stdout) mcw01
[root@mcw01 ~/mcw]$ 

异步执行功能,-P 0会返回job_id,然后针对主机根据job_id查询执行结果

[root@mcw01 ~/mcw]$ ansible docker -B 120 -P 0 -m shell -a 'sleep 10;hostname' -f 5 -o
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_job_id": "639569984173.2219", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/639569984173.2219", "started": 1}
10.0.0.13 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_job_id": "484845210255.1938", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/484845210255.1938", "started": 1}
10.0.0.11 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "ansible_job_id": "536908581108.6669", "changed": true, "finished": 0, "results_file": "/root/.ansible_async/536908581108.6669", "started": 1}
[root@mcw01 ~/mcw]$ 

根据对应主机,生成的job_id,通过async_status模块查看异步任务的状态和结果

[root@mcw01 ~/mcw]$ ansible 10.0.0.11 -m async_status -a 'jid=536908581108.6669'  #上面最后一个
10.0.0.11 | CHANGED => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "ansible_job_id": "536908581108.6669", 
    "changed": true, 
    "cmd": "sleep 10;hostname", 
    "delta": "0:00:10.011848", 
    "end": "2022-10-17 22:15:28.807455", 
    "finished": 1, 
    "rc": 0, 
    "start": "2022-10-17 22:15:18.795607", 
    "stderr": "", 
    "stderr_lines": [], 
    "stdout": "mcw01", 
    "stdout_lines": [
        "mcw01"
    ]
}
[root@mcw01 ~/mcw]$ 

-P 参数大于0,会自动根据job_id去轮询查询执行结果

[root@mcw01 ~/mcw]$ ansible docker -B 120 -P 1 -m shell -a 'sleep 5;hostname' -f 5 -o
10.0.0.12 | CHANGED => {"ansible_job_id": "620511648163.2293", "changed": true, "cmd": "sleep 5;hostname", "delta": "0:00:05.010433", "end": "2022-10-17 22:19:35.792721", "finished": 1, "rc": 0, "start": "2022-10-17 22:19:30.782288", "stderr": "", "stderr_lines": [], "stdout": "mcw02", "stdout_lines": ["mcw02"]}
10.0.0.13 | CHANGED => {"ansible_job_id": "928152102107.2079", "changed": true, "cmd": "sleep 5;hostname", "delta": "0:00:05.030950", "end": "2022-10-17 22:19:35.837632", "finished": 1, "rc": 0, "start": "2022-10-17 22:19:30.806682", "stderr": "", "stderr_lines": [], "stdout": "mcw03", "stdout_lines": ["mcw03"]}
10.0.0.11 | CHANGED => {"ansible_job_id": "90920163368.7394", "changed": true, "cmd": "sleep 5;hostname", "delta": "0:00:05.016046", "end": "2022-10-17 22:19:35.775778", "finished": 1, "rc": 0, "start": "2022-10-17 22:19:30.759732", "stderr": "", "stderr_lines": [], "stdout": "mcw01", "stdout_lines": ["mcw01"]}
[root@mcw01 ~/mcw]$ 

复制文件

批量下发文件

[root@mcw01 ~/mcw]$ ansible docker  -m copy -a 'src=mcw.py dest=/root/mcw.py owner=root group=root mode=644 backup=yes'  -o
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "checksum": "43eda5c263b92f73f5d8a4372b1b3f45c22f6655", "dest": "/root/mcw.py", "gid": 0, "group": "root", "md5sum": "987dc3e139ff6e84af06de81f1916539", "mode": "0644", "owner": "root", "size": 715, "src": "/root/.ansible/tmp/ansible-tmp-1666016653.42-8131-100136329222525/source", "state": "file", "uid": 0}
10.0.0.13 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "checksum": "43eda5c263b92f73f5d8a4372b1b3f45c22f6655", "dest": "/root/mcw.py", "gid": 0, "group": "root", "md5sum": "987dc3e139ff6e84af06de81f1916539", "mode": "0644", "owner": "root", "size": 715, "src": "/root/.ansible/tmp/ansible-tmp-1666016653.44-8132-195324969036986/source", "state": "file", "uid": 0}
10.0.0.11 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "checksum": "43eda5c263b92f73f5d8a4372b1b3f45c22f6655", "dest": "/root/mcw.py", "gid": 0, "group": "root", "md5sum": "987dc3e139ff6e84af06de81f1916539", "mode": "0644", "owner": "root", "size": 715, "src": "/root/.ansible/tmp/ansible-tmp-1666016653.42-8129-164733943098808/source", "state": "file", "uid": 0}
[root@mcw01 ~/mcw]$ 

批量验证文件下发功能

[root@mcw01 ~/mcw]$ ansible docker  -m shell -a 'md5sum /root/mcw.py'  -o
10.0.0.12 | CHANGED | rc=0 | (stdout) 987dc3e139ff6e84af06de81f1916539  /root/mcw.py
10.0.0.13 | CHANGED | rc=0 | (stdout) 987dc3e139ff6e84af06de81f1916539  /root/mcw.py
10.0.0.11 | CHANGED | rc=0 | (stdout) 987dc3e139ff6e84af06de81f1916539  /root/mcw.py
[root@mcw01 ~/mcw]$ 

包和服务管理

 安装包

[root@mcw01 ~/mcw]$ ansible docker  -m yum -a 'name=httpd state=latest'  -f 5 -o
10.0.0.11 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "changes": {"installed": ["httpd"], "updated": []}, "msg": "", "obsoletes": {"grub2": {"dist": "x86_64", "repo": "@anaconda", "version": "1:2.02-0.64.el7.centos"}, "grub2-tools": {"dist": "x86_64", "repo": "@anaconda", "version": "1:2.02-0.64.el7.centos"}, "iwl7265-firmware": {"dist": "noarch", "repo": "@anaconda", "version": "22.0.7.0-56.el7"}}, "rc": 0, "results": ["Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Running transaction check\n---> Package httpd.x86_64 0:2.4.6-97.el7.centos.5 will be installed\n--> Processing Dependency: httpd-tools = 2.4.6-97.el7.centos.5 for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Processing Dependency: /etc/mime.types for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Processing Dependency: libaprutil-1.so.0()(64bit) for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Processing Dependency: libapr-1.so.0()(64bit) for package: httpd-2.4.6-97.el7.centos.5.x86_64\n--> Running transaction check\n---> Package apr.x86_64 0:1.4.8-7.el7 will be installed\n---> Package apr-util.x86_64 0:1.5.2-6.el7 will be installed\n---> Package httpd-tools.x86_64 0:2.4.6-97.el7.centos.5 will be installed\n---> Package mailcap.noarch 0:2.1.41-2.el7 will be installed\n--> Finished Dependency Resolution\n\nDependencies Resolved\n\n================================================================================\n Package           Arch         Version                     Repository     Size\n================================================================================\nInstalling:\n httpd             x86_64       2.4.6-97.el7.centos.5       updates       2.7 M\nInstalling for dependencies:\n apr               x86_64       1.4.8-7.el7                 base          104 k\n apr-util          x86_64       1.5.2-6.el7                 base           92 k\n httpd-tools       x86_64       2.4.6-97.el7.centos.5       updates        94 k\n mailcap           noarch       2.1.41-2.el7                base           31 k\n\nTransaction Summary\n================================================================================\nInstall  1 Package (+4 Dependent packages)\n\nTotal download size: 3.0 M\nInstalled size: 10 M\nDownloading packages:\n--------------------------------------------------------------------------------\nTotal                                              1.1 MB/s | 3.0 MB  00:02     \nRunning transaction check\nRunning transaction test\nTransaction test succeeded\nRunning transaction\n  Installing : apr-1.4.8-7.el7.x86_64                                       1/5 \n  Installing : apr-util-1.5.2-6.el7.x86_64                                  2/5 \n  Installing : httpd-tools-2.4.6-97.el7.centos.5.x86_64                     3/5 \n  Installing : mailcap-2.1.41-2.el7.noarch                                  4/5 \n  Installing : httpd-2.4.6-97.el7.centos.5.x86_64                           5/5 \n  Verifying  : apr-1.4.8-7.el7.x86_64                                       1/5 \n  Verifying  : mailcap-2.1.41-2.el7.noarch                                  2/5 \n  Verifying  : httpd-tools-2.4.6-97.el7.centos.5.x86_64                     3/5 \n  Verifying  : apr-util-1.5.2-6.el7.x86_64                                  4/5 \n  Verifying  : httpd-2.4.6-97.el7.centos.5.x86_64                           5/5 \n\nInstalled:\n  httpd.x86_64 0:2.4.6-97.el7.centos.5                                          \n\nDependency Installed:\n  apr.x86_64 0:1.4.8-7.el7                      apr-util.x86_64 0:1.5.2-6.el7   \n  httpd-tools.x86_64 0:2.4.6-97.el7.centos.5    mailcap.noarch 0:2.1.41-2.el7   \n\nComplete!\n"]}
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "changes": {"installed": ["httpd"], "updated": []}, "msg": "", "obsoletes": {"grub2": {"dist": "x86_64", "repo": "@anaconda", "version": "1:2.02-0.64.el7.centos"}, "grub2-tools": {"dist": "x86_64", "repo": "@anaconda", "version": "1:2.02-0.64.el7.centos"}, "iwl7265-firmware": {"dist": "noarch", "repo": "@anaconda", "version": "22.0.7.0-56.el7"}}, "rc": 0, "results": ["Loaded plugins: fastestmirror\nLoading mirror speeds from cached hostfile\nResolving Dependencies\n--> Ru
.........

启动服务,验证服务运行情况。

[root@mcw01 ~/mcw]$ ansible docker  -m service -a 'name=httpd state=started'  -f 5 -o
10.0.0.13 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "name": "httpd", "state": "started", "status": {"ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", "After": "tmp.mount -.mount basic.target system.slice remote-fs.target systemd-journald.socket nss-lookup.target network.target", "AllowIsolate": "no", "AmbientCapabilities": "0", "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 Apache HTTP Server", "DevicePolicy": "auto", "Documentation": "man:httpd(8) man:apachectl(8)", "EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)", "ExecMainCode": "0", "ExecMainExitTimestampMonotonic": "0", "ExecMainPID": "0", "ExecMainStartTimestampMonotonic": "0", "ExecMainStatus": "0", "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStop": "{ path=/bin/kill ; argv[]=/bin/kill -WINCH ${MAINPID} ; 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/httpd.service", "GuessMainPID": "yes", "IOScheduling": "0", "Id": "httpd.service", "IgnoreOnIsolate": "no", "IgnoreOnSnapshot": "no", "IgnoreSIGPIPE": "yes", "InactiveEnterTimestampMonotonic": "0", "InactiveExitTimestampMonotonic": "0", "JobTimeoutAction": "none", "JobTimeoutUSec": "0", "KillMode": "control-group", "KillSignal": "18", "LimitAS": "18446744073709551615", "LimitCORE": "18446744073709551615", "LimitCPU": "18446744073709551615", "LimitDATA": "18446744073709551615", "LimitFSIZE": "18446744073709551615", "LimitLOCKS": "18446744073709551615", "LimitMEMLOCK": "65536", "LimitMSGQUEUE": "819200", "LimitNICE": "0", "LimitNOFILE": "4096", "LimitNPROC": "7206", "LimitRSS": "18446744073709551615", "LimitRTPRIO": "0", "LimitRTTIME": "18446744073709551615", "LimitSIGPENDING": "7206", "LimitSTACK": "18446744073709551615", "LoadState": "loaded", "MainPID": "0", "MemoryAccounting": "no", "MemoryCurrent": "18446744073709551615", "MemoryLimit": "18446744073709551615", "MountFlags": "0", "Names": "httpd.service", "NeedDaemonReload": "no", "Nice": "0", "NoNewPrivileges": "no", "NonBlocking": "no", "NotifyAccess": "main", "OOMScoreAdjust": "0", "OnFailureJobMode": "replace", "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", "TasksAccounting": "no", "TasksCurrent": "18446744073709551615", "TasksMax": "18446744073709551615", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Transient": "no", "Type": "notify", "UMask": "0022", "UnitFilePreset": "disabled", "UnitFileState": "disabled", "Wants": "system.slice", "WatchdogTimestampMonotonic": "0", "WatchdogUSec": "0"}}
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "name": "httpd", "state": "started", "status": {"ActiveEnterTimestampMonotonic": "0", "ActiveExitTimestampMonotonic": "0", "ActiveState": "inactive", "After": "systemd-journald.socket network.target remote-fs.target basic.target system.slice nss-lookup.target tmp.mount -.mount", "AllowIsolate": "no", "AmbientCapabilities": "0", "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 Apache HTTP Server", "DevicePolicy": "auto", "Documentation": "man:httpd(8) man:apachectl(8)", "EnvironmentFile": "/etc/sysconfig/httpd (ignore_errors=no)", "ExecMainCode": "0", "ExecMainExitTimestampMonotonic": "0", "ExecMainPID": "0", "ExecMainStartTimestampMonotonic": "0", "ExecMainStatus": "0", "ExecReload": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -k graceful ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStart": "{ path=/usr/sbin/httpd ; argv[]=/usr/sbin/httpd $OPTIONS -DFOREGROUND ; ignore_errors=no ; start_time=[n/a] ; stop_time=[n/a] ; pid=0 ; code=(null) ; status=0/0 }", "ExecStop": "{ path=/bin/kill ; argv[]=/bin/kill -WINCH ${MAINPID} ; 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/httpd.service", "GuessMainPID": "yes", "IOScheduling": "0", "Id": "httpd.service", "IgnoreOnIsolate": "no", "IgnoreOnSnapshot": "no", "IgnoreSIGPIPE": "yes", "InactiveEnterTimestampMonotonic": "0", "InactiveExitTimestampMonotonic": "0", "JobTimeoutAction": "none", "JobTimeoutUSec": "0", "KillMode": "control-group", "KillSignal": "18", "LimitAS": "18446744073709551615", "LimitCORE": "18446744073709551615", "LimitCPU": "18446744073709551615", "LimitDATA": "18446744073709551615", "LimitFSIZE": "18446744073709551615", "LimitLOCKS": "18446744073709551615", "LimitMEMLOCK": "65536", "LimitMSGQUEUE": "819200", "LimitNICE": "0", "LimitNOFILE": "4096", "LimitNPROC": "7206", "LimitRSS": "18446744073709551615", "LimitRTPRIO": "0", "LimitRTTIME": "18446744073709551615", "LimitSIGPENDING": "7206", "LimitSTACK": "18446744073709551615", "LoadState": "loaded", "MainPID": "0", "MemoryAccounting": "no", "MemoryCurrent": "18446744073709551615", "MemoryLimit": "18446744073709551615", "MountFlags": "0", "Names": "httpd.service", "NeedDaemonReload": "no", "Nice": "0", "NoNewPrivileges": "no", "NonBlocking": "no", "NotifyAccess": "main", "OOMScoreAdjust": "0", "OnFailureJobMode": "replace", "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", "TasksAccounting": "no", "TasksCurrent": "18446744073709551615", "TasksMax": "18446744073709551615", "TimeoutStartUSec": "1min 30s", "TimeoutStopUSec": "1min 30s", "TimerSlackNSec": "50000", "Transient": "no", "Type": "notify", "UMask": "0022", "UnitFilePreset": "disabled", "UnitFileState": "disabled", "Wants": "system.slice", "WatchdogTimestampMonotonic": "0", "WatchdogUSec": "0"}}
10.0.0.11 | FAILED! => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "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"}
[root@mcw01 ~/mcw]$ systemctl status httpd.service
● httpd.service - The Apache HTTP Server
   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Mon 2022-10-17 22:34:49 CST; 54s ago
     Docs: man:httpd(8)
           man:apachectl(8)
  Process: 10043 ExecStop=/bin/kill -WINCH ${MAINPID} (code=exited, status=1/FAILURE)
  Process: 10041 ExecStart=/usr/sbin/httpd $OPTIONS -DFOREGROUND (code=exited, status=1/FAILURE)
 Main PID: 10041 (code=exited, status=1/FAILURE)

Oct 17 22:34:49 mcw01 httpd[10041]: (98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
Oct 17 22:34:49 mcw01 httpd[10041]: (98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
Oct 17 22:34:49 mcw01 httpd[10041]: no listening sockets available, shutting down
Oct 17 22:34:49 mcw01 httpd[10041]: AH00015: Unable to open logs
Oct 17 22:34:49 mcw01 systemd[1]: httpd.service: main process exited, code=exited, status=1/FAILURE
Oct 17 22:34:49 mcw01 kill[10043]: kill: cannot find process ""
Oct 17 22:34:49 mcw01 systemd[1]: httpd.service: control process exited, code=exited status=1
Oct 17 22:34:49 mcw01 systemd[1]: Failed to start The Apache HTTP Server.
Oct 17 22:34:49 mcw01 systemd[1]: Unit httpd.service entered failed state.
Oct 17 22:34:49 mcw01 systemd[1]: httpd.service failed.
[root@mcw01 ~/mcw]$ 

用户管理

用openssl对密码加密。每次执行生成的不一样。这里是-1,是数字,不是英文l。

[root@mcw01 ~/mcw]$ echo ansible | openssl passwd -1 -stdin
$1$FcSSjfiL$pUtrs8BMzsnnODj/.bEru.
[root@mcw01 ~/mcw]$ echo ansible | openssl passwd -1 -stdin
$1$KSriNFoA$LwK8/pyHxja.8NPGRYUG00
[root@mcw01 ~/mcw]$ echo ansible | openssl passwd -1 -stdin
$1$hEDDgbqP$sNpyypRRWNbcg1VTQuCW6/
[root@mcw01 ~/mcw]$ 

批量创建用户

[root@mcw01 ~/mcw]$ ansible docker -m user -a 'name=xiaomaguohe password="$1$hEDDgbqP$sNpyypRRWNbcg1VTQuCW6/"' -f 5 -o
10.0.0.12 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/xiaomaguohe", "name": "xiaomaguohe", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001}
10.0.0.13 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/xiaomaguohe", "name": "xiaomaguohe", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001}
10.0.0.11 | CHANGED => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": true, "comment": "", "create_home": true, "group": 1001, "home": "/home/xiaomaguohe", "name": "xiaomaguohe", "password": "NOT_LOGGING_PASSWORD", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1001}
[root@mcw01 ~/mcw]$ 

验证登录成功,用ansible这个密码。

[root@mcw01 ~/mcw]$ su - xiaomaguohe
[xiaomaguohe@mcw01 ~]$ logout
[root@mcw01 ~/mcw]$ ssh 10.0.0.13 -l xiaomaguohe
xiaomaguohe@10.0.0.13's password: 
Permission denied, please try again.
xiaomaguohe@10.0.0.13's password: 
Permission denied, please try again.
xiaomaguohe@10.0.0.13's password: 
Last failed login: Mon Oct 17 22:43:29 CST 2022 from 10.0.0.11 on ssh:notty
There were 2 failed login attempts since the last successful login.
[xiaomaguohe@mcw03 ~]$ 

 Ansible facts

facts所有信息

[root@mcw01 ~/mcw]$ ansible 10.0.0.13 -m setup
10.0.0.13 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.0.13", 
            "172.16.0.13"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::6782:98:f742:b0e8", 
            "fe80::6faf:5935:98b1:7f8d", 
            "fe80::cdd:d005:758:ad29", 
            "fe80::d4fb:80c5:2bc7:80e9"
        ], 
        "ansible_apparmor": {
            "status": "disabled"
        }, 
        "ansible_architecture": "x86_64", 
        "ansible_bios_date": "07/02/2015", 
        "ansible_bios_version": "6.00", 
        "ansible_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-3.10.0-693.el7.x86_64", 
            "LANG": "en_US.UTF-8", 
            "crashkernel": "auto", 
            "quiet": true, 
            "rd.lvm.lv": "centos/swap", 
            "rhgb": true, 
            "ro": true, 
            "root": "/dev/mapper/centos-root"
        }, 
        "ansible_date_time": {
[root@mcw01 ~/mcw]$ ansible 10.0.0.13 -m setup
10.0.0.13 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.0.13", 
            "172.16.0.13"
        ], 
        "ansible_all_ipv6_addresses": [
            "fe80::6782:98:f742:b0e8", 
            "fe80::6faf:5935:98b1:7f8d", 
            "fe80::cdd:d005:758:ad29", 
            "fe80::d4fb:80c5:2bc7:80e9"
        ], 
        "ansible_apparmor": {
            "status": "disabled"
        }, 
        "ansible_architecture": "x86_64", 
        "ansible_bios_date": "07/02/2015", 
        "ansible_bios_version": "6.00", 
        "ansible_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-3.10.0-693.el7.x86_64", 
            "LANG": "en_US.UTF-8", 
            "crashkernel": "auto", 
            "quiet": true, 
            "rd.lvm.lv": "centos/swap", 
            "rhgb": true, 
            "ro": true, 
            "root": "/dev/mapper/centos-root"
        }, 
        "ansible_date_time": {
            "date": "2022-10-17", 
            "day": "17", 
            "epoch": "1666017976", 
            "hour": "22", 
            "iso8601": "2022-10-17T14:46:16Z", 
            "iso8601_basic": "20221017T224616026674", 
            "iso8601_basic_short": "20221017T224616", 
            "iso8601_micro": "2022-10-17T14:46:16.026674Z", 
            "minute": "46", 
            "month": "10", 
            "second": "16", 
            "time": "22:46:16", 
            "tz": "CST", 
            "tz_offset": "+0800", 
            "weekday": "Monday", 
            "weekday_number": "1", 
            "weeknumber": "42", 
            "year": "2022"
        }, 
        "ansible_default_ipv4": {
            "address": "10.0.0.13", 
            "alias": "ens33", 
            "broadcast": "10.0.0.255", 
            "gateway": "10.0.0.253", 
            "interface": "ens33", 
            "macaddress": "00:0c:29:3b:e7:8f", 
            "mtu": 1500, 
            "netmask": "255.255.255.0", 
            "network": "10.0.0.0", 
            "type": "ether"
        }, 
        "ansible_default_ipv6": {}, 
        "ansible_device_links": {
            "ids": {
                "dm-0": [
                    "dm-name-centos-root", 
                    "dm-uuid-LVM-dPgwZzREeFU4XPCeqlcpP8lN2yoWi5UR0ZmzJBkIPuFo9MclDJ2EFsWc9dsEkMKU"
                ], 
                "dm-1": [
                    "dm-name-centos-swap", 
                    "dm-uuid-LVM-dPgwZzREeFU4XPCeqlcpP8lN2yoWi5URvkvhq0DHBdCqWbyactVt1ViDOksA632r"
                ], 
                "sda2": [
                    "lvm-pv-uuid-tXyMIX-7OPp-Sz1l-2m6Z-9aWg-1NHr-j1w32L"
                ], 
                "sr0": [
                    "ata-VMware_Virtual_IDE_CDROM_Drive_10000000000000000001"
                ]
            }, 
            "labels": {
                "sr0": [
                    "CentOS\\x207\\x20x86_64"
                ]
            }, 
            "masters": {
                "sda2": [
                    "dm-0", 
                    "dm-1"
                ]
            }, 
            "uuids": {
                "dm-0": [
                    "fdafc50d-fb7e-4d66-a450-300c4ac8956c"
                ], 
                "dm-1": [
                    "2707bb63-44e7-4aa9-81e8-d7f2d5b9686f"
                ], 
                "sda1": [
                    "6838ae3d-d71e-48b2-809b-d39f412c0b41"
                ], 
                "sr0": [
                    "2017-09-06-10-51-00-00"
                ]
            }
        }, 
        "ansible_devices": {
            "dm-0": {
                "holders": [], 
                "host": "", 
                "links": {
                    "ids": [
                        "dm-name-centos-root", 
                        "dm-uuid-LVM-dPgwZzREeFU4XPCeqlcpP8lN2yoWi5UR0ZmzJBkIPuFo9MclDJ2EFsWc9dsEkMKU"
                    ], 
                    "labels": [], 
                    "masters": [], 
                    "uuids": [
                        "fdafc50d-fb7e-4d66-a450-300c4ac8956c"
                    ]
                }, 
                "model": null, 
                "partitions": {}, 
                "removable": "0", 
                "rotational": "1", 
                "sas_address": null, 
                "sas_device_handle": null, 
                "scheduler_mode": "", 
                "sectors": "38658048", 
                "sectorsize": "512", 
                "size": "18.43 GB", 
                "support_discard": "0", 
                "vendor": null, 
                "virtual": 1
            }, 
            "dm-1": {
                "holders": [], 
                "host": "", 
                "links": {
                    "ids": [
                        "dm-name-centos-swap", 
                        "dm-uuid-LVM-dPgwZzREeFU4XPCeqlcpP8lN2yoWi5URvkvhq0DHBdCqWbyactVt1ViDOksA632r"
                    ], 
                    "labels": [], 
                    "masters": [], 
                    "uuids": [
                        "2707bb63-44e7-4aa9-81e8-d7f2d5b9686f"
                    ]
                }, 
                "model": null, 
                "partitions": {}, 
                "removable": "0", 
                "rotational": "1", 
                "sas_address": null, 
                "sas_device_handle": null, 
                "scheduler_mode": "", 
                "sectors": "1638400", 
                "sectorsize": "512", 
                "size": "800.00 MB", 
                "support_discard": "0", 
                "vendor": null, 
                "virtual": 1
            }, 
            "sda": {
                "holders": [], 
                "host": "SCSI storage controller: LSI Logic / Symbios Logic 53c1030 PCI-X Fusion-MPT Dual Ultra320 SCSI (rev 01)", 
                "links": {
                    "ids": [], 
                    "labels": [], 
                    "masters": [], 
                    "uuids": []
                }, 
                "model": "VMware Virtual S", 
                "partitions": {
                    "sda1": {
                        "holders": [], 
                        "links": {
                            "ids": [], 
                            "labels": [], 
                            "masters": [], 
                            "uuids": [
                                "6838ae3d-d71e-48b2-809b-d39f412c0b41"
                            ]
                        }, 
                        "sectors": "1638400", 
                        "sectorsize": 512, 
                        "size": "800.00 MB", 
                        "start": "2048", 
                        "uuid": "6838ae3d-d71e-48b2-809b-d39f412c0b41"
                    }, 
                    "sda2": {
                        "holders": [
                            "centos-root", 
                            "centos-swap"
                        ], 
                        "links": {
                            "ids": [
                                "lvm-pv-uuid-tXyMIX-7OPp-Sz1l-2m6Z-9aWg-1NHr-j1w32L"
                            ], 
                            "labels": [], 
                            "masters": [
                                "dm-0", 
                                "dm-1"
                            ], 
                            "uuids": []
                        }, 
                        "sectors": "40302592", 
                        "sectorsize": 512, 
                        "size": "19.22 GB", 
                        "start": "1640448", 
                        "uuid": null
                    }
                }, 
                "removable": "0", 
                "rotational": "1", 
                "sas_address": null, 
                "sas_device_handle": null, 
                "scheduler_mode": "deadline", 
                "sectors": "41943040", 
                "sectorsize": "512", 
                "size": "20.00 GB", 
                "support_discard": "0", 
                "vendor": "VMware,", 
                "virtual": 1
            }, 
            "sr0": {
                "holders": [], 
                "host": "IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01)", 
                "links": {
                    "ids": [
                        "ata-VMware_Virtual_IDE_CDROM_Drive_10000000000000000001"
                    ], 
                    "labels": [
                        "CentOS\\x207\\x20x86_64"
                    ], 
                    "masters": [], 
                    "uuids": [
                        "2017-09-06-10-51-00-00"
                    ]
                }, 
                "model": "VMware IDE CDR10", 
                "partitions": {}, 
                "removable": "1", 
                "rotational": "1", 
                "sas_address": null, 
                "sas_device_handle": null, 
                "scheduler_mode": "cfq", 
                "sectors": "8830976", 
                "sectorsize": "2048", 
                "size": "4.21 GB", 
                "support_discard": "0", 
                "vendor": "NECVMWar", 
                "virtual": 1
            }
        }, 
        "ansible_distribution": "CentOS", 
        "ansible_distribution_file_parsed": true, 
        "ansible_distribution_file_path": "/etc/redhat-release", 
        "ansible_distribution_file_variety": "RedHat", 
        "ansible_distribution_major_version": "7", 
        "ansible_distribution_release": "Core", 
        "ansible_distribution_version": "7.4", 
        "ansible_dns": {
            "nameservers": [
                "223.5.5.5"
            ]
        }, 
        "ansible_domain": "", 
        "ansible_effective_group_id": 0, 
        "ansible_effective_user_id": 0, 
        "ansible_ens33": {
            "active": true, 
            "device": "ens33", 
            "features": {
                "busy_poll": "off [fixed]", 
                "fcoe_mtu": "off [fixed]", 
                "generic_receive_offload": "on", 
                "generic_segmentation_offload": "on", 
                "highdma": "off [fixed]", 
                "hw_tc_offload": "off [fixed]", 
                "l2_fwd_offload": "off [fixed]", 
                "large_receive_offload": "off [fixed]", 
                "loopback": "off [fixed]", 
                "netns_local": "off [fixed]", 
                "ntuple_filters": "off [fixed]", 
                "receive_hashing": "off [fixed]", 
                "rx_all": "off", 
                "rx_checksumming": "off", 
                "rx_fcs": "off", 
                "rx_vlan_filter": "on [fixed]", 
                "rx_vlan_offload": "on", 
                "rx_vlan_stag_filter": "off [fixed]", 
                "rx_vlan_stag_hw_parse": "off [fixed]", 
                "scatter_gather": "on", 
                "tcp_segmentation_offload": "on", 
                "tx_checksum_fcoe_crc": "off [fixed]", 
                "tx_checksum_ip_generic": "on", 
                "tx_checksum_ipv4": "off [fixed]", 
                "tx_checksum_ipv6": "off [fixed]", 
                "tx_checksum_sctp": "off [fixed]", 
                "tx_checksumming": "on", 
                "tx_fcoe_segmentation": "off [fixed]", 
                "tx_gre_csum_segmentation": "off [fixed]", 
                "tx_gre_segmentation": "off [fixed]", 
                "tx_gso_partial": "off [fixed]", 
                "tx_gso_robust": "off [fixed]", 
                "tx_ipip_segmentation": "off [fixed]", 
                "tx_lockless": "off [fixed]", 
                "tx_mpls_segmentation": "off [fixed]", 
                "tx_nocache_copy": "off", 
                "tx_scatter_gather": "on", 
                "tx_scatter_gather_fraglist": "off [fixed]", 
                "tx_sctp_segmentation": "off [fixed]", 
                "tx_sit_segmentation": "off [fixed]", 
                "tx_tcp6_segmentation": "off [fixed]", 
                "tx_tcp_ecn_segmentation": "off [fixed]", 
                "tx_tcp_mangleid_segmentation": "off", 
                "tx_tcp_segmentation": "on", 
                "tx_udp_tnl_csum_segmentation": "off [fixed]", 
                "tx_udp_tnl_segmentation": "off [fixed]", 
                "tx_vlan_offload": "on [fixed]", 
                "tx_vlan_stag_hw_insert": "off [fixed]", 
                "udp_fragmentation_offload": "off [fixed]", 
                "vlan_challenged": "off [fixed]"
            }, 
            "hw_timestamp_filters": [], 
            "ipv4": {
                "address": "10.0.0.13", 
                "broadcast": "10.0.0.255", 
                "netmask": "255.255.255.0", 
                "network": "10.0.0.0"
            }, 
            "ipv6": [
                {
                    "address": "fe80::6782:98:f742:b0e8", 
                    "prefix": "64", 
                    "scope": "link"
                }, 
                {
                    "address": "fe80::6faf:5935:98b1:7f8d", 
                    "prefix": "64", 
                    "scope": "link"
                }, 
                {
                    "address": "fe80::cdd:d005:758:ad29", 
                    "prefix": "64", 
                    "scope": "link"
                }
            ], 
            "macaddress": "00:0c:29:3b:e7:8f", 
            "module": "e1000", 
            "mtu": 1500, 
            "pciid": "0000:02:01.0", 
            "promisc": false, 
            "speed": 1000, 
            "timestamping": [
                "tx_software", 
                "rx_software", 
                "software"
            ], 
            "type": "ether"
        }, 
        "ansible_ens34": {
            "active": true, 
            "device": "ens34", 
            "features": {
                "busy_poll": "off [fixed]", 
                "fcoe_mtu": "off [fixed]", 
                "generic_receive_offload": "on", 
                "generic_segmentation_offload": "off [requested on]", 
                "highdma": "off [fixed]", 
                "hw_tc_offload": "off [fixed]", 
                "l2_fwd_offload": "off [fixed]", 
                "large_receive_offload": "off [fixed]", 
                "loopback": "off [fixed]", 
                "netns_local": "off [fixed]", 
                "ntuple_filters": "off [fixed]", 
                "receive_hashing": "off [fixed]", 
                "rx_all": "off [fixed]", 
                "rx_checksumming": "off [fixed]", 
                "rx_fcs": "off [fixed]", 
                "rx_vlan_filter": "off [fixed]", 
                "rx_vlan_offload": "off [fixed]", 
                "rx_vlan_stag_filter": "off [fixed]", 
                "rx_vlan_stag_hw_parse": "off [fixed]", 
                "scatter_gather": "off", 
                "tcp_segmentation_offload": "off", 
                "tx_checksum_fcoe_crc": "off [fixed]", 
                "tx_checksum_ip_generic": "off [fixed]", 
                "tx_checksum_ipv4": "off [fixed]", 
                "tx_checksum_ipv6": "off [fixed]", 
                "tx_checksum_sctp": "off [fixed]", 
                "tx_checksumming": "off", 
                "tx_fcoe_segmentation": "off [fixed]", 
                "tx_gre_csum_segmentation": "off [fixed]", 
                "tx_gre_segmentation": "off [fixed]", 
                "tx_gso_partial": "off [fixed]", 
                "tx_gso_robust": "off [fixed]", 
                "tx_ipip_segmentation": "off [fixed]", 
                "tx_lockless": "off [fixed]", 
                "tx_mpls_segmentation": "off [fixed]", 
                "tx_nocache_copy": "off", 
                "tx_scatter_gather": "off [fixed]", 
                "tx_scatter_gather_fraglist": "off [fixed]", 
                "tx_sctp_segmentation": "off [fixed]", 
                "tx_sit_segmentation": "off [fixed]", 
                "tx_tcp6_segmentation": "off [fixed]", 
                "tx_tcp_ecn_segmentation": "off [fixed]", 
                "tx_tcp_mangleid_segmentation": "off [fixed]", 
                "tx_tcp_segmentation": "off [fixed]", 
                "tx_udp_tnl_csum_segmentation": "off [fixed]", 
                "tx_udp_tnl_segmentation": "off [fixed]", 
                "tx_vlan_offload": "off [fixed]", 
                "tx_vlan_stag_hw_insert": "off [fixed]", 
                "udp_fragmentation_offload": "off [fixed]", 
                "vlan_challenged": "off [fixed]"
            }, 
            "hw_timestamp_filters": [], 
            "ipv4": {
                "address": "172.16.0.13", 
                "broadcast": "172.16.0.255", 
                "netmask": "255.255.255.0", 
                "network": "172.16.0.0"
            }, 
            "ipv6": [
                {
                    "address": "fe80::d4fb:80c5:2bc7:80e9", 
                    "prefix": "64", 
                    "scope": "link"
                }
            ], 
            "macaddress": "00:0c:29:3b:e7:99", 
            "module": "pcnet32", 
            "mtu": 1500, 
            "pciid": "0000:02:02.0", 
            "promisc": false, 
            "timestamping": [
                "rx_software", 
                "software"
            ], 
            "type": "ether"
        }, 
        "ansible_env": {
            "HOME": "/root", 
            "LANG": "en_US.UTF-8", 
            "LESSOPEN": "||/usr/bin/lesspipe.sh %s", 
            "LOGNAME": "root", 
            "LS_COLORS": "rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=01;05;37;41:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=01;36:*.au=01;36:*.flac=01;36:*.mid=01;36:*.midi=01;36:*.mka=01;36:*.mp3=01;36:*.mpc=01;36:*.ogg=01;36:*.ra=01;36:*.wav=01;36:*.axa=01;36:*.oga=01;36:*.spx=01;36:*.xspf=01;36:", 
            "MAIL": "/var/mail/root", 
            "PATH": "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin", 
            "PWD": "/root", 
            "SHELL": "/bin/bash", 
            "SHLVL": "2", 
            "SSH_CLIENT": "10.0.0.11 16479 22", 
            "SSH_CONNECTION": "10.0.0.11 16479 10.0.0.13 22", 
            "SSH_TTY": "/dev/pts/1", 
            "TERM": "xterm", 
            "USER": "root", 
            "XDG_RUNTIME_DIR": "/run/user/0", 
            "XDG_SESSION_ID": "15", 
            "_": "/usr/bin/python"
        }, 
        "ansible_fibre_channel_wwn": [], 
        "ansible_fips": false, 
        "ansible_form_factor": "Other", 
        "ansible_fqdn": "mcw03", 
        "ansible_hostname": "mcw03", 
        "ansible_hostnqn": "", 
        "ansible_interfaces": [
            "ens34", 
            "lo", 
            "ens33"
        ], 
        "ansible_is_chroot": false, 
        "ansible_iscsi_iqn": "", 
        "ansible_kernel": "3.10.0-693.el7.x86_64", 
        "ansible_kernel_version": "#1 SMP Tue Aug 22 21:09:27 UTC 2017", 
        "ansible_lo": {
            "active": true, 
            "device": "lo", 
            "features": {
                "busy_poll": "off [fixed]", 
                "fcoe_mtu": "off [fixed]", 
                "generic_receive_offload": "on", 
                "generic_segmentation_offload": "on", 
                "highdma": "on [fixed]", 
                "hw_tc_offload": "off [fixed]", 
                "l2_fwd_offload": "off [fixed]", 
                "large_receive_offload": "off [fixed]", 
                "loopback": "on [fixed]", 
                "netns_local": "on [fixed]", 
                "ntuple_filters": "off [fixed]", 
                "receive_hashing": "off [fixed]", 
                "rx_all": "off [fixed]", 
                "rx_checksumming": "on [fixed]", 
                "rx_fcs": "off [fixed]", 
                "rx_vlan_filter": "off [fixed]", 
                "rx_vlan_offload": "off [fixed]", 
                "rx_vlan_stag_filter": "off [fixed]", 
                "rx_vlan_stag_hw_parse": "off [fixed]", 
                "scatter_gather": "on", 
                "tcp_segmentation_offload": "on", 
                "tx_checksum_fcoe_crc": "off [fixed]", 
                "tx_checksum_ip_generic": "on [fixed]", 
                "tx_checksum_ipv4": "off [fixed]", 
                "tx_checksum_ipv6": "off [fixed]", 
                "tx_checksum_sctp": "on [fixed]", 
                "tx_checksumming": "on", 
                "tx_fcoe_segmentation": "off [fixed]", 
                "tx_gre_csum_segmentation": "off [fixed]", 
                "tx_gre_segmentation": "off [fixed]", 
                "tx_gso_partial": "off [fixed]", 
                "tx_gso_robust": "off [fixed]", 
                "tx_ipip_segmentation": "off [fixed]", 
                "tx_lockless": "on [fixed]", 
                "tx_mpls_segmentation": "off [fixed]", 
                "tx_nocache_copy": "off [fixed]", 
                "tx_scatter_gather": "on [fixed]", 
                "tx_scatter_gather_fraglist": "on [fixed]", 
                "tx_sctp_segmentation": "on", 
                "tx_sit_segmentation": "off [fixed]", 
                "tx_tcp6_segmentation": "on", 
                "tx_tcp_ecn_segmentation": "on", 
                "tx_tcp_mangleid_segmentation": "on", 
                "tx_tcp_segmentation": "on", 
                "tx_udp_tnl_csum_segmentation": "off [fixed]", 
                "tx_udp_tnl_segmentation": "off [fixed]", 
                "tx_vlan_offload": "off [fixed]", 
                "tx_vlan_stag_hw_insert": "off [fixed]", 
                "udp_fragmentation_offload": "on", 
                "vlan_challenged": "on [fixed]"
            }, 
            "hw_timestamp_filters": [], 
            "ipv4": {
                "address": "127.0.0.1", 
                "broadcast": "", 
                "netmask": "255.0.0.0", 
                "network": "127.0.0.0"
            }, 
            "ipv6": [
                {
                    "address": "::1", 
                    "prefix": "128", 
                    "scope": "host"
                }
            ], 
            "mtu": 65536, 
            "promisc": false, 
            "timestamping": [
                "rx_software", 
                "software"
            ], 
            "type": "loopback"
        }, 
        "ansible_local": {}, 
        "ansible_lsb": {}, 
        "ansible_lvm": {
            "lvs": {
                "root": {
                    "size_g": "18.43", 
                    "vg": "centos"
                }, 
                "swap": {
                    "size_g": "0.78", 
                    "vg": "centos"
                }
            }, 
            "pvs": {
                "/dev/sda2": {
                    "free_g": "0", 
                    "size_g": "19.21", 
                    "vg": "centos"
                }
            }, 
            "vgs": {
                "centos": {
                    "free_g": "0", 
                    "num_lvs": "2", 
                    "num_pvs": "1", 
                    "size_g": "19.21"
                }
            }
        }, 
        "ansible_machine": "x86_64", 
        "ansible_machine_id": "9c116b87e41d4108aa3772cb45766f57", 
        "ansible_memfree_mb": 1275, 
        "ansible_memory_mb": {
            "nocache": {
                "free": 1650, 
                "used": 173
            }, 
            "real": {
                "free": 1275, 
                "total": 1823, 
                "used": 548
            }, 
            "swap": {
                "cached": 0, 
                "free": 799, 
                "total": 799, 
                "used": 0
            }
        }, 
        "ansible_memtotal_mb": 1823, 
        "ansible_mounts": [
            {
                "block_available": 167483, 
                "block_size": 4096, 
                "block_total": 203945, 
                "block_used": 36462, 
                "device": "/dev/sda1", 
                "fstype": "xfs", 
                "inode_available": 409272, 
                "inode_total": 409600, 
                "inode_used": 328, 
                "mount": "/boot", 
                "options": "rw,relatime,attr2,inode64,noquota", 
                "size_available": 686010368, 
                "size_total": 835358720, 
                "uuid": "6838ae3d-d71e-48b2-809b-d39f412c0b41"
            }, 
            {
                "block_available": 4040310, 
                "block_size": 4096, 
                "block_total": 4829696, 
                "block_used": 789386, 
                "device": "/dev/mapper/centos-root", 
                "fstype": "xfs", 
                "inode_available": 9631409, 
                "inode_total": 9664512, 
                "inode_used": 33103, 
                "mount": "/", 
                "options": "rw,relatime,attr2,inode64,noquota", 
                "size_available": 16549109760, 
                "size_total": 19782434816, 
                "uuid": "fdafc50d-fb7e-4d66-a450-300c4ac8956c"
            }
        ], 
        "ansible_nodename": "mcw03", 
        "ansible_os_family": "RedHat", 
        "ansible_pkg_mgr": "yum", 
        "ansible_proc_cmdline": {
            "BOOT_IMAGE": "/vmlinuz-3.10.0-693.el7.x86_64", 
            "LANG": "en_US.UTF-8", 
            "crashkernel": "auto", 
            "quiet": true, 
            "rd.lvm.lv": [
                "centos/root", 
                "centos/swap"
            ], 
            "rhgb": true, 
            "ro": true, 
            "root": "/dev/mapper/centos-root"
        }, 
        "ansible_processor": [
            "0", 
            "GenuineIntel", 
            "Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz"
        ], 
        "ansible_processor_cores": 1, 
        "ansible_processor_count": 1, 
        "ansible_processor_threads_per_core": 1, 
        "ansible_processor_vcpus": 1, 
        "ansible_product_name": "VMware Virtual Platform", 
        "ansible_product_serial": "VMware-56 4d 73 0d c4 f8 d6 8e-49 9a aa d0 4b 3b e7 8f", 
        "ansible_product_uuid": "0D734D56-F8C4-8ED6-499A-AAD04B3BE78F", 
        "ansible_product_version": "None", 
        "ansible_python": {
            "executable": "/usr/bin/python", 
            "has_sslcontext": true, 
            "type": "CPython", 
            "version": {
                "major": 2, 
                "micro": 5, 
                "minor": 7, 
                "releaselevel": "final", 
                "serial": 0
            }, 
            "version_info": [
                2, 
                7, 
                5, 
                "final", 
                0
            ]
        }, 
        "ansible_python_version": "2.7.5", 
        "ansible_real_group_id": 0, 
        "ansible_real_user_id": 0, 
        "ansible_selinux": {
            "status": "disabled"
        }, 
        "ansible_selinux_python_present": true, 
        "ansible_service_mgr": "systemd", 
        "ansible_ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBGyISYkhvbLT8t+3cPzqR90VU2jZ86IhYoLxgDCECSQiVFwxi017qOfcIjxacb6/i/K6PEo9kSEcAIIPzqVwk5I=", 
        "ansible_ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAICoAiTwDt4QEjQ4OvpXI4MG6bsyeePHoZPDD+wt0RR9F", 
        "ansible_ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQC8Cz0BUtBytTrJP25idcQLh0Q2DG7opqrIshMhGRc/sbwZOqe2kmFv3EEedHK5Flz2LOtxMURGRioGfgkobGeFUgfs+qCXhF4JHTno8bDQMpcS3shr4kRWl0jVvRqcka7Aq7b3zokGpJmJ8lXSZnTDhsliQPG7fyYSn1nORQdbRbQ5uVXvKYFDPn5rTWBu1lRz/8z5xGQU2ejLVj6f1QGNCWgxYVj7jd8LW81jg8zQ5aZH+GjlMuZGVBW225eWsIlOvHs/8gQzOtansD7PUk1klivueby8/KyTVBkrxGkTIKbKSv9b8U9742dsq1zAsyJ0Ij6Ney4RqlDG7B49BfFf", 
        "ansible_swapfree_mb": 799, 
        "ansible_swaptotal_mb": 799, 
        "ansible_system": "Linux", 
        "ansible_system_capabilities": [
            "cap_chown", 
            "cap_dac_override", 
            "cap_dac_read_search", 
            "cap_fowner", 
            "cap_fsetid", 
            "cap_kill", 
            "cap_setgid", 
            "cap_setuid", 
            "cap_setpcap", 
            "cap_linux_immutable", 
            "cap_net_bind_service", 
            "cap_net_broadcast", 
            "cap_net_admin", 
            "cap_net_raw", 
            "cap_ipc_lock", 
            "cap_ipc_owner", 
            "cap_sys_module", 
            "cap_sys_rawio", 
            "cap_sys_chroot", 
            "cap_sys_ptrace", 
            "cap_sys_pacct", 
            "cap_sys_admin", 
            "cap_sys_boot", 
            "cap_sys_nice", 
            "cap_sys_resource", 
            "cap_sys_time", 
            "cap_sys_tty_config", 
            "cap_mknod", 
            "cap_lease", 
            "cap_audit_write", 
            "cap_audit_control", 
            "cap_setfcap", 
            "cap_mac_override", 
            "cap_mac_admin", 
            "cap_syslog", 
            "35", 
            "36+ep"
        ], 
        "ansible_system_capabilities_enforced": "True", 
        "ansible_system_vendor": "VMware, Inc.", 
        "ansible_uptime_seconds": 3384, 
        "ansible_user_dir": "/root", 
        "ansible_user_gecos": "root", 
        "ansible_user_gid": 0, 
        "ansible_user_id": "root", 
        "ansible_user_shell": "/bin/bash", 
        "ansible_user_uid": 0, 
        "ansible_userspace_architecture": "x86_64", 
        "ansible_userspace_bits": "64", 
        "ansible_virtualization_role": "guest", 
        "ansible_virtualization_type": "VMware", 
        "discovered_interpreter_python": "/usr/bin/python", 
        "gather_subset": [
            "all"
        ], 
        "module_setup": true
    }, 
    "changed": false
}
[root@mcw01 ~/mcw]$ 
全部返回结果

 facts查看指定信息

[root@mcw01 ~/mcw]$ ansible 10.0.0.13 -m setup -a 'filter=ansible_all_ipv4_addresses'
10.0.0.13 | SUCCESS => {
    "ansible_facts": {
        "ansible_all_ipv4_addresses": [
            "10.0.0.13", 
            "172.16.0.13"
        ], 
        "discovered_interpreter_python": "/usr/bin/python"
    }, 
    "changed": false
}
[root@mcw01 ~/mcw]$ 

使用facter扩展facts信息,使用ohai扩展facts信息

 Ansible role 以Nginx为案例

 查看目录结构

[root@mcw01 ~/mcw]$ tree 
.
├── roles
│   └── nginx
│       ├── files
│       │   └── index.html
│       ├── handlers
│       │   └── main.yaml
│       ├── tasks
│       │   └── main.yaml
│       ├── templates
│       │   └── nginx.conf.j2
│       └── vars
│           └── main.yaml
└── site.yaml

7 directories, 6 files
[root@mcw01 ~/mcw]$ 

 查看文件内容,下面的是有错误的

 

[root@mcw01 ~/mcw]$ cat site.yaml 
- hosts: 10.0.0.12
    roles:
      - { role: nginx ,version: 1.0.15}
[root@mcw01 ~/mcw]$ cat roles/nginx/tasks/main.yaml 
- name: Install nginx package
    yum: name=nginx-{{ version }} state=present
- name: Copy nginx.conf Template
    template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root backup=yes mode=0644
    notify: restart nginx
- name: Copy index html
    copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
- name: make sure nginx service running
    service: name=nginx state=started
[root@mcw01 ~/mcw]$ cat roles/nginx/handlers/main.yaml 
- name: restart nginx
    service: name=nginx state=restarted
[root@mcw01 ~/mcw]$ cat roles/nginx/templates/nginx.conf.j2 |grep '\{{'
worker_processes {{ ansible_processor_cores }};
[root@mcw01 ~/mcw]$ cat roles/nginx/files/index.html 
hello mcw
[root@mcw01 ~/mcw]$ cat roles/nginx/templates/nginx.conf.j2 
user nginx;
worker_processes {{ ansible_processor_cores }};
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;


include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

}
[root@mcw01 ~/mcw]$ 

查看主机2是没有安装Nginx的

 

[root@mcw02 ~]$ rpm -qa|grep nginx
[root@mcw02 ~]$ 

 

错误:

直接是-hosts是不行的,前面得加个- name起个名字

[root@mcw01 ~/mcw]$ cat site.yaml 
- hosts: 10.0.0.12
    remote_user: root
    roles: 
        - { role: nginx, version: 1.0.15 }
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml --syntax-check
[WARNING]: Unable to parse /root/mcw/inventory as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: No JSON object could be decoded

Syntax Error while loading YAML.
  mapping values are not allowed in this context

The error appears to be in '/root/mcw/site.yaml': line 2, column 16, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- hosts: 10.0.0.12
    remote_user: root
               ^ here

起个名字之后报错变了:变成其它问题了

[root@mcw01 ~/mcw]$ cat site.yaml
- name: install  nginx
  hosts: 10.0.0.12
  roles:
      - { role: nginx ,version: 1.0.15}
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml
[WARNING]: Unable to parse /root/mcw/inventory as an inventory source
[WARNING]: No inventory was parsed, only implicit localhost is available
[WARNING]: provided hosts list is empty, only localhost is available. Note that the implicit localhost does not match 'all'
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: No JSON object could be decoded

Syntax Error while loading YAML.
  mapping values are not allowed in this context

The error appears to be in '/root/mcw/roles/nginx/tasks/main.yaml': line 2, column 8, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- name: Install nginx package
    yum: name=nginx-{{ version }} state=present
       ^ here
We could be wrong, but this one looks like it might be an issue with
missing quotes. Always quote template expression brackets when they
start a value. For instance:

    with_items:
      - {{ foo }}

Should be written as:

    with_items:
      - "{{ foo }}"
[root@mcw01 ~/mcw]$ 

多了两个空格都不行。- 空格 name:,下面的模块跟-只差两个字符的距离,空格多了就报错

[root@mcw01 ~/mcw]$ cat roles/nginx/tasks/main.yaml
- name: Install nginx package
  yum: name=nginx-{{ version }} state=present
- name: Copy nginx.conf Template
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root backup=yes mode=0644
  notify: restart nginx
- name: Copy index html
    copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
- name: make sure nginx service running
    service: name=nginx state=started
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml --syntax-check
ERROR! We were unable to read either as JSON nor YAML, these are the errors we got from each:
JSON: No JSON object could be decoded

Syntax Error while loading YAML.
  mapping values are not allowed in this context

The error appears to be in '/root/mcw/roles/nginx/tasks/main.yaml': line 7, column 9, but may
be elsewhere in the file depending on the exact syntax problem.

The offending line appears to be:

- name: Copy index html
    copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
        ^ here
[root@mcw01 ~/mcw]$ 

正确的文件配置

[root@mcw01 ~/mcw]$ cat site.yaml
- name: install  nginx
  hosts: 10.0.0.12
  roles:
      - { role: nginx ,version: 1.0.15}
[root@mcw01 ~/mcw]$ cat roles/nginx/tasks/main.yaml
- name: Install nginx package
  yum: name=nginx-{{ version }} state=present
- name: Copy nginx.conf Template
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root backup=yes mode=0644
  notify: restart nginx
- name: Copy index html
  copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
- name: make sure nginx service running
  service: name=nginx state=started
[root@mcw01 ~/mcw]$ cat roles/nginx/handlers/main.yaml 
- name: restart nginx
  service: name=nginx state=restarted
[root@mcw01 ~/mcw]$ cat roles/nginx/templates/nginx.conf.j2 |grep '\{{'
worker_processes {{ ansible_processor_cores }};
[root@mcw01 ~/mcw]$ cat roles/nginx/files/index.html
hello mcw
[root@mcw01 ~/mcw]$ 

部署role

语法检查没有问题,就部署,因为版本没有,就改了个有的版本

[root@mcw01 ~/mcw]$ ansible-playbook site.yaml --syntax-check

playbook: site.yaml
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml 

PLAY [install  nginx] ******************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12]

TASK [Install nginx package] ***********************************************************************************************************************
fatal: [10.0.0.12]: FAILED! => {"changed": false, "msg": "No package matching 'nginx-1.0.15' found available, installed or updated", "rc": 126, "results": ["No package matching 'nginx-1.0.15' found available, installed or updated"]}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ vim site.yaml
[root@mcw01 ~/mcw]$ cat site.yaml
- name: install  nginx
  hosts: 10.0.0.12
  roles:
      - { role: nginx ,version: 1.20.1 }
[root@mcw01 ~/mcw]$ ansible-playbook site.yaml 

PLAY [install  nginx] ******************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12]

TASK [Install nginx package] ***********************************************************************************************************************
changed: [10.0.0.12]

TASK [Copy nginx.conf Template] ********************************************************************************************************************
changed: [10.0.0.12]

TASK [nginx : Copy index html] *********************************************************************************************************************
changed: [10.0.0.12]

TASK [make sure nginx service running] *************************************************************************************************************
changed: [10.0.0.12]

RUNNING HANDLER [restart nginx] ********************************************************************************************************************
changed: [10.0.0.12]

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

 虽然多级目录不存在,但是这里yum安装默认生成的目录,然后将配置文件替换掉生成文件

[root@mcw02 ~]$ ls /usr/share/nginx/
html  modules
[root@mcw02 ~]$ 

分析role

 

[root@mcw01 ~/mcw]$ cat site.yaml
- name: install  nginx
  hosts: 10.0.0.12
  roles:
      - { role: nginx ,version: 1.0.15}
[root@mcw01 ~/mcw]$ cat roles/nginx/tasks/main.yaml
- name: Install nginx package
  yum: name=nginx-{{ version }} state=present
- name: Copy nginx.conf Template
  template: src=nginx.conf.j2 dest=/etc/nginx/nginx.conf owner=root group=root backup=yes mode=0644
  notify: restart nginx
- name: Copy index html
  copy: src=index.html dest=/usr/share/nginx/html/index.html owner=root group=root backup=yes mode=0644
- name: make sure nginx service running
  service: name=nginx state=started
[root@mcw01 ~/mcw]$ cat roles/nginx/handlers/main.yaml 
- name: restart nginx
  service: name=nginx state=restarted
[root@mcw01 ~/mcw]$ cat roles/nginx/templates/nginx.conf.j2 |grep '\{{'
worker_processes {{ ansible_processor_cores }};
[root@mcw01 ~/mcw]$ cat roles/nginx/files/index.html
hello mcw
[root@mcw01 ~/mcw]$ 

 playbook基本语法案例

 Nginx剧本案例和检查

[root@mcw01 ~/mcw]$ cat nginx.yaml 
- hosts: all
  tasks:
    - name: install nginx package
      yum: name=nginx state=present
    - name: copy nginx.conf
      template: src=./nginx.conf.j2 dest=/etc/nginx/nginx.conf
      notify:
        - ReStart Nginx Service
  handlers:
    - name: ReStart Nginx Service
      service: name=nginx state=restarted
[root@mcw01 ~/mcw]$ cat hosts 
[nginx]
10.0.0.1[1:3]
[nginx:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ 
[root@mcw01 ~/mcw]$ cat hosts  #定义主机组,定义这个主机组有的变量,变量包含解释器路径和密码
[nginx]
10.0.0.1[1:3]
[nginx:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ grep worker_processes nginx.conf.j2  #模板使用工作进程数,是和ansible进程核数相同
worker_processes {{ ansible_processor_cores }};

[root@mcw01 ~/mcw]$ ansible-playbook -i hosts nginx.yaml --syntax-check  #检查语法

playbook: nginx.yaml
[root@mcw01 ~/mcw]$ ansible-playbook -i hosts nginx.yaml --list-task   #检查剧本有哪些任务。这里只有两个

playbook: nginx.yaml

  play #1 (all): all    TAGS: []
    tasks:
      install nginx package    TAGS: []
      copy nginx.conf    TAGS: []
[root@mcw01 ~/mcw]$ ansible-playbook -i hosts nginx.yaml --list-hosts  #检查剧本执行的主机列表

playbook: nginx.yaml

  play #1 (all): all    TAGS: []
    pattern: [u'all']
    hosts (3):
      10.0.0.11
      10.0.0.13
      10.0.0.12
[root@mcw01 ~/mcw]$ 

把Nginx yum安装的,没有注释掉 的配置拿出来,改了个工作进程数配置

[root@mcw01 ~/mcw]$ cat nginx.conf.j2 
user nginx;
worker_processes {{ ansible_processor_cores }};
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;


include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile            on;
    tcp_nopush          on;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    include /etc/nginx/conf.d/*.conf;

    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }

}
[root@mcw01 ~/mcw]$ 

Nginx剧本执行

 部署过程。我的一台部署了gitlab,好像是它的Nginx进程占用了80端口,导致yum装的没法启动

[root@mcw01 ~/mcw]$ ansible-playbook -i hosts nginx.yaml -f 3

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

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12]
ok: [10.0.0.11]
ok: [10.0.0.13]

TASK [install nginx package] ***********************************************************************************************************************
changed: [10.0.0.12]
changed: [10.0.0.11]
changed: [10.0.0.13]

TASK [copy nginx.conf] *****************************************************************************************************************************
changed: [10.0.0.12]
changed: [10.0.0.13]
changed: [10.0.0.11]

RUNNING HANDLER [ReStart Nginx Service] ************************************************************************************************************
changed: [10.0.0.12]
changed: [10.0.0.13]
fatal: [10.0.0.11]: FAILED! => {"changed": false, "msg": "Unable to start service nginx: Job for nginx.service failed because the control process exited with error code. See \"systemctl status nginx.service\" and \"journalctl -xe\" for details.\n"}

NO MORE HOSTS LEFT *********************************************************************************************************************************

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=3    changed=2    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=4    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ ss -lntup|grep 80
tcp    LISTEN     0      1024   127.0.0.1:8080                  *:*                   users:(("bundle",pid=2132,fd=9),("bundle",pid=2128,fd=9),("bundle",pid=917,fd=9))
tcp    LISTEN     0      511       *:80                    *:*                   users:(("nginx",pid=769,fd=7),("nginx",pid=706,fd=7))
tcp    LISTEN     0      511       *:8060                  *:*                   users:(("nginx",pid=769,fd=8),("nginx",pid=706,fd=8))
tcp    LISTEN     0      50        *:3306                  *:*                   users:(("mysqld",pid=1480,fd=14))
tcp    LISTEN     0      50       :::8081                 :::*                   users:(("java",pid=1850,fd=160))
[root@mcw01 ~/mcw]$ systemctl status nginx.service
● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; disabled; vendor preset: disabled)
   Active: failed (Result: exit-code) since Tue 2022-10-18 20:31:34 CST; 56s ago
  Process: 6315 ExecStart=/usr/sbin/nginx (code=exited, status=1/FAILURE)
  Process: 6313 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 6311 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)

Oct 18 20:31:31 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:32 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:32 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:33 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:33 mcw01 nginx[6315]: nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
Oct 18 20:31:34 mcw01 nginx[6315]: nginx: [emerg] still could not bind()
Oct 18 20:31:34 mcw01 systemd[1]: nginx.service: control process exited, code=exited status=1
Oct 18 20:31:34 mcw01 systemd[1]: Failed to start The nginx HTTP and reverse proxy server.
Oct 18 20:31:34 mcw01 systemd[1]: Unit nginx.service entered failed state.
Oct 18 20:31:34 mcw01 systemd[1]: nginx.service failed.
[root@mcw01 ~/mcw]$ 

查看端口是否开启监听,配置文件是否正确

[root@mcw01 ~/mcw]$ ansible -i hosts all -m shell -a 'netstat -tpln|grep :80' -f 3
10.0.0.12 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2130/nginx: master  
tcp6       0      0 :::80                   :::*                    LISTEN      2130/nginx: master  
10.0.0.13 | CHANGED | rc=0 >>
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      2024/nginx: master  
tcp6       0      0 :::80                   :::*                    LISTEN      2024/nginx: master  
10.0.0.11 | CHANGED | rc=0 >>
tcp        0      0 127.0.0.1:8080          0.0.0.0:*               LISTEN      917/unicorn master  
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      706/nginx: master p 
tcp        0      0 0.0.0.0:8060            0.0.0.0:*               LISTEN      706/nginx: master p 
tcp6       0      0 :::8081                 :::*                    LISTEN      1850/java           
[root@mcw01 ~/mcw]$ ansible -i hosts all -m shell -a 'grep worker_processes /etc/nginx/nginx.conf' -f 3
10.0.0.13 | CHANGED | rc=0 >>
worker_processes 1;
10.0.0.12 | CHANGED | rc=0 >>
worker_processes 1;
10.0.0.11 | CHANGED | rc=0 >>
worker_processes 1;
[root@mcw01 ~/mcw]$ 

只运行一个任务,指定一个任务运行。如果只需要修改Nginx配置,只运行这个任务就行。貌似现在使用这个参数不行,不可识别的参数了。有时间再研究有没有替代的参数或者是没写对参数

[root@mcw01 ~/mcw]$ ansible -i hosts all -f 3 --start-at-task='copy nginx.conf'

 Ansible Playbook常用参数

- hosts: 10.0.0.12:10.0.0.13
  patterns:
  remote_user: root
  sudo: yes
  sudo_user: machangwei
  gather_facts: no
  accelerate: no
  accelerate_port: 5099
  max_fail_percentage: 30
  connection: local
  serial: 15
  vars:
    nginx_port: 80
  vars_files:
    - name: "password vaes"
      prompt: "Enter password"
      default: "secret"
      private: yes
      encrypt: "md5_crypt"
      confirm: yes
      salt: 1234
      salt_size: 8
  pre_tasks:
    - name: pre_tasks
      shell: hostname
  roles:
    - docker
    - { role: docker,version: '1.5.0', when: "ansible_system == 'Linux'", tags: [docker,install] }
    - { role: docker, when: ansible_all_ipv4_addresses == '10.0.0.12' }
  tasks:
    - include: tasks.yaml
    - include: tasks.yaml ansible_distribution='CentOS' ansible_distribution_VERSION='6.6'
    - { include: tasks.yaml, version: '1.1', package: [nginx,httpd] }
    - include: tasks_10.0.0.12.yaml
      when: ansible_all_ipv4_addresses  == '10.0.0.12'
  post_tasks:
    - name: post_tasks
      shell: hostname
  handlers:
    - include: handlers.yml
View Code
- hosts: 10.0.0.12:10.0.0.13          #目标主机支持'Ad-Hoc'模式的所有
  patterns:
  remote_user: root                   #远程SSH认证用户
  sudo: yes                           #设置‘playbook sudo’操作
  sudo_user: machangwei               #设置‘playbook sudo’用户
  gather_facts: no                    #设置‘facts’信息收集
  accelerate: no                      #设置'accelerate'模式
  accelerate_port: 5099               #设置'accelerate'端口
  max_fail_percentage: 30             #设置'palayboook tasks'失败百分比
  connection: local                   #设置远程连接方式
  serial: 15                          #设置'playbook'并发数目
  vars:                               #设置'playbook'变量
    nginx_port: 80                   
  vars_files:                         #设置'playbook'变量引用文件
    - name: "password vaes"           
      prompt: "Enter password"        #使用'prompt'模块加密输入变量
      default: "secret"  
      private: yes
      encrypt: "md5_crypt"
      confirm: yes
      salt: 1234
      salt_size: 8
  pre_tasks:                          #设置'playbook'运行之前的'task'
    - name: pre_tasks
      shell: hostname
  roles:                              #设置引入'role'
    - docker
    - { role: docker,version: '1.5.0', when: "ansible_system == 'Linux'", tags: [docker,install] }
    - { role: docker, when: ansible_all_ipv4_addresses == '10.0.0.12' }
  tasks:                               #设置引入'task'
    - include: tasks.yaml
    - include: tasks.yaml ansible_distribution='CentOS' ansible_distribution_VERSION='6.6'
    - { include: tasks.yaml, version: '1.1', package: [nginx,httpd] }
    - include: tasks_10.0.0.12.yaml
      when: ansible_all_ipv4_addresses  == '10.0.0.12'
  post_tasks:                           #设置'playbook'运行之后的'tasks'
    - name: post_tasks
      shell: hostname
  handlers:                             #设置'palybooks''handlers'
    - include: handlers.yml

 playbook变量与引用

 1、通过Inventory文件定义主机以及主机组变量

对每台主机设置变量名key。使用debug模块查看变量的值,inventory_hostname,当前执行到的主机

[root@mcw01 ~/mcw]$ cat variable.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: display Host Variable from hostfile 
      debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ 

[root@mcw01 ~/mcw]$ cat hosts 
10.0.0.11  key=11 ansible_ssh_pass='123456'
10.0.0.12  key=12 ansible_ssh_pass='123456'
10.0.0.13  key=13 ansible_ssh_pass='123456'
[nginx]
10.0.0.1[1:3]
[nginx:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ ansible-playbook -i hosts variable.yaml 

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The 10.0.0.11 Vaule is 11"
}
ok: [10.0.0.12] => {
    "msg": "The 10.0.0.12 Vaule is 12"
}
ok: [10.0.0.13] => {
    "msg": "The 10.0.0.13 Vaule is 13"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

下面看主机组变量的设置

[root@mcw01 ~/mcw]$ cat variable.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: display Host Variable from hostfile 
      debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ cat hosts 
#10.0.0.11  key=11 ansible_ssh_pass='123456'
#10.0.0.12  key=12 ansible_ssh_pass='123456'
#10.0.0.13  key=13 ansible_ssh_pass='123456'
[nginx]
10.0.0.1[1:3]
[nginx:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
key=nginx
[root@mcw01 ~/mcw]$ ansible-playbook -i hosts variable.yaml 

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The 10.0.0.11 Vaule is nginx"
}
ok: [10.0.0.12] => {
    "msg": "The 10.0.0.12 Vaule is nginx"
}
ok: [10.0.0.13] => {
    "msg": "The 10.0.0.13 Vaule is nginx"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

2、通过/etc/ansible/下的文件定义主机以及主机组变量

要在剧本执行当前目录下创建主机变量目录和主机组变量。主机变量里面按照主机ip为文件名,里面定义变量,冒号隔开;主机组变量里面写个文件然后定义变量就行

下面是主机变量

[root@mcw01 ~/mcw]$ tree
.
├── group_vars
│   └── nginx
├── hosts
├── host_vars
│   ├── 10.0.0.11
│   ├── 10.0.0.12
│   └── 10.0.0.13
└── variable.yaml

2 directories, 6 files
[root@mcw01 ~/mcw]$ cat group_vars/*
key: NGINX
[root@mcw01 ~/mcw]$ cat host_vars/*
key: 10.0.0.11
key: 10.0.0.12
key: 10.0.0.13
[root@mcw01 ~/mcw]$ 
[root@mcw01 ~/mcw]$ 
[root@mcw01 ~/mcw]$ head host_vars/*
==> host_vars/10.0.0.11 <==
key: 10.0.0.11

==> host_vars/10.0.0.12 <==
key: 10.0.0.12

==> host_vars/10.0.0.13 <==
key: 10.0.0.13
[root@mcw01 ~/mcw]$ cat group_vars/nginx 
key: NGINX
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml 

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.12] => {
    "msg": "The 10.0.0.12 Vaule is 10.0.0.12"
}
ok: [10.0.0.13] => {
    "msg": "The 10.0.0.13 Vaule is 10.0.0.13"
}
ok: [10.0.0.11] => {
    "msg": "The 10.0.0.11 Vaule is 10.0.0.11"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

下面是主机组变量,主机组变量失败,以后再研究一下吧

[root@mcw01 ~/mcw]$ ls
group_vars  hosts  host_vars  variable.yaml
[root@mcw01 ~/mcw]$ mv host_vars ..
[root@mcw01 ~/mcw]$ ls
group_vars  hosts  variable.yaml
[root@mcw01 ~/mcw]$ cat group_vars/nginx 
key: NGINX
[root@mcw01 ~/mcw]$ cat variable.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: display Host Variable from hostfile 
      debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml 

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
fatal: [10.0.0.11]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: display Host Variable from hostfile\n      ^ here\n"}
fatal: [10.0.0.13]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: display Host Variable from hostfile\n      ^ here\n"}
fatal: [10.0.0.12]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: display Host Variable from hostfile\n      ^ here\n"}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ ls
group_vars  hosts  variable.yaml

下面是出错的,我放到ansible配置文件同级目录下不行。yum装的,不知道哪里的问题

[root@mcw01 /etc/ansible]$ head host_vars/*
==> host_vars/10.0.0.11 <==
key: 10.0.0.11

==> host_vars/10.0.0.12 <==
key: 10.0.0.12

==> host_vars/10.0.0.13 <==
key: 10.0.0.13
[root@mcw01 /etc/ansible]$ cat group_vars/nginx 
key: NGINX
[root@mcw01 /etc/ansible]$ cd /root/mcw
[root@mcw01 ~/mcw]$ ls
hosts  variable.yaml
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml 

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
fatal: [10.0.0.11]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: display Host Variable from hostfile\n      ^ here\n"}
fatal: [10.0.0.12]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: display Host Variable from hostfile\n      ^ here\n"}
fatal: [10.0.0.13]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: 'key' is undefined\n\nThe error appears to be in '/root/mcw/variable.yaml': line 4, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: display Host Variable from hostfile\n      ^ here\n"}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$

 3、通过ansible-playbook命令行传入

 命令行传入单个变量。这里不知道读取的那里的host文件

[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -e "key=KEY"

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The 10.0.0.11 Vaule is KEY"
}
ok: [10.0.0.12] => {
    "msg": "The 10.0.0.12 Vaule is KEY"
}
ok: [10.0.0.13] => {
    "msg": "The 10.0.0.13 Vaule is KEY"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

命令行传入多个变量之json格式文件

[root@mcw01 ~/mcw]$ vim var.json
[root@mcw01 ~/mcw]$ cat var.json 
{ "key": "JSON" }
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -e "@var.json"

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The 10.0.0.11 Vaule is JSON"
}
ok: [10.0.0.12] => {
    "msg": "The 10.0.0.12 Vaule is JSON"
}
ok: [10.0.0.13] => {
    "msg": "The 10.0.0.13 Vaule is JSON"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

命令行传入多个变量之yaml格式文件

[root@mcw01 ~/mcw]$ vim var.yaml
[root@mcw01 ~/mcw]$ cat var.yaml 
key: YAML
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -e "@var.yaml"

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The 10.0.0.11 Vaule is YAML"
}
ok: [10.0.0.12] => {
    "msg": "The 10.0.0.12 Vaule is YAML"
}
ok: [10.0.0.13] => {
    "msg": "The 10.0.0.13 Vaule is YAML"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

 4、在playbook文件内使用vars

 

[root@mcw01 ~/mcw]$ cat variable.yaml 
- hosts: all
  gather_facts: False
  vars:
    key: Ansible
  tasks:
    - name: display Host Variable from hostfile 
      debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml 

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The 10.0.0.11 Vaule is Ansible"
}
ok: [10.0.0.12] => {
    "msg": "The 10.0.0.12 Vaule is Ansible"
}
ok: [10.0.0.13] => {
    "msg": "The 10.0.0.13 Vaule is Ansible"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

5、在playbook文件内使用vars_files

[root@mcw01 ~/mcw]$ cat var.yaml 
key: mcwYAML
[root@mcw01 ~/mcw]$ cat variable.yaml 
- hosts: all
  gather_facts: False
  vars_files:
    - var.yaml
  tasks:
    - name: display Host Variable from hostfile 
      debug: msg="The {{ inventory_hostname }} Vaule is {{ key }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml 

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

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The 10.0.0.11 Vaule is mcwYAML"
}
ok: [10.0.0.12] => {
    "msg": "The 10.0.0.12 Vaule is mcwYAML"
}
ok: [10.0.0.13] => {
    "msg": "The 10.0.0.13 Vaule is mcwYAML"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

6、使用register内的变量

 直接把注册的变量打印出来

[root@mcw01 ~/mcw]$ vim variable.yaml 
[root@mcw01 ~/mcw]$ cat variable.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: register variable
      shell: hostname
      register: info
    - name: display Host Variable from hostfile 
      debug: msg="The varibale is {{ info }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml 

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

TASK [register variable] ***************************************************************************************************************************
changed: [10.0.0.12]
changed: [10.0.0.13]
changed: [10.0.0.11]

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The varibale is {'stderr_lines': [], u'changed': True, u'end': u'2022-10-18 22:42:21.431996', 'failed': False, u'stdout': u'mcw01', u'cmd': u'hostname', u'rc': 0, u'start': u'2022-10-18 22:42:21.407263', u'stderr': u'', u'delta': u'0:00:00.024733', 'stdout_lines': [u'mcw01'], 'ansible_facts': {u'discovered_interpreter_python': u'/usr/bin/python'}}"
}
ok: [10.0.0.12] => {
    "msg": "The varibale is {'stderr_lines': [], u'changed': True, u'end': u'2022-10-18 22:42:21.161343', 'failed': False, u'stdout': u'mcw02', u'cmd': u'hostname', u'rc': 0, u'start': u'2022-10-18 22:42:21.133783', u'stderr': u'', u'delta': u'0:00:00.027560', 'stdout_lines': [u'mcw02'], 'ansible_facts': {u'discovered_interpreter_python': u'/usr/bin/python'}}"
}
ok: [10.0.0.13] => {
    "msg": "The varibale is {'stderr_lines': [], u'changed': True, u'end': u'2022-10-18 22:42:21.119016', 'failed': False, u'stdout': u'mcw03', u'cmd': u'hostname', u'rc': 0, u'start': u'2022-10-18 22:42:21.107955', u'stderr': u'', u'delta': u'0:00:00.011061', 'stdout_lines': [u'mcw03'], 'ansible_facts': {u'discovered_interpreter_python': u'/usr/bin/python'}}"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

只打印注册的变量的标准输出,如果是shell命令,那么就是直接是shell命令的返回结果。取标准输出,相当于python字典取值的方法

[root@mcw01 ~/mcw]$ vim variable.yaml 
[root@mcw01 ~/mcw]$ cat variable.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: register variable
      shell: hostname
      register: info
    - name: display Host Variable from hostfile 
      debug: msg="The varibale is {{ info['stdout'] }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml 

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

TASK [register variable] ***************************************************************************************************************************
changed: [10.0.0.13]
changed: [10.0.0.12]
changed: [10.0.0.11]

TASK [display Host Variable from hostfile] *********************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The varibale is mcw01"
}
ok: [10.0.0.12] => {
    "msg": "The varibale is mcw02"
}
ok: [10.0.0.13] => {
    "msg": "The varibale is mcw03"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

7、使用vars_prompt传入

命令行需要传参,私有的话,输入的值是看不到的。可以设置默认值

[root@mcw01 ~/mcw]$ cat variable.yaml 
- hosts: all
  gather_facts: False
  vars_prompt:
    - name: "one"
      prompt: "please input one value"
      private: no
    - name: "two"
      prompt: "please input two value"
      default: 'good'
      private: yes
  tasks:
    - name: display one value
      debug: msg="one value is {{ one }}"
    - name: display two value
      debug: msg="two value is {{ two }}"
[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -l 10.0.0.12
please input one value: name
please input two value [good]: 

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

TASK [display one value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
    "msg": "one value is name"
}

TASK [display two value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
    "msg": "two value is xiangjiao"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -l 10.0.0.12
please input one value: name
please input two value [good]: 

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

TASK [display one value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
    "msg": "one value is name"
}

TASK [display two value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
    "msg": "two value is good"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ ansible-playbook variable.yaml -l 10.0.0.12
please input one value: 
please input two value [good]: 

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

TASK [display one value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
    "msg": "one value is "
}

TASK [display two value] ***************************************************************************************************************************
ok: [10.0.0.12] => {
    "msg": "two value is good"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

playbook循环

 1.标准Loops(多个普通变量(可以用字典形式)循环任务)

 with_items

[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: debug loops
      debug: msg="name ------>{{ item }}"
      with_items: 
        - one
        - two
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=one) => {
    "msg": "name ------>one"
}
ok: [10.0.0.12] => (item=two) => {
    "msg": "name ------>two"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

字典形式的变量

[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: debug loops
      debug: msg="name ------>{{ item.key }}   vaule---->{{ item.vaule }}"
      with_items: 
        - {key: "one", vaule: "VAULE1"}
        - {key: "two", vaule: "VAULE2"}

[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item={u'vaule': u'VAULE1', u'key': u'one'}) => {
    "msg": "name ------>one   vaule---->VAULE1"
}
ok: [10.0.0.12] => (item={u'vaule': u'VAULE2', u'key': u'two'}) => {
    "msg": "name ------>two   vaule---->VAULE2"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

对所有主机都循环这两个任务

[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml 

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.11] => (item={u'vaule': u'VAULE1', u'key': u'one'}) => {
    "msg": "name ------>one   vaule---->VAULE1"
}
ok: [10.0.0.11] => (item={u'vaule': u'VAULE2', u'key': u'two'}) => {
    "msg": "name ------>two   vaule---->VAULE2"
}
ok: [10.0.0.12] => (item={u'vaule': u'VAULE1', u'key': u'one'}) => {
    "msg": "name ------>one   vaule---->VAULE1"
}
ok: [10.0.0.12] => (item={u'vaule': u'VAULE2', u'key': u'two'}) => {
    "msg": "name ------>two   vaule---->VAULE2"
}
ok: [10.0.0.13] => (item={u'vaule': u'VAULE1', u'key': u'one'}) => {
    "msg": "name ------>one   vaule---->VAULE1"
}
ok: [10.0.0.13] => (item={u'vaule': u'VAULE2', u'key': u'two'}) => {
    "msg": "name ------>two   vaule---->VAULE2"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

2、嵌套Loops(一对多嵌套组合循环任务)

 

[root@mcw01 ~/mcw]$ vim loops.yaml 
[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: debug loops
      debug: msg="name ------>{{ item[0] }}   vaule---->{{ item[1] }}"
      with_nested:
        - ['A']
        - ['a','b','c']
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=[u'A', u'a']) => {
    "msg": "name ------>A   vaule---->a"
}
ok: [10.0.0.12] => (item=[u'A', u'b']) => {
    "msg": "name ------>A   vaule---->b"
}
ok: [10.0.0.12] => (item=[u'A', u'c']) => {
    "msg": "name ------>A   vaule---->c"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

3、散列loops(含嵌套字段的循环任务)

 注意引用字典变量的是需要用到jinja2引用变量的方法。实现了如下数据结构的循环

{

"xiaoma": {"name":“xiaoma”,"shell":"bash"},

"daguo": {"name":"daguo","shell":"zsh"}

}

[root@mcw01 ~/mcw]$ vim loops.yaml 
[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  vars:
    user:
      xiaoma:
        name: xiaoma
        shell: bash
      daguo:
        name: daguo
        shell: zsh
  tasks:
    - name: debug loops
      debug: msg="name ------->{{ item.key }}  vaule --->{{ item.value.name }}" shell ---->{{ item.value.shell }}
      with_dict: "{{ user }}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item={u'key': u'xiaoma', u'value': {u'shell': u'bash', u'name': u'xiaoma'}}) => {
    "msg": "name ------->xiaoma  vaule --->xiaoma"
}
ok: [10.0.0.12] => (item={u'key': u'daguo', u'value': {u'shell': u'zsh', u'name': u'daguo'}}) => {
    "msg": "name ------->daguo  vaule --->daguo"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

4、文件匹配loops(满足条件的文件做同样的任务)

 这个有问题,它找的是主机1上的文件,而我命令行让它查的是主机2上的文件,主机二上实际是没有这个yaml文件的

[root@mcw01 ~/mcw]$ ls
loops.yaml
[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: debug loops
      debug: msg="files ------->{{ item }}"
      with_fileglob: 
        - /root/*.yaml
[root@mcw01 ~/mcw]$ ls /root/
anaconda-ks.cfg                       hosts                          mcw                                   nginx-role.tar.gz
gitlab2-hook.hpi                      host_vars                      mcw2                                  nginx.yaml
gitlab-ce-10.0.0-ce.0.el7.x86_64.rpm  inventory                      mcw3                                  roles
gitlab-hook                           jenkins-2.73.1-1.1.noarch.rpm  mcw.py                                site.yaml
gitlab-hook.hpi                       jpress-web-newest              multibranch-scan-webhook-trigger.hpi  sonarqube-8.9.9.56886.zip
group_vars                            jpress-web-newest.tar.gz       nginx.conf.j2                         tomcat
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=/root/nginx.yaml) => {
    "msg": "files ------->/root/nginx.yaml"
}
ok: [10.0.0.12] => (item=/root/site.yaml) => {
    "msg": "files ------->/root/site.yaml"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

如下,主机2实际是没有的

[root@mcw02 ~]$ ls
10.0.0.11        apache-tomcat-8.0.27         demo.sh            jpress-web-newest.tar.gz  logs  mcw.py     sonar-scanner-cli-4.7.0.2747-linux.zip
anaconda-ks.cfg  apache-tomcat-8.0.27.tar.gz  jpress-web-newest  jpress-web-newest.war     mcw   sonarqube  tomcat
[root@mcw02 ~]$ 

5、随机选择loops(任务变量随机)

 

[root@mcw01 ~/mcw]$ vim loops.yaml 
[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: debug loops
      debug: msg="name   ------->{{ item }}"
      with_random_choice:
        - "ansible1"
        - "ansible2"
        - "ansible3"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=ansible1) => {
    "msg": "name   ------->ansible1"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=ansible2) => {
    "msg": "name   ------->ansible2"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=ansible3) => {
    "msg": "name   ------->ansible3"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
ok: [10.0.0.12] => (item=ansible3) => {
    "msg": "name   ------->ansible3"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

6、条件判断loops(可实现任务重试当某个任务失败时)

[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  tasks:
    - name: debug loops
      shell: cat /root/Ansible
      register: host
      until: host.stdout.startswith("Master")
      retries: 5
      delay: 5
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
FAILED - RETRYING: debug loops (5 retries left).  #多次重试任务
FAILED - RETRYING: debug loops (4 retries left).
FAILED - RETRYING: debug loops (3 retries left).
FAILED - RETRYING: debug loops (2 retries left).
FAILED - RETRYING: debug loops (1 retries left).
fatal: [10.0.0.12]: FAILED! => {"attempts": 5, "changed": true, "cmd": "cat /root/Ansible", "delta": "0:00:00.011660", "end": "2022-10-18 23:55:23.791639", "msg": "non-zero return code", "rc": 1, "start": "2022-10-18 23:55:23.779979", "stderr": "cat: /root/Ansible: No such file or directory", "stderr_lines": ["cat: /root/Ansible: No such file or directory"], "stdout": "", "stdout_lines": []}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 




当我们在执行重试时,立马创建文件并输入数据,让它成功读取。于是ansible就不重试了,成功读取到信息
[root@mcw02 ~]$ echo "Master" >>/root/Ansible
[root@mcw02 ~]$ 

[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [debug loops] *********************************************************************************************************************************
FAILED - RETRYING: debug loops (5 retries left).
FAILED - RETRYING: debug loops (4 retries left).
changed: [10.0.0.12]

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

7、文件优先匹配Loops(遍历文件使用匹配上的第一个作为变量)

这个有问题,回头再看看

[root@mcw01 ~/mcw]$ vim loops.yaml 
[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: True
  tasks:
    - name: debug loops
      debug: msg="file --------> {{ item }}"
      with_first_found:
        - "{{ ansible_distribution }}.yaml"
        - "default.yaml"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12]

TASK [debug loops] *********************************************************************************************************************************
fatal: [10.0.0.12]: FAILED! => {"msg": "No file was found when using first_found. Use errors='ignore' to allow this task to be skipped if no files are found"}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$

8、register Loops

register: ret    任务单个执行注册变量,在传给其它任务

任务多个循环 执行结果注册变量,再传给其它任务,多个结果for循环调用

[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: True
  tasks:
    - name: debug loops
      shell: "{{ item }}"
      with_items:
        - hostname
        - uname
      register: ret
    - name: display loops
      debug: msg="{% for i in ret.results %} {{ i.stdout }} {% endfor %}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.12

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

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.12]

TASK [debug loops] *********************************************************************************************************************************
changed: [10.0.0.12] => (item=hostname)
changed: [10.0.0.12] => (item=uname)

TASK [display loops] *******************************************************************************************************************************
ok: [10.0.0.12] => {
    "msg": " mcw02  Linux "
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.12                  : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

playbook lookups

1、lookup file 

[root@mcw01 ~/mcw]$ ls
loops.yaml  mcw.conf
[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  vars:
    contents: "{{ lookup('file','mcw.conf') }}"
  tasks:
    - name: debug lookups
      debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
[root@mcw01 ~/mcw]$ cat mcw.conf 
db: mysql
hostname: mcw
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11

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

TASK [debug lookups] *******************************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The contents is  db: mysql  hostname: mcw "
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

2、lookups  password

加密字符串。调用密码,输出时会使用加密后的字符串

[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  vars:
    contents: "{{ lookup('password','ansible_book') }}"
  tasks:
    - name: debug lookups
      debug: msg="The contents is {{ contents }}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11

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

TASK [debug lookups] *******************************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The contents is 7EKiRimgFJ88AyYAxe5,"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$

上面那个貌似还在本地生成了一个密码文件

[root@mcw01 ~/mcw]$ ls
ansible_book loops.yaml mcw.conf
[root@mcw01 ~/mcw]$ cat ansible_book
7EKiRimgFJ88AyYAxe5,
[root@mcw01 ~/mcw]$

3、lookups pipe  将shell命令的打印信息赋值给变量

使用日期

[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  vars:
    contents: "{{ lookup('pipe','date +%Y-%m-%d') }}"
  tasks:
    - name: debug lookups
      debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11

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

TASK [debug lookups] *******************************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The contents is  2022-10-19 "
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

 

4、lookups redis_kv

5、lookups template jinja模板渲染完后再读取

[root@mcw01 ~/mcw]$ cat lookups.j2
worker_processes {{ ansible_processor_cores }};
IPaddress {{ ansible_ens33.ipv4.address }}
[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: True
  vars:
    contents: "{{ lookup('template','./lookups.j2') }}"
  tasks:
    - name: debug lookups
      debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11

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

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.11]

TASK [debug lookups] *******************************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The contents is  worker_processes 1;  IPaddress 10.0.0.11   "
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

如果需要用到ansible内置变量,需要收集facts信息,否则使用的话就是未定义的

[root@mcw01 ~/mcw]$ cat lookups.j2 
worker_processes {{ ansible_processor_cores }};
IPaddress {{ ansible_ens33.ipv4.address }}
[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  gather_facts: False
  vars:
    contents: "{{ lookup('template','./lookups.j2') }}"
  tasks:
    - name: debug lookups
      debug: msg="The contents is {% for i in contents.split("\n") %} {{ i }} {% endfor %}"
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11

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

TASK [debug lookups] *******************************************************************************************************************************
fatal: [10.0.0.11]: FAILED! => {"msg": "The task includes an option with an undefined variable. The error was: {{ lookup('template','./lookups.j2') }}: 'ansible_processor_cores' is undefined\n\nThe error appears to be in '/root/mcw/loops.yaml': line 6, column 7, but may\nbe elsewhere in the file depending on the exact syntax problem.\n\nThe offending line appears to be:\n\n  tasks:\n    - name: debug lookups\n      ^ here\n"}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=0    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

playbook conditionals 逻辑判断when

条件判断在每个name的最下面。满足条件执行,不满足不执行

[root@mcw01 ~/mcw]$ cat loops.yaml 
- hosts: all
  tasks:
    - name: Host 10.0.0.11 run this task
      debug: msg="{{ ansible_default_ipv4.address }}"
      when: ansible_default_ipv4.address == "10.0.0.11"
    - name: memtotal < 500M and processor_cores == 2 run this task
      debug: msg="{{ ansible_fqdn }}"
      when: ansible_memtotal_mb < 500 and ansible_processor_cores == 2
    - name: all host run this task
      shell: hostname
      register: info
    - name: Hostname is python Machie run this task
      debug: msg="{{ ansible_fqdn }}"
      when: info['stdout'] == "python"
    - name: Hostname is startswith M run this task
      debug: msg="{{ ansible_fqdn }}"
      when: info['stdout'].startswith('M')
[root@mcw01 ~/mcw]$ ansible-playbook loops.yaml -l 10.0.0.11

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

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.11]

TASK [Host 10.0.0.11 run this task] ****************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "10.0.0.11"
}

TASK [memtotal < 500M and processor_cores == 2 run this task] **************************************************************************************
skipping: [10.0.0.11]

TASK [all host run this task] **********************************************************************************************************************
changed: [10.0.0.11]

TASK [Hostname is python Machie run this task] *****************************************************************************************************
skipping: [10.0.0.11]

TASK [Hostname is startswith M run this task] ******************************************************************************************************
skipping: [10.0.0.11]

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=3    changed=1    unreachable=0    failed=0    skipped=3    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

Jinja2 filter 常用filter

 感觉太严格了,有点拼写错误,又没有准确的提示,太难找拼写错误了有时候是

[root@mcw01 ~/mcw]$ cat lookups.yaml 
- hosts: all
  gather_facts: False
  vars:
    list: [1,2,3,4,5]
    one: "1"
    str: "string"
  tasks:
    - name: run commands
      shell: df -h
      register: info
    - name: debug pprint filter
      debug: msg="{{ info.stdout | pprint }}"
    - name: debug int capitalize filter
      debug: msg="The int value {{ one | int }}" The lower value is {{ str | capitalize }}
    - name: debug default filter
      debug: msg="The Variable value is {{ ansible | default('ansible is not define') }}"
    - name: debug list max and min filter
      debug: msg="The list max value is {{list | max}} The list min value is {{ list | min }}"
    - name: debug ramdom filter
      debug: msg="The list ramdom value is {{ list | random }} and generate a random value is {{ 1000|random(1,10) }}"
    - name: debug join filter
      debug: msg="The join filter value is {{ list | join("+") }}"
    - name: debug replace and regex_replace filter
      debug: msg="The replace value is {{ str | replace('t','T') }} The regex_replace vaule is {{ str | regex_replace('.*tr(.*)$','\\1') }}"
[root@mcw01 ~/mcw]$ ansible-playbook lookups.yaml -l 10.0.0.11

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

TASK [run commands] ********************************************************************************************************************************
changed: [10.0.0.11]

TASK [debug pprint filter] *************************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "u'Filesystem               Size  Used Avail Use% Mounted on\\n/dev/mapper/centos-root   19G  6.4G   13G  35% /\\ndevtmpfs                 1.4G     0  1.4G   0% /dev\\ntmpfs                    1.4G  128K  1.4G   1% /dev/shm\\ntmpfs                    1.4G  8.7M  1.4G   1% /run\\ntmpfs                    1.4G     0  1.4G   0% /sys/fs/cgroup\\n/dev/sda1                797M  143M  655M  18% /boot\\ntmpfs                    284M     0  284M   0% /run/user/0'"
}

TASK [debug int capitalize filter] *****************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The int value 1"
}

TASK [debug default filter] ************************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The Variable value is ansible is not define"
}

TASK [debug list max and min filter] ***************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The list max value is 5 The list min value is 1"
}

TASK [debug ramdom filter] *************************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The list ramdom value is 5 and generate a random value is 291"
}

TASK [debug join filter] ***************************************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The join filter value is 1+2+3+4+5"
}

TASK [debug replace and regex_replace filter] ******************************************************************************************************
ok: [10.0.0.11] => {
    "msg": "The replace value is sTring The regex_replace vaule is ing"
}

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=8    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$ 

 内置变量的使用案例

 

 

[root@mcw01 ~/mcw]$ ls
docker  hosts  jinja.j2  template.yaml
[root@mcw01 ~/mcw]$ cat template.yaml 
- hosts: all
  tasks:
    - name: test template
      template: src=jinja.j2 dest=/root/cpis
[root@mcw01 ~/mcw]$ cat jinja.j2 
==========
groups info
{{ groups }}
===================

================docker groups info ============
{% for host in groups['docker'] %}
={{ hostvars[host]['inventory_hostname'] }} eth0 IP is {{ hostvars[host]['ansible_default_ipv4']['address'] }}
+{{ hostvars[host]['inventory_hostname'] }} groups is {{ group_names }}
_{{ hostvars[host]['inventory_hostname'] }} short is {{ inventory_hostname_short }}
*{{ play_hosts }}
@{{ inventory_dir }}
{% endfor %}
[root@mcw01 ~/mcw]$ cat hosts 
10.0.0.11   ansible_ssh_pass='123456'
10.0.0.12   ansible_ssh_pass='123456'
10.0.0.13   ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ cat docker 
[docker]
10.0.0.1[1:3]
[docker:vars]
ansible_python_interpreter=/usr/bin/python
ansible_ssh_pass='123456'
[root@mcw01 ~/mcw]$ ansible-playbook template.yaml 

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

TASK [Gathering Facts] *****************************************************************************************************************************
ok: [10.0.0.13]
ok: [10.0.0.12]
ok: [10.0.0.11]

TASK [test template] *******************************************************************************************************************************
ok: [10.0.0.13]
ok: [10.0.0.12]
ok: [10.0.0.11]

PLAY RECAP *****************************************************************************************************************************************
10.0.0.11                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.12                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.13                  : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@mcw01 ~/mcw]$
[root@mcw01 ~/mcw]$ ansible all -m shell -a "cat /root/cpis"
10.0.0.12 | CHANGED | rc=0 >>
==========
groups info
{'ungrouped': [], 'all': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'ansible': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'docker': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']}
===================

================docker groups info ============
=10.0.0.11 eth0 IP is 10.0.0.11
+10.0.0.11 groups is [u'ansible', u'docker']
_10.0.0.11 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.12 eth0 IP is 10.0.0.12
+10.0.0.12 groups is [u'ansible', u'docker']
_10.0.0.12 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.13 eth0 IP is 10.0.0.13
+10.0.0.13 groups is [u'ansible', u'docker']
_10.0.0.13 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
10.0.0.13 | CHANGED | rc=0 >>
==========
groups info
{'ungrouped': [], 'all': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'ansible': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'docker': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']}
===================

================docker groups info ============
=10.0.0.11 eth0 IP is 10.0.0.11
+10.0.0.11 groups is [u'ansible', u'docker']
_10.0.0.11 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.12 eth0 IP is 10.0.0.12
+10.0.0.12 groups is [u'ansible', u'docker']
_10.0.0.12 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.13 eth0 IP is 10.0.0.13
+10.0.0.13 groups is [u'ansible', u'docker']
_10.0.0.13 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
10.0.0.11 | CHANGED | rc=0 >>
==========
groups info
{'ungrouped': [], 'all': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'ansible': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13'], u'docker': [u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']}
===================

================docker groups info ============
=10.0.0.11 eth0 IP is 10.0.0.11
+10.0.0.11 groups is [u'ansible', u'docker']
_10.0.0.11 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.12 eth0 IP is 10.0.0.12
+10.0.0.12 groups is [u'ansible', u'docker']
_10.0.0.12 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
=10.0.0.13 eth0 IP is 10.0.0.13
+10.0.0.13 groups is [u'ansible', u'docker']
_10.0.0.13 short is 10
*[u'10.0.0.11', u'10.0.0.12', u'10.0.0.13']
@/root/inventory
[root@mcw01 ~/mcw]$ 

 用ansible-vault保护敏感数据

工具子命令

[root@mcw01 ~/mcw]$ ansible-vault -h
usage: ansible-vault [-h] [--version] [-v]
                     {create,decrypt,edit,view,encrypt,encrypt_string,rekey}
                     ...

encryption/decryption utility for Ansible data files

positional arguments:
  {create,decrypt,edit,view,encrypt,encrypt_string,rekey}
    create              Create new vault encrypted file
    decrypt             Decrypt vault encrypted file
    edit                Edit vault encrypted file
    view                View vault encrypted file
    encrypt             Encrypt YAML file
    encrypt_string      Encrypt a string
    rekey               Re-key a vault encrypted file

optional arguments:
  --version             show program's version number, config file location,
                        configured module search path, module location,
                        executable location and exit
  -h, --help            show this help message and exit
  -v, --verbose         verbose mode (-vvv for more, -vvvv to enable
                        connection debugging)

See 'ansible-vault <command> --help' for more information on a specific
command.
[root@mcw01 ~/mcw]$ 

命令的基本使用

先添加vim作为编辑器到环境变量

[root@mcw01 ~]$ vim .bash_profile 
[root@mcw01 ~]$ grep vim .bash_profile
export EDITOR=vim
[root@mcw01 ~]$ source .bash_profile 
[root@mcw01 ~]$ 

我这里都是123456

下面是我们编辑过程中,输入的内容

查看编辑的文件内容,是加密的

我们修改的话可以输入文件的密码,然后进入编辑模式,此时文件内容不是加密的

 

 编辑完之后保存退出

 

 我们rekey变更加密数据的密钥,然后可以用新密码进入文件,可以编辑文件内容了。

 

 1、保护ansible role中的敏感数据(未写,有时间再补充)

2、使用加密做用户认证

3、保护Nginx中的ssl密钥

 

 

 

 

 

 

 

 

 

 

 

参考:https://blog.csdn.net/qq_39122146/article/details/109173969

posted @ 2021-12-16 13:04  马昌伟  阅读(826)  评论(0编辑  收藏  举报
博主链接地址:https://www.cnblogs.com/machangwei-8/