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
- 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