资讯动态

企业级 Ansible 实战:变量管理、模板渲染与角色拆分

发布时间:2026/10/14 13:22:53 来源:尧图企业网站定制
1. 从手工敲命令到批量管机器Ansible 实战进阶的核心思路干运维这行的朋友大概都有过这样的经历手里管着几十台甚至上百台服务器每次上线新服务、改配置、查日志都得一台台 SSH 上去敲命令。刚开始机器少还能扛等到规模上来了光是给所有机器统一改个时区就能耗掉一整个下午。我早期也是这么过来的后来接触到 Ansible 之后才真正体会到什么叫批量操作的爽感。这个系列走到第十二篇、Ansible 的第六篇其实已经过了装个 Ansible 跑个 ping 模块的入门阶段了。前面几篇我们聊了 inventory 怎么写、ad-hoc 命令怎么用、playbook 的基本结构长什么样。到了这一篇我想聊的是真正在企业环境里把 Ansible 用起来的那些关键能力——变量管理、模板渲染、条件判断、循环处理、角色Role拆分以及怎么把这些东西组合成一个能维护、能复用、能交接给同事的自动化体系。为什么这些能力重要因为企业运维和自己在虚拟机里玩玩的本质区别在于环境是多样的需求是变化的人员是流动的。你写一个 playbook 只针对一台测试机那怎么写都行但你要让同一个 playbook 同时适配开发、测试、预发、生产四套环境还要让新来的同事能看懂、能改、能扩展那就必须有一套结构化的方法论。Ansible 提供的这些机制就是帮你把一次性脚本升级成可维护的自动化资产。这篇文章适合谁看如果你已经能跑通基本的 playbook但对着一堆变量和目录结构不知道怎么组织或者你写的 playbook 每次改一点就要动全身那这篇就是写给你的。如果你还没接触过 Ansible建议先回头看看前几篇的基础内容不然直接看这篇会有点吃力。下面我会按照设计思路 → 核心机制 → 实操落地 → 问题排查的顺序把企业级 Ansible 实战中最容易踩坑、也最能体现功力的部分掰开揉碎讲清楚。2. 企业级 Ansible 的整体设计思路拆解2.1 为什么不能把所有东西塞进一个 playbook我见过不少刚上手 Ansible 的同事习惯把所有任务写在一个 YAML 文件里从装包、改配置、起服务到配防火墙一路往下写。刚开始确实方便一个文件搞定所有事。但问题是当你要给 Web 服务器和数据库服务器分别部署时这个文件就开始膨胀了——你得用when判断机器类型用不同的变量区分路径改一处逻辑要通读全文确认没影响别的地方。到最后这个文件变成几百行谁都不敢动。企业级 Ansible 的核心设计原则就一条关注点分离。把做什么和在哪做分开把通用逻辑和环境差异分开把一个完整的功能单元封装成独立的角色。这样带来的好处是显而易见的角色可以跨项目复用环境差异通过变量注入通用逻辑改一次所有地方生效。具体来说我通常会把一个项目的 Ansible 目录组织成这样ansible-project/ ├── ansible.cfg ├── inventory/ │ ├── dev │ ├── test │ └── prod ├── group_vars/ │ ├── all.yml │ ├── webservers.yml │ └── dbservers.yml ├── host_vars/ │ └── special-host.yml ├── roles/ │ ├── common/ │ ├── nginx/ │ └── mysql/ └── site.yml这个结构不是拍脑袋定的每一层都有明确的分工。inventory目录按环境拆分是因为不同环境的机器列表天然不同group_vars按主机组拆分是因为同一类机器的配置参数往往一致roles目录存放功能单元是因为部署 Nginx 的逻辑和部署 MySQL 的逻辑完全独立site.yml作为入口负责把角色和主机组编排起来。2.2 变量优先级Ansible 最容易被误解的机制说到变量就不得不提 Ansible 的变量优先级。这是新手最容易翻车的地方——明明在group_vars里定义了变量怎么跑起来还是用的默认值答案往往就是优先级搞错了。Ansible 的变量来源非常多从低到高大致是这样的只列常用的优先级变量来源典型用途低role defaults角色默认值最容易被覆盖↓inventory group_vars主机组级别的变量↓inventory host_vars单台主机的变量↓play varsplaybook 中定义的变量↓role vars角色内部固定变量不易覆盖↓set_fact / register运行时动态生成的变量高extra vars (-e)命令行传入最高优先级理解这个表的关键在于越靠近具体执行的变量优先级越高。role defaults是给角色定一个兜底值方便别人不传参也能跑group_vars是给一组机器定共性配置host_vars是给个别机器开小灶-e是临时覆盖用于调试或特殊场景。我踩过的一个典型坑是在role defaults里定义了nginx_port: 80然后在group_vars/webservers.yml里也写了nginx_port: 8080结果跑起来还是 80。当时百思不得其解后来才发现是角色里的模板文件直接引用了defaults里的变量名而group_vars里的定义因为拼写差了一个字母没生效。所以我的经验是变量命名要有统一前缀改完用ansible-inventory --list或-e调试确认实际生效值。2.3 幂等性自动化脚本的底线幂等性这个词听起来学术说白了就是同一个 playbook 跑一遍和跑十遍结果应该一样。这是 Ansible 相比 shell 脚本最大的优势也是企业环境里必须守住的红线。为什么因为生产环境经常需要重复执行。比如某台机器部署失败了你修好之后重新跑一遍 playbook这时候前面已经成功的步骤不能因为重复执行而出问题。如果你用 shell 模块写mkdir /data/app第二次跑就会报目录已存在但用 file 模块写state: directory第二次跑会直接跳过因为状态已经满足。我在实际工作中总结了几条保证幂等性的原则能用专用模块就不用shell/command用shell时尽量加上creates或removes参数做条件判断文件操作用copy/template而不是echo 服务管理用service/systemd模块而不是systemctl restart。这些细节看起来琐碎但正是它们决定了你的 playbook 是能跑还是能放心跑。3. 核心机制深度解析与实操要点3.1 变量管理从散落各处到集中治理变量管理是 Ansible 实战的分水岭。写得好的 playbook变量层次分明、命名规范、来源清晰写得差的变量满天飞改一个地方要全局搜索。我的做法是遵循三层变量原则第一层是角色默认值放在roles/xxx/defaults/main.yml。这一层定义角色运行所需的最小参数集相当于给角色定一个接口。比如 Nginx 角色需要知道监听端口、站点根目录、上游地址这些都在 defaults 里给一个合理的默认值。第二层是环境变量放在group_vars/下。这一层定义不同环境的差异比如开发环境数据库地址是dev-db.internal生产环境是prod-db.internal。这些变量按主机组组织同一组机器共享。第三层是主机变量放在host_vars/下。这一层处理个别机器的特殊需求比如某台机器磁盘特别大需要单独指定数据目录。举个实际例子。假设我们要部署一个应用需要配置数据库连接。在roles/app/defaults/main.yml里app_db_host: 127.0.0.1 app_db_port: 3306 app_db_name: myapp app_db_user: appuser app_db_pool_size: 10在group_vars/webservers.yml里覆盖app_db_host: db-cluster.internal app_db_pool_size: 20在host_vars/web-01.yml里再覆盖app_db_pool_size: 50这样当 playbook 在web-01上执行时app_db_pool_size最终是 50在其他 Web 服务器上是 20如果某台机器不在任何组里就是默认的 10。整个链路清晰可追溯新人接手时看一眼目录结构就明白变量从哪来。注意变量名尽量用蛇形命名法snake_case并且加上角色前缀比如nginx_、mysql_避免不同角色的变量互相覆盖。这个习惯在角色多了之后能救命。3.2 模板渲染让配置文件随环境自动变化企业环境里同一份配置文件在不同环境往往只有几个参数不同。如果每个环境维护一份配置文件改一个参数要改四份迟早会漏。Ansible 的template模块配合 Jinja2 模板就是解决这个问题的。Jinja2 的基本语法不复杂{{ variable }}输出变量{% if %}做条件判断{% for %}做循环。但在实际使用中有几个细节特别容易出问题。第一个是变量未定义时的处理。如果模板里引用了{{ app_db_host }}但这个变量没定义Ansible 会直接报错。解决办法是在模板里用默认值语法{{ app_db_host | default(127.0.0.1) }}。这样即使变量没传也有兜底值。第二个是布尔值的渲染。Jinja2 渲染True会输出True但很多配置文件需要的是true或yes。这时候要用过滤器{{ enable_ssl | lower }}输出true或者{{ enable_ssl | ternary(yes, no) }}根据布尔值输出 yes/no。第三个是列表和字典的遍历。比如配置多个上游服务器upstream backend { {% for server in app_backend_servers %} server {{ server.host }}:{{ server.port }} weight{{ server.weight | default(1) }}; {% endfor %} }对应的变量定义app_backend_servers: - host: 10.0.1.10 port: 8080 weight: 2 - host: 10.0.1.11 port: 8080这种写法在配置 Nginx upstream、HAProxy backend、数据库集群时特别常用。我建议在模板里对循环加一些防御性判断比如{% if app_backend_servers is defined and app_backend_servers %}避免变量为空时生成一个空的 upstream 块导致服务启动失败。实操心得模板文件建议放在角色的templates/目录下文件名以.j2结尾方便识别。渲染后的文件权限、属主通过template模块的owner、group、mode参数指定不要依赖源文件的权限。3.3 条件判断与循环让一个 playbook 适配多种场景企业环境里没有一刀切的部署。CentOS 和 Ubuntu 的包管理命令不同物理机和虚拟机的磁盘配置不同生产环境和测试环境的服务参数不同。Ansible 的when和loop就是处理这些差异的利器。when的用法很直观就是给任务加一个条件条件为真才执行。常用的判断包括- name: 安装 NginxDebian 系 apt: name: nginx state: present when: ansible_os_family Debian - name: 安装 NginxRedHat 系 yum: name: nginx state: present when: ansible_os_family RedHat这里用到了 Ansible 自动收集的 facts 变量ansible_os_family。facts 是 Ansible 在执行 playbook 前自动收集的目标机器信息包括操作系统、IP 地址、内存大小、磁盘挂载等。你可以用ansible all -m setup查看某台机器的所有 facts然后在条件判断里引用。loop用于重复执行相似任务。比如批量创建用户- name: 创建运维用户 user: name: {{ item.name }} groups: {{ item.groups }} shell: /bin/bash loop: - { name: deploy, groups: www-data } - { name: monitor, groups: adm } - { name: backup, groups: adm }loop配合when可以实现更精细的控制。比如只对生产环境的机器创建某个用户- name: 创建生产环境专用用户 user: name: prodops shell: /bin/bash loop: {{ groups[prod] | default([]) }} when: inventory_hostname in groups[prod]这里有个小技巧groups[prod]在组不存在时会报错所以加| default([])做兜底。这种防御性写法在企业 playbook 里应该成为习惯因为环境差异导致某个组不存在是常有的事。3.4 角色拆分把 playbook 变成可复用的积木角色Role是 Ansible 组织代码的最高形式。一个角色就是一个独立的功能单元包含任务、变量、模板、文件、处理器等。把功能拆成角色之后部署一套完整环境就变成了选择角色 传入变量的组合。一个标准角色的目录结构是这样的roles/nginx/ ├── defaults/ │ └── main.yml ├── handlers/ │ └── main.yml ├── tasks/ │ └── main.yml ├── templates/ │ └── nginx.conf.j2 ├── files/ │ └── index.html ├── vars/ │ └── main.yml └── meta/ └── main.yml每个目录的作用tasks是任务入口handlers定义处理器比如重启服务templates放 Jinja2 模板files放静态文件defaults放默认变量vars放角色内部变量meta定义角色依赖。拆角色的粒度怎么把握我的经验是一个角色对应一个可独立部署的软件或功能。比如 Nginx 是一个角色MySQL 是一个角色监控 Agent 是一个角色系统基础配置时区、DNS、yum 源是一个角色。不要把一个角色拆得太细否则角色之间依赖关系复杂维护成本反而高也不要一个角色包打天下那样就失去了复用的意义。角色之间的依赖通过meta/main.yml声明dependencies: - role: common - role: nginx vars: nginx_port: 8080这样在执行这个角色之前Ansible 会先执行common和nginx角色。依赖关系让角色可以像搭积木一样组合比如部署一个 Web 应用这个角色依赖基础环境和Nginx执行时自动把前置条件准备好。注意角色依赖默认只执行一次。如果多个角色都依赖commoncommon只会跑一遍。这个行为大多数时候是符合预期的但如果你确实需要重复执行可以在依赖声明里加allow_duplicates: true。4. 完整实操流程与关键环节实现4.1 环境准备与基础配置在开始写 playbook 之前先把基础环境搭好。假设我们有三台机器一台 Web 服务器、一台数据库服务器、一台监控服务器操作系统是常见的 Linux 发行版。第一步是配置ansible.cfg。这个文件控制 Ansible 的全局行为放在项目根目录下Ansible 会自动读取[defaults] inventory ./inventory/prod remote_user deploy host_key_checking False retry_files_enabled False stdout_callback yaml log_path ./ansible.log [privilege_escalation] become True become_method sudo become_user root become_ask_pass False这里几个参数值得说明host_key_checking False关闭 SSH 指纹检查避免第一次连接时卡在确认提示stdout_callback yaml让输出更易读become True默认提权执行因为大部分运维操作需要 root 权限。第二步是写 inventory 文件。我习惯用 INI 格式简单直观[webservers] web-01 ansible_host192.168.1.10 [dbservers] db-01 ansible_host192.168.1.20 [monitoring] mon-01 ansible_host192.168.1.30 [all:vars] ansible_python_interpreter/usr/bin/python3ansible_host指定实际 IP主机名只是逻辑标识。ansible_python_interpreter指定目标机器的 Python 路径这个在混合了不同发行版的环境里特别重要因为有些系统默认 Python 是 2.x而 Ansible 需要 3.x。第三步是验证连通性ansible all -m ping如果所有机器都返回pong说明基础环境没问题。如果有机器不通先排查 SSH 连接、防火墙、Python 版本这几个常见问题。4.2 编写基础角色以系统初始化为例系统初始化是每台机器都要做的包括设置时区、配置 DNS、更新 yum/apt 源、安装常用工具。这个角色叫common是所有其他角色的基础。roles/common/tasks/main.yml- name: 设置时区为 Asia/Shanghai timezone: name: Asia/Shanghai when: ansible_os_family ! Windows - name: 配置 DNS 服务器 template: src: resolv.conf.j2 dest: /etc/resolv.conf owner: root group: root mode: 0644 - name: 安装常用工具Debian 系 apt: name: {{ common_packages }} state: present update_cache: yes when: ansible_os_family Debian - name: 安装常用工具RedHat 系 yum: name: {{ common_packages }} state: present when: ansible_os_family RedHat - name: 确保 chronyd 服务运行 service: name: {{ common_ntp_service }} state: started enabled: yesroles/common/defaults/main.ymlcommon_packages: - vim - curl - wget - htop - net-tools - telnet - rsync common_ntp_service: {{ chronyd if ansible_os_family RedHat else systemd-timesyncd }}roles/common/templates/resolv.conf.j2{% for ns in common_dns_servers %} nameserver {{ ns }} {% endfor %} options timeout:2 attempts:3 rotategroup_vars/all.ymlcommon_dns_servers: - 223.5.5.5 - 119.29.29.29这个角色虽然简单但体现了几个关键设计用when处理不同发行版的差异用模板渲染 DNS 配置用变量控制安装包列表。跑一遍之后所有机器的时区、DNS、基础工具都统一了。4.3 部署 Nginx 角色模板与处理器的配合Nginx 角色稍微复杂一些涉及模板渲染、服务管理和处理器触发。roles/nginx/tasks/main.yml- name: 安装 Nginx package: name: nginx state: present - name: 创建站点目录 file: path: {{ nginx_site_root }} state: directory owner: {{ nginx_user }} group: {{ nginx_group }} mode: 0755 - name: 渲染 Nginx 主配置 template: src: nginx.conf.j2 dest: /etc/nginx/nginx.conf owner: root group: root mode: 0644 notify: reload nginx - name: 渲染站点配置 template: src: site.conf.j2 dest: /etc/nginx/conf.d/{{ nginx_site_name }}.conf owner: root group: root mode: 0644 notify: reload nginx - name: 部署静态首页 copy: src: index.html dest: {{ nginx_site_root }}/index.html owner: {{ nginx_user }} group: {{ nginx_group }} mode: 0644 - name: 确保 Nginx 运行 service: name: nginx state: started enabled: yesroles/nginx/handlers/main.yml- name: reload nginx service: name: nginx state: reloadedroles/nginx/defaults/main.ymlnginx_user: www-data nginx_group: www-data nginx_port: 80 nginx_site_root: /var/www/html nginx_site_name: default nginx_worker_processes: auto nginx_worker_connections: 1024 nginx_upstream_servers: []roles/nginx/templates/nginx.conf.j2user {{ nginx_user }}; worker_processes {{ nginx_worker_processes }}; events { worker_connections {{ nginx_worker_connections }}; } http { include /etc/nginx/mime.types; default_type application/octet-stream; sendfile on; keepalive_timeout 65; {% if nginx_upstream_servers %} upstream backend { {% for server in nginx_upstream_servers %} server {{ server.host }}:{{ server.port }} weight{{ server.weight | default(1) }}; {% endfor %} } {% endif %} include /etc/nginx/conf.d/*.conf; }roles/nginx/templates/site.conf.j2server { listen {{ nginx_port }}; server_name _; root {{ nginx_site_root }}; index index.html; location / { try_files $uri $uri/ 404; } {% if nginx_upstream_servers %} location /api/ { proxy_pass http://backend/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } {% endif %} }这个角色有几个设计亮点notify触发reload nginx处理器只有配置文件变化时才重载服务避免无谓的重启nginx_upstream_servers默认为空列表模板里用{% if %}判断没有上游时就不生成 upstream 块nginx_worker_processes默认auto让 Nginx 自己根据 CPU 核数决定。4.4 用 site.yml 编排完整部署有了common和nginx两个角色就可以写入口 playbook 了- name: 基础环境初始化 hosts: all roles: - common - name: 部署 Web 服务器 hosts: webservers roles: - nginx - name: 部署数据库服务器 hosts: dbservers roles: - mysql - name: 部署监控服务器 hosts: monitoring roles: - monitoring执行的时候ansible-playbook site.yml如果想只跑 Web 服务器部分ansible-playbook site.yml --limit webservers如果想临时覆盖某个变量ansible-playbook site.yml -e nginx_port8080这种编排方式的好处是整个环境的部署逻辑一目了然哪个角色跑在哪些机器上清清楚楚。新人接手时看site.yml就知道整个系统由哪些部分组成。4.5 参数计算与选择过程在实际部署中有些参数需要根据机器规格计算不能拍脑袋定。比如 Nginx 的worker_connections和worker_processes直接关系到能承载多少并发。worker_processes一般设为 CPU 核数auto就是让 Nginx 自动检测。worker_connections表示每个 worker 能处理的最大连接数理论最大并发 worker_processes × worker_connections。但实际能承载的并发还受限于系统文件描述符限制、内存等因素。假设一台机器 4 核 8Gworker_processes设为 4worker_connections设为 1024理论最大并发 4096。但如果系统ulimit -n只有 1024那实际每个 worker 只能处理 1024 个连接包括和上游服务器的连接。所以还需要调整系统限制- name: 调整文件描述符限制 pam_limits: domain: {{ nginx_user }} limit_type: soft limit_item: nofile value: 65535 - name: 调整系统级文件描述符限制 sysctl: name: fs.file-max value: 1000000 state: present reload: yes这种应用参数 系统参数配套调整的思路在企业部署中很常见。只改 Nginx 配置不改系统限制等于白改。5. 常见问题与排查技巧实录5.1 变量不生效的排查思路变量问题是 Ansible 使用中最常见的困扰。明明定义了变量跑起来却不是预期的值。我的排查步骤是这样的第一步确认变量定义的位置和优先级。用ansible-inventory --list查看 inventory 层面的变量用ansible-playbook --list-tasks确认任务列表用-e临时覆盖测试。第二步在 playbook 里加调试任务- name: 调试变量 debug: var: nginx_port verbosity: 0debug模块会打印变量的实际值配合verbosity控制输出级别。如果变量是嵌套字典可以用debug: msg{{ nginx_config | to_nice_json }}格式化输出。第三步检查变量名拼写。Ansible 对变量名大小写敏感nginx_port和nginx_Port是两个不同的变量。我建议统一用小写加下划线避免这类问题。第四步检查变量作用域。role defaults里的变量在角色外部默认不可见如果要在 playbook 层面引用需要用vars或set_fact提升作用域。避坑技巧在ansible.cfg里设置inject_facts_as_vars False避免 facts 变量和自定义变量冲突。同时养成习惯自定义变量统一加前缀比如app_、nginx_、mysql_。5.2 任务执行失败的常见原因Ansible 任务失败的原因五花八门但归纳起来无非几类失败现象常见原因排查方法SSH 连接超时网络不通、防火墙拦截、SSH 端口非默认ansible host -m ping -vvv看详细日志权限拒绝become 配置错误、sudo 需要密码检查ansible.cfg的 become 配置确认 sudoers模块不存在目标机器 Python 版本过低检查ansible_python_interpreter设置包安装失败源不可用、包名错误手动在目标机器执行安装命令验证模板渲染失败变量未定义、Jinja2 语法错误用--check模式预演看具体报错行服务启动失败配置文件语法错误、端口被占用查看服务日志用nginx -t等命令验证配置我特别想说的是--check模式。这个模式让 Ansible 只报告会做什么不实际执行。在改完 playbook 准备上生产之前先跑一遍--check能提前发现大部分问题ansible-playbook site.yml --check --diff--diff会显示文件内容的变化对于模板渲染特别有用。你能看到改之前和改之后配置文件的具体差异确认无误再真正执行。5.3 性能优化让大批量执行更快当机器数量上百台时Ansible 的默认配置会显得慢。优化手段主要有几个开启 SSH 长连接。在ansible.cfg里配置[ssh_connection] pipelining True ssh_args -o ControlMasterauto -o ControlPersist60spipelining减少 SSH 连接次数ControlPersist复用 SSH 连接。这两个参数配合使用执行速度能提升好几倍。调整 forks 数量。forks控制并行执行的主机数默认是 5。机器多的时候可以调大[defaults] forks 50但不要调得太大否则控制机的 CPU 和网络会成为瓶颈。一般设为控制机 CPU 核数的 2-4 倍比较合适。使用strategy: free。默认的linear策略是等所有主机完成一个任务再开始下一个free策略让每台主机独立推进快的主机不用等慢的- hosts: all strategy: free tasks: - ...减少 facts 收集。如果 playbook 不需要 facts可以关闭- hosts: all gather_facts: no或者只收集需要的部分- hosts: all gather_subset: - !all - !min - network5.4 敏感信息管理别把密码写在 playbook 里企业环境里数据库密码、API 密钥这类敏感信息绝对不能明文写在 playbook 或变量文件里。Ansible 提供了ansible-vault来加密敏感文件。基本用法# 创建加密文件 ansible-vault create group_vars/prod/vault.yml # 编辑加密文件 ansible-vault edit group_vars/prod/vault.yml # 加密已有文件 ansible-vault encrypt group_vars/prod/secrets.yml # 执行时提供密码 ansible-playbook site.yml --ask-vault-pass # 或者用密码文件 ansible-playbook site.yml --vault-password-file ~/.vault_pass加密文件的内容可以是任意 YAMLvault_db_password: 实际密码 vault_api_key: 实际密钥然后在普通变量文件里引用app_db_password: {{ vault_db_password }}这样敏感信息只在加密文件里出现普通变量文件可以放心提交到代码仓库。密码文件~/.vault_pass要设置权限600并且加入.gitignore。实操心得vault 密码一旦丢失加密文件就无法恢复。建议把密码文件备份到安全的地方或者用密码管理器管理。团队协作时可以通过 CI/CD 系统的密钥管理功能注入 vault 密码避免人工传递。6. 从能跑到好用我的几点实战体会写了这么多最后聊几点我在实际工作中积累的体会都是踩过坑之后才明白的。第一playbook 是代码要用写代码的态度对待。版本控制、代码审查、命名规范、注释这些软件工程的实践同样适用于 Ansible。我见过太多团队把 playbook 当脚本写改完直接在生产上跑出了问题再回滚。这种模式在机器少的时候还能应付规模上来之后必然出事。第二先在小范围验证再全量执行。Ansible 的--limit参数可以指定只对部分主机执行新写的 playbook 先拿一台机器试确认没问题再扩大范围。这个习惯能避免一个手误搞挂整个集群的悲剧。第三日志和审计不能少。在ansible.cfg里配置log_path所有执行记录都会保存下来。出问题的时候翻日志比凭记忆靠谱得多。另外关键操作可以配合--step参数逐步确认或者用--start-at-task从指定任务开始执行。第四不要追求一步到位。自动化是一个渐进的过程先把最频繁、最重复的操作自动化再逐步扩展。一上来就想把所有运维工作都塞进 Ansible往往会因为复杂度太高而半途而废。我自己的节奏是先自动化部署再自动化配置管理最后自动化巡检和告警。第五文档和注释是给未来的自己看的。三个月后你回头看自己写的 playbook如果没有注释很可能想不起来当时为什么这么设计。在角色目录下放一个README.md说明角色的用途、依赖、变量含义这个投入绝对值得。这套东西说到底核心就一句话把运维知识固化成代码让机器去执行让人去思考。Ansible 只是工具真正有价值的是你对系统的理解和把理解转化为自动化逻辑的能力。工具会变这个能力不会。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