文章目录
-
- Ansible特点
- Ansible架构
- Ansible工作原理
- 重要文件位置
- Ansible系列命令
-
- ansible命令的参数
- [ansible-playbook 命令参数](#ansible-playbook 命令参数)
- Ansbile常用模块
- Playbook文件编写
- roles
-
- 项目根目录
- [`roles` 目录](#
roles
目录) -
- [`mysql` 角色目录](#
mysql
角色目录)
- [`mysql` 角色目录](#
Ansible特点
- Ansible不需要启动服务,因为他只是一个工具,并且他的模块可以用任何模块开发。
- 基于OpenSSH连接
- 幂等性,一个任务执行1遍和执行n遍效果一样,不因重复执行带来意外情况,除非执行的时候值会改变。
- 基于python语言
关于幂等性有如下解释:
- 绿色:执行成功并且不需要做改变的操作(幂等性的结果)
- 黄色:执行成功并且对目标主机做变更
- 红色:执行失败
Ansible架构
- 核心:ansible
- 核心模块(Core Modules):ansible自带的模块
- 扩展模块(Custom Modules):如果核心模块不足以完成某种功能,可以添加扩展模块
- 插件(Plugins):通过插件来实现记录日志,发送邮件或其他功能
- 剧本(Playbooks):YAML格式文件,多任务自定义在一个文件中,定义主机需要调用哪些模块来完成的功能。
- 连接插件(Connectior Plugins):ansible基于连接插件连接到每个主机上的,虽然ansible是使用ssh连接到每个主机上的,但是它还支持其他的连接方式。
- 主机群(Host Inventory):记录由Ansible管理的主机信息,包括端口、密码、ip等。
Ansible工作原理
把我们执行的命令翻译为shell命令,通过 open ssh 拷贝到目标主机 /root/.ansible/tmp/ 下(生成py文件),然后再执行,执行完成后删除tmp文件。
剧本playbook执行过程:将已有编排好的任务集写入Ansible-Playbook通过ansible-playbook命令分拆任务集至逐条ansible命令,按预定规则逐条执行

重要文件位置

主机清单:/etc/ansible/hosts/
/etc/ansible/hosts文件格式
inventory文件遵循INI文件风格,中括号中的字符为组名。
可以将同一个主机同时归并到多个不同的组中;
此外,当如若目标主机使用了非默认的SSH端口,还可以在主机名称之后使用冒号加端口号
来标明
--------------------写法一--------------------
ntp.xingyun.com 不分组,直接加
--------------------写法二--------------------
[webservers] webservers组
www1.xingyun.com:2222 可以指定端口
www2.xingyun.com
[dbservers]
db1.xingyun.com
db2.xingyun.com
db3.xingyun.com
配置文件:Ansible 配置文件/etc/ansible/ansible.cfg (一般保持默认)
ini
[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系列命令
- /usr/bin/ansible 主程序,临时命令执行工具
- /usr/bin/ansible-doc 查看配置文档,模块功能查看工具,相当于man
- /usr/bin/ansible-playbook 定制自动化任务,编排剧本工具,相当于脚本
- /usr/bin/ansible-galaxy 下载/上传优秀代码或Roles模块的官网平台
- /usr/bin/ansible-pull 远程执行命令的工具
- /usr/bin/ansible-vault 文件加密工具
- /usr/bin/ansible-console 基于Console界面与用户交互的执行工具
- /usr/bin/ansible-config 查看,编辑管理ansible的配置文件
- /usr/bin/ansible-inventory 查看被控制端主机清单的详细信息
ansible命令的参数
例:ansible 192.168.242.100 -m ping
- -a 指定模块的参数
- --version 显示版本
- -f FORKS, --forks FORKS fork多少进程并发处理,默认为5个
- -m module 指定使用的模块,默认为command
- -v 查看执行的详细过程(-vv、-vvv更详细)
- -i 指定hosts文件路径,默认:/etc/ansible/hosts
- -I 指定pattern,对已匹配的主机中再过滤一次
- --list-hosts 显示主机列表(可以简写为--list)
- 如:ansible all --list
- -k,--ask-pass 提示输入ssh连接密码,默认使用key验证
- -K,--ask-become-pass 提示执行输入sudo的密码
- -C,--check 检查,并不执行
- -c 设置连接类型(default=smart)
- -T,--timeout=TIMEOUT 执行命令的超时时间,默认10s
- -t 日志输出到该目录,日志文件名以主机命名
- -u,--user=REMOTE_USER 指定远程执行的执行用户,若不指定用户,则使用当前用户身份
- -U sudo到哪个用户,默认为root
- -b,--become 代替旧版本的sudo切换
- --become-user=USERNAME 指定sudo的runas用户,默认为root
- -h,--help 显示帮助信息
- -s sudo运行
- -o 压缩输出,摘要输出
ansible-playbook 命令参数
指定主机变为指定yml文件,其余参数与ansbile差不多,具体如下:
Options:
--ask-vault-pass
#ask for vault password
#加密playbook文件时提示输入密码
-C, --check
#don't make any changes; instead, try to predict some of the changes that may occur
#模拟执行,不会真正在机器上执行(查看执行会产生什么变化)
-D, --diff
#when changing (small) files and templates, show the differences in those files; works great with --check
#当更新的文件数及内容较少时,该选项可显示这些文件不同的地方,该选项结合-C用会有较好的效果
-e EXTRA_VARS, --extra-vars=EXTRA_VARS
#set additional variables as key=value or YAML/JSON
#在Playbook中引入外部参数变量
--flush-cache
#clear the fact cache
#将fact清除到的远程主机缓存
--force-handlers
#run handlers even if a task fails
#强制运行handlers的任务,即使在任务失败的情况下
-f FORKS, --forks=FORKS
#specify number of parallel processes to use(default=5)
#并行任务数。FORKS被指定为一个整数,默认是5
-h, --help
#show this help message and exit
#打开帮助文档API
-i INVENTORY, --inventory-file=INVENTORY
#specify inventory host path (default=/etc/ansible/hosts) or comma separated host list.
#指定要读取的Inventory文件
-l SUBSET, --limit=SUBSET
#further limit selected hosts to an additional pattern
#限定执行的主机范围
--list-hosts
#outputs a list of matching hosts; does not execute anything else
#列出执行匹配到的主机,但并不会执行
--list-tags
#list all available tags
#列出所有可用的tags
--list-tasks
#list all tasks that would be executed
#列出所有即将被执行的任务
-M MODULE_PATH, --module-path=MODULE_PATH
#specify path(s) to module library (default=None)
#要执行的模块的路径
--new-vault-password-file=NEW_VAULT_PASSWORD_FILE
#new vault password file for rekey
#
--output=OUTPUT_FILE
#output file name for encrypt or decrypt; use - for stdout
#
--skip-tags=SKIP_TAGS
#only run plays and tasks whose tags do not match these values
#跳过指定的tags任务
--start-at-task=START_AT_TASK
#start the playbook at the task matching this name
#从第几条任务(START_AT_TASK)开始执行
--step
#one-step-at-a-time: confirm each task before running
#逐步执行Playbook定义的任务,并经人工确认后继续执行下一步任务
--syntax-check
#perform a syntax check on the playbook, but do not execute it
#检查Playbook中的语法书写,并不实际执行
-t TAGS, --tags=TAGS
#only run plays and tasks tagged with these values
#指定执行该tags的任务
--vault-password-file=VAULT_PASSWORD_FILE
#vault password file
#
-v, --verbose
#verbose mode (-vvv for more, -vvvv to enable connection debugging)
#执行详细输出
--version
#show program's version number and exit
#显示版本
Connection Options:
control as whom and how to connect to hosts
-k, --ask-pass
#ask for connection password
#
--private-key=PRIVATE_KEY_FILE, --key-file=PRIVATE_KEY_FILE
#use this file to authenticate the connection
#
-u REMOTE_USER, --user=REMOTE_USER
#connect as this user (default=None)
#指定远程主机以USERNAME运行命令
-c CONNECTION, --connection=CONNECTION
#connection type to use (default=smart)
#指定连接方式,可用选项paramiko (SSH)、ssh、local,local方式常用于crontab和kickstarts
-T TIMEOUT, --timeout=TIMEOUT
#override the connection timeout in seconds(default=10)
#SSH连接超时时间设定,默认10s
--ssh-common-args=SSH_COMMON_ARGS
#specify common arguments to pass to sftp/scp/ssh (e.g.ProxyCommand)
#
--sftp-extra-args=SFTP_EXTRA_ARGS
#specify extra arguments to pass to sftp only (e.g. -f, -l)
#
--scp-extra-args=SCP_EXTRA_ARGS
#specify extra arguments to pass to scp only (e.g. -l)
#
--ssh-extra-args=SSH_EXTRA_ARGS
#specify extra arguments to pass to ssh only (e.g. -R)
#
Privilege Escalation Options:
control how and which user you become as on target hosts
-s, --sudo
#run operations with sudo (nopasswd) (deprecated, use become)
#相当于Linux系统下的sudo命令
-U SUDO_USER, --sudo-user=SUDO_USER
#desired sudo user (default=root) (deprecated, use become)
#使用sudo,相当于Linux下的sudo命令
-S, --su
#run operations with su (deprecated, use become)
#
-R SU_USER, --su-user=SU_USER
#run operations with su as this user (default=root)(deprecated, use become)
-b, --become
#run operations with become (does not imply password prompting)
#
--become-method=BECOME_METHOD
#privilege escalation method to use (default=sudo),valid choices: [ sudo | su | pbrun | pfexec | doas |dzdo | ksu | runas ]
#
--become-user=BECOME_USER
#run operations as this user (default=root)
#
--ask-sudo-pass
#ask for sudo password (deprecated, use become)
#传递sudo密码到远程主机,来保证sudo命令的正常运行
--ask-su-pass
#ask for su password (deprecated, use become)
#
-K, --ask-become-pass
#ask for privilege escalation password
#
Ansbile常用模块
Command
这个模块可以执行shell命令,但与shell模块不同(详见shell模块)
bash
如下就是一个标准命令,-m指定模块,-a指定要运行的命令(相当于模块cmmand的参数)
ansible 192.168.242.72 -m command -a 'ps -aux'
shell
他与command的区别:
- command 模块命令将不会使用 shell 执行. 因此, 像
$HOME
这样的变量是不可用的。还有像<
,>
,|
,;
,&
都将不可用。 - shell 模块通过shell程序执行, 默认是
/bin/sh
,<
,>
,|
,;
,&
可用。但这样有潜在的 shell 注入风险, 后面会详谈. - command 模块更安全,因为他不受用户环境的影响。 也很大的避免了潜在的 shell 注入风险.
bash
ansible 192.168.242.72 -m shell -a 'ps -aux'
script
用于在远程机器上执行脚本
bash
ansible db -m script -a "/root/a.sh" # 执行本地的文件,主控机的文件
ansible db -m script -a "creates=/root/a.sh /root/a.sh" # 判断被控机上的文件是否存在,如果不存在,就执行,如果存在,就跳过
ansible db -m script -a "creates=/tmp /root/a.sh" # 判断被控机上的文件或目录是否存在,如果存在则不执行,如果不存在,则执行
copy
- src : 源文件 指定拷贝文件的本地路径 (如果有/ 则拷贝目录内容,比拷贝目录本身)
- dest: 指定目标路径
- mode: 设置权限
- backup: 备份源文件
- content: 代替src 指定本机文件内容,生成目标主机文件
bash
> ansible websrvs -m copy -a "src=/root/test1.sh dest=/tmp/test2.sh owner=wang mode=600 backup=yes"
如果目标存在,默认覆盖,此处指定先备份
> ansible websrvs -m copy -a "content='test content\nxxx' dest=/tmp/test.txt"
指定内容,直接生成目标文件
fetch
Fetch:从远程主机提取文件至主控端,copy相反,目前不支持目录,可以先打包,再提取文件
bash
> ansible websrvs -m fetch -a 'src=/root/test.sh dest=/data/scripts'
会生成每个被管理主机不同编号的目录,不会发生文件名冲突
> ansible all -m shell -a 'tar jxvf test.tar.gz /root/test.sh'
> ansible all -m fetch -a 'src=/root/test.tar.gz dest=/data/'
file
- File:设置文件属性
- path: 要管理的文件路径 (强制添加)
- recurse: 递归,文件夹要用递归
- src: 创建硬链接,软链接时,指定源目标,配合'state=link' 'state=hard' 设置软链接,硬链接
- state: 状态
- absent 缺席,删除
bash
ansible websrvs -m file -a 'path=/app/test.txt state=touch'
# 创建文件
ansible websrvs -m file -a "path=/data/testdir state=directory"
# 创建目录
ansible websrvs -m file -a "path=/root/test.sh owner=wang mode=755"
# 设置权限755
ansible websrvs -m file -a 'src=/data/testfile dest=/data/testfile-link state=link'
# 创建软链接
ansible srv -m file -a 'path=/data/test.txt state=touch'
# 创建空文件
ansible srv -m file -a 'path=/data/test.txt state=absent'
#删除空文件
ansible srv -m file -a 'path=/root/test.txt owner=linux mod=755'
#创建文件时,指定文件属主和权限
ansible srv -m file -a 'path=/data/mysql state=directory owner=mysql group=mysql'
# 创建目录
ansible srv -m file -a 'path=/data/mysql state=absent'
# 删除目录
ansible srv -m file -a 'src=/data/testfile dest=/data/testfilelink state=link'
# 创建软链接
ansible srv -m file -a 'src=/data/testfile dest=/data/testfilelink state=absent'
# 删除软链接
ansible 192.168.42.210 -m file -a 'path=/root/tester/ state=directory recurse=True owner=zxnbmk group=zxnbmk mode=700'
# 递归设置目录及文件属性,必须和state=directory结合使用
unarchive(解压)
unarchive:解包解压缩,有两种用法:
- 将ansible主机上的压缩包传到远程主机后解压缩至特定目录,设置copy=yes.
- 将远程主机上的某个压缩包解压缩到指定路径下,设置copy=no
- copy:默认为yes,当copy=yes,拷贝的文件是从ansible主机复制到远程主机上,如果设置为copy=no,会在远程主机上寻找src源文件
- src: 源路径,可以是ansible主机上的路径,也可以是远程主机上的路径,如果是远程主机上的路径,则需要设置copy=no
- dest:远程主机上的目标路径
- mode:设置解压缩后的文件权限
bash
ansible websrvs -m unarchive -a 'src=foo.tgz dest=/var/lib/foo'
#默认copy为yes ,将本机目录文件解压到目标主机对应目录下
ansible websrvs -m unarchive -a 'src=/tmp/foo.zip dest=/data copy=no mode=0777'
# 解压被管理主机的foo.zip到data目录下, 并设置权限777
ansible websrvs -m unarchive -a 'src=https://zxnbmk.com/example.zip dest=/data copy=no'
# 解压网络上的压缩包到被控主机的/data下
archive(压缩)
- Archive:打包压缩,将远程主机目录打包
- path: 指定路径
- dest: 指定目标文件
- format: 指定打包格式
- owner: 指定所属者
- mode: 设置权限
bash
ansible all -m archive -a 'path=/etc/sysconfig dest=/data/sysconfig.tar.bz2 format=bz2 owner=wang mode=0777'
# 压缩被控主机的/data/sysconfig.tar.bz2到/etc/sysconfig路径
Hostname
没什么好说的
bash
ansible appsrvs -m hostname -a "name=zxnbmk"
# 更改一组的主机名
ansible 192.168.38.103 -m hostname -a "zxnbmk"
# 更改单个主机名
Cron
- name:任务计划名称
- cron_file:替换客户端该用户的任务计划的文件
- minute:分(0-59, * ,*/2)
- hour:时(0-23, * ,*/2)
- day:日(1-31, * ,*/2)
- month:月(1-12, * , */2)
- weekday:周(0-6或1-7, *)
- job:任何计划执行的命令
- backup:是否备份之前的任务计划
- user:新建任务计划的用户
- state:指定任务计划present、absent
- disabled:yes代表禁用默认启用或no
bash
ansible websrvs -m cron -a "minute=*/5 job='/usr/sbin/ntpdate 172.16.0.1 &>/dev/null' name=Synctime" #创建任务
ansible websrvs -m cron -a 'state=absent name=Synctime'
#删除任务
ansible websrvs -m cron -a 'minute=*/10 job='/usr/sbin/ntpdate 172.30.0.100" name=synctime disabled=yes'
#注释任务,不在生效,添加时名字必须不同,不加名称为None(crontab -l查看计划任务)
ansible web -m cron -a "minute=12 name=touchfile job='touch /tmp/xiaoqiang.txt'"
# 该计划任务将在每分钟的第12秒执行,任务内容是在 /tmp 目录下创建一个名为 xiaoqiang.txt 的文件。
ansible web -m cron -a "name=touchfile state=absent"
# 如果存在名为 touchfile 的 cron 任务,则将其删除。
ansible web -m cron -a "minute=12 name=touchfile2 job='touch /tmp/jason.txt' disabled=yes"
# 每分钟12秒)执行 touch /tmp/jason.txt 这个操作,但是被禁用了
ansible web -m cron -a "name=None state=absent"
# 删除名称为空的计划任务
ansible nginx-servers -m cron -a "minute=*/2 hour=2,5 name=makedir job='mkdir /tmp/test'"
每天2点和5点的这两个小时的时候每两分钟运行一次'mkdir /tmp/test'
ansible test -m cron -a "name='check dirs' hour=5,2 job='ls -alh'"
每天的2点和5点这两个小时的时候运行'ls -alh' (故意写成5,2 实际上反着写的效果依然是你想的那样)
Yum
- enablerepo 启用某个源
- disablerepo 禁用某个源
- name:要进行操作的软件包的名字,也可以传递一个url或者一个本地的rpm包的路径
State:present安装(installed也可以) absent删除(removed) latest安装最新的
bash
ansible all -m yum -a "name=php,php-mysql,php-gd state=present"
# 安装php,php-mysql,php-gd
ansible all -m yum -a "name=epel state=present enablerepo=epel"
# 启用epel
ansible all -m yum -a "name=epel state=present disablerepo=epel"
# 禁用epel
service
- enabled:开机启动 yes|no
- name:服务名称,必选项
- runlevel:运行级别
- state:started,stopped,restarted,reloaded
bash
ansible srv -m service -a 'name=httpd state=stopped'
#停止服务httpd
ansible srv -m service -a 'name=httpd state=started enabled=yes'
#启动服务,并设为开机自启httpd
ansible srv -m service -a 'name=httpd state=reloaded'
#重新加载httpd
ansible srv -m service -a 'name=httpd state=restarted'
#重启服务httpd
ansible web -m service -a "name=httpd state=started"
#启动httpd
ansible web -m service -a "name=keepalived enabled=yes"
#设置keepalived开机自启动
systemd
systemd模块用于控制远程主机的systemd服务,说白了,就是Linux下的systemd命令。需要远程主机支持systemd。用法和service模块基本相同。
bash
ansible test -m systemd -a "name=httpd state=started"
ansible test -m systemd -a "name=httpd state=stopped"
ansible test -m systemd -a "name=httpd state=restarted"
ansible test -m systemd -a "name=httpd state=reloaded"
User
- User:管理用户
- group:属组
- groups: 附加组
- home:设置家目录
- comment:为用户添加注释,也就是/etc/passwd的第五列
- name:用户名
- remove:删除用户并删除用户的家目录
- shell:用户登录后的shell
- system:系统用户
- uid:用户的id
- state:
-
- present(默认值):用于确保指定用户存在。如果用户不存在,Ansible会创建该用户;如果用户已存在,Ansible会根据其他参数(如 password、groups 等)来更新
- absent:用于确保指定用户不存在。如果用户存在,Ansible会删除该用户及其主目录(默认情况下,可通过 remove=yes 控制是否删除主目录等相关文件和目录)。
- locked:锁定指定用户,使其无法登录系统。这通常通过修改用户的密码过期信息来实现。
- unlocked:解锁指定用户,使其可以正常登录系统。
- shell:制定用户shell环境
bash
ansible websrvs -m user -a 'name=user1 comment="test user" uid=2048 home=/app/user1 group=root'
# 简单的创建一个用户
ansible websrvs -m user -a 'name=user1 state=absent remove=yes'
#清空用户所有数据
ansible websrvs -m user -a 'name=app uid=88 system=yes home=/app groups=root shell=/sbin/nologin password="$ogwd$dzsyfVddojmPddy$dZIdcLcvxnX"'
# 创建用户
ansible websrvs -m user -a 'name=app state=absent'
# 不会删除家目录
group
- gid:组id
- system:系统组
- name:组名称
bash
ansible web -m group -a "name=zxnbmk system=yes gid=1000"
# 创建系统组
ansible web -m group -a "name=zxnbmk"
# 创建普通的组
ansible web -m group -a "name=zxnbmk state=absent"
# 删除组
mount
- src:指定要挂载的设备或分区路径。
- path:指定要挂载到的目标路径。
- fstype:指定要挂载的文件系统类型。
- state:指定挂载状态,可选值为 mounted(写入文件➕挂载)、unmounted (只写入开机挂载文件,不立即挂载)或 absent(卸载设备并清理开机自动挂载文件) 。
- opts:指定挂载选项,例如挂载选项或参数。
bash
ansible dbservers -m mount -a 'src=/dev/sr0 path=/mnt state=mounted fstype=iso9660'
#使用 Ansible 的 mount 模块将设备 /dev/sr0 的内容挂载到目标路径 /mnt。
#文件系统类型为 iso9660,并将该设备标记为已挂载状态
setup
- setup 模块用于收集远程主机的一些基本信息。
- filter参数:用于进行条件过滤。如果设置,仅返回匹配过滤条件的信息。
bash
ansible websrvs -m setup
# 返回的信息非常多,很多情况我们并不需要全部的信息,可以通过过滤获得指定的信息。获取主机ip
ansible websrvs -m setup -a "filter=ansible_all_ipv4_addresses"
# 获取对应主机ipv4地址
ansible ansible-demo3 -m setup -a "filter=*mb"
# 通过通配符实现模糊匹配,比如以"mb"关键字结尾的信息
firewalld
- state:必须参数,指定防火墙策略状态,enable表示策略生效(放行流量),disable表示策略禁用(阻止流量),present表示新建策略,absent表示删除策略·
- service:向防火墙添加/删除的服务名称,该服务必须在firewall-cmd --get-services可以查询到·
- port:要从防火墙添加或删除端口或端口范围,必须以端口/协议,端口范围/协议的形式书写·
- permanent:保存策略,在下次启动时自动加载
- immediate:配置永久策略后立即生效·
- interface:添加/删除 出入防火墙的接口·
- offline:脱机状态运行防火墙·
- zone:添加/删除防火墙区域,有如下区域可供配置
- drop:丢弃所有进入的包,而不给出任何响应
- block:拒绝所有外部发起的连接,允许内部发起的连接
- public:允许指定的进入连接
- extermal:同上,对伪装的进入连接,一般用于路由转发
- dmz:允许受限制的进入连接
- work:允许受信任的计算机被限制的进入连接,类似 workgroup
- home:同上,类似 homegroup
- intermal:同上,范围针对所有互联网用户
- trusted:信任所有连接·
- source:指定从防火墙添加/删除的网段·
- timeout:非永久性规则的生效时间
bash
ansible all -m firewalld -a 'port=443/tcp permanent=no state=enabled'
# 启用443端口放行
ansible all -m firewalld -a 'service=http permanent=no state=enabled'
# http的端口放行
get_url
用于将文件或软件从http、https或ftp下载到本地节点上或被管理机节点上
bash
ansible 192.168.42.210 -m get_url -a "dest=/opt/ owner=zxnbmk group=zxnbmk mode=600
url=http://archive.apache.org/dist/httpd/httpd-2.4.7.tar.gz"
下载到192.168.42.210上的/opt/下
Playbook文件编写
- Hosts 执行的远程主机列表
-
- Websrvs:dbsrvs #或者,两个组的并集
Websrvs:&dbsrvs #与,两个组的交集
webservers:!phoenix #在websrvs组,但不在dbsrvs组
- Websrvs:dbsrvs #或者,两个组的并集
- Tasks 任务集
- Variables 内置变量或自定义变量在playbook中调用
- Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件Handlers 和 notify 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间依然会非常地长。此时,如果确信其没有变化,就可以通过tags跳过此些代码片断
安装nginx实例:
yaml
---
# install nginx
- hosts: nginx
remote_user: root
tasks:
- name: add group nginx
user: name=nginx state=present
- name: add user nginx
user: name=nginx state=present group=nginx
- name: Install Nginx
yum: name=nginx state=present
- name: web page
copy: src=files/index.html dest=/usr/share/nginx/html/index.html
- name: Start Nginx
service: name=nginx state=started enabled=yes
handlers和notify结合使用触发条件
Handlers 实际上就是一个触发器 ,是task列表,这些task与前述的task并没有本质上的不同 ,用于当关注的资源发生变化时,才会采取一定的操作
Notify此action可用于在每个play的最后被触发,这样可避免多次有改变发生时每次都执行指定的操作,仅在所有的变化发生完成后一次性地执行指定操作。在notify中列出的操作称为handler,也即notify中调用handler中定义的操作
yaml
---
- name: Example Playbook
hosts: web_servers
tasks:
- name: Install Apache
apt:
name: apache2
state: present
notify:
- Restart Apache
- name: Copy Apache configuration
copy:
src: httpd.conf
dest: /etc/apache2/httpd.conf
notify:
- Restart Apache
handlers:
- name: Restart Apache
service:
name: apache2
state: restarted
- name: zxnbmk
service:
name: stop apache2
state: stopped
在上述示例中,
Install Apache
和Copy Apache configuration
这两个任务都标记了通知Restart Apache
这个 Handler。要是这些任务的状态发生了改变(例如安装了新软件或者配置文件被更新),Restart Apache
这个 Handler 就会在所有任务执行完毕后运行。如果触发zxnbmk
那就执行zxnbmk这个Handler,当然一个notify
可以触发多个标记
tags
yaml
---
- name: Example Playbook with Tags
hosts: web_servers
tasks:
- name: Install Apache
apt:
name: apache2
state: present
tags:
- install
- apache
- name: Start Apache
service:
name: apache2
state: started
tags:
- start
- apache
- name: Copy Apache configuration
copy:
src: httpd.conf
dest: /etc/apache2/httpd.conf
tags:
- config
- apache
ansible-playbook example.yml --tags "install"
上面这个命令即可只执行tags标记为install的这部分语句
remote_user
remote_user: 可用于Host和task中。也可以通过指定其通过sudo的方式在远程主机上执行任务,其可用于play全局或某任务;此外,甚至可以在sudo时使用sudo_user指定sudo时切换的用户
yaml
- hosts: websrvs
remote_user: root
tasks:
- name: test connection
ping:
remote_user: zxnbmk
sudo: yes #开启权限提升功能
sudo_user: zxnbmk #sudo给到zxnbmk
Playbook中的变量
在 Playbook 内定义
yaml
# vi http.yaml
---
- name: Example Playbook with Variables
hosts: web_servers
vars:
http_port: 80
max_clients: 200
tasks:
- name: Display Variables
debug:
msg: "HTTP port is {{ http_port }} and max clients are {{ max_clients }}"
在单独的文件中定义
yaml
# vars.yml
http_port: 8080
max_clients: 300
# vi http.yaml
---
- name: Example Playbook with External Variables
hosts: web_servers
vars_files:
- vars.yml
tasks:
- name: Display Variables
debug:
msg: "HTTP port is {{ http_port }} and max clients are {{ max_clients }}"
j2文件定义变量
yaml
# vi httpd.conf.j2
Listen {{ http_port }}
MaxClients {{ max_clients }}
# vi http.yaml
- name: Copy Apache Configuration
template:
src: httpd.conf.j2
dest: /etc/apache2/httpd.conf
notify:
- Restart Apache
template
模块的作用是将 Jinja2 模板文件渲染成普通文件,并复制到目标主机的指定位置。Jinja2 模板允许在文件中使用变量、循环、条件语句等动态内容,使得配置文件可以根据不同的环境进行灵活生成。如果这里不用j2就要写一个配置文件,然后使用copy模块了
主机清单中定义变量
yaml
# 主机变量
192.168.242.5 http_port=80 max_clients=200
192.168.242.6 http_port=8080 max_clients=300
# 组变量
[webservers]
192.168.242.5 http_port=82
192.168.242.6
[webservers:vars]
http_port=80
max_clients=200
---
- name: Example Playbook with Inventory Variables
hosts: webservers
tasks:
- name: Display Variables
debug:
msg: "HTTP port for {{ inventory_hostname }} is {{ http_port }} and max clients are {{ max_clients }}"
主机级别的变量优先级大于组级变量(
inventory_hostname
属于 Ansible 的内置变量,其用途是标识清单中的主机名)
变量的注册(debug用)
yaml
---
- hosts: 192.168.20.23
remote_user: root
tasks:
- name: Shell Command
shell: netstat -ntlp
register: port_status
- name: Get Port Status
debug: msg="{{ port_status.stdout_lines }}"
register会将Shell Command的结果存储,然后再后面的debug中打印出来变量名注意是register标记的值,stdout_lines将内容按行分割,存储为一个列表。列表中的每个元素代表标准输出的一行内容。
roles
角色(roles):角色集合 ,可以将多个的role,分别放至roles目录下的独立子目录中
roles目录结构:
playbook.yml 调用角色
roles/
project/ (角色名称)
tasks/
files/
vars/
templates/
handlers/
default/ 不常用
meta/ 不常用
例:单个完整目录
role.yml(与roles目录同级)
Ansible/
├── roles
│ └── mysql
│ ├── defaults
│ │ └── main.yaml
│ ├── files
│ │ └── mysql.conf
│ ├── handlers
│ ├── meta
│ │ └── main.yaml
│ ├── tasks
│ │ ├── main.yaml
│ │ └── mysql.yaml
│ ├── templates
│ │ └── init.j2
│ └── vars
│ └── main.yaml
└── site.yaml
项目根目录
site.yaml
:它是 Ansible 项目的主剧本文件。在执行 Ansible 任务时,通常会从这个文件开始。此文件可用于组织和调用各个角色,从而实现对多个主机或主机组的配置管理。
roles
目录
roles
目录用于存放 Ansible 角色,每个角色对应一个特定的功能或任务,像安装软件、配置服务等。这里的 mysql
角色就是用于管理 MySQL 数据库的安装与配置。
mysql
角色目录
-
defaults
目录main.yaml
:该文件定义了角色的默认变量。这些变量可在运行时被覆盖,起到为角色提供默认配置的作用。例如,你可以在此定义 MySQL 的默认版本、默认端口等。
-
files
目录mysql.conf
:此文件是静态文件,会被 Ansible 复制到目标主机。它一般包含 MySQL 的配置信息,如my.cnf
这样的配置文件。
-
handlers
目录:这里存放处理程序的 YAML 文件。处理程序是特殊的任务,只有在其他任务通知它们时才会执行。例如,当 MySQL 配置文件被修改后,可通知处理程序重启 MySQL 服务。 -
meta
目录main.yaml
:该文件用于定义角色的元数据,包含角色的依赖关系、作者信息、许可证等。通过定义依赖关系,能确保在使用该角色前,其依赖的其他角色已被正确安装和配置。
-
tasks
目录main.yaml
:它是角色的主任务文件,会包含其他任务文件,也可直接定义任务。mysql.yaml
:这个文件包含与 MySQL 相关的具体任务,例如安装 MySQL、创建数据库、创建用户等。
-
templates
目录init.j2
:这是一个 Jinja2 模板文件,Ansible 会根据该模板生成动态文件。在生成文件时,可使用角色变量来填充模板中的占位符。例如,可根据变量生成不同的 MySQL 初始化脚本。
-
vars
目录main.yaml
:该文件定义了角色的变量。与defaults
中的变量不同,这些变量的优先级更高,不会被轻易覆盖。通常用于存放一些固定的配置信息。
下面是一个简单的
site.yaml
示例:
yaml
---
- name: Install and configure MySQL
hosts: mysql_servers
roles:
- mysql