ansible-必知必会

Ansible 101 Getting Started. Ansible is an agentless automation that… | by  Winton Huang | Medium

中文文档

原理

Ansible的名字来自小说<安德的游戏>是一个跨越时空的通讯工具

Ansible本质上只是一个框架,用python开发,实际通过它的库实现功能,其中有三个关键库:

  • Paramiko: Python对ssh的实现
  • PyYaml: 解析和生成yaml
  • jinjia2: 用于模板的生成,在使用 template 模块自动生成文件时特别有用

特性:

  • 基于python和ssh,无需agent
  • 安全,基于openssh
  • 幂等: 一个任务执行一遍和执行n遍效果一样,不会因重复执行而带来意料之外的效果

安装使用

1
2
yum -y install epel-release
yum -y install ansible

配置ssh –> 定义inventory –> 执行ansible命令/执行playbook

Inventory

Ansible管理的主机清单配置文件, 默认地址: /etc/ansible/hosts

ansible可以同时操作一个组的多台主机

组和主机之间的关系通过inventory文件配置

可以同时使用多个inventory文件

INI格式

也支持yaml格式, 个人觉得ini更清晰易读.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 单个主机
server1.example.com

# 主机组 'web' 下的主机
[web]
server2.example.com
server3.example.com

# 范围指定的主机
[database]
db[01:10].example.com

# 使用端口和变量的主机定义
[loadbalancer]
lb.example.com:8080 ansible_connection=ssh ansible_ssh_user=myuser

定义属于整个组的变量

1
2
3
4
5
6
7
[atlanta]
host1
host2

[atlanta:vars]
ntp_server=ntp.atlanta.example.com
proxy=proxy.atlanta.example.com

把一个组作为另一个组的子成员

1
2
3
4
5
6
7
8
9
10
11
12
[webservers]
web1.example.com
web2.example.com

[dbservers]
db1.example.com
db2.example.com

# 使用children关键字定义linux父组下有webservers和dbservers子组
[linux:children]
webservers
dbservers

分文件保存变量

ansible>1.4才有的功能

在inventory文件中保存所有变量并不是最佳实践,以独立文件的方式保存是更优选择.这些文件应该使用yaml格式配置.

假设有一个主机名为: football, 它同时属于两个组: foobar,那么以下配置文件中的变量都可以为它所用

1
2
3
4
5
# /etc/ansible/group_vars/<group_name>
# /etc/ansible/host_vars/<hostname_name>
/etc/ansible/group_vars/foo
/etc/ansible/group_vars/bar
/etc/ansible/host_vars/football

另外,还可以为一个主机一个组创建一个以主机名或组名命名的目录,目录中创建多个文件,目录中的文件的变量都会被读取为主机或组的变量.

1
2
3
# /etc/ansible/group_vars/<group_name>/<any_file_name>
/etc/ansible/group_vars/raleigh/db_settings
/etc/ansible/group_vars/raleigh/cluster_settings
  • Tip1: ansible1.2+,group_varshost_vars可以放在inventory目录下/etc/ansible/hosts或是playbook目录下,其中palybook优先级更高.
  • Tips: 把inventory文件和变量文件都放入git中管理,是推荐做法

inventory参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ansible_ssh_host #将要连接的远程主机名.与你想要设定的主机的别名不同的话,可通过此变量设置.

ansible_ssh_port #ssh端口号.如果不是默认的端口号,通过此变量设置.

ansible_ssh_user #默认的 ssh 用户名

ansible_ssh_pass #ssh 密码(这种方式并不安全,我们强烈建议使用 --ask-pass 或 SSH 密钥)

ansible_sudo_pass # sudo 密码(这种方式并不安全,我们强烈建议使用 --ask-sudo-pass)

ansible_sudo_exe (new in version 1.8) #sudo 命令路径(适用于1.8及以上版本)

ansible_connection #与主机的连接类型.比如:local, ssh 或者 paramiko. Ansible 1.2 以前默认使用 paramiko.1.2 以后默认使用 'smart','smart' 方式会根据是否支持 ControlPersist, 来判断'ssh' 方式是否可行.

ansible_ssh_private_key_file #ssh 使用的私钥文件.适用于有多个密钥,而你不想使用 SSH 代理的情况.

