ansible 知识点【回顾梳理】

ansible 知识点

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

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

1. 剧本

剧本很重要的就是,定义演员的信息(其实就是定义主机的信息),演员的具体任务(以及主机要执行的模块,动作)

ansible剧本也是由两个最基本的部分组成

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

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

剧本格式:

yaml 复制代码
# 1
---
- name: first task
  hosts: db
# gather_facts: no
  vars:
    var1: a
    var2: b
  tasks:
    - name: task1
      command:..
    - name: task2
      command:..
- name: second task
  hosts: web
    - name: task1 
      command:..
    ...
# 2    
--- 
- hosts: all
  vars:
    var1: a
    var2: b
  tasks:
    - name: task1 
    ...

官网内置模块说明\]([Ansible.Builtin --- Ansible Community Documentation](https://docs.ansible.com/ansible/latest/collections/ansible/builtin/)) 安装nfs ```sh [root@localhost ansible]# cat 01.nfs_install.yml --- - hosts: all gather_facts: yes tasks: - name: backup repo shell: "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 repo yum_repository: name: aliyun_repo description: aliyun linux repository baseurl: http://mirrors.aliyun.com/repo/Centos-{{ ansible_distribution_major_version }}.repo enabled: yes gpgcheck: no - name: install nfs rpcbind yum: name: "{{ item }}" state: present with_items: - rpcbind - nfs-utils - name: started server systemd: name: "{{ item }}" state: started enabled: yes with_items: - rpcbind - nfs-utils ``` ```sh [root@localhost ansible]# ansible-playbook -i hosts 01.nfs_install.yml PLAY [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数量 * 提供的或可用的内存 * 可用磁盘空间 查看详细信息 ```sh [root@localhost ansible]# ansible-playbook -i hosts 02.facts.yml PLAY [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.hostname | ansible_facts\['hostname'\] | ansible_hostname | | 完全限定域名 | ansible_facts.fqdn | ansible_facts\['fqdn'\] | ansible_fqdn | | IPv4地址 | ansible_facts.default_ipv4.address | ansible_facts\['default_ipv4'\]\['address'\] | ansible_default_ipv4 | | 所有网络接口的名称列表 | ansible_facts.interfaces | ansible_facts\['interfaces '\] | ansible_interfaces | | DNS服务器列表 | ansible_facts.dns | ansible_facts\['dns'\] | ansible_dns | | 当前运行的内核版本 | ansible_facts.kernel | ansible_facts\['kernel'\] | ansible_kernel | 三种格式都可以使用,看自己喜好 ```sh [root@localhost ansible]# cat 02.facts.yml --- - hosts: db tasks: - name: print ipv4 1 debug: msg: "{{ ansible_facts.default_ipv4.address }}" - name: print ipv4 2 debug: msg: "{{ ansible_facts['default_ipv4']['address'] }}" - name: print ipv4 3 debug: msg: "{{ ansible_default_ipv4.address }}" [root@localhost ansible]# ansible-playbook -i hosts 02.facts.yml PLAY [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`关键字来捕获任务的输出并将其保存为一个变量。例如: ```sh [root@localhost ansible]# cat 03.register.yml --- - hosts: db tasks: - name: define a var1 shell: "whoami" register: whoami - debug: "msg={{ whoami }}" - debug: "msg={{ whoami.stdout }}" [root@localhost ansible]# ansible-playbook -i hosts 03.register.yml PLAY [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`指令引入这些代码片段。 ```sh [root@localhost ansible]# cat 04.useradd.yml --- - name: add user user: name: "{{ username }}" state: present create_home: no [root@localhost ansible]# cat 04.include.yml --- - hosts: db vars: username: lisi tasks: - include: 04.useradd.yml - shell: "tail /etc/passwd" register: content - debug: "msg={{content}}" ``` > 注意:提取的代码片段yml只配任务内容,不需要配置hosts ```sh [root@localhost ansible]# ansible-playbook -i hosts 04.include.yml PLAY [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可以用于执行各种操作,如重启服务、重新加载配置文件等。 ```sh [root@localhost ansible]# cat 05.handlers.yml --- - hosts: db tasks: - copy: src: ./exports dest: /etc/exports notify: restart nfs handlers: - name: restart nfs systemd: name: nfs state: restarted [root@localhost ansible]# ansible-playbook -i hosts 05.handlers.yml PLAY [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不会被触发 ```sh [root@localhost ansible]# ansible-playbook -i hosts 05.handlers.yml PLAY [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`语句的使用非常灵活,可以基于变量、事实、先前任务的输出或其他表达式的结果来决定是否执行某个任务‌ ```sh [root@localhost ansible]# cat 06.when.yml --- - hosts: db tasks: - name: CentOS Install httpd yum: name=httpd state=present when: (ansible_distribution=="CentOS") - name: Ubuntu Install httpd yum: name=httpd state=present when: (ansible_distribution=="Ubuntu") - name: start httpd systemd: name: httpd state: started enabled: no - shell: "systemctl status httpd" register: state_httpd - debug: "msg={{state_httpd}}" ``` ```sh [root@localhost ansible]# ansible-playbook -i hosts 06.when.yml PLAY [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`用于遍历列表或字典,并对每个元素执行任务。其基本语法如下: ```sh tasks: - command: some_command "{{ item }}" with_items: - item1 - item2 - item3 ``` 使用场景包括:创建多个用户,安装多个软件包,启动多个服务,拷贝多个文件等等 ```sh [root@localhost ansible]# cat 07.with_items.yml --- - hosts: db gather_facts: no tasks: - name: useradd user: name: "{{item}}" state: present create_home: no with_items: - yurq1 - yurq2 - yurq3 ``` ```sh [root@localhost ansible]# ansible-playbook -i hosts 07.with_items.yml PLAY [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 则是原封不动的将文件拷贝至被控端。 ```sh [root@localhost ansible]# cat exports.j2 #{{ansible_hostname}} /data/ *(rw,sync,all_squash) [root@localhost ansible]# cat 08.jinja2.yml --- - hosts: db tasks: - template: src: ./exports.j2 dest: /etc/exports notify: restart nfs - shell: "cat /etc/exports" register: content - debug: "msg={{content}}" handlers: - name: restart nfs systemd: name: nfs state: restarted [root@localhost ansible]# ansible-playbook -i hosts 08.jinja2.yml PLAY [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` 文件内容可能是: ```json http_port: 80 max_connections: 1024 ``` 不过,一般我们都只定义一个all的文件,供所有组使用 ```sh [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 └── hosts 1 directory, 14 files [root@localhost ansible]# cat group_vars/all user4: yurq4 ``` ```sh [root@localhost ansible]# ansible-playbook -i hosts 09.group_vars.yml PLAY [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格式,帮助大家理解 ```sh [root@localhost ansible]# cat 08.jinja2.yml --- - hosts: db tasks: - template: src: ./exports.j2 dest: /etc/exports notify: restart nfs - shell: "cat /etc/exports" register: content - debug: "msg={{content}}" handlers: - name: restart nfs systemd: name: nfs state: restarted ``` 如下: ```sh [root@localhost roles]# tree . ├── 10.roles.yml ├── db │ ├── handlers │ │ └── main.yml │ ├── tasks │ │ └── main.yml │ └── templates │ └── exports.j2 └── hosts 4 directories, 5 files ``` tasks/ ```sh [root@localhost roles]# cat db/tasks/main.yml - template: src: ./exports.j2 dest: /etc/exports notify: restart nfs - shell: "cat /etc/exports" register: content - debug: "msg={{content}}" ``` handlers/ ```sh [root@localhost roles]# cat db/handlers/main.yml - name: restart nfs systemd: name: nfs state: restarted ``` templates/ ```sh [root@localhost roles]# cat db/templates/exports.j2 #{{ansible_hostname}} /data/ *(rw,sync,all_squash) ``` 10.roles.yml ```sh [root@localhost roles]# cat 10.roles.yml --- - hosts: db roles: - db ``` 执行 ```sh [root@localhost roles]# ansible-playbook -i hosts 10.roles.yml PLAY [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的剧本本质是一样的,不过改变了目录结构,方便管理

相关推荐
AquaPluto3 天前
Ansible-Playbook详解
ansible·playbook·roles
chairon10 天前
Ansible:playbook的高级用法
linux·运维·服务器·ansible·apache
树下一少年10 天前
ansible+docker+docker-compose快速部署4节点高可用minio集群
docker·容器·ansible·docker-compose·minio集群
千航@abc11 天前
Ansible 实战:Roles,运维的 “魔法函数”
ansible·playbook·roles·角色·模版·剧本
一个高效工作的家伙11 天前
ansible可视化自动化平台-semaphore
ansible
树下一少年11 天前
通过ansible+docker-compose快速安装一主两从redis+三sentinel
redis·docker·ansible·sentinel·docker-compose
独隅12 天前
针对Ansible执行脚本时报错“可执行文件格式错误”,以下是详细的解决步骤和示例
运维·开发语言·ansible·lua·lua5.4
大小科圣13 天前
Ansible playbook
ansible
大小科圣13 天前
ansible条件判断及循环
ansible
狂奔solar14 天前
ansible-playbook 写arm版达梦7数据库的一键安装脚本
ansible