欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 养生 > ansible 知识点【回顾梳理】

ansible 知识点【回顾梳理】

2025/2/8 11:13:28 来源:https://blog.csdn.net/u010230019/article/details/145031839  浏览:    关键词:ansible 知识点【回顾梳理】

ansible 知识点

    • 1. 剧本
    • 2. facts变量
    • 3. register变量
    • 4. include功能
    • 5. handlers
    • 6. when 条件
    • 7. with_items 循环
    • 8. Jinja2模板
    • 9. group_vars
    • 10. roles :star::star::star:

在这里插入图片描述

看起来字数很多,实际有很多是脚本执行结果,内容不多哦

1. 剧本

剧本很重要的就是,定义演员的信息(其实就是定义主机的信息),演员的具体任务(以及主机要执行的模块,动作)
ansible剧本也是由两个最基本的部分组成

  • hosts定义的被管理的主机列表信息(演员有哪些)

  • tasks关键词定义的是被管理主机需要执行的动作(演员要做什么事)

剧本格式:

# 1
---
- name: first taskhosts: db
# gather_facts: novars:var1: avar2: btasks:- name: task1command:..- name: task2command:..
- name: second taskhosts: web- name: task1 command:.....
# 2    
--- 
- hosts: allvars:var1: avar2: btasks:- name: task1 ...

[官网内置模块说明](Ansible.Builtin — Ansible Community Documentation)

安装nfs

[root@localhost ansible]# cat 01.nfs_install.yml
---
- hosts: allgather_facts: yestasks:- name: backup reposhell: "if [ -f /etc/yum.repos.d/CentOS-Base.repo ];then mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak; fi"- name: update yum repoyum_repository:name: aliyun_repodescription: aliyun linux repositorybaseurl: http://mirrors.aliyun.com/repo/Centos-{{ ansible_distribution_major_version }}.repoenabled: yesgpgcheck: no- name: install nfs rpcbindyum:name: "{{ item }}"state: presentwith_items:- rpcbind- nfs-utils- name: started serversystemd:name: "{{ item }}"state: startedenabled: yeswith_items:- rpcbind- nfs-utils
[root@localhost ansible]# ansible-playbook -i hosts 01.nfs_install.ymlPLAY [all] *************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.85.212]TASK [backup repo] *****************************************************************************************************************************************************
changed: [182.92.85.212]TASK [update yum repo] *************************************************************************************************************************************************
changed: [182.92.85.212]TASK [install nfs rpcbind] *********************************************************************************************************************************************
[DEPRECATION WARNING]: Invoking "yum" only once while using a loop via squash_actions is deprecated. Instead of using a loop to supply multiple items and specifying
`name: "{{ item }}"`, please use `name: ['rpcbind', 'nfs-utils']` and remove the loop. This feature will be removed in version 2.11. Deprecation warnings can be
disabled by setting deprecation_warnings=False in ansible.cfg.
ok: [182.92.85.212] => (item=[u'rpcbind', u'nfs-utils'])TASK [started server] **************************************************************************************************************************************************
ok: [182.92.85.212] => (item=rpcbind)
changed: [182.92.85.212] => (item=nfs-utils)PLAY RECAP *************************************************************************************************************************************************************
182.92.85.212              : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

笔者发现新版本的ansible,yum已经被dnf取代了,不过目前yum仍可用

2.9及以前版本还能搜到yum的说明,以后的版本就只能搜dnf喽

2. facts变量

在Ansible中,事实变量(facts)是由Ansible自动从受管主机收集的系统信息。这些事实变量包含了与主机相关的各类信息,并且可以在playbook中用于条件判断、循环等场景。

每次运行playbook中的每个play时,Ansible会自动运行一个名为setup的模块来收集受管主机的事实信息。这些信息包含如下内容:

  • 主机名称
  • 内核版本
  • 网络接口
  • IP地址
  • 操作系统版本
  • 各种环境变量
  • CPU数量
  • 提供的或可用的内存
  • 可用磁盘空间

查看详细信息

[root@localhost ansible]# ansible-playbook -i hosts 02.facts.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.85.212]TASK [print host msg] **************************************************************************************************************************************************
ok: [182.92.85.212] => {"msg": {"all_ipv4_addresses": ["172.19.91.7"],"all_ipv6_addresses": ["fe80::216:3eff:fe34:19c2"],"ansible_local": {},"apparmor": {"status": "disabled"},"architecture": "x86_64","bios_date": "04/01/2014","bios_version": "449e491","cmdline": {"BOOT_IMAGE": "/boot/vmlinuz-3.10.0-1160.119.1.el7.x86_64","console": "ttyS0,115200n8","crashkernel": "auto","net.ifnames": "0","noibrs": true,"nvme_core.admin_timeout": "4294967295","nvme_core.io_timeout": "4294967295","quiet": true,"rhgb": true,"ro": true,"root": "UUID=c8b5b2da-5565-4dc1-b002-2a8b07573e22","spectre_v2": "retpoline"},"date_time": {"date": "2025-01-08","day": "08","epoch": "1736304161","hour": "10","iso8601": "2025-01-08T02:42:41Z","iso8601_basic": "20250108T104241255861","iso8601_basic_short": "20250108T104241","iso8601_micro": "2025-01-08T02:42:41.255861Z","minute": "42","month": "01","second": "41","time": "10:42:41","tz": "CST","tz_offset": "+0800","weekday": "Wednesday","weekday_number": "3","weeknumber": "01","year": "2025"},"default_ipv4": {"address": "172.19.91.7","alias": "eth0","broadcast": "172.19.95.255","gateway": "172.19.95.253","interface": "eth0","macaddress": "00:16:3e:34:19:c2","mtu": 1500,"netmask": "255.255.240.0","network": "172.19.80.0","type": "ether"},"default_ipv6": {},"device_links": {"ids": {"vda": ["virtio-2zea4qo6616yh2wqh6ia"],"vda1": ["virtio-2zea4qo6616yh2wqh6ia-part1"]},"labels": {},"masters": {},"uuids": {"vda1": ["c8b5b2da-5565-4dc1-b002-2a8b07573e22"]}},"devices": {"vda": {"holders": [],"host": "SCSI storage controller: Red Hat, Inc. Virtio block device","links": {"ids": ["virtio-2zea4qo6616yh2wqh6ia"],"labels": [],"masters": [],"uuids": []},"model": null,"partitions": {"vda1": {"holders": [],"links": {"ids": ["virtio-2zea4qo6616yh2wqh6ia-part1"],"labels": [],"masters": [],"uuids": ["c8b5b2da-5565-4dc1-b002-2a8b07573e22"]},"sectors": "83883999","sectorsize": 512,"size": "40.00 GB","start": "2048","uuid": "c8b5b2da-5565-4dc1-b002-2a8b07573e22"}},"removable": "0","rotational": "1","sas_address": null,"sas_device_handle": null,"scheduler_mode": "mq-deadline","sectors": "83886080","sectorsize": "512","size": "40.00 GB","support_discard": "0","vendor": "0x1af4","virtual": 1}},"discovered_interpreter_python": "/usr/bin/python","distribution": "CentOS","distribution_file_parsed": true,"distribution_file_path": "/etc/redhat-release","distribution_file_variety": "RedHat","distribution_major_version": "7","distribution_release": "Core","distribution_version": "7.9","dns": {"nameservers": ["100.100.2.136","100.100.2.138"],"options": {"attempts": "3","rotate": true,"single-request-reopen": true,"timeout": "2"}},"domain": "","effective_group_id": 0,"effective_user_id": 0,"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": "175.168.185.6 55563 22","SSH_CONNECTION": "175.168.185.6 55563 172.19.91.7 22","SSH_TTY": "/dev/pts/2","TERM": "xterm","USER": "root","XDG_RUNTIME_DIR": "/run/user/0","XDG_SESSION_ID": "7482","_": "/usr/bin/python"},"eth0": {"active": true,"device": "eth0","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": "off [fixed]","netns_local": "off [fixed]","ntuple_filters": "off [fixed]","receive_hashing": "off [fixed]","rx_all": "off [fixed]","rx_checksumming": "on [fixed]","rx_fcs": "off [fixed]","rx_gro_hw": "off [fixed]","rx_udp_tunnel_port_offload": "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","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_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": "on","tx_tcp_ecn_segmentation": "on","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": "off [fixed]","tx_vlan_stag_hw_insert": "off [fixed]","udp_fragmentation_offload": "on","vlan_challenged": "off [fixed]"},"hw_timestamp_filters": [],"ipv4": {"address": "172.19.91.7","broadcast": "172.19.95.255","netmask": "255.255.240.0","network": "172.19.80.0"},"ipv6": [{"address": "fe80::216:3eff:fe34:19c2","prefix": "64","scope": "link"}],"macaddress": "00:16:3e:34:19:c2","module": "virtio_net","mtu": 1500,"pciid": "virtio2","promisc": false,"timestamping": ["rx_software","software"],"type": "ether"},"fibre_channel_wwn": [],"fips": false,"form_factor": "Other","fqdn": "ali01","gather_subset": ["all"],"hostname": "ali01","hostnqn": "","interfaces": ["lo","eth0"],"is_chroot": false,"iscsi_iqn": "","kernel": "3.10.0-1160.119.1.el7.x86_64","kernel_version": "#1 SMP Tue Jun 4 14:43:51 UTC 2024","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_gro_hw": "off [fixed]","rx_udp_tunnel_port_offload": "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_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"},"lsb": {"codename": "Core","description": "CentOS Linux release 7.9.2009 (Core)","id": "CentOS","major_release": "7","release": "7.9.2009"},"machine": "x86_64","machine_id": "88b247814be64fbf8fa045566b89ce3e","memfree_mb": 259,"memory_mb": {"nocache": {"free": 1512,"used": 244},"real": {"free": 259,"total": 1756,"used": 1497},"swap": {"cached": 0,"free": 0,"total": 0,"used": 0}},"memtotal_mb": 1756,"module_setup": true,"mounts": [{"block_available": 8998392,"block_size": 4096,"block_total": 10288203,"block_used": 1289811,"device": "/dev/vda1","fstype": "ext4","inode_available": 2556564,"inode_total": 2621440,"inode_used": 64876,"mount": "/","options": "rw,relatime,data=ordered","size_available": 36857413632,"size_total": 42140479488,"uuid": "c8b5b2da-5565-4dc1-b002-2a8b07573e22"}],"nodename": "ali01","os_family": "RedHat","pkg_mgr": "yum","proc_cmdline": {"BOOT_IMAGE": "/boot/vmlinuz-3.10.0-1160.119.1.el7.x86_64","console": ["tty0","ttyS0,115200n8"],"crashkernel": "auto","net.ifnames": "0","noibrs": true,"nvme_core.admin_timeout": "4294967295","nvme_core.io_timeout": "4294967295","quiet": true,"rhgb": true,"ro": true,"root": "UUID=c8b5b2da-5565-4dc1-b002-2a8b07573e22","spectre_v2": "retpoline"},"processor": ["0","GenuineIntel","Intel(R) Xeon(R) Platinum","1","GenuineIntel","Intel(R) Xeon(R) Platinum"],"processor_cores": 1,"processor_count": 1,"processor_threads_per_core": 2,"processor_vcpus": 2,"product_name": "Alibaba Cloud ECS","product_serial": "33a7cfe4-534e-418a-adbe-783fb05884e8","product_uuid": "33A7CFE4-534E-418A-ADBE-783FB05884E8","product_version": "pc-i440fx-2.1","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]},"python_version": "2.7.5","real_group_id": 0,"real_user_id": 0,"selinux": {"status": "disabled"},"selinux_python_present": true,"service_mgr": "systemd","ssh_host_key_dsa_public": "AAAAB3NzaC1kc3MAAACBAPoheUF1Sp83cZqdmAbfPqAEkBCLnvAB0b06r8wJE7y9nck2s4BLhChHPK+DYPlpmJOFJzhfA3TDiQqGBw6f3tmtWwtaej65Cnb1jg03EldfzXUZjOWaSBAAv20uWjjHLLB9epezwgpYfXI6lH8J5kcHBQAJr6ReQjVnid4H4T4pAAAAFQDBuMSFQWXhqlqLhdRzdd1WbMbrUQAAAIEA0BdoMMTrcc9QdqI0N2RevOrsiSUCaAcs2BwXGIvN1bCA/D/Juvy7L8YKN7TqD2wHxOEe6bd7YtQlg4mm9XxKnaGpO9/DRRDfjv/ZePrxU2bONHlYTG3yIiuhrlbTkp8Apl6fJpEPeGP/tqOv0T9Yx8BPhRgEuCkmmQ+S7An2hFAAAACBAN0QTG1gltjcqWjVW8OK+u1ih9YkLiciD873rG7LVfpN3X7DgiuxFUmcFBqBbKOObMU1vsqbkfHmGDseWeTvOZlQfjmffU56bRWEHMt1JAvwwkwGFKwGjYzBCy8vsqlzGik559yIQxPF6xijqXDrtH4zSgtvgZE+QRhmZl3tPp7E","ssh_host_key_ecdsa_public": "AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBE9BHIH3QSoFRbL7br23p3N7rz5FRq19rKEqqucK21bD8bQn4a7O5slXleeGjZQtHMUaTNF4MqyGzFCrcdxw9mQ=","ssh_host_key_ed25519_public": "AAAAC3NzaC1lZDI1NTE5AAAAIHnPv/S9xAofLvaR7cs1hpSXVg8rP36LED54L5m96kH5","ssh_host_key_rsa_public": "AAAAB3NzaC1yc2EAAAADAQABAAABAQC+pOYVVQ5JR7F4i2DM7Lu3CkQDuyJ4OMDA40V8vAFdMKQonrCb/TTUdkBXjwhSet8ucpPIj3UcRrYn0znPFhyCVfPZTCRDREy8pbF+mV9Tby4fTjvk2RDXHf2OihmUIeCKjZmYsNe2zV1fBWp/7Sb+9qP2U5znM3DfmGbrkUfordQEPiyfunQPIUkLGJuJhuWJl6KygE1ZOWPYaZtlR4jK4rvCKmayVUsWXHePVSGXuC5+Fn9D8vXgALb5GENNok45xjkEDyHfmyIm6MCf13r4+hnhPNEJJVfhbv//63R6R/l4al+G7AduZBP91+f1b41p2pVQ5cfqdX1Fow+ZO5Cp","swapfree_mb": 0,"swaptotal_mb": 0,"system": "Linux","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"],"system_capabilities_enforced": "True","system_vendor": "Alibaba Cloud","uptime_seconds": 3786285,"user_dir": "/root","user_gecos": "root","user_gid": 0,"user_id": "root","user_shell": "/bin/bash","user_uid": 0,"userspace_architecture": "x86_64","userspace_bits": "64","virtualization_role": "guest","virtualization_type": "kvm"}
}PLAY RECAP *************************************************************************************************************************************************************
182.92.85.212              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

实际上,我们大概率只会选取经常使用的变量,如下表

事实方式1方式2方式3
短主机名ansible_facts.hostnameansible_facts[‘hostname’]ansible_hostname
完全限定域名ansible_facts.fqdnansible_facts[‘fqdn’]ansible_fqdn
IPv4地址ansible_facts.default_ipv4.addressansible_facts[‘default_ipv4’][‘address’]ansible_default_ipv4
所有网络接口的名称列表ansible_facts.interfacesansible_facts['interfaces ']ansible_interfaces
DNS服务器列表ansible_facts.dnsansible_facts[‘dns’]ansible_dns
当前运行的内核版本ansible_facts.kernelansible_facts[‘kernel’]ansible_kernel

三种格式都可以使用,看自己喜好

[root@localhost ansible]# cat 02.facts.yml
---
- hosts: dbtasks:- name: print ipv4 1debug:msg: "{{ ansible_facts.default_ipv4.address }}"- name: print ipv4 2debug:msg: "{{ ansible_facts['default_ipv4']['address'] }}"- name: print ipv4 3debug:msg: "{{ ansible_default_ipv4.address }}"
[root@localhost ansible]# ansible-playbook -i hosts 02.facts.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.85.212]TASK [print ipv4 1] ****************************************************************************************************************************************************
ok: [182.92.85.212] => {"msg": "172.19.91.7"
}TASK [print ipv4 2] ****************************************************************************************************************************************************
ok: [182.92.85.212] => {"msg": "172.19.91.7"
}TASK [print ipv4 3] ****************************************************************************************************************************************************
ok: [182.92.85.212] => {"msg": "172.19.91.7"
}PLAY RECAP *************************************************************************************************************************************************************
182.92.85.212              : ok=4    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

3. register变量

在Ansible中,可以通过register关键字将任务的输出结果注册为变量,以便在后续任务中使用。

  • 注册变量的基本用法

在Ansible playbook中,可以使用register关键字来捕获任务的输出并将其保存为一个变量。例如:

[root@localhost ansible]# cat 03.register.yml
---
- hosts: dbtasks:- name: define a var1shell: "whoami"register: whoami- debug: "msg={{ whoami }}"- debug: "msg={{ whoami.stdout }}"
[root@localhost ansible]# ansible-playbook -i hosts  03.register.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.85.212]TASK [define a var1] ***************************************************************************************************************************************************
changed: [182.92.85.212]TASK [debug] ***********************************************************************************************************************************************************
ok: [182.92.85.212] => {"msg": {"changed": true,"cmd": "whoami","delta": "0:00:00.046106","end": "2025-01-09 10:37:55.151360","failed": false,"rc": 0,"start": "2025-01-09 10:37:55.105254","stderr": "","stderr_lines": [],"stdout": "root","stdout_lines": ["root"]}
}TASK [debug] ***********************************************************************************************************************************************************
ok: [182.92.85.212] => {"msg": "root"
}PLAY RECAP *************************************************************************************************************************************************************
182.92.85.212              : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

4. include功能

‌Ansible的include功能主要用于在Ansible playbook中提取和重用公共的逻辑代码段,使结构更加清晰,方便阅读和维护。通过使用include,可以将重复的任务、变量或handlers等代码片段提取到一个单独的文件中,然后在主playbook中通过include指令引入这些代码片段。

[root@localhost ansible]# cat 04.useradd.yml
---
- name: add useruser:name: "{{ username }}"state: presentcreate_home: no
[root@localhost ansible]# cat 04.include.yml
---
- hosts: dbvars:username: lisitasks:- include: 04.useradd.yml- shell: "tail /etc/passwd"register: content- debug: "msg={{content}}"

注意:提取的代码片段yml只配任务内容,不需要配置hosts

[root@localhost ansible]# ansible-playbook -i hosts 04.include.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.85.212]TASK [add user] ********************************************************************************************************************************************************
ok: [182.92.85.212]TASK [shell] ***********************************************************************************************************************************************************
changed: [182.92.85.212]TASK [debug] ***********************************************************************************************************************************************************
ok: [182.92.85.212] => {"msg": {"changed": true,"cmd": "tail /etc/passwd","delta": "0:00:00.041112","end": "2025-01-09 10:58:22.351314","failed": false,"rc": 0,"start": "2025-01-09 10:58:22.310202","stderr": "","stderr_lines": [],"stdout": "postfix:x:89:89::/var/spool/postfix:/sbin/nologin\nchrony:x:998:996::/var/lib/chrony:/sbin/nologin\nnscd:x:28:28:NSCD Daemon:/:/sbin/nologin\ntcpdump:x:72:72::/:/sbin/nologin\nrpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin\nrpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin\nnfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin\necs-assist-user:x:1000:1000::/home/ecs-assist-user:/sbin/nologin\nnginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin\nlisi:x:1001:1001::/home/lisi:/bin/bash","stdout_lines": ["postfix:x:89:89::/var/spool/postfix:/sbin/nologin","chrony:x:998:996::/var/lib/chrony:/sbin/nologin","nscd:x:28:28:NSCD Daemon:/:/sbin/nologin","tcpdump:x:72:72::/:/sbin/nologin","rpc:x:32:32:Rpcbind Daemon:/var/lib/rpcbind:/sbin/nologin","rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin","nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin","ecs-assist-user:x:1000:1000::/home/ecs-assist-user:/sbin/nologin","nginx:x:997:995:Nginx web server:/var/lib/nginx:/sbin/nologin","lisi:x:1001:1001::/home/lisi:/bin/bash"]}
}PLAY RECAP *************************************************************************************************************************************************************
182.92.85.212              : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

5. handlers

Handlers是Ansible Playbooks中的一种特殊任务类型。它们类似于事件处理程序,用于在特定条件下触发和执行任务。Handlers通常与任务关联,当任务的状态发生变化时,Handlers会被触发执行。Handlers可以用于执行各种操作,如重启服务、重新加载配置文件等。

[root@localhost ansible]# cat 05.handlers.yml
---
- hosts: dbtasks:- copy:src: ./exportsdest: /etc/exportsnotify: restart nfshandlers:- name: restart nfssystemd:name: nfsstate: restarted
[root@localhost ansible]# ansible-playbook -i hosts 05.handlers.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.85.212]TASK [copy] ************************************************************************************************************************************************************
changed: [182.92.85.212]RUNNING HANDLER [restart nfs] ******************************************************************************************************************************************
changed: [182.92.85.212]PLAY RECAP *************************************************************************************************************************************************************
182.92.85.212              : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

当我们未对文件进行修改,再次执行,handlers不会被触发

[root@localhost ansible]# ansible-playbook -i hosts 05.handlers.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.85.212]TASK [copy] ************************************************************************************************************************************************************
ok: [182.92.85.212]PLAY RECAP *************************************************************************************************************************************************************
182.92.85.212              : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

6. when 条件

‌Ansible中的when语句用于条件判断,根据特定的条件来决定是否执行某个任务。当条件为真时,任务将会执行;当条件为假时,任务将被跳过。when语句的使用非常灵活,可以基于变量、事实、先前任务的输出或其他表达式的结果来决定是否执行某个任务‌

[root@localhost ansible]# cat 06.when.yml
---
- hosts: dbtasks:- name: CentOS Install httpdyum: name=httpd state=presentwhen: (ansible_distribution=="CentOS")- name: Ubuntu Install httpdyum: name=httpd state=presentwhen: (ansible_distribution=="Ubuntu")- name: start httpdsystemd:name: httpdstate: startedenabled: no- shell: "systemctl status httpd"register: state_httpd- debug: "msg={{state_httpd}}"
[root@localhost ansible]# ansible-playbook -i hosts 06.when.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.85.212]TASK [CentOS Install httpd] ********************************************************************************************************************************************
ok: [182.92.85.212]TASK [Ubuntu Install httpd] ********************************************************************************************************************************************
skipping: [182.92.85.212]TASK [start httpd] *****************************************************************************************************************************************************
ok: [182.92.85.212]TASK [shell] ***********************************************************************************************************************************************************
changed: [182.92.85.212]TASK [debug] ***********************************************************************************************************************************************************
ok: [182.92.85.212] => {"msg": {"changed": true,"cmd": "systemctl status httpd","delta": "0:00:00.044066","end": "2025-01-09 12:34:02.429361","failed": false,"rc": 0,"start": "2025-01-09 12:34:02.385295","stderr": "","stderr_lines": [],"stdout": "● httpd.service - The Apache HTTP Server\n   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)\n   Active: active (running) since Thu 2025-01-09 12:32:34 CST; 1min 27s ago\n     Docs: man:httpd(8)\n           man:apachectl(8)\n Main PID: 8474 (httpd)\n   Status: \"Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec\"\n   CGroup: /system.slice/httpd.service\n           ├─8474 /usr/sbin/httpd -DFOREGROUND\n           ├─8475 /usr/sbin/httpd -DFOREGROUND\n           ├─8476 /usr/sbin/httpd -DFOREGROUND\n           ├─8477 /usr/sbin/httpd -DFOREGROUND\n           ├─8478 /usr/sbin/httpd -DFOREGROUND\n           └─8479 /usr/sbin/httpd -DFOREGROUND\n\nJan 09 12:32:34 ali01 systemd[1]: Starting The Apache HTTP Server...\nJan 09 12:32:34 ali01 httpd[8474]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::216:3eff:fe34:19c2. Set the 'ServerName' directive globally to suppress this message\nJan 09 12:32:34 ali01 systemd[1]: Started The Apache HTTP Server.","stdout_lines": ["● httpd.service - The Apache HTTP Server","   Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)","   Active: active (running) since Thu 2025-01-09 12:32:34 CST; 1min 27s ago","     Docs: man:httpd(8)","           man:apachectl(8)"," Main PID: 8474 (httpd)","   Status: \"Total requests: 0; Current requests/sec: 0; Current traffic:   0 B/sec\"","   CGroup: /system.slice/httpd.service","           ├─8474 /usr/sbin/httpd -DFOREGROUND","           ├─8475 /usr/sbin/httpd -DFOREGROUND","           ├─8476 /usr/sbin/httpd -DFOREGROUND","           ├─8477 /usr/sbin/httpd -DFOREGROUND","           ├─8478 /usr/sbin/httpd -DFOREGROUND","           └─8479 /usr/sbin/httpd -DFOREGROUND","","Jan 09 12:32:34 ali01 systemd[1]: Starting The Apache HTTP Server...","Jan 09 12:32:34 ali01 httpd[8474]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using fe80::216:3eff:fe34:19c2. Set the 'ServerName' directive globally to suppress this message","Jan 09 12:32:34 ali01 systemd[1]: Started The Apache HTTP Server."]}
}PLAY RECAP *************************************************************************************************************************************************************
182.92.85.212              : ok=5    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0

语法和逻辑运算符

when语句的语法与Python的语法非常相似,支持多种条件表达式和逻辑运算符:

  • 比较运算符‌:==、!=、>、<、>=、<=
  • 逻辑运算符‌:and、or、not
  • 组合条件‌:可以使用括号()来组合多个条件,改变运算的优先级‌

7. with_items 循环

在Ansible Playbook中,with_items用于遍历列表或字典,并对每个元素执行任务。其基本语法如下:

tasks:- command: some_command "{{ item }}"with_items:- item1- item2- item3

使用场景包括:创建多个用户,安装多个软件包,启动多个服务,拷贝多个文件等等

[root@localhost ansible]# cat 07.with_items.yml
---
- hosts: dbgather_facts: notasks:- name: useradduser:name: "{{item}}"state: presentcreate_home: nowith_items:- yurq1- yurq2- yurq3
[root@localhost ansible]# ansible-playbook -i hosts 07.with_items.ymlPLAY [db] **************************************************************************************************************************************************************TASK [useradd] *********************************************************************************************************************************************************
changed: [182.92.85.212] => (item=yurq1)
changed: [182.92.85.212] => (item=yurq2)
changed: [182.92.85.212] => (item=yurq3)PLAY RECAP *************************************************************************************************************************************************************
182.92.85.212              : ok=1    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0[root@localhost ansible]# ansible -i hosts db -m shell -a "tail -3 /etc/passwd"
182.92.85.212 | CHANGED | rc=0 >>
yurq1:x:1002:1002::/home/yurq1:/bin/bash
yurq2:x:1003:1003::/home/yurq2:/bin/bash
yurq3:x:1004:1004::/home/yurq3:/bin/bash

8. Jinja2模板

Jinja2 是 Python 的全功能模板引擎
Ansible 需要使用 Jinja2 模板来修改被管理主机的配置文件。

ansible 使用 jinja2 模板需要借助 template 模块实现,那 template 模块是用来做什么的?
template 模块和 copy 模块完全一样,都是拷贝文件至远程主机,区别在于template 模块会解析要拷贝的文件中变量的值,而 copy 则是原封不动的将文件拷贝至被控端。

[root@localhost ansible]# cat exports.j2
#{{ansible_hostname}}
/data/  *(rw,sync,all_squash)
[root@localhost ansible]# cat 08.jinja2.yml
---
- hosts: dbtasks:- template:src: ./exports.j2dest: /etc/exportsnotify: restart nfs- shell: "cat /etc/exports"register: content- debug: "msg={{content}}"handlers:- name: restart nfssystemd:name: nfsstate: restarted
[root@localhost ansible]# ansible-playbook -i hosts 08.jinja2.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.84.211]TASK [template] ********************************************************************************************************************************************************
changed: [182.92.84.211]TASK [shell] ***********************************************************************************************************************************************************
changed: [182.92.84.211]TASK [debug] ***********************************************************************************************************************************************************
ok: [182.92.84.211] => {"msg": {"changed": true,"cmd": "cat /etc/exports","delta": "0:00:00.039831","end": "2025-01-09 13:03:56.418589","failed": false,"rc": 0,"start": "2025-01-09 13:03:56.378758","stderr": "","stderr_lines": [],"stdout": "#ali01\n/data/  *(rw,sync,all_squash) ","stdout_lines": ["#ali01","/data/  *(rw,sync,all_squash) "]}
}RUNNING HANDLER [restart nfs] ******************************************************************************************************************************************
changed: [182.92.84.211]PLAY RECAP *************************************************************************************************************************************************************
182.92.84.211              : ok=5    changed=3    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

9. group_vars

ansible中变量有很多种,包括:

  • 资产变量,即我们配置在hosts文件中的变量
  • facts变量,即ansible为我们收集的主机信息变量
  • 注册变量,即register注册的变量,在脚本内为后续使用
  • 剧本变量,如vars定义在文件前部,供后续使用
  • 全局变量,一般是ansible命令行使用的

group_vars 下的文件名应该与 Ansible inventory 中定义的组名匹配,文件名无需添加任何扩展名,内容为该组下所有主机共有的变量。一般用于定义剧本变量。

例如,假设你有一个名为 webservers 的组,group_vars/webservers 文件内容可能是:

http_port: 80
max_connections: 1024

不过,一般我们都只定义一个all的文件,供所有组使用

[root@localhost ansible]# tree
.
├── 01.nfs_install.yml
├── 02.facts.yml
├── 03.register.yml
├── 04.include.yml
├── 04.useradd.yml
├── 05.handlers.yml
├── 06.when.yml
├── 07.with_items.yml
├── 08.jinja2.yml
├── 09.group_vars.yml
├── exports
├── exports.j2
├── group_vars
│   └── all
└── hosts1 directory, 14 files
[root@localhost ansible]# cat group_vars/all
user4: yurq4
[root@localhost ansible]# ansible-playbook -i hosts 09.group_vars.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.84.211]TASK [useradd 2] *******************************************************************************************************************************************************
changed: [182.92.84.211]PLAY RECAP *************************************************************************************************************************************************************
182.92.84.211              : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0[root@localhost ansible]# ansible -i hosts all -m shell -a "tail -1 /etc/passwd"
182.92.84.211 | CHANGED | rc=0 >>
yurq4:x:1005:1005::/home/yurq4:/bin/bash

看到了吗?我们未做任何导入工作,就可以直接调用user4,非常方便

10. roles ⭐️⭐️⭐️

Ansible roles是Ansible的一个组织结构,它允许你将配置任务封装为可重用的单元,这样你可以在多个playbook中使用它们。

一个Ansible role通常包含以下目录结构:

  • defaults/ :设定变量的默认值。
  • files/ :存放由copy或script模块等调用的文件。
  • handlers/ :包含处理器的定义,处理器可以在特定的条件下触发。
  • meta/ :定义role的依赖关系。
  • tasks/ :包含主要的任务集。
  • templates/ :包含Jinja2模板文件,这些模板文件可以根据变量渲染内容。
  • vars/ :定义变量,这些变量会覆盖defaults中的同名变量。

文件:

  • README.md :对role的简要说明。

  • meta/main.yml :定义role的特定行为。

  • tasks/main.yml :列出role要执行的任务。

  • handlers/main.yml :列出可由任务触发的处理器。

  • vars/main.yml :定义role使用的变量。

上面的目录并不是每个项目都需要的,一般常用的有:

  • files/

  • handlers/

  • tasks/

  • templates/

  • vars/

我们把08.jinja2.yml拆分为roles格式,帮助大家理解

[root@localhost ansible]# cat 08.jinja2.yml
---
- hosts: dbtasks:- template:src: ./exports.j2dest: /etc/exportsnotify: restart nfs- shell: "cat /etc/exports"register: content- debug: "msg={{content}}"handlers:- name: restart nfssystemd:name: nfsstate: restarted

如下:

[root@localhost roles]# tree
.
├── 10.roles.yml
├── db
│   ├── handlers
│   │   └── main.yml
│   ├── tasks
│   │   └── main.yml
│   └── templates
│       └── exports.j2
└── hosts4 directories, 5 files

tasks/

[root@localhost roles]# cat db/tasks/main.yml
- template:src: ./exports.j2dest: /etc/exportsnotify: restart nfs
- shell: "cat /etc/exports"register: content
- debug: "msg={{content}}"

handlers/

[root@localhost roles]# cat db/handlers/main.yml
- name: restart nfssystemd:name: nfsstate: restarted

templates/

[root@localhost roles]# cat db/templates/exports.j2
#{{ansible_hostname}}
/data/  *(rw,sync,all_squash)

10.roles.yml

[root@localhost roles]# cat 10.roles.yml
---
- hosts: dbroles:- db

执行

[root@localhost roles]# ansible-playbook -i hosts 10.roles.ymlPLAY [db] **************************************************************************************************************************************************************TASK [Gathering Facts] *************************************************************************************************************************************************
ok: [182.92.84.211]TASK [db : template] ***************************************************************************************************************************************************
ok: [182.92.84.211]TASK [db : shell] ******************************************************************************************************************************************************
changed: [182.92.84.211]TASK [db : debug] ******************************************************************************************************************************************************
ok: [182.92.84.211] => {"msg": {"changed": true,"cmd": "cat /etc/exports","delta": "0:00:00.039530","end": "2025-01-09 13:35:27.995178","failed": false,"rc": 0,"start": "2025-01-09 13:35:27.955648","stderr": "","stderr_lines": [],"stdout": "#ali01\n/data/  *(rw,sync,all_squash) ","stdout_lines": ["#ali01","/data/  *(rw,sync,all_squash) "]}
}PLAY RECAP *************************************************************************************************************************************************************
182.92.84.211              : ok=4    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0

其实执行起来和08的剧本本质是一样的,不过改变了目录结构,方便管理

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com