ansible_shell_type #目标系统的shell类型.默认情况下,命令的执行使用 'sh' 语法,可设置为 'csh' 或 'fish'.

ansible_python_interpreter # 目标主机的 python 路径.适用于的情况: 系统中有多个 Python, 或者命令路径不是"/usr/bin/python",比如 \*BSD, 或者 /usr/bin/python
# 不是 2.X 版本的 Python.我们不使用 "/usr/bin/env" 机制,因为这要求远程用户的路径设置正确,且要求 "python" 可执行程序名不可为 python以外的名字(实际有可能名为python26).

ansible_[ruby|perl]_interpreter
# 与 ansible_python_interpreter 的工作方式相同,可设定如 ruby 或 perl 的路径....

一个配置例子

1
2
3
4
some_host         ansible_ssh_port=2222     ansible_ssh_user=manager
aws_host ansible_ssh_private_key_file=/home/example/.ssh/aws.pem
freebsd_host ansible_python_interpreter=/usr/local/bin/python
ruby_module_host ansible_ruby_interpreter=/usr/bin/ruby.1.9.3

动态Inventory

动态生成或发现目标主机的清单,并不是预先固定写在一个静态文件里面.允许ansible与云服务提供商,虚拟化平台或其他API驱动的服务集成,从而实时获取和更新主机信息.也可以收用kubernetes模块与k8s集群集成.

Ansible ad-hoc命令

其实就是命令行执行ansible命令

1
2
3
4
5
6
7
8
9
10
11
12
ansible --help
-a MODULE_ARGS
-C #dry run模式,测试
-f FORK #ansible一般用来管控多台主机,此选项定义ansible分批发送管控请求,一次多少台
--list-hosts #列出本次操作会对哪些主机执行,不真正执行
--syntax-check #语法检查
-t TREE #将日志输出到指定目录
-u UESERNAME #指明使用哪个用户名连接目标主机
-b,--become #sudo切换root
--become-user=USERNAME #指定sudo的runas用户,默认root
-K #提示输入sudo时的口令
-k #提示输入ssh连接密码

用法

1
ansible HOST-PATTERN -m MOD_NAME -a MOD_ARGS -f FORKS

Pattern

PATTERN是指如何指定要操作的主机,可以是主机名,也可以是组名,除此以为还有很多高级写法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# invertory内的所有主机
all
*
# IP或多个主机名(":"分割),支持"*"通配
one.example.com
one.example.com:two.example.com
192.168.1.50
192.168.1.*
# 多个组(":"分割)
webservers:dbservers
# 组排队
webservers:!phoenix # 执行的主机必须隶属webservers组但同时不在phoenix组
webservers:dbservers:&staging:!phoenix # ‘webservers’ 和 ‘dbservers’ 两个组中隶属于 ‘staging’ 组并且不属于 ‘phoenix’ 组的机器才执行命令
# 还可以通过-e传变量
webservers:!{{excluded}}:&{{required}}
# 组编号选主机
webservers[0]
webservers[0-25]
# 支持通配和正则,通配何以和组混用
one*.com:dbservers
~(web|db).*\.example\.com
# --limit排除目标
ansible-playbook site.yml --limit datacenter2
# ansible1.2后支持从文件读取hosts,使用"@"
ansible-playbook site.yml --limit @retry_hosts.txt

支持与或非:

  • :&: 与
  • :: 或
  • :!: 非

模块

-m指定使用的模块,-a指定模块参数.ansible的具体功能都由这些模块提供.下面列举一些常用模块和常用参数.

1
2
ansible-doc -l #列出可用模块
ansible-doc -s MOD_NAME #列出模块可用参数和playbook片段

group

创建删除组

args:

  • gid

  • *name: 自定义组名

  • state

    • present: 存在,即创建
    • absent: 不存在,即删除
  • system: 是否创建系统用户组

    • yes
    • no
    1
    ansible all -m group -a "gid=3000 name=mygrp state=present system=no"

user

创建删除用户

args:

  • *name

  • uid

  • groups

  • home

  • state=present | absent

  • system=yes | no

  • move_home=yes | no

    如果系统已存在该用户,但ansible又创建了一遍,两次定义的家目录路径不一致,是否移动家目录到新位置

  • generate_ssh_key=yes | no

    是否为用户自动创建ssh密钥,如果原来就有了,不会覆盖原来的,而是创建新的

    1
    ansible all -m user -a "uid=5000 name=testuser state=present groups=mygrp shell=/bin/tcsh"

copy

以并行的方式同时 SCP 大量的文件到多台机器

args:

  • *dest: 目标路径

  • *src:源路径,支持相对/绝对地址

    源是目录,默认会递归复制

    源以”/“结尾,只复制目录内的内容

    源不以”/“结尾,则把目录本身也复制过去

  • owner: 属主

  • group: 属组

  • mode: 权限

  • remote_src: 从远程源复制到主机

    1
    2
    3
    ansible all -m copy -a "src=/etc/fstab dest=/tmp/fstab.ansible mode=600"
    ansible all -m copy -a "src=/etc/pam.d/ dest=/tmp/"
    ansible all -m copy -a "content='hi there\n' dest=/tmp/hi.txt"

fetch

从远端复制文件到本机

file

创建或删除文件/目录

  • state=present | absent | directory | file | link

    1
    2
    3
    ansible all -m file -a "path=/var/tmp/hello.txt state=directory"
    ansible all -m file -a "path=/var/tmp/hello.txt state=file"
    ansible all -m file -a "src=/var/tmp/hello.txt path=/var/tmp/fstab.link state=link" #创建软链文件

command

执行给定的命令,但不会使用目标主机shell环境,因此不支持shell特有的语法和通配符.

command模块不是幂等的,重复执行会失败.

比如你用command模块创建文件夹,多次执行,就会失败.command模块有相关的参数比如createremove去处理这种情况.

当然也可以选择其他幂等的module去处理有不幂等风险的操作.

  • chdir: 切换工作目录

  • executable: 切换执行程序的shell,要使用绝对路径

  • free_from: 自由格式(命令直接给出没不需要kv格式)

    1
    2
    3
    ansible all -m command -a "ifconfig"
    ansible all -m command -a "chdir=/var/tmp mkdir hi.dir"
    ansible all -m command -a "echo mageedu | passwd --stdin testuser" # 执行失败

shell

使用目标主机的shell环境执行命令,这意味着它支持管道,通配,重定向等shell特有的操作,以及可以使用环境变量.

1
ansible all -m shell -a "echo mageedu | passwd --stdin testuser" # 用shell就会成功

cron

设定周期性任务,实际上就是操作目标主机的crontab

  • name: 指定任务名称, 默认为none

  • day

  • hour

  • job

  • state=present | absent

    1
    2
    ansible all -m cron -a "minute=*/3 job='/usr/sbin/update 172.16.0.1 &> /dev/null'"
    ansible all -m cron -a "minute=*/3 job='/usr/sbin/update 172.16.0.1 &> /dev/null' name=None state=absent"

yum/dnf

包管理程序

一般redhat 8及以上使用dnf

redhat 8以下使用yum

  • *name: 包名

  • state=present | installed | latest | absent | removed

  • disable_gpg_check

  • disablerepo

    1
    ansible all -m yum -a "name=nginx state=installed"

service

通用的服务管理模块,它会检测系统使用的是哪一种服务管理方式(sysvinit, upstart, systemd等),并尝试用正确的方式来广利服务.

当然,针对不同的服务管理方式,ansible都有对应模块,如果不清楚,或者通用功能就行,就使用service就好了

  • *name: 服务名

  • pattern: 如果服务不支持status命令,可以使用pattern过滤字符以获取运行状态

  • runlevel: 设定启动等级

  • enabled: 开机自启动

  • state=started | stopped

    1
    ansible all -m service -a "name=nginx state=started"

script

复制本地脚本到目标主机运行,不幂等

  • chdir: 切换目标主机的工作目录

  • cmd: 要使用的本地脚本的路径, 后面可以跟参数

    1
    ansible all -m script -a "/tmp/test.sh"

配置文件

/etc/ansible/ansible.cfg

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[defaults]
#inventory = /etc/ansible/hosts # 主机列表配置文件
#library = /usr/share/my_modules/ # 库文件存放目录
#remote_tmp = $HOME/.ansible/tmp # 临时py命令文件存放在远程主机目录
#local_tmp = $HOME/.ansible/tmp # 本机的临时命令执行目录
#forks = 5 # 默认并发数,同时可以执行5次
#sudo_user = root # 默认sudo 用户
#ask_sudo_pass = True # 每次执行ansible命令是否询问ssh密码
#ask_pass = True # 每次执行ansible命令是否询问ssh口令
#remote_port = 22 # 远程主机的端口号(默认22)

#建议优化项:

host_key_checking = False # 检查对应服务器的host_key,建议取消注释
log_path=/var/log/ansible.log # 日志文件,建议取消注释
module_name = command # 默认模块

ansible命令执行过程

  1. 加载配置文件/etc/ansible/ansible.cfg
  2. 加载自己对应的模块文件
  3. 通过ansible将模块命令生成临时的py文件
    1. 并将该文件传输到目标主机对应执行用户的$HOME/.ansible/tmp/ansible-tmp-数字/XXX.py
  4. 给文件+x
  5. 执行并返回结果
  6. 删除临时py文件, sleep 0 退出

执行结果:

  • 绿色: 成功应用变更

  • 黄色: 成功但无变更

  • 红色: 失败

ansible-playbook

ad-hoc与playbook就类似shell命令与shell脚本的关系.

playbook使用yaml编写.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
- name: Enhanced Playbook Example # playbook name
hosts: web_servers # inventory pattern
become: yes # 用于权限提升或用户切换
become_method: sudo # 指定权限提升或用户切换的具体方式
remote_user: admin # 定义执行远程任务的用户帐户。当 Ansible 与远程主机建立连接时,它将使用这个用户的身份来登录
tasks: # 任务列表
- name: Install Apache # task name
yum: # 使用的模块
name: httpd # 模块参数
state: present
notify: # notify是handlers的触发标志
- Restart Apache # 触发哪个handlers
tags: # 标签,可以根据标签指定运行或跳过运行某个或某些task
- installation

- name: Copy Apache Configuration File
copy:
src: /path/to/conf/httpd.conf
dest: /etc/httpd/conf/httpd.conf
notify:
- Restart Apache
tags:
- configuration

handlers: # 定义handlers任务列表
- name: Restart Apache
service:
name: httpd
state: restarted
tags:
- handlers

其实就是命令调用模块改为yaml写法.

notify和handlers

notify是触发器,handlers是响应器.

如果notify所在的task没有触发变更,notify所定义的handler也不会被触发

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
---
- name: 确保 web 服务正确运行
hosts: web_servers
become: true
tasks:
- name: 将配置文件拷贝到远程服务器
copy:
src: /src/webserver.conf
dest: /etc/webserver.conf
notify:
- 重启 web 服务

handlers:
- name: 重启 web 服务
service:
name: webserver
state: restarted

tags

1
2
3
4
# 指执行有这个tag的任务
ansible-playbook install_apache.yml --tags "configuration"
# 跳过执行有这个tag的任务
ansible-playbook install_apache.yml --skip-tags "configuration"

常用参数

1
2
3
4
5
6
-C #dry run
--syntax-check #语法检查
-t #指定调用对应标签的任务
--list-hosts
--list-tags
--list-tasks

Variables

vars定义变量,{{var_name}}调用变量

Fact

ansible的setup模块获取的主机自带的系统信息

1
2
3
4
5
6
7
yum -y install facter
# 获取本机的系统信息,setup模块获取的也就是这些信息
facter -p
# 查看setup模块参数
ansible-doc -s setup
# 获取facts并通过filter参数过滤想要的fact
ansible all -i inventory.ini -m setup -a 'filter=ansible_*_mb'

这种类型的变量直接调用即可.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- name: Collect only certain facts
hosts: all
tasks:
- name: Gather only memory related facts
setup: # 通过setup模块获取fact
filter: ansible_*_mb # 过滤fact
- name: Print out the total memory
debug: # debug模块用于打印或调试信息,它主要用于输出变量的值来帮助理解和调试 playbook 的执行流程。`debug`可以用来输出字符串信息,也可以用来展示`register`所捕获的变量内容。
msg: "Total memory on this machine is {{ ansible_memtotal_mb }} MB" # 直接使用fact变量

- name: Check if a directory exists
ansible.builtin.stat: # Ansible 中的一个内置模块,它用于获取文件或文件夹在远程主机上的状态信息。这些信息包括文件的存在性、类型、大小、权限、所属用户、所属组、最后修改时间等。
path: "/a/specific/path"
register: result # register关键词用于捕获任务执行的输出结果,例如命令执行的输出,模块执行的详细结果等。通过`register`保存的结果可以被后续的任务使用,像条件判断、循环迭代等。

- name: Display results if directory exists
debug:
msg: "The directory exists!"
when: result.stat.exists

用户自定义

  1. 命令行定义

    1
    ansible-playbook -e pkgname=memcached test.yaml
  2. playbook中定义

    1
    2
    3
    vars:
    - var1: value1
    - var2: value2

通过roles传递

通过 Invertory传递

前面有说过Invertory文件可以定义变量,但是要注意跟inventory参数的区分

template模块

主要用来动态生成配置文件.

用于基于Jinja2模板语言处理模板文件。Jinja2模板中可以包含变量和表达式,这些变量将在Ansible运行时根据具体的上下文环境进行替换。template 模块主要用于生成配置文件或其他类型的文本文件,并且将这些文件复制到远程主机上.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
- name: Configure nginx
hosts: webservers
vars: # playbook定义的变量,会被使用到模板上
http_port: 80
max_clients: 200

tasks:
- name: Create nginx configuration file from template
template:
src: /srv/http/nginx.conf.j2 # 要使用的jinja2模板
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'

task高级用法

条件测试

关键字: when

1
2
3
4
5
6
7
tasks:
- name: install conf file to centos7
template: src=files/nginx.conf.c7.j2
when: ansible_distribution_major_version == "7" # when语句为true则执行
- name: install conf file to centos6
template: src=files/nginx.conf.c6.j2
when: ansible_distribution_major_version == "6"

迭代循环

关键字:

  • 旧版本: item, with_item

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    - name: install some packages
    yum: name={{ item }} state=present
    with_items:
    - nginx
    - memcached
    - php-fpm
    - name: add some groups
    group: name={{ item }} state=present
    with_items:
    - group1
    - group2
    - name: add some users
    user: name={{ item.name }} group={{ item.group }} state=present
    with_items:
    - { name: 'user1', group: 'group1' }
    - { name: 'user2', group: 'group2' }
  • 新版本: loop,item

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    # 基本迭代,迭代列表的每一项
    - name: Add several users
    ansible.builtin.user:
    name: "{{ item }}"
    state: present
    groups: "wheel"
    loop:
    - testuser1
    - testuser2
    - testuser3
    ---
    # 迭代字典
    - name: Ensure several users have specific properties
    ansible.builtin.user:
    name: "{{ item.key }}"
    state: present
    groups: "{{ item.value.groups }}"
    uid: "{{ item.value.uid }}"
    loop: "{{ users | dict2items }}" # dict2items过滤器将字典转换为项列表
    vars:
    users: # dict name
    alice:
    uid: 1001
    groups: "wheel"
    bob:
    uid: 1002
    groups: "staff"

role

是一种组织playbook的方式,可以把复杂的任务拆分成更小的,可复用的文件.类似python的模块,role也可以让ansible代码更加模块化,更容易管理和服用.

1
2
# 创建role
ansible-galaxy init my_role

目录架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
my_role/
├── defaults
│   └── main.yml # 定义变量默认值
├── files # 存放role需要复制到目标主机的源文件
├── handlers
│   └── main.yml # 存放handlers任务,只有被notify触发才会执行
├── meta
│   └── main.yml # 定义role的元数据(作者信息, 支持平台, 依赖关系等)
├── README.md # 项目README
├── tasks
│   └── main.yml # 定义role要执行的主要任务列表,当角色被引用,这里的任务将会按序执行
├── templates # jinjia2模板文件
├── tests # 用于存放测试role的文件
│   ├── inventory # 列出测试用的主机
│   └── test.yml # 测试用playbook (ansible-playbook -i tests/inventory tests/test.yml)
└── vars
└── main.yml # 定义变量

meta/main.yaml 例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
galaxy_info: # role的相关信息
author: your_name
description: Example role for web server setup
company: Your Company (optional)
license: MIT (或你选择的其他许可证)
min_ansible_version: 2.9 (或其他最小版本要求) # ansible版本要求
platforms: # 支持的平台
- name: EL
versions:
- 7
- 8
- name: Ubuntu
versions:
- xenial
- bionic
- focal
galaxy_tags: # 类似于标签,用于在Ansible Galaxy中分类和搜索你的角色
- web
- server
- httpd

dependencies: # 如果你的角色依赖于其他角色,则在这里列出
- role: other_role
- { role: conditional_role, when: "some_condition|bool", var1: "value1", var2: "value2" }

default/main.yaml

列出kv定义变量和默认值即可

1
2
3
nginx_user: www-data
nginx_http_port: 80
nginx_configure_default_site: true

handlers/main.yaml

1
2
3
4
5
6
7
8
9
10
11
- name: restart nginx
service:
name: nginx
state: restarted
become: true # 若需要管理员权限,则设置为true

- name: reload nginx
service:
name: nginx
state: reloaded
become: true

task/main.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
- name: Install nginx
apt:
name: nginx
state: present
become: true

- name: Configure nginx
template:
src: nginx.conf.j2
dest: /etc/nginx/nginx.conf
notify:
- restart nginx

- name: Ensure nginx is running (and enable it at boot)
service:
name: nginx
state: started
enabled: true
become: true

vars/main.yaml

1
2
3
4
5
6
7
nginx_version: "1.14.2"
nginx_core_module_settings:
worker_processes: "auto"
worker_connections: 1024
multi_accept: "on"
nginx_event_module_settings: # 嵌套变量,通过"."表达式引用: {{ nginx_event_module_settings.use }}
use: "epoll"

playbook引用

1
2
3
4
5
6
- hosts: webservers
become: yes
roles: # role可以引用多个,playbook将会按次序执行
- common
- nginx
- application

完整的目录架构

一个完整的playbook+role的典型目录架构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
playbook-directory/

├── ansible.cfg # Ansible 配置文件(可选)不存在则使用默认的/etc/ansible/ansible.cfg
├── inventory # 存储库存信息的文件或目录 (可选) 不存在则使用默认的/etc/ansible/hosts

├── group_vars/
│ └── group1 # 组1的变量

├── host_vars/
│ └── hostname # 特定主机的变量

├── roles/
│ ├── role1/ # 第一个 role
│ │ ├── defaults/
│ │ │ └── main.yml # role 的默认变量
│ │ ├── handlers/
│ │ │ └── main.yml # role 的 handlers
│ │ ├── meta/
│ │ │ └── main.yml # role 的元数据
│ │ ├── tasks/
│ │ │ └── main.yml # role 的任务列表
│ │ ├── templates/
│ │ │ └── template.j2 # Jinja2 模版文件
│ │ └── vars/
│ │ └── main.yml # role 的其他变量
│ │
│ └── role2/ # 第二个 role
│ ├── defaults/
│ ├── handlers/
│ ├── meta/
│ ├── tasks/
│ ├── templates/
│ └── vars/

├── site.yml # 主 playbook 文件
├── webservers.yml # 针对 web 服务器的 playbook
└── databases.yml # 针对数据库服务器的 playbook

import_playbook

playbook可以通过import来调用,这就有了上面的主playbook

例如site.yml可以这么写

1
2
- import_playbook: webservers.yml
- import_playbook: databases.yml

ansible会按次序执行webservers.yml和databases.yml两个playbook

ansible-galaxy

官网

在 Ansible 中,共享和使用别人创建的 roles 是一个常见的做法,用于促进可重用性和合作。Ansible 的主要方式是通过 Ansible Galaxy,它是一个共享和寻找 Ansible role 的中心化平台。

1
ansible-galaxy install geerlingguy.apache -p /path/to/role

requirements.yaml

与python一样,playbook目录可以创建一个requirements.yaml,里面列出需要的role,通过命令一次安装

1
ansible-galaxy install -r requirements.yml
1
2
3
# requirements.yaml
- src: geerlingguy.apache
version: 1.0.0

ansible-必知必会
http://example.com/2024/02/22/ansible-mustknow/
作者
Peter Pan
发布于
2024年2月22日
许可协议