ansible使用总结
注意事项
- 在 YAML 中,当使用 Jinja2 模板表达式(如
{{ control_nova_rpm.stdout }})作为值的开始时,应该将其用双引号包裹起来以避免解析错误 - 在 Ansible 中,任务(task)是执行特定操作的单位。每个任务通过一个 " 动作声明 " 来指定它要做什么。每个任务只能有一个动作声明,因为任务是为了解决一个具体的问题或完成一项具体的工作。如果尝试在一个任务中使用多个动作声明,比如同时使用
blockinfile和lineinfile,Ansible 就会感到困惑:因为它不知道该优先执行哪个动作,这就导致了错误。
模块用法
vars_promp
主要功能
vars_prompt 是 Ansible 提供的一个关键字,用于在运行 playbook 前通过命令行提示用户输入变量的值。这对于需要动态提供配置信息或者敏感数据(如密码)特别有用。
具体参数及使用方法
在 Ansible Playbook 中,vars_prompt 通常放置在 play 的顶层,与 hosts 或其他 play 级别的关键词同级。每个 vars_prompt 条目至少包含两个键:name 和 prompt。此外,还可以添加更多选项以增强其功能。
必需参数
- name: 变量名。这个名称将被用作 Ansible 内部引用该变量的标识符。
- prompt: 用户在命令行中看到的提示文本。
可选参数
- private: 如果设置为
yes,用户的输入将不会显示在屏幕上(例如,当你收集密码时)。默认是no。 - default: 提供一个默认值,如果用户直接按下回车而不输入任何内容,则使用此默认值。
- encrypt: 定义是否加密用户的输入。注意,这要求你已经设置了 Ansible Vault 密码。可以是
any、sha512_crypt等,但实践中很少直接在vars_prompt使用,通常会结合ansible-vault进行更安全的数据管理。
下面是一个具体的例子来展示如何使用这些参数:
- name: 使用 vars_prompt 的示例
hosts: all
vars_prompt:
- name: "user_name"
prompt: "请输入用户名"
private: no
default: "admin"
- name: "user_password"
prompt: "请输入密码"
private: yes
tasks:
- debug:
msg: "用户名是 {{ user_name }},已设置密码"
在这个例子中:
- 当运行这个 playbook 时,Ansible 首先会提示用户输入
user_name。如果用户不输入任何东西并直接按回车,默认值"admin"将被使用。 - 接下来,用户会被提示输入
user_password。因为private被设为yes,所以输入的内容不会显示在屏幕上。
shell
在 Ansible 中,shell 模块允许你在受管节点上运行任意 shell 命令。这个模块非常适合用于执行那些需要特殊 shell 功能(如管道、重定向等)的命令。接下来,我将详细介绍 shell 模块的主要功能和具体参数的使用方法。
主要功能
- 执行任意 shell 命令。
- 支持命令链、管道、输入输出重定向等高级 shell 特性。
- 与
command模块不同,shell模块通过指定的 shell 解释器来执行命令,默认是/bin/sh。
具体参数及使用方法
必需参数
- cmd: 要执行的命令字符串。这是
shell模块的核心参数,指定了你希望在目标机器上执行的具体命令。
可选参数
- chdir: 在执行命令之前,先切换到指定目录。如果目录不存在,则任务会失败。
- creates: 如果给定文件存在,则不会执行该命令。这可以用于避免重复执行某些操作。
- removes: 如果给定文件不存在,则不会执行该命令。与
creates相反。 - warn: 控制是否显示特定警告信息。默认值为
yes。 - executable: 指定用来执行命令的 shell 程序路径。例如,如果你想使用 bash 而不是系统的默认 shell,可以设置此选项为
/bin/bash。 - free_form: 这实际上不是直接使用的参数名,而是当没有其他参数时,任何传递给模块的第一个参数都会被视为要执行的命令(即
cmd的内容)。
下面是一个使用 shell 模块的例子:
- name: 使用 shell 模块执行命令
hosts: all
tasks:
- name: 切换目录并列出目录内容
shell:
cmd: ls -l
chdir: /path/to/directory
- name: 仅在文件不存在时创建文件
shell:
cmd: touch /path/to/file.txt
creates: /path/to/file.txt
- name: 仅在文件存在时删除文件
shell:
cmd: rm -f /path/to/file.txt
removes: /path/to/file.txt
- name: 使用 bash 来执行特定命令
shell:
cmd: echo $HOME
executable: /bin/bash
这些例子展示了如何使用不同的参数来控制命令的行为。例如,使用 chdir 参数可以在执行命令前切换到特定目录,而 creates 和 removes 参数则可以帮助避免不必要的命令执行。
此外,因为 shell 模块提供了对 shell 功能的完全访问权限,请确保你了解所执行命令的安全含义,特别是在处理不受信任的输入时。
copy
Ansible 的 copy 模块用于将文件从控制节点复制到受管节点。它非常适合用来部署配置文件、脚本和其他静态内容。下面我将详细介绍 copy 模块的主要功能和具体参数的使用方法。
主要功能
- 将文件从本地或远程文件(通过
src参数指定)复制到目标主机上的特定路径(通过dest参数指定)。 - 支持文件权限管理(通过
mode参数设置)。 - 支持文件内容替换,可以将变量插入到目标文件中。
- 支持创建符号链接(通过
remote_src和follow参数组合使用)。 - 可以选择是否覆盖已存在的目标文件(通过
force参数控制)。
具体参数及使用方法
必需参数
- dest: 目标文件在受管节点上的路径。如果源是一个目录且递归地被复制,则这是目标目录的路径。
常用可选参数
- src: 要复制的源文件或目录的路径。可以是控制节点上的绝对路径或相对路径。如果是相对路径,则相对于角色的 files 目录。
- content: 如果不想使用文件作为源,而是直接提供文件内容,则可以使用此选项。不能与
src同时使用。 - mode: 设置目标文件的权限,可以用八进制数表示(如 '0644'),也可以用符号表示法(如 'u=rw,g=r,o=r')。
- owner: 设置目标文件的所有者。
- group: 设置目标文件的所属组。
- backup: 如果设为
yes,在覆盖前备份现有的目标文件。 - force: 如果设为
no,只有当目标文件不存在时才执行复制操作。默认值为yes。 - directory_mode: 当复制一个目录时,设置目录的权限模式。
- remote_src: 如果设为
yes,则src是指远程机器上的文件路径而非控制节点。默认值为no。 - [[copy模块validate参数|validate]]: 在复制文件之前运行验证命令。该命令应该包含一个
%s占位符,这会被临时文件的位置所替换。
以下是一些使用 copy 模块的例子:
- name: 复制单个文件到目标位置
copy:
src: /path/to/source/file.conf
dest: /etc/file.conf
owner: root
group: root
mode: '0644'
- name: 直接提供文件内容而不是从源文件复制
copy:
content: '# 这是一个示例配置文件\noption=value'
dest: /etc/example.conf
owner: root
group: root
mode: '0644'
- name: 使用 validate 参数确保配置正确
copy:
src: /path/to/source/nginx.conf
dest: /etc/nginx/nginx.conf
owner: root
group: root
mode: '0644'
validate: '/usr/sbin/nginx -t -c %s'
这些例子展示了如何使用不同的参数来满足特定的需求,比如设置文件权限、所有者和所属组,以及如何使用 [[copy模块validate参数|validate]] 来确保配置文件的有效性。copy 模块是非常强大的,适用于多种场景下的文件管理任务。
fetch
fetch 模块主要用于从远程主机上获取文件并将其存储到 Ansible 控制节点上,常用于日志收集、配置备份等场景。下面将详细介绍 fetch 模块的主要功能及其参数的具体用法。
主要功能
- 文件传输:从远程主机复制一个或多个文件到本地 Ansible 控制机。
- 目录结构保持:可以保持源文件的目录结构。
- 文件过滤:支持通过指定路径来筛选要获取的文件。
参数说明
- src: 必需参数,指定了远程主机上的文件路径。
- dest: 必需参数,指定了目标位置,即你希望将文件存储在本地机器上的哪个路径。如果提供了文件名,则会直接存储为该名称;若只提供目录,则使用源文件名作为目标文件名,并且会在目标路径下创建与源文件相同的相对路径。
- flat: 可选参数,当设置为
yes时,不会保留源文件的目录结构,默认值是no,意味着会保留源文件的目录结构。 - validate_checksum: 可选参数,默认是
yes。如果设置为yes,则在传输后验证文件的校验和以确保文件完整性。 - fail_on_missing: 可选参数,如果设置为
yes,当指定的源文件不存在时任务将失败,默认是no,即不处理缺失文件的情况。
示例
基本用法
- name: 从远程服务器获取特定的日志文件
fetch:
src: /var/log/myapp.log
dest: /local/backup/
flat: yes
在此示例中,myapp.log 文件将会被复制到 /local/backup/myapp.log,而不会创建任何反映其原始位置的子目录。
保持目录结构
- name: 获取整个日志目录并保持其结构
fetch:
src: /var/log/myapp/
dest: /local/backup/
这里,/var/log/myapp/ 目录下的所有内容都会被复制到 /local/backup/,并且会保持原有的目录结构。
处理缺失文件
- name: 尝试获取特定文件,如果不存在则任务失败
fetch:
src: /path/to/nonexistent/file.txt
dest: /local/backup/
fail_on_missing: yes
此任务将会由于指定的源文件不存在而失败。
service
Ansible 的 service 模块用于管理服务的启动、停止、启用(开机自启)、禁用等操作。它是处理 Linux 系统服务的一个重要工具,可以跨多种操作系统使用,但具体的参数可能会根据不同的 init 系统(如 systemd, sysv, upstart 等)有所不同。下面详细介绍 service 模块的主要功能及其参数的具体用法。
主要功能
- 服务状态管理:可以用来启动、停止、重启、重载服务。
- 服务启用/禁用管理:可以配置服务是否在系统启动时自动运行。
- 检查服务状态:能够检查一个服务当前是否正在运行。
参数说明
- name: 必需参数,指定了你想要管理的服务名称。
- state: 可选参数,定义了对服务执行的操作:
started: 确保服务已启动。stopped: 停止服务。restarted: 重启服务。reloaded: 重载服务配置(如果支持)。absent: 不推荐使用,建议使用enabled和disabled来代替。
- enabled: 可选参数,控制服务是否开机自启:
yes: 开机启动该服务。no: 禁用开机启动。
- daemon_reload: 可选参数,仅适用于使用 systemd 的系统。设置为
yes时,在管理服务之前会重新加载 systemd 配置。 - arguments: 可选参数,指定服务启动时附加的参数或选项。
- pattern: 可选参数,当服务无法通过标准方法查询状态时,可以提供一个正则表达式来匹配进程列表中的服务进程名。
示例
基本服务管理
- name: 确保Apache服务已启动并设置为开机自启
service:
name: httpd
state: started
enabled: yes
在这个例子中,Ansible 将确保 Apache 服务(在某些系统上可能叫做 httpd)已经启动,并且配置为随系统启动而自动运行。
服务重启
- name: 重启Nginx服务以应用新的配置
service:
name: nginx
state: restarted
此任务将会重启 Nginx 服务,通常用于应用新的配置文件之后。
使用 daemon_reload
对于使用 systemd 管理服务的情况,如果更改了服务文件或添加了新的服务文件,您需要先重新加载 systemd 配置:
- name: 重新加载systemd配置并重启服务
service:
name: my_service
state: restarted
daemon_reload: yes
使用 pattern 参数
如果服务不是通过标准方式管理的,您可以使用 pattern 参数来匹配服务进程:
- name: 如果存在则启动my_legacy_service
service:
name: my_legacy_service
state: started
pattern: "my_legacy_service"
在此示例中,Ansible 会尝试通过提供的模式匹配找到对应的服务进程,并确保其处于运行状态。
yum
Ansible 的 yum 模块主要用于在基于 RPM 的 Linux 发行版(如 CentOS、RHEL 和 Fedora)上管理软件包。通过这个模块,你可以安装、更新、删除软件包,并且可以处理软件仓库的配置等任务。下面是关于 yum 模块的主要功能介绍及其参数的具体用法。
主要功能
- 软件包安装:可以指定单个或多个软件包进行安装。
- 软件包更新:可以更新已有的软件包到最新版本。
- 软件包卸载:可以从系统中移除不再需要的软件包。
- 软件包组管理:支持对软件包组的操作,例如安装或移除一组相关的软件包。
- 仓库管理:能够启用、禁用特定的软件仓库,或设置优先级等。
参数说明
- name: 必需参数,指定了你想要操作的软件包或软件包组名称。可以使用逗号分隔多个包名,或者使用通配符来匹配多个包。如果要指定版本,可以使用格式
package_name-version。 - state: 可选参数,定义了对软件包执行的操作:
present: 确保软件包已被安装(默认值)。latest: 确保软件包为最新版本。absent: 卸载指定的软件包。
- enablerepo: 可选参数,允许指定一个或多个额外的软件仓库(以逗号分隔),这些仓库将在安装或更新过程中被临时启用。
- disablerepo: 可选参数,允许指定一个或多个软件仓库(以逗号分隔),这些仓库将被临时禁用。
- conf_file: 可选参数,用于指定 yum 配置文件的路径,默认是使用系统的 yum 配置文件。
- disable_gpg_check: 可选参数,当设置为
yes时,会跳过 GPG 签名检查。 - update_cache: 可选参数,当设置为
yes时,会强制刷新 yum 缓存。 - exclude: 可选参数,可用于排除某些软件包,防止它们被升级或安装。
示例
安装单个软件包
- name: 安装Nginx
yum:
name: nginx
state: present
此任务将确保 Nginx 已经安装在目标机器上。
安装多个软件包
- name: 安装多个软件包
yum:
name: "{{ item }}"
state: present
with_items:
- nginx
- vim
- git
在这个例子中,with_items 循环用于指定多个软件包进行安装。
更新软件包至最新版本
- name: 将所有软件包更新到最新版本
yum:
name: "*"
state: latest
这将更新系统上的所有软件包到最新版本。
使用特定仓库安装软件包
- name: 从EPEL仓库安装htop
yum:
name: htop
state: present
enablerepo: epel
该示例展示了如何从特定的软件仓库(这里是指 EPEL)安装软件包。
刷新 yum 缓存
- name: 强制刷新yum缓存
yum:
name: "*"
update_cache: yes
此任务将强制刷新 yum 的本地缓存,这对于确保获取最新的软件包信息非常有用。
include_vars
include_vars 是 Ansible 中用于动态加载变量文件的一个模块。它允许你根据条件或者在运行时包含一个或多个 YAML 或 JSON 格式的变量文件,从而增强 Playbook 的灵活性和可维护性。
主要功能
- 动态加载变量:可以根据任务、角色或者条件动态地加载不同的变量文件。
- 提高代码重用性和可维护性:通过将变量分离到不同的文件中,可以更容易地管理和更新配置数据,同时也能减少重复定义。
- 支持条件加载:可以根据 Ansible 的事实(facts)、主机变量、组变量等条件来决定是否加载某个变量文件。
使用方法
include_vars 模块可以通过多种方式使用,下面是一些常见的例子:
基本用法
- name: 加载默认变量文件
include_vars:
file: default_variables.yml
在这个例子中,default_variables.yml 文件中的所有变量都会被加载,并且可以在后续的任务中使用。
条件加载
你可以基于某些条件来决定是否加载特定的变量文件。例如,根据操作系统类型加载不同的变量文件:
- name: 根据操作系统加载特定的变量文件
include_vars:
file: "{{ ansible_os_family | lower }}.yml"
这里,如果目标主机的操作系统家族是 "Debian",那么 debian.yml 变量文件将会被加载。
目录加载
除了单个文件外,你还可以指定一个目录,Ansible 会自动加载该目录下的所有 .yml 或 .json 文件:
- name: 从目录加载所有变量文件
include_vars:
dir: group_vars/mygroup/
extensions:
- "yml"
- "json"
这将加载 group_vars/mygroup/ 目录下所有的 .yml 和 .json 文件中的变量。
与注册变量一起使用
你也可以先执行一些操作,然后根据结果决定要加载哪个变量文件。例如:
- name: 确定要使用的配置版本
shell: cat /path/to/version.txt
register: version_info
- name: 根据版本信息加载相应的变量文件
include_vars:
file: "vars/config_{{ version_info.stdout }}.yml"
上述示例首先运行一个 shell 命令获取版本信息,然后根据这个版本信息加载相应的变量文件。
cron
Ansible 的 cron 模块主要用于管理(添加、更新或删除)远程主机上的 cron 作业。使用这个模块,你可以自动化设置定时任务,而无需手动登录到每台机器进行配置。下面介绍 ansible cron 模块的主要功能和具体参数用法。
主要功能
- 添加/更新 cron 作业:可以在目标机器上创建新的 cron 作业或者更新已有的作业。
- 删除 cron 作业:可以指定删除某个特定的 cron 作业。
- 定义作业执行时间:允许用户通过不同的时间字段来精确控制作业的运行时间。
- 环境变量设置:可以在 cron 作业中设置环境变量。
- 特殊的时间关键字:支持像
@reboot,@daily,@weekly, 等特殊字符串来简化时间设定,[[cron模块special_time#anisble中|详细请参考special_time用法]]。
常用参数
以下是 cron 模块的一些常用参数:
name: (必需) 用于唯一标识该 cron 作业的名称。这对于确保幂等性(即多次执行相同的 playbook 不会导致重复的 cron 作业被创建)非常重要。minute: (可选) 作业应该执行的分钟数(0-59)。默认为"*",表示每一分钟。hour: (可选) 作业应该执行的小时数(0-23)。默认为"*",表示每小时。day: (可选) 作业应该执行的日(1-31)。默认为"*",表示每天。month: (可选) 作业应该执行的月(1-12)。默认为"*",表示每月。weekday: (可选) 作业应该执行的星期几(0-7)(周日既可以是 0 也可以是 7)。默认为"*",表示每周。job: (必需) 要执行的命令或脚本路径。state: (可选) 指定是添加/更新 (present) 还是删除 (absent) cron 作业。默认值为"present".user: (可选) 定义哪个用户的 crontab 将被修改。默认是当前用户。special_time: (可选) 使用如@reboot,@daily,@weekly等特殊时间字符串代替具体的minute,hour, 等设置。
示例
添加一个每日备份数据库的 cron 作业
- name: Add a cron job to backup database daily
cron:
name: "Daily Database Backup"
minute: "0"
hour: "2" # 每天凌晨2点执行
job: "/usr/local/bin/db_backup.sh"
state: present
user: root
删除一个 cron 作业
如果你需要移除上面添加的 cron 作业,只需将 state 设置为 absent:
- name: Remove the Daily Database Backup cron job
cron:
name: "Daily Database Backup"
state: absent
user: root
lineinfile
lineinfile 是 Ansible 中的一个模块,用于确保文件中包含特定的一行文本。如果该行不存在,则添加;如果存在但内容不同,则替换为指定的内容。这个模块非常适合用来修改配置文件或在文件中插入或更新一行。
主要功能
- 添加或更新行:确保文件中有一行与给定的正则表达式匹配。如果不匹配,则根据设置添加或替换该行。
- 删除行:可以根据提供的正则表达式从文件中移除匹配的行。
- 备份文件:在对文件进行更改之前,可以创建一个备份文件。
常用参数说明
以下是 lineinfile 模块的一些重要参数及其用法:
-
path 或 dest(必需):指定要操作的目标文件路径。
dest是旧版本中的参数名,现在推荐使用path。 -
regexp:用于匹配文件中现有行的正则表达式。如果找到匹配项,则可能根据其他参数更新该行;如果没有找到匹配项,则根据
line参数添加新行。 -
line:当没有找到匹配行时要添加到文件中的文本行,或者是要替换现有行的文本内容。
-
state:指定是应该呈现(present,默认值)还是移除(absent)指定的行。
-
backup:如果是
yes,在修改文件前会创建一个备份文件。 -
insertafter:如果没有找到匹配行,指定在哪一行之后插入新行。可以是一个正则表达式,表示在匹配该模式的行之后插入。
- insertafter: EOF:将新行插入到文件的末尾。
- insertafter: '^foo':在以 "foo" 开头的行之后插入新行。
- insertafter: 'somestring':在匹配 "somestring" 的行之后插入新行。
^5646b2
-
insertbefore:类似于
insertafter,但指定了在某一行之前插入新行。 -
create:如果目标文件不存在,是否创建它。默认值是
no。
示例
-
确保文件中有特定的一行
- name: Ensure a specific line exists in the file ansible.builtin.lineinfile: path: /etc/myconfig.conf regexp: '^my_setting=' line: 'my_setting=value' -
删除文件中的特定行
- name: Remove a specific line from the file ansible.builtin.lineinfile: path: /etc/myconfig.conf state: absent regexp: '^deprecated_option=' -
在匹配行后插入新行,并创建备份
- name: Insert a line after a match and create backup ansible.builtin.lineinfile: path: /etc/myconfig.conf insertafter: '^# My Section$' line: 'new_setting=new_value' backup: yes
blockinfile
blockinfile 是 Ansible 中的一个模块,用于管理文件中的文本块(block)。与 lineinfile 不同,它不是操作单行文本,而是允许你插入、更新或删除由特定标记包围的多行文本块。这对于配置文件中需要维护的一段配置特别有用。
主要功能
- 添加或更新块:确保文件中存在一个被特定标记包围的文本块。如果该块不存在,则添加;如果存在但内容不同,则替换为指定的内容。
- 删除块:可以根据提供的标记从文件中移除整个文本块。
- 备份文件:在对文件进行更改之前,可以创建一个备份文件。
常用参数说明
以下是 blockinfile 模块的一些重要参数及其用法:
-
path 或 dest(必需):指定要操作的目标文件路径。
dest是旧版本中的参数名,现在推荐使用path。 -
block(必需):要插入或更新到文件中的文本块。通常是由换行符分隔的多行文本。
-
marker:定义包围文本块的标记格式。默认是
# {mark} ANSIBLE MANAGED BLOCK,其中{mark}会被替换为BEGIN或END。 -
state:指定是应该呈现(present,默认值)还是移除(absent)指定的块。
-
backup:如果是
yes,在修改文件前会创建一个备份文件。 -
insertafter:如果没有找到匹配块,指定在哪一行之后插入新块。可以是一个正则表达式,表示在匹配该模式的行之后 [[#^5646b2|插入]]。
-
insertbefore:类似于
insertafter,但指定了在某一行之前插入新块。 -
create:如果目标文件不存在,是否创建它。默认值是
no。
示例
-
确保文件中有特定的一段配置
- name: Ensure a specific configuration block exists in the file ansible.builtin.blockinfile: path: /etc/myconfig.conf block: | setting1=value1 setting2=value2 -
自定义标记并确保文件中有特定的一段配置
- name: Ensure a specific configuration block with custom markers exists in the file ansible.builtin.blockinfile: path: /etc/myconfig.conf block: | setting1=value1 setting2=value2 marker: "# {mark} MY CUSTOM BLOCK" -
删除文件中的特定块
- name: Remove a specific block from the file ansible.builtin.blockinfile: path: /etc/myconfig.conf block: "" state: absent -
在匹配行后插入新块,并创建备份
- name: Insert a block after a match and create backup ansible.builtin.blockinfile: path: /etc/myconfig.conf insertafter: '^# My Section$' block: | new_setting1=new_value1 new_setting2=new_value2 backup: yes
通过这些示例和参数介绍,可以发现 blockinfile 这个模块非常适合用来维护那些需要以完整代码块形式存在的配置项。
set_fact
set_fact 是 Ansible 中的一个模块,它允许你动态地设置变量,并将这些变量作为事实(facts)添加到你的 playbook 运行环境中。这意味着你可以基于某些条件或逻辑,在运行时创建变量,并在后续的任务中使用它们。
基本用法
最基本的 set_fact 使用方法是定义一个或多个变量,并赋予它们特定的值。例如:
- name: Set a fact dynamically
set_fact:
my_dynamic_fact: "This is a dynamic fact"
在这个例子中,我们创建了一个名为 my_dynamic_fact 的事实,其值为 "This is a dynamic fact"。这个事实可以在当前 playbook 的任何地方使用,就像其他 Ansible 变量一样。
条件性设置事实
你也可以根据条件来设置不同的事实值。比如,根据操作系统类型设置不同的路径变量:
- name: Set path based on OS family
set_fact:
app_path: /usr/local/bin/app
when: ansible_os_family == 'Debian'
- name: Set alternative path for other OS families
set_fact:
app_path: /opt/bin/app
when: ansible_os_family != 'Debian'
在这组任务中,app_path 将根据目标主机的操作系统家族被设置为不同的值。
动态计算值
set_fact 还可以用于执行一些计算并将结果存储在一个变量中。例如,假设你需要计算两个数字的和:
- name: Calculate sum of two numbers
set_fact:
total: "{{ num1 + num2 }}"
vars:
num1: 5
num2: 3
在这里,total 将被设置为 8 (num1 和 num2 的和)。
组合使用
set_fact 经常与注册变量、循环和其他控制结构结合使用,以实现更复杂的逻辑。例如,你可以基于某个命令的输出来设置一个事实:
- name: Check if a file exists
stat:
path: /path/to/your/file
register: file_info
- name: Set fact based on file existence
set_fact:
file_exists: "{{ file_info.stat.exists }}"
这里,首先通过 stat 模块检查文件是否存在,并将结果注册到 file_info 变量中。然后,基于 file_info 的内容,使用 set_fact 设置一个新的事实 file_exists。
debug
Ansible 的 debug 模块主要用于在 Playbook 执行期间输出信息,这对于调试非常有用。你可以使用它来打印变量的值、表达式的结果或者简单的文本消息。下面是一些关于如何使用 debug 模块的具体信息,包括其常用参数。
基本用法
- name: 示例 Playbook
hosts: localhost
tasks:
- name: 打印一条消息
debug:
msg: "这是一条调试消息"
在这个例子中,msg 参数用于指定要显示的消息。当你运行这个 Playbook 时,你会看到这条消息被打印出来。
主要参数
-
msg: (字符串)这是你想要输出的信息。可以是静态文本,也可以是变量或表达式的组合。
-
var: 如果你想要输出一个特定变量的内容,而不是直接编写消息,可以使用
var参数。例如:- name: 打印变量 debug: var: ansible_os_family这将输出
ansible_os_family变量的值。 -
vars: 允许你同时输出多个变量。这是一个字典列表,每个字典包含一个键和它的值。不过,通常直接使用
var或者在msg中嵌入变量更为常见。 -
verbosity: 控制该调试信息需要的详细级别。默认情况下,所有
debug任务都会显示,但通过设置此选项,你可以控制信息仅在更高详细级别下显示。例如,verbosity: 2表示只有当用户以-vvv(即三倍详细模式)或更高级别运行 Playbook 时才显示该调试信息。
示例
输出变量内容
- name: 显示主机操作系统家族
hosts: all
tasks:
- name: 获取系统信息
setup:
register: setup_result
- name: 打印操作系统家族
debug:
var: setup_result.ansible_facts.ansible_os_family
使用条件进行调试
有时你可能只想在满足某些条件时输出调试信息。你可以结合 when 关键字使用 debug 模块。例如:
- name: 条件调试示例
hosts: all
tasks:
- name: 仅在特定条件下打印消息
debug:
msg: "满足条件的情况"
when: ansible_os_family == "Debian"
这些只是 debug 模块的一些基本用途和参数介绍。通过灵活运用这些功能,你可以在开发和调试 Ansible Playbooks 时获得很大的帮助。
file
Ansible 的 file 模块是用于管理文件属性的非常基础且功能强大的模块。它能够创建或删除文件和目录,并修改它们的权限、所有权等属性。以下是对该模块的主要功能介绍及其常用参数的说明。
主要功能
- 创建文件或目录:可以用来创建文件、目录或者符号链接。
- 删除文件或目录:支持递归地删除文件或目录。
- 设置文件或目录权限:允许设置或更改文件或目录的权限(mode)。
- 修改文件或目录的所有权:可更改文件或目录的用户和组所有者。
- 设置文件的访问时间与修改时间:允许手动设置文件的访问时间和修改时间(atime 和 mtime)。
常用参数说明
以下是 file 模块的一些重要参数及其使用方法:
-
path 或 dest(必需):指定目标文件或目录的路径。
dest是旧版本中的参数名,现在推荐使用path。 -
state:定义文件或目录的目标状态。常见选项包括:
file:确保是一个普通文件。directory:确保是一个目录。link:创建一个符号链接。absent:确保文件或目录不存在。touch:如果文件不存在则创建,存在则更新其访问时间和修改时间。
-
mode:设置文件或目录的权限。可以使用八进制表示法(如
0644)或者符号模式(如u=rw,g=r,o=r)。 -
owner:指定文件或目录的用户所有者。
-
group:指定文件或目录的组所有者。
-
recurse:当
state=directory时,若设置为yes,可以递归地设置目录下所有文件和子目录的权限。 -
src:当
state=link时,需要指定符号链接指向的目标路径。 -
follow:如果目标是符号链接,是否跟随链接并操作链接指向的实际文件或目录。默认为
no。
示例
-
创建文件并设置权限
- name: Create a file and set permissions ansible.builtin.file: path: /tmp/myfile.txt state: touch mode: '0644' -
创建目录并设置权限和所有权
- name: Create a directory and set permissions and ownership ansible.builtin.file: path: /tmp/mydir state: directory mode: '0755' owner: myuser group: mygroup -
创建符号链接
- name: Create a symbolic link ansible.builtin.file: src: /path/to/source dest: /path/to/link state: link -
删除文件或目录
- name: Remove a file or directory ansible.builtin.file: path: /path/to/remove state: absent
通过这些示例和参数说明,你可以根据自己的需求灵活运用 Ansible 的 file 模块来管理和配置系统上的文件和目录。这个模块对于需要精确控制文件属性的任务来说是非常有用的。
ansible Vault
Ansible Vault 是 Ansible 提供的一个功能,用于加密敏感数据(如密码、API 密钥等),以便安全地存储在版本控制系统中或与他人共享。使用 Ansible Vault 可以确保这些敏感信息不会以明文形式暴露,从而增加安全性。
主要功能
- 加密文件:可以加密整个文件或者文件中的特定部分。
- 解密文件:当你需要编辑加密的内容时,可以临时解密文件。
- 透明加密/解密:在执行 playbook 时,如果遇到加密内容,Ansible 会自动解密它们(前提是提供了正确的密码)。
- 加密字符串:可以加密单个字符串,适用于直接在命令行上进行操作。
使用方法
创建一个新的加密文件
你可以创建一个新的加密文件,并直接在里面编写你的敏感信息:
ansible-vault create credentials.yml
执行这条命令后,系统会提示你输入一个密码。之后,会打开默认的文本编辑器让你编辑这个加密文件。在这个文件中,你可以定义你的变量,例如:
db_password: "your_secure_password"
api_key: "your_api_key"
完成后保存并关闭编辑器,文件将会被加密。
编辑已有的加密文件
若要编辑一个已经存在的加密文件,可以使用以下命令:
ansible-vault edit credentials.yml
同样,你需要提供之前设置的密码来解锁文件进行编辑。
加密现有文件
如果你有一个包含敏感信息但未加密的文件,可以使用以下命令来加密它:
ansible-vault encrypt credentials.yml
解密文件
如果你想永久解密一个文件,可以使用如下命令:
ansible-vault decrypt credentials.yml
查看加密文件内容
想要查看加密文件的内容而不解密它,可以使用 ansible-vault view 命令:
ansible-vault view credentials.yml
在 Playbook 中使用加密文件
要在 playbook 中引用加密文件中的变量,可以通过 vars_files 导入:
- hosts: all
vars_files:
- credentials.yml
tasks:
- name: Use the encrypted password
debug:
msg: "The database password is {{ db_password }}"
记得在运行 playbook 时,添加 --ask-vault-pass 参数来提供解密所需的密码:
ansible-playbook site.yml --ask-vault-pass
通过这些方法,你可以有效地管理和保护你的敏感信息,同时还能充分利用 Ansible 的自动化能力。
ansible 循环
在 Ansible 中,循环用于简化重复任务的执行过程。通过使用循环,你可以对一系列项目进行操作,而不需要为每个项目单独编写任务。下面是一些常见的循环用法及其示例。
基本循环 (loop)
从 Ansible 2.5 版本开始,推荐使用 loop 来替代旧的 with_<type> 格式的循环。loop 更加直观且与现代 Ansible 的最佳实践相一致。
示例:文件复制
假设你需要将多个文件复制到目标机器上的同一目录中:
- name: Copy multiple files to destination
copy:
src: "{{ item }}"
dest: /etc/fooapp/
loop:
- foo.conf
- bar.conf
使用 with_items
尽管现在更推荐使用 loop,但在一些场景下你可能会看到或需要使用 with_items。
示例:安装多个软件包
如果你需要在目标机器上安装多个软件包:
- name: Ensure several packages are installed
apt:
name: "{{ item }}"
state: present
with_items:
- git
- curl
- vim
使用 with_sequence
with_sequence 用来生成一个数字序列,并将其作为循环变量使用。
示例:创建一组目录
如果你想根据序列创建一组目录:
- name: Create directories based on a sequence
file:
path: "/tmp/test{{ item }}"
state: directory
with_sequence: start=1 end=3
这将在 /tmp 目录下创建 test1, test2, 和 test3 目录。
使用 loop_control 自定义变量名
有时候,默认的 item 变量名可能不够清晰,你可以使用 loop_control 来指定一个不同的变量名以提高代码可读性。
示例:自定义变量名
- name: Show custom loop variable
debug:
msg: "This is a message {{ custom_var }}."
loop: [ 'one', 'two', 'three' ]
loop_control:
loop_var: custom_var
结合条件语句使用循环
你还可以在循环内部使用条件语句来进一步控制哪些项应被处理。
示例:基于条件安装软件包
- name: Install software if the OS family is correct
package:
name: "{{ item }}"
state: present
when: ansible_os_family == "Debian"
loop:
- python3
- nginx
ansible 判断
在 Ansible 中,条件判断用于根据特定条件决定是否执行某个任务。这可以通过 when 语句实现。when 语句允许你基于变量的值、事实(facts)、注册的变量结果等来控制任务的执行。下面是一些常见的用法示例。
基本条件判断
示例:基于变量值的条件判断
假设有一个变量 is_web_server,你可以根据它的值决定是否安装 Nginx:
- name: Install Nginx if is_web_server is true
apt:
name: nginx
state: present
when: is_web_server
在这个例子中,如果 is_web_server 变量为真(True),那么将会安装 Nginx。
结合事实进行判断
Ansible 会在目标主机上收集一些系统信息,称为 " 事实 "。你可以使用这些事实来进行条件判断。
示例:基于操作系统的条件判断
如果你想仅在基于 Debian 的系统上安装软件包,可以这样写:
- name: Install Nginx on Debian-based systems
apt:
name: nginx
state: present
when: ansible_os_family == "Debian"
使用注册变量的结果进行判断
当你运行一个命令或 shell 脚本时,可以将输出结果注册到一个变量中,并根据该结果决定后续步骤。
示例:检查文件是否存在
- name: Check if a file exists
stat:
path: /path/to/your/file
register: file_check
- name: Copy file if it does not exist
copy:
src: /path/to/source/file
dest: /path/to/your/file
when: not file_check.stat.exists
在这个例子中,首先使用 stat 模块检查文件是否存在,并将结果存储在 file_check 变量中。接下来的任务会根据 file_check.stat.exists 的值(即文件是否存在)来决定是否复制文件。
复杂条件表达式
你也可以结合多个条件或者使用逻辑运算符(如 and, or, not)来创建更复杂的条件判断。
示例:复杂条件表达式
假设你需要在满足两个条件的情况下才执行任务:操作系统是 Debian 家族且一个自定义变量 deploy_env 等于 production。
- name: Perform action only in production environment on Debian systems
debug:
msg: "This is a production system running Debian."
when: ansible_os_family == "Debian" and deploy_env == "production"

浙公网安备 33010602011771号