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的剧本本质是一样的,不过改变了目录结构,方便管理

相关推荐
leo__5201 天前
自动化运维:使用Ansible简化日常任务
运维·自动化·ansible
风清再凯6 天前
自动化工具ansible,以及playbook剧本
运维·自动化·ansible
IT乌鸦坐飞机6 天前
ansible部署数据库服务随机启动并创建用户和设置用户有完全权限
数据库·ansible·centos7
遇见火星19 天前
如何使用Ansible一键部署MinIO集群?
ansible
粥周粥19 天前
ANSIBLE
ansible
码农101号19 天前
Linux中ansible模块补充和playbook讲解
linux·运维·ansible
码农101号19 天前
Linux的Ansible软件基础使用讲解和ssh远程连接
ansible
烟雨书信21 天前
ANSIBLE运维自动化管理端部署
运维·自动化·ansible
碎碎-li21 天前
ANSIBLE(运维自动化)
运维·自动化·ansible
@donshu@24 天前
Linux运维-ansible-python开发-获取inventroy信息
linux·运维·ansible