2026/1/16 13:54:23
网站建设
项目流程
怎么制作网站开发设计,网站开发年收入,中国企业集成网,源码出售平台ansible自动化运维
1、部署ansible
#安装软件#xff0c;创建配置文件及域名解析
[rootRocky9 ~] dnf -y install ansible #安装ansible软件
[rootRocky9 ~] mkdir ansible #创建工作目录
[rootRocky9 ~] cd ansible/
[rootRocky9 ansible] vim ansible.cfg #创建配置文件…ansible自动化运维1、部署ansible#安装软件创建配置文件及域名解析[rootRocky9 ~]dnf -yinstallansible#安装ansible软件[rootRocky9 ~]mkdiransible#创建工作目录[rootRocky9 ~]cdansible/[rootRocky9 ansible]vimansible.cfg#创建配置文件[defaults]host_key_checkingfalse#不启用主机秘钥inventoryinventory#定义主机清单为当前目录的inventory #注意不能出现注释[rootRocky9 ansible]viminventory#定义主机清单[webservers]web1ansible_host192.168.88.110 web2ansible_host192.168.88.120[clients]client1ansible_host192.168.88.130[all:vars]ansible_userrootansible_ssh_pass666666#向/etc/hosts添加域名解析[rootRocky9 ansible]sed-i/::1/a 192.168.88.110 web1/etc/hosts[rootRocky9 ansible]sed-i/::1/a 192.168.88.120 web2/etc/hosts[rootRocky9 ansible]sed-i/::1/a 192.168.88.130 client/etc/hosts[rootRocky9 ansible]cat/etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6192.168.88.130 client192.168.88.120 web2192.168.88.110 web1#设置免密登录[rootRocky9 ansible]ssh-keygen#生成公钥私钥[rootRocky9 ansible]ssh-copy-id192.168.88.130[rootRocky9 ansible]ssh-copy-id192.168.88.110[rootRocky9 ansible]ssh-copy-id192.168.88.120#测试连接[rootRocky9 ansible]ansible all --list-hosts#查看可控主机hosts(3): web1 web2 client1[rootRocky9 ansible]ansible all -mping#测试连接性2、adhoc临时命令语法ansible 主机或组列表 -m 模块 -a参数# -a是可选的[rootRocky9 ansible]ansible-doc -l|grepyum#根据名称查找模块[rootRocky9 ansible]ansible-doc yum#查看帮助目录/EXAMPLES#使用查找功能能查看使用案例1command模块[rootRocky9 ansible]ansible all -mcommand-amkdir /root/abc.txt#-m command可以省略不写web2|CHANGED|rc0web1|CHANGED|rc0client1|CHANGED|rc0[rootRocky9 ansible]ansible all -asudo shutdown -h now#command模块不支持管道和重定向2shell模块#和command命令效果相似支持管道和重定向[rootRocky9 ansible]ansible all -m shell -acat /etc/passwd | wc -lclient1|CHANGED|rc020web2|CHANGED|rc020web1|CHANGED|rc0203script模块#执行shell脚本[rootRocky9 ansible]vimtest.sh#!/bin/bashforiin{1..3}douseradduser$idone[rootRocky9 ansible]ansible all -m script -atest.sh#执行脚本内容4file模块- 可以创建文件、目录、链接等还可以修改权限、属性等 - 常用的选项 - path指定文件路径 - owner设置文件所有者 - group设置文件所属组 - state状态。touch表示创建文件directory表示创建目录link表示创建软链接absent表示删除 - mode设置权限 下面两个是创建软链接时使用的 - srcsource的简写源 - destdestination的简写目标[rootRocky9 ansible]ansible all -mfile-aname/root/abc.txt statetouch#创建文件[rootRocky9 ansible]ansible all -mfile-aname/root/ab.d statedirectory#创建目录[rootRocky9 ansible]ansible all -mfile-asrc/etc/hostname dest/root/haha statelink#创建软链接5copy模块用途从ansible本机将文件复制到其他被控制的机器 src源。控制端的文件路径 dest目标。被控制端的文件路径 content内容。需要写到文件中的内容 [rootRocky9 ansible] ansible all -m copy -a src/etc/hostname dest/root/ #拷贝本机文件到目标机 [rootRocky9 ansible] ansible all -m copy -a contenthahahhhadest/opt/abc#直接写入内容到目标机文件6fetch模块用途将文件从被控制主机取回到ansible主机 src源。被控制端的文件路径 dest目标。控制端的文件路径[rootRocky9 ansible]ansible all -m fetch -asrc/etc/hostname dest/root/#将所有目标机的hostname文件保存到本机[rootRocky9 ansible]ls/root anaconda-ks.cfg ansible client1 good web1 web2#每台主机的文件独立的目录7lineinfile模块用途用于确保存目标文件中有某一行内容也可以替换一行 path待修改的文件路径 line写入文件的一行内容 regexp正则表达式用于查找文件中的内容 [rootRocky9 ansible] ansible all -m lineinfile -a path/etc/issue linehello world #webservers组中的主机/etc/issue中一定要有一行Hello World。如果该行不存在则默认添加到文件结尾 [rootRocky9 ansible] ansible all -m lineinfile -a path/etc/issue lineci le mei regexphello#查找包含hello的行将整行内容更换为ci le mei8replace模块用途replace可以替换关键词path待修改的文件路径 replace将正则表达式查到的内容替换成replace的内容 regexp正则表达式用于查找文件中的内容[rootRocky9 ansible]ansible all -m replace -apath/etc/issue regexpci replaceccccccc#issue文件内的ci替换为ccccccc9user模块name待创建的用户名 uid用户ID group设置主组 groups设置附加组 home设置家目录 password设置用户密码 state状态。present表示创建它是默认选项。absent表示删除 remove删除家目录、邮箱等。值为yes或true都可以。[rootRocky9 ansible]ansible all -m user -anameabc statepresent groupsbin#创建用户附加组设置为bin[rootRocky9 ansible]ansible all -m user -anameuser66 password{{123|password_hash(sha512) }}[rootRocky9 ansible]ansible webservers -m user -anamelisi uid1010 groupadm groupsdaemon,root home/home/lisi#创建用户指定名称、uid、基本组、附加组、家目录[rootRocky9 ansible]ansible webservers -m user -anamezhangsan stateabsent#删除用户[rootRocky9 ansible]ansible webservers -m user -anamelisi stateabsent removeyes#删除用户同时删除家目录10group模块name待创建的组名 gid组的ID号 statepresent表示创建它是默认选项。absent表示删除[rootAAAAA ansible]ansible all -m group -anamegroup01 statepresent[rootR9 an]ansible all -m group -anamegroup01 stateabsent11yum_repository模块用于配置yum[rootR9 an]ansible all -mfile-apath/etc/yum.repos.d/rocky-lan.repo stateabsent#删除原来的yum源[rootR9 an]ansible all -m yum_repository -afiledvd.repo namedvd descriptionappstream baseurlfile:///mnt/AppStream gpgcheckno enabledyes[rootR9 an]ansible all -m yum_repository -afiledvd.repo namedvd1 descriptionbaseos baseurlfile:///mnt/BaseOS gpgcheckno enabledyes#配置第二个库时文件名一致[rootR9 an]ansible all -mmount-apath/mnt src/dev/sr0 statemounted fstypeiso9660#永久挂载[rootR9 an]ansible all -ayum repolistclient1|CHANGED|rc0仓库id仓库名称 dvd appstream dvd1 baseos web2|CHANGED|rc0仓库id仓库名称 dvd appstream dvd1 baseos web1|CHANGED|rc0仓库id仓库名称 dvd appstream dvd1 baseos12yum模块用于安装软件 name包名 state状态。present表示安装如果已安装则忽略latest表示安装或升级到最新版本absent表示卸载。[rootR9 an]ansible all -m yum -anametar statepresent[rootR9 an]ansible all -m yum -anamenet-tools,wget[rootR9 an]ansible all -m yum -anamewget stateabsent13service模块用于控制服务。启动、关闭、重启、开机自启。 常用选项 name控制的服务名 statestarted表示启动stopped表示关闭restarted表示重启 enabledyes表示设置开机自启no表示设置开机不要自启。[rootR9 an]ansible all -mservice-anamehttpd statestarted enabledyes14创建卷组lvg模块创建、删除卷组修改卷组大小 常用选项 vg定义卷组名。vgvolume group pvs由哪些物理卷构成。pvsphysical volumes[rootR9 an]ansible all -m yum -anamelvm2[rootR9 an]ansible all -m lvg -avgvg1 pvs/dev/nvme0n2#创建卷组[rootR9 an]ansible all -avgs[rootR9 an]ansible all -m lvg -avgvg1 pvs/dev/nvme0n2,/dev/nvme0n3#扩容卷组[rootR9 an]ansible all -m lvg -avgvg1 stateabsent#删除卷组15创建逻辑卷lvol模块创建、删除逻辑卷修改逻辑卷大小 常用选项 vg指定在哪个卷组上创建逻辑卷 lv创建的逻辑卷名。lvlogical volume size逻辑卷的大小不写单位以M为单位[rootR9 an]ansible all -m lvol -avgvg1 lvlv1 size2G#创建逻辑卷[rootR9 an]ansible all -alvs[rootR9 an]ansible all -m lvol -avgvg1 lvlv1 size6G#扩容逻辑卷[rootR9 an]ansible all -m lvol -avgvg1 lvlv1 stateabsent forceyes#删除逻辑卷16格式化filesystem模块用于格式化也就是创建文件系统 常用选项 fstype指定文件系统类型 dev指定要格式化的设备可以是分区可以是逻辑卷[rootR9 an]ansible all -m filesystem -afstypexfs dev/dev/vg1/lv1#格式化[rootR9 an]ansible all -ablkid /dev/vg1/lv117挂载mount模块用于挂载文件系统 常用选项 path挂载点。如果挂载点不存在自动创建。 src待挂载的设备 fstype文件系统类型 statemounted表示永久挂载[rootR9 an]ansible all -mmount-apath/data src/dev/vg1/lv1 statemounted fstypexfs#挂载[rootR9 an]ansible all -mmount-apath/data stateabsent#卸载18parted分区模块用于硬盘分区管理 常用选项 device待分区的设备 number分区编号 statepresent表示创建absent表示删除 part_start分区的起始位置不写表示从开头 part_end表示分区的结束位置不写表示到结尾19firewalld模块用于配置防火墙的模块 常用选项 port声明端口 permanent永久生效但不会立即生效 immediate立即生效临时生效 stateenabled放行disabled拒绝# 配置防火墙规则放行http协议[rootpubserver ansible]# vim firewall.yml----name:configure webservershosts:webserverstasks:-name:install nginx pkg# 这里通过yum模块装httpdyum:name:nginxstate:present-name:start nginx service# 这里通过service模块启httpd服务service:name:nginxstate:startedenabled:yes-name:install firewalld pkg# 这里通过yum模块安装firewalldyum:name:firewalldstate:present-name:start firewalld service# 这里通过service模块启service服务service:name:firewalldstate:startedenabled:yes-name:set firewalld rules# 通过firewalld模块开放80端口firewalld:port:80/tcppermanent:yesimmediate:yesstate:enabled20template模块copy模块可以上传文件但是文件内容固定 template模块可以上传具有特定格式的文件如文件中包含变量 当远程主机接收到文件之后文件中的变量将会变成具体的值 template模块上传的文件使用的语法叫Jinja2。 常用选项 src要上传的文件 dest目标文件路径# 使用template模块将含有变量的文件上传到webservers组中的主机[rootpubserver ansible]# vim index.htmlWelcome to{{ansible_hostname}}on{{ansible_eth0.ipv4.address}}[rootpubserver ansible]# vim templ.yml----name:upload indexhosts:webserverstasks:-name:create web indextemplate:src:index.htmldest:/usr/share/nginx/html/index.html3、playbookyaml文件的文件名一般以yml或yaml作为扩展名 文件一般以---作为第一行不是必须的但是常用 键值对使用冒号:表示冒号后面必须有空格。 数组使用-表示-后面必须有空格。 相同的层级必须有相同的缩进。如果缩进不对则有语法错误。每一级缩进建议2个空格。 全文不能使用tab必须使用空格。----name:testhosts:alltasks:-name:ping testping:1文件处理剧本# 在dbs组的主机和web1上创建/tmp/demo目录权限是0755。将控制端/etc/hosts拷贝到目标主机的/tmp/demo中[rootR9 an]vim file.yaml----name:create fileshosts:alltasks:-name:dirfile:path:/tmp/demostate:directorymode:0755-name:cpcopy:src:/etc/hostsdest:/tmp/dem# 在webservers组中的主机上创建用户bob附加组是adm在db1主机上创建/tmp/hi.txt其内容为Hello World.[rootR9 an]vim test02.yaml----name:userhosts:webserverstasks:-name:useruser:name:bobgroups:adm-name:filehosts:clientstasks:-name:filecopy:content:hello worlddest:/tmp/hi.txt#通过copy模块创建/tmp/1.txt文件中有两行内容分别是Hello World和ni hao[rootR9 an]touch /root/1.txt[rootR9 an]vim test03.yaml----name:1hosts:alltasks:-name:1-1copy:dest:/root/1.txtcontent:|hello world nihao2用户管理剧本#在webservers组中的主机上创建john用户它的uid是1040主组是daemon密码为123、[rootR9 an]vimtest04.yaml --- - name:1hosts: webservers tasks: - name:1-1 user: name:joinuid:1040password:{{123|password_hash(sha512)}}- name:1-2 group: name: daemony3磁盘管理剧本[rootR9 an]vim test05.yaml----name:1hosts:alltasks:-name:parted#分区1parted:device:/dev/nvme0n2number:1part_end:1GiBstate:present-name:new parted#第二次分区parted:device:/dev/nvme0n2number:2part_start:1GiBpart_end:6GiBstate:present-name:create vg#创建卷组vg1lvg:vg:vg1pvs:/dev/nvme0n2p1,/dev/nvme0n2p2-name:create lv#创建逻辑卷lvol:vg:vg1lv:lv1size:1G-name:filesystem#格式化文件系统filesystem:fstype:xfsdev:/dev/vg1/lv1-name:mounted#挂载mount:path:/datasrc:/dev/vg1/lv1state:mountedfstype:xfs4软件安装剧本# 在webservers组中的主机上安装httpd、php、php-mysqlnd[rootR9 an]vim pkg.yaml----name:install pkghosts:alltasks:-name:install pkgyum:name:httpd,php,php-mysqlndstate:present-name:install groupyum:name:Development Tools-name:updateyum:name:*state:latest4、ansible变量1facts变量常用的facts变量 ansible_all_ipv4_addresses所有的IPV4地址 ansible_bios_versionBIOS版本信息 ansible_memtotal_mb总内存大小 ansible_hostname主机名[rootR9 an]ansible webservers -m setup#查看所有facts变量[rootR9 an]ansible webservers -m setup -afilteransible_all_ipv4_addresses#查看所有的IPV4地址filter是过滤的意思[rootpubserver ansible]ansible webservers -m setup -afilteransible_memfree_mb# 查看可用内存# 显示远程主机的主机名和内存大小。在ansible中变量使用{{}}表示# debug模块用于输出信息常用的参数是msg用于输出指定内容[rootpubserver ansible]# vim debug.yml--- - name: displayhostinfo hosts: webservers tasks: - name: displayhostnameand memory debug:# debug是模块它的选项msg可以输出指定信息msg:hostname: {{ansible_hostname}}; mem: {{ansible_memtotal_mb}} MB2inventory变量# 使用inventory变量。[rootpubserver ansible]# vim inventory[webservers]web1 web2[dbs]db1 usernamewangwu# 定义主机变量的方法[webservers:vars]# 定义组变量的方法:vars是固定格式usernamezhaoliu# 通过变量创建用户[rootpubserver ansible]# vim var1.yml----name:webservers create userhosts:webserverstasks:-name:create useruser:name:{{username}}state:present-name:create user in dbshosts:dbstasks:-name:create some usersuser:name:{{username}}state:present3playbook定义变量# 在webservers组中的主机上创建用户jack他的密码是123456[rootpubserver ansible]# vim user_jack.yml----name:create userhosts:webserversvars:# 固定格式用于声明变量username:jack# 此处引号可有可无mima:123456# 此处引号是需要的表示数字字符tasks:-name:create some usersuser:name:{{username}}# {}出现在开头必须有引号state:presentpassword:{{mima|password_hash(sha512)}}4在文件中定义变量# 将变量定义在文件中[rootpubserver ansible]# vim vars.yml # 文件名自定义---yonghu:rosemima:abcd[rootpubserver ansible]# vim user_rose.yml----name:create userhosts:webserversvars_files:vars.yml# vars_files用于声明变量文件tasks:-name:create some usersuser:name:{{yonghu}}# 这里的变量来自于vars.ymlstate:presentpassword:{{mima|password_hash(sha512)}}5、进阶语法1错误处理# 编辑myerr.yml如果myslqd服务无法启动则忽略它[rootpubserver ansible]# vim myerr.yml----name:my errorshosts:webserverstasks:-name:start mysqld serviceservice:name:mysqldstate:startedenabled:yesignore_errors:yes# 即使这个任务失败了也要继续执行下去-name:touch a filefile:path:/tmp/service.txtstate:touch#通过全局设置无论哪个任务出现问题都要忽略[rootpubserver ansible]# vim myerr.yml----name:my errorshosts:webserversignore_errors:yestasks:-name:start mysqld serviceservice:name:mysqldstate:startedenabled:yes-name:touch a filefile:path:/tmp/mysql.txtstate:touch2触发执行任务通过handlers定义触发执行的任务 handlers中定义的任务不是一定会执行的 在tasks中定义的任务通过notify关键通知handlers中的哪个任务要执行 只有tasks中的任务状态是changed才会进行通知。# 修改Playbook只有配置文件变化了才重启服务[rootpubserver ansible]# vim trigger.yml----name:configure nginxhosts:webserversvars:http_port:80tasks:-name:upload nginx.conftemplate:src:./nginx.confdest:/etc/nginx/nginx.confnotify:restart nginx# 通知restart httpd需要执行handlers:-name:restart nginxservice:name:nginxstate:restarted# 第一次运行Playbook因为第1个任务是黄色的changed所以handlers中的任务也被触发执行3when条件只有满足某一条件时才执行任务 常用的操作符 相等!不等大于 小于 小于等于大于等于 多个条件或以使用and或or进行连接 when表达式中的变量可以不使用{{}}# 当dbs组中的主机内存大于2G的时候才安装mysql-server[rootpubserver ansible]# vim when1.yml----name:install mysql-serverhosts:dbstasks:-name:install mysql-server pkgyum:name:mysql-serverstate:presentwhen:ansible_memtotal_mb2048# 如果目标主机没有2GB内存则不会安装mysqld-server# 多条件。系统发行版是Rocky8才执行任务# /etc/motd中的内容将会在用户登陆时显示在屏幕上[rootpubserver ansible]# vim motd_____________ hello world-------------\ ^__^ \ (oo)\_______ (__)\ )\/\||----w|||||[rootpubserver ansible]# vim when2.yml----name:when conditionhosts:webserverstasks:-name:modify /etc/motdcopy:dest:/etc/motdsrc:motdwhen:# 以下三行合并成一行ansible_distribution Rocky and ansible_distribution_major_version 84regitster注册变量register是一个关键字可以将任务执行的结果赋值给指定的变量名称。这个变量可以在后续任务中使用。 register模块可以捕获各种类型的输出包括stdout、stderr、rc、changed等。它可以与其他模块一起使用例如“when”条件、“loop”循环等。# 在web1组的主机上执行任务创建/tmp/regfile1.txt并打印创建结果[rootpubserver ansible]# vim reg1.yml----name:create file /tmp/regfile1.txthosts:web1tasks:-name:create filefile:path:/tmp/rgefile1.txtstate:touchregister:result-name:display outputdebug:msg:{{result}}# 在web1主机上执行任务创建文件/tmp/ademo/abc。如果创建不成功则通过debug输出create failed[rootpubserver ansible]# vim reg2.yml----name:create file /tmp/ademo/abchosts:web1ignore_errors:yestasks:-name:create filefile:path:/tmp/ademo/abcstate:touchregister:result-name:debug outputdebug:msg:create failedwhen:result.failed5block任务快可以通过block关键字将多个任务组合到一起 可以将整个block任务组一起控制是否要执行# 如果webservers组中的主机系统发行版是Rocky则安装并启动nginx[rootpubserver ansible]# vim block1.yml----name:block taskshosts:webserverstasks:-name:define a group of tasksblock:-name:install nginx# 通过yum安装nginxyum:name:nginxstate:present-name:start nginx# 通过service启动nginx服务service:name:nginxstate:startedenabled:yeswhen:ansible_distributionRocky# 条件为真才会执行上面的任务6rescue和alwaysblock和rescue、always联合使用 block中的任务都成功rescue中的任务不执行 block中的任务出现失败failedrescue中的任务执行 block中的任务不管怎么样always中的任务总是执行[rootpubserver ansible]# vim block2.yml----name:block testhosts:webserverstasks:-name:block / rescue / always test1block:-name:touch a filefile:path:/tmp/test1.txtstate:touchrescue:-name:touch file test2.txtfile:path:/tmp/test2.txtstate:touchalways:-name:touch file test3.txtfile:path:/tmp/test3.txtstate:touch# 执行playbook web1上将会出现/tmp/test1.txt和/tmp/test3.txt7loop循环相当于shell中for循环 ansible中循环用到的变量名是固定的叫item# 在test组中的主机上创建5个目录/tmp/{aaa,bbb,ccc,ddd,eee}[rootpubserver ansible]# vim loop1.yml----name:use loophosts:webserverstasks:-name:create directoryfile:path:/tmp/{{item}}state:directoryloop:[aaa,bbb,ccc,ddd,eee]# 上面写法也可以改为----name:use loophosts:webserverstasks:-name:create directoryfile:path:/tmp/{{item}}state:directoryloop:-aaa-bbb-ccc-ddd-eee# 使用复杂变量。创建zhangsan用户密码是123创建lisi用户密码是456# item是固定的用于表示循环中的变量# 循环时loop中每个-后面的内容作为一个整体赋值给item。# loop中{}中的内容是自己定义的写法为key:val# 取值时使用句点表示。如下例中取出用户名就是{{item.uname}}[rootpubserver ansible]# vim loop_user.yml----name:create usershosts:webserverstasks:-name:create multiple usersuser:name:{{item.uname}}password:{{item.upass|password_hash(sha512)}}loop:-{uname:zhangsan,upass:123}-{uname:lisi,upass:456}8role角色为了实现playbook重用可以使用role角色 角色role相当于把任务打散放到不同的目录中 再把一些固定的值如用户名、软件包、服务等用变量来表示 role角色定义好之后可以在其他playbook中直接调用# 使用常规playbook修改/etc/motd的内容# 1. 创建motd模板文件[rootpubserver ansible]# vim motdHostname:{{ansible_hostname}}# facts变量主机名Date:{{ansible_date_time.date}}# facts变量日期Contact to:{{admin}}# 自定义变量# 2. 编写playbook[rootpubserver ansible]# vim motd.yml----name:modifty /etc/motdhosts:webserversvars:admin:roottedu.cn# 自定义名为admin的变量tasks:-name:modify motdtemplate:src:motddest:/etc/motd[rootpubserver ansible]# ansible-playbook motd.yml[rootweb1 ~]# cat /etc/motdHostname:web1Date:2021-11-01Contact to:roottedu.cn# 创建角色# 1. 声明角色存放的位置[rootpubserver ansible]# vim ansible.cfg[defaults]inventory hosts roles_path roles# 定义角色存在当前目录的roles子目录中# 2. 创建角色目录[rootpubserver ansible]# mkdir roles# 3. 创建名为motd的角色[rootpubserver ansible]# ansible-galaxy init roles/motd[rootpubserver ansible]# ls roles/motd# 生成了motd角色目录[rootpubserver ansible]# yum install -y tree[rootpubserver ansible]# tree roles/motd/roles/motd/ ├── defaults# 定义变量的目录优先级最低│ └── main.yml ├── files# 保存上传的文件如copy模块用到的文件├── handlers# handlers任务写到这个目录的main.yml中│ └── main.yml ├── meta# 保存说明数据如角色作者、版本等│ └── main.yml ├── README.md# 保存角色如何使用之类的说明├── tasks# 保存任务│ └── main.yml ├── templates# 保存template模块上传的模板文件├── tests# 保存测试用的playbook。可选│ ├── inventory │ └── test.yml └── vars# 定义变量的位置推荐使用的位置└── main.yml# 4. 将不同的内容分别写到对应目录的main.yml中# 4.1 创建motd模板文件[rootpubserver ansible]# vim roles/motd/templates/motdHostname:{{ansible_hostname}}Date:{{ansible_date_time.date}}Contact to:{{admin}}# 4.2 创建变量[rootpubserver ansible]# vim roles/motd/vars/main.yml # 追加一行admin:zzgtedu.cn# 4.3 创建任务[rootpubserver ansible]# vim roles/motd/tasks/main.yml # 追加-name:modify motdtemplate:src:motd# 这里的文件自动到templates目录下查找dest:/etc/motd# 5. 创建playbook调用motd角色[rootpubserver ansible]# vim role_motd.yml----name:modify motd with rolehosts:webserversroles:-motd# 6. 执行playbook[rootpubserver ansible]# ansible-playbook role_motd.yml