Ansible速查手册
Ansible playbook/模块/变量/命令速查
📃 inventory 主机清单
最常用格式;中括号定义分组,支持编号范围。
# hosts.ini
web[1:3].example.com
[web]
10.0.0.11 ansible_user=root
10.0.0.12 ansible_user=deploy ansible_port=2200
[db]
db1.example.com
db2.example.com ansible_host=10.0.1.20
[prod:children]
web
db
主机级写在行尾,组级在 [组名:vars];目录方式放 group_vars/host_vars 自动加载。
[web:vars]
http_port=80
ansible_python_interpreter=/usr/bin/python3
# 目录结构(与 playbook 同级)
# inventories/prod/
# ├── hosts
# ├── group_vars/
# │ ├── all.yml # 所有主机
# │ └── web.yml # web 组
# └── host_vars/
# └── web1.example.com.yml
YAML 结构更适合嵌套变量;ansible.cfg 设置默认行为。
# hosts.yml
all:
vars:
ansible_user: root
children:
web:
hosts:
web1.example.com:
web2:
ansible_host: 10.0.0.12
db:
hosts:
db1.example.com:
# ansible.cfg
[defaults]
inventory = ./hosts.ini
host_key_checking = False
forks = 20
remote_user = root
📘 playbook 结构
一个 YAML 文件由一个或多个 play 组成,每个 play 含 tasks。
---
- name: 部署 Nginx
hosts: web
become: true
vars:
http_port: 80
tasks:
- name: 安装 nginx
yum:
name: nginx
state: present
- name: 启动并设开机自启
service:
name: nginx
state: started
enabled: true
提权、收集事实、并发滚动、标签等在 play 级别控制。
- hosts: web
become: true
become_user: root
gather_facts: true # false 可加速
serial: 2 # 每批滚动 2 台
max_fail_percentage: 20
any_errors_fatal: false
tags: [web]
vars_files:
- vars/common.yml
pre_tasks:
- name: 更新时间检查
debug:
msg: "开始于 {{ ansible_date_time.iso8601 }}"
roles: [common, nginx]
post_tasks: []
📦 包与文件模块
按系统选择;state 决定 present/latest/absent。
- name: CentOS 安装软件
yum:
name:
- nginx
- vim
state: present
update_cache: no
- name: Ubuntu 安装最新版
apt:
name: ['nginx', 'curl']
state: latest
update_cache: yes
cache_valid_time: 3600
- name: 卸载
yum: { name: httpd, state: absent }
内容不变幂等;content 直接写小文件,backup 保留备份。
- name: 拷贝配置文件
copy:
src: files/nginx.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
backup: yes
validate: 'nginx -t -c %s'
- name: 直接写内容
copy:
dest: /etc/motd
content: |
欢迎使用生产服务器
请勿随意重启
mode: '0644'
.j2 文件支持变量与循环;变化后通常 notify 重启服务。
- name: 渲染虚拟主机配置
template:
src: vhost.conf.j2
dest: /etc/nginx/conf.d/{{ site_name }}.conf
owner: root
mode: '0644'
notify: restart nginx
state: directory/file/link/touch/absent。
- name: 创建目录
file:
path: /data/logs
state: directory
owner: www
group: www
mode: '0755'
- name: 创建软链接
file:
src: /data/app/current
dest: /opt/app
state: link
- name: 删除文件或目录
file: { path: /tmp/old, state: absent }
- name: 只改权限(已存在文件)
file: { path: /opt/run.sh, mode: '0755' }
get_url 下载校验,unarchive 解压,lineinfile 改单行,blockinfile 改整段。
- get_url:
url: https://example.com/app.tar.gz
dest: /tmp/app.tar.gz
checksum: sha256:abcd1234
- unarchive:
src: /tmp/app.tar.gz
dest: /opt/
remote_src: yes
creates: /opt/app/bin
- git: { repo: 'https://github.com/x/y.git', dest: /srv/y, version: main }
- lineinfile:
path: /etc/ssh/sshd_config
regexp: '^#?PermitRootLogin'
line: 'PermitRootLogin no'
notify: restart sshd
🛎 服务与命令执行
started/stopped/reloaded/restarted;enabled 控制开机自启。
- service:
name: nginx
state: started
enabled: yes
- systemd:
name: docker
state: reloaded
daemon_reload: yes
enabled: yes
不经过 shell,管道重定向无效;creates/removes 实现幂等。
- name: 执行初始化脚本
command: /opt/app/bin/init.sh
args:
creates: /var/lib/app/init.done
- command: make install
args:
chdir: /usr/local/src/app
creates: /usr/local/bin/app
- command: /usr/bin/uptime
register: up
changed_when: false
- debug: { var: up.stdout }
需要 | > && 变量展开时才用 shell,注意注入与幂等。
- name: 管道操作
shell: "ss -tlnp | grep :8080 || true"
register: port
changed_when: false
- name: 带环境变量
shell: "./deploy.sh"
args:
chdir: /opt/app
executable: /bin/bash
environment:
APP_ENV: prod
# 有专用模块时不要用 shell(yum/copy/file/service 等)
🐞 debug 与 assert
msg 输出文本,var 直接打印变量(含结构)。
- debug:
msg: "系统 {{ ansible_distribution }} {{ ansible_distribution_version }}"
- debug:
var: ansible_default_ipv4.address
- debug:
msg: "主机名={{ inventory_hostname }}, IP={{ ansible_host | default('未设置') }}"
verbosity: 1
关键操作前校验变量/系统状态,失败即中止。
- name: 确认系统与磁盘
assert:
that:
- ansible_distribution in ['CentOS', 'RedHat', 'Rocky']
- ansible_devices is defined
- min_disk_gb | int >= 20
fail_msg: "系统或磁盘不满足要求"
success_msg: "检查通过"
- name: 立即失败
fail:
msg: "该 playbook 不支持在 {{ ansible_distribution }} 运行"
when: ansible_distribution == 'Windows'
🔔 handlers 处理器
被 notify 的 handler 在本批 task 结束后统一执行,且只执行一次。
- name: 修改 nginx 配置
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify:
- test nginx
- restart nginx
handlers:
- name: test nginx
command: nginx -t
- name: restart nginx
service:
name: nginx
state: restarted
# 立即执行 handlers(不等到末尾):- meta: flush_handlers
🔡 变量
常见:role defaults(最低)< group_vars < host_vars < vars < 命令行 -e(最高)。
vars:
app_name: demo
ports: [80, 443]
cfg:
host: 127.0.0.1
port: 3306
vars_files:
- vars/secrets.yml
- name: 引用
debug:
msg: "{{ app_name }} {{ cfg.host }}:{{ cfg.port }} {{ ports[0] }}"
# 命令行优先级最高
# ansible-playbook site.yml -e "app_name=test" -e @extra.yml
register 保存命令输出;set_fact 在运行中动态设变量。
- command: id deploy
register: deploy_user
ignore_errors: true
- name: 不存在则创建用户
user: { name: deploy }
when: deploy_user.rc != 0
- set_fact:
deploy_dir: "/opt/{{ app_name }}/{{ ansible_date_time.date }}"
- debug: { var: deploy_dir }
default 给默认值,to_json/yaml 序列化,regex_replace 正则替换。
{{ var | default('fallback') }}
{{ var | default([]) | length }}
{{ list | join(',') }}
{{ "hello" | upper }}
{{ cfg | to_nice_json }}
{{ obj | to_yaml }}
{{ "127.0.0.1" | ipaddr }}
{{ path | basename }} / {{ path | dirname }}
{{ cmd_out.stdout_lines | first }}
{{ version is version('2.0', '>=') }}
{{ password | password_hash('sha512') }}
{{ ['a','b'] | map('upper') | list }}
📐 Jinja2 模板
{{ }} 输出值,{% %} 写控制语句,{# #} 注释。
server {
listen {{ http_port | default(80) }};
server_name {{ site_name }};
{# 仅在 HTTPS 时输出 #}
{% if enable_ssl %}
ssl_certificate /etc/ssl/{{ site_name }}.pem;
ssl_certificate_key /etc/ssl/{{ site_name }}.key;
{% endif %}
}
for 遍历列表/字典;groups 是内置的 inventory 分组变量。
upstream backend {
{% for host in groups['web'] %}
server {{ hostvars[host].ansible_host | default(host) }}:8080;
{% endfor %}
}
{% for k, v in cfg.items() %}
# {{ k }} = {{ v }}
{% else %}
# cfg 为空
{% endfor %}
{% set timeout = 30 %}
proxy_read_timeout {{ timeout }}s;
🔀 when / loop / block
when 是裸 Jinja 表达式(不要套 {{ }});and/or/not 组合。
- yum: { name: httpd }
when: ansible_os_family == "RedHat"
- apt: { name: apache2 }
when: ansible_os_family == "Debian"
- debug: { msg: "高内存主机" }
when:
- ansible_memtotal_mb >= 4096
- ansible_distribution in ['CentOS', 'Rocky']
- file: { path: /tmp/old, state: absent }
when: force_clean | default(false) | bool
替代老式 with_items;item 是当前元素,支持字典与 register 聚合。
- name: 安装多个包
yum: { name: "{{ item }}", state: present }
loop: [nginx, vim, curl, git]
- name: 创建多个用户
user:
name: "{{ item.name }}"
groups: "{{ item.groups }}"
loop:
- { name: 'alice', groups: 'wheel' }
- { name: 'bob', groups: 'docker' }
- name: 遍历字典
debug: { msg: "{{ item.key }}={{ item.value }}" }
loop: "{{ cfg | dict2items }}"
rescue 捕获块内失败,always 必执行;block 上还能统一加 when。
- block:
- name: 尝试主路径发布
command: /opt/deploy.sh
rescue:
- name: 回滚
command: /opt/rollback.sh
- debug: { msg: "已回滚" }
always:
- name: 通知结束
debug: { msg: "流程结束" }
when: ansible_os_family == "RedHat"
🎭 roles 与复用
约定优于配置,tasks/handlers/templates/files/vars/defaults 自动加载。
# roles/nginx/
# ├── tasks/main.yml 入口任务
# ├── handlers/main.yml
# ├── templates/nginx.conf.j2
# ├── files/index.html
# ├── vars/main.yml 高优先级变量
# ├── defaults/main.yml 默认变量(最低优先级)
# └── meta/main.yml 依赖信息
- hosts: web
become: true
roles:
- common
- { role: nginx, tags: ['web'], when: ansible_os_family == 'RedHat' }
import 静态(解析期展开),include 动态(运行时决定)。
- import_playbook: init.yml
- import_playbook: deploy.yml
tasks:
- import_tasks: tasks/redhat.yml
when: ansible_os_family == 'RedHat'
- include_tasks: tasks/{{ ansible_os_family | lower }}.yml
- include_role:
name: nginx
tags: [nginx]
⌨️ 常用命令
不写 playbook 直接跑模块:-m 指定模块,-a 传参数。
ansible all -m ping -i hosts.ini
ansible web -m setup -i hosts.ini # 收集系统事实
ansible web -m shell -a "uptime" -i hosts.ini
ansible web -m yum -a "name=vim state=present" --become
ansible web -m copy -a "src=a.conf dest=/etc/a.conf"
ansible web -m file -a "path=/data state=directory mode=0755"
-i 清单、-l 限定主机、-t 标签、--check 演练。
ansible-playbook site.yml -i hosts.ini
ansible-playbook site.yml -l web1.example.com
ansible-playbook site.yml -l web -t nginx
ansible-playbook site.yml --skip-tags slow
ansible-playbook site.yml --check --diff
ansible-playbook site.yml -u root -k -K
ansible-playbook site.yml --syntax-check
ansible-playbook site.yml --list-tasks
ansible-playbook site.yml -e "env=prod" --start-at-task="安装 nginx"
ansible-playbook site.yml -f 30 # 并发数
敏感变量用 vault 加密;galaxy 安装社区角色/集合。
ansible-vault create secret.yml
ansible-vault encrypt vars/prod.yml
ansible-vault edit vars/prod.yml
ansible-vault decrypt vars/prod.yml
ansible-vault view vars/prod.yml
ansible-vault rekey vars/prod.yml
ansible-playbook site.yml --ask-vault-pass
ansible-playbook site.yml --vault-password-file ~/.vault.pass
ansible-galaxy install geerlingguy.nginx
ansible-galaxy install -r requirements.yml
ansible-galaxy collection install community.general
😶 没有匹配的条目,换个关键词试试
📖 使用说明
全程在浏览器本地运行。
操作步骤:
- 搜索或浏览分类条目;
- 查看YAML示例;
- 点击复制代码块。
💬 用户评论 (0)
还没有评论,快来抢沙发!