ansibleplaybookplaybookyml说明playbook由一个或多个play组成。playbook中每个play必须包含hosts和tasks。playbook以yaml语法编写。可读性强脚本语言交互性能力强使用实现语言的数据类型一致性的信息模型易于实现基于流模式处理表达能力好,扩展性强YAML约定以开头和开始不同的play。YAML以作为注释。YAML必须统一缩进,空格与tab不能混用,缩进的级别也必须相同,同级缩进代表同样的级别。YAML文件内容是大小写敏感的,跟Linux一样区分大小写。YAMLkeyvalue形式可写在同一行也可以换行写。同行使用:隔开。YAML一个完整的代码块功能最少包含2个元素。如name:taskYAML一个name下只能包含一个taskYAML开头的为列表,keyvalue形式的为字典。YAML特性playbook核心元素hosts远程主机列表(ipaddrhostnamegroupname)tasks任务集,任务列表,有两种写法。action:moduleargsaction参数。module:args参数(一般使用这种)。ignoreerrors:True当前task出错时仍然会向下执行。varniables内置变量或自定义变量在playbook文件中调用。templates模板,可替换模板文件中的变量并实现一些简单逻辑的文件。handles与notity结合使用,由特定条件触发的操作,满足条件执行,否则不执行。tags标签指定任务执行,用于执行一个playbook中的部分代码。主要用于测试ansible的语法与执行验证。ansibleplaybook命令ansibleplaybookCcheckCheck检查脚本运行情况,不会在远程服务器里运行。listhosts列出执行此任务的主机。listtasks列出任务组的具体任务列表。limit只对主机列表中的某台主机执行。vvvvvv显示详细的执行DEBUG信息过程,多个v参数等于DEBUG信息的叠加,显示更为详细。ansibleplaybooksetup介绍:这个模块默认会被playbooks自动调用,用于收集远程主机的相关变量信息,获取到变量信息可以被playbooks调用。针对setup模块,我们经常使用的是fact,在此只对fact做详细讲解,其他的就不过多叙述了,如果想了解详细信息,可以访问官方文档获取帮助。fact是ansible模块setup的功能,主要用于获取相关信息作为变量继承给playbook子任务调用。gatherfacts:ansiblek3sclustermsetupubuntu20bj03SUCCESS{ansiblefacts:{ansibleallipv4addresses:〔10。0。16。4〕,ansibleallipv6addresses:〔fe80::5054:ff:fed6:42a8〕,ansibleapparmor:{status:enabled},ansiblearchitecture:x8664,ansiblebiosdate:04012014,ansiblebiosvendor:SeaBIOS,ansiblebiosversion:seabios1。9。1qemuproject。org,ansibleboardassettag:NA,ansibleboardname:NA,ansibleboardserial:NA,ansibleboardvendor:NA,ansibleboardversion:NA,ansiblechassisassettag:NA,ansiblechassisserial:NA,ansiblechassisvendor:Smdbmds,ansiblechassisversion:3。0,多余的冗余信息就不放了,自己可以执行验证下。setup获得变量信息,都可以用于继承给playbook调用。}自定义Fact手动设置:ansible除了能获取到内置的fact的变量信息,还可以手动为某个主机组或者主机定制本地fact。本地fact默认存放宿主机的etcansiblefacts。d目录下,支持的文件格式为ini、json。加载后的fact的key是ansiblelocal的特殊变量。 denistest。fact〔general〕packagevsftpdservicevsftpdstatestarte setupfacts。yamlname:InstallRemoteFactshosts:k3sclustervars:remotedir:etcansiblefacts。dfactsfile:denistest。facttasks:name:CreateDirectoryfile:state:directoryrecurse:yespath:{{remotedir}}name:Installthenewfactscopy:src:{{factsfile}}dest:{{remotedir}} 执行测试ansibleplaybooksetupfacts。yamlansibletestmsetupubuntu20bj03SUCCESS{ansiblefacts:{分隔符ansiblelocal:{custom:{general:{package:vsftpd,service:vsftpd,state:started}}},分隔符} 调用测试 denisstest。yamlname:InstallApacheandstartstheservicehosts:k3sclustertasks:name:InstallPackageyum:name:{{ansiblefacts。ansiblelocal。custom。general。package}}state:latestname:StartServiceservice:name:{{ansiblefacts。ansiblelocal。custom。general。service}}state:{{ansiblefacts。ansiblelocal。custom。general。state}}ansibleplaybooksetfact使用setfact设置新的变量setfact可以自定义变量通过template或者变量的方式在playbook中继承使用。如:假设你需要获取一个进程使用的内存的使用率,必须通过setfact来进行计算之后得出结果,并将其值在playbook中继承使用。 denissfactdemo。yamlname:setfactdemohosts:k3sclustertasks:name:CalculateInnoDBbufferpoolsizesetfact:innodbbufferpoolsizemb{{ansiblememtotalmb2int}}debug:varinnodbbufferpoolsizemb 执行测试ansibleplaybookdenissfactdemo。yamlPLAY〔setfactdemo〕TASK〔GatheringFacts〕ok:〔ubuntu20bj03〕TASK〔CalculateInnoDBbufferpoolsize〕ok:〔ubuntu20bj03〕TASK〔debug〕ok:〔ubuntu20bj03〕{innodbbufferpoolsizemb:2911。2}PLAYRECAPubuntu20bj03:ok3changed0unreachable0failed0skipped0rescued0ignored0手动采集fact我们在运行playbook的时候,Ansible会先ssh连接被控端采集fact,如果被控制端的ssh还没有完成运行,就会导致整个playbook执行失败。解决这个问题,可以先在配置中关闭fact采集,然后在task中通过waitfor探测被控端ssh端口是否正常监听,然后在task中在手动setup模块来采集fact。hosts:k3sclustername:testdemogatherfacts:Falsetasks:name:waitforsshtoberunninglocalaction:waitforport22host{{inventoryhostname}}searchregexOpenSSHname:gatherfactssetup:fact缓存如果在playbook中需要继承fact,可启用fact缓存来提高效率。fact支持缓存json、memcached、redisansible。cfg中的配置说明:json以json格式文件作为fact缓存后端,ansible将会把采集的fact写入到宿主机的本地目录,最好是SSD硬盘。redis使用redis做缓存。memcached使用memcached做缓存。smart表示默认收集facts,但facts已有的情况下不会收集,即使用缓存facts;implicit表示默认收集facts,要禁止收集,必须使用gatherfacts:False;explicit则表示默认不收集,要显式收集,必须使用gatherfacts:Ture。〔defaults〕gatheringsmart缓存时间factcachingtimeout86400factcaching{jsonfileredismemcached}指定ansible包含fact的json文件位置,如果目录不存在,会自动创建localfactcachingconnectiontmpansiblefactcacheredisfactcachingconnection127。0。0。1:6379:adminmemcachedfactcachingconnection〔127。0。0。1:11211〕关闭fact(提高执行效率)在配置中关闭fact,整个playbookfact变量将不会在显示,可以提高执行效率,但是有时候又需要使用facts中的信息,这时候可以按照上述设置facts的缓存,在空闲的时候收集facts,缓存下来,在需要的时候直接读取缓存进行引用。playbook配置hosts:k3sclustergatherfacts:noansible。cfg配置〔defaults〕gatheringexplicitansibleplaybook变量变量名要求:只允许使用字母、数字、组成,而且只能以字母开头。内置的公共变量:ansiblek3sclustermsetupafilteraddresses可使用filter参数进行过滤使用ansiblek3sclustermsetup可以获取到主机的系统变量名称通过文件自定义变量:对主机组中的主机单独定义变量,优先级高于公共变量。对主机组中的所有主机定义统一变量,优先级低于对单独主机定义的变量。etcansiblehosts文件中定义〔appserver〕定义变量nodeid10。0。8。2nodeid17对主机组定义统一变量domainname〔k3scluster:vars〕domainnamedeniss。wang使用变量灵活配置不同主机的hostnamehosts:k3sclusterbecome:yesbecomeuser:roottasks:name:sethostnamehostname:name{{nodeid}}。{{domainname}}通过命令行定义变量:通过命令行定义的变量优先级是最高的ansibleplaybookevarnamevalur在playbook文件里定义变量。通过{{变量名}}使用变量,另外需要注意的是,如果有中文,需要使用把变量括起来。通过vars:列表定义多个变量。hosts:k3sclusterremoteuser:root定义变量vars:pkgname:httpdenvname:prodtasks:name:{{envname}}install{{pkgname}}yum:name{{pkgname}}通过定义单独的变量文件用于统一存放变量,可避免变量的重复定义。定义单独的变量文件,只需要将所有变量以key:value形式写入到yaml文件中既可。在playbook文件中,只需要使用varsfiles:指定yaml文件路径既可。vars。yaml变量文件pkgname:httpdfilename:deniss。wanginstall。yamlhosts:k3sclusterremoteuser:root配置模板文件varsfiles:指定文件的路径vars。yamltasks:name:install{{pkgname}}yum:name{{pkgname}}name:create{{filename}}filefile:nametmp{{filename}}。txtstatetouch执行playbook操作ansibleplaybookinstall。yamlPLAY〔k3scluster〕TASK〔GatheringFacts〕ok:〔10。0。8。2〕TASK〔installhttpd〕changed:〔10。0。8。2〕TASK〔createdeniss。wangfile〕changed:〔10。0。8。2〕PLAYRECAP10。0。8。2:ok3changed2unreachable0failed0skipped0rescued0ignored0ansibleplaybooktemplatetemplate是ansibleplaybook一个模块,用于存放生成配置的模板,使用jinja2语言编写,后缀为xx。j2,只能用于playbook。templates文件,可嵌套引用脚本。字符串:使用单引号或双引号。数字:整数,浮点数。列表:〔A1,A2,〕元组:(B1,B2,)字典:{key1:value1,key2:value2,}布尔值:truefalse算术运算:,,,,,,比较操作:,!,,,,逻辑运算:and,or,not流表达式:for,if,whenJinja2语法:templates根据模板块文件动态生成对应的配置文件templates的模板文件必须存放于templates目录下,并且以。j2为后缀。templates目录需要与playbook的yaml文件在同级目录中。treenginxnginx。yamltemplatesnginx。conf。j2 算术运算nginx。conf。j2usernginx;这里使用环境变量vcpus2,会根据操作系统CPU自动生成。workerprocesses{{ansibleprocessorvcpus2}};errorlogvarlognginxerror。log;pidrunnginx。pid;includeusrsharenginxmodules。conf;events{workerconnections10240;}http{logformatmainremoteaddrremoteuser〔timelocal〕requeststatusbodybytessenthttprefererhttpuseragenthttpxforwardedfor;accesslogvarlognginxaccess。logmain;sendfileon;tcpnopushon;tcpnodelayon;keepalivetimeout65;typeshashmaxsize2048;includeetcnginxmime。types;defaulttypeapplicationoctetstream;includeetcnginxconf。d。conf;server{listen80defaultserver;listen〔::〕:80defaultserver;servername;rootusrsharenginxhtml;Loadconfigurationfilesforthedefaultserverblock。includeetcnginxdefault。d。conf;location{}errorpage404404。html;location40x。html{}errorpage50050250350450x。html;location50x。html{}}}nginx。yamlhosts:k3sclusterbecome:yesbecomeuser:roottasks:name:installnginxyum:namenginxname:nginxtemplateconf如果yaml与templates在同一目录,src直接写。j2文件template:srca2020imgdataimg。jpgdatasrcnginx。conf。j2destetcnginxnginx。confnotify:restartnginxname:startnginxservice:namenginxstatestartedenabledyeshandlers:name:restartnginxservice:namenginxstaterestarted when条件语句when条件语句例子treenginxnginx。yamltemplatesnginx。conf。centos7。j2nginx。conf。centos8。j2playbook文件hosts:k3sclusterbecome:yesbecomeuser:roottasks:name:installnginxyum:namenginxname:templatecentos7conf如果yaml与templates在同一目录,src直接写。j2文件。template:srca2020imgdataimg。jpgdatasrcnginx。conf。centos7。j2destetcnginxnginx。conf使用when语句进行判断如果变量为7执行以下操作when:ansibledistributionmajorversion7notify:restartnginxname:templatecentos8conf同上template:srca2020imgdataimg。jpgdatasrcnginx。conf。centos8。j2destetcnginxnginx。conf使用when语句进行判断如果变量为Ubuntu且版本为20执行以下操作when:(ansibledistributionUbuntuandansibledistributionmajorversion20notify:restartnginxname:startnginxservice:namenginxstatestartedenabledyeshandlers:name:restartnginxservice:namenginxstaterestarted执行playbook文件skipping状态表示跳过执行这个TASK。ansibleplaybooknginx。ymlPLAY〔k3scluster〕TASK〔GatheringFacts〕ok:〔10。0。8。2〕TASK〔installnginx〕ok:〔10。0。8。2〕TASK〔templatecentos7conf〕changed:〔10。0。8。2〕TASK〔templatecentos8conf〕skipping:〔10。0。8。2〕TASK〔startnginx〕ok:〔10。0。8。2〕RUNNINGHANDLER〔restartnginx〕changed:〔10。0。3。13〕PLAYRECAP10。0。8。2:ok5changed2unreachable0failed0skipped1rescued0ignored0 迭代变量withtiems迭代withitems执行重复任务。对于迭代选项,固定变量名为item。在task中使用withitems指定需要迭代的元素列表。元素列表支持字符串和字典。hosts:k3sclusterbecome:yesbecomeuser:roottasks:name:createmultifiles{{item}}为内置特殊变量,代表withitems列表中的内容file:nametmp{{item}}statetouchwithitems:fileonefiletwofilethreefilefourname:installmultisoftwareyum:name{{item}}withitems:vsftpdnettoolsiftop 代嵌套子变量(字典)迭代嵌套子变量。对迭代中的变量进行嵌套关联的操作。playbook文件hosts:k3sclusterbecome:yesbecomeuser:roottasks:name:createsomefiles{{item}}为特殊变量,代表withitmes列表中的内容file:nametmp{{item}}statetouchwithitems:fileonefiletwofilethreefilefourname:createmultigroupgroup:name{{item}}withitems:jinja2file1jinja2file2jinja2file3jinja2file4name:createmultiuser使用item。key值进行引用user:name{{item。name}}group{{item。group}}使用字典定义嵌套的子变量withitems:{name:fileone,group:jinja2file1}{name:filetwo,group:jinja2file2}{name:filethree,group:jinja2file3}{name:filefour,group:jinja2file4}name:permissionmultifilesfile:nametmp{{item。name}}owner{{item。name}}group{{item。group}}withitems:{file:fileone,name:fileone,group:jinja2file1}{file:filetwo,name:filetwo,group:jinja2file2}{file:filethree,name:filethree,group:jinja2file3}{file:filefour,name:filefour,group:jinja2file4}执行playbook文件ansibleplaybookfile。ymlPLAY〔k3scluster〕TASK〔GatheringFacts〕ok:〔10。0。8。2〕TASK〔createmultifiles〕changed:〔10。0。8。2〕(itemfileone)changed:〔10。0。8。2〕(itemfiletwo)changed:〔10。0。8。2〕(itemfilethree)changed:〔10。0。8。2〕(itemfilefour)TASK〔createmultigroup〕changed:〔10。0。8。2〕(itemjinja2file1)changed:〔10。0。8。2〕(itemjinja2file2)changed:〔10。0。8。2〕(itemjinja2file3)changed:〔10。0。8。2〕(itemjinja2file4)TASK〔createmultiuser〕changed:〔10。0。8。2〕(item{ugroup:ujinja2file1,uname:ufileone})changed:〔10。0。8。2〕(item{ugroup:ujinja2file2,uname:ufiletwo})changed:〔10。0。8。2〕(item{ugroup:ujinja2file3,uname:ufilethree})changed:〔10。0。8。2〕(item{ugroup:ujinja2file4,uname:ufilefour})TASK〔permissionmultifiles〕changed:〔10。0。8。2〕(item{ugroup:ujinja2file1,uname:ufileone,ufile:ufile1})changed:〔10。0。8。2〕(item{ugroup:ujinja2file2,uname:ufiletwo,ufile:ufile2})changed:〔10。0。8。2〕(item{ugroup:ujinja2file3,uname:ufilethree,ufile:ufile3})changed:〔10。0。8。2〕(item{ugroup:ujinja2file4,uname:ufilefour,ufile:ufile4})PLAYRECAP10。0。8。2:ok5changed4unreachable0failed0skipped0rescued0ignored0 流程控制、循环for与iffor循环{for语句块}。。。{endfor}ansibleplaybook文件hosts:k3sclusterbecome:yesbecomeuser:rootvars:列表listenport:808182字典service:name:web1domain:deniss。wangport:9090user:nginxpath:varwwwhtmlname:web2domain:deniss。wangport:9091user:nginxpath:varwwwhtmlname:web3domain:deniss。wangport:9092user:nginxpath:varwwwhtmltasks:name:copytemplateconftemplate:srca2020imgdataimg。jpgdatasrcfor。conf。j2desttmpfor。conffor。conf。j2文件{forportinlistenport}语句listenport为playbook中定义的vars。{forportinlistenport}server{listen{{port}}}{endfor}查看生成for。conf文件catrootfor。confserver{listen80}server{listen81}server{listen82}字典形式nginx。yamlhosts:k3sclusterbecome:yesbecomeuser:rootvars:字典的形式service:name:web1domain:deniss。wangport:9090user:nginxpath:varwwwhtmlname:web2domain:deniss。wangport:9091user:nginxpath:varwwwhtmlname:web3domain:deniss。wangport:9092user:nginxpath:varwwwhtmltasks:name:copytemplateconftemplate:srca2020imgdataimg。jpgdatasrcnginx。conf。j2desttmpnginx。confnginx。conf。j2文件,放在templates下面{forsinservice}user{{s。user}};workerprocesses{{ansibleprocessorvcpus2}};pidrunnginx。pid;server{listen{{s。port}}defaultserver;listen〔::〕:{{s。port}}defaultserver;servername{{s。name}}。{{s。domain}};root{{s。path}};}{endfor}if流程控制{if语句块}。。。{else}。。。{endif}playbook文件其中web1,web2不传user变量,web3传user变量。hosts:k3sclusterbecome:yesbecomeuser:rootvars:字典service:name:web1domain:deniss。wangport:90path:varwwwhtmlname:web2domain:deniss。wangport:91path:varwwwhtmlname:web3domain:deniss。wangport:92user:nginxpath:varwwwhtmltasks:name:copytemplateconftemplate:srca2020imgdataimg。jpgdatasrcnginx2。conf。j2desttmpnginx2。confnginx2。conf。j2文件{ifs。userisdefined}判断是否有s。user这个变量{forsinservice}{ifs。userisdefined}user{{s。user}};{else}userroot;{endif}workerprocesses{{ansibleprocessorvcpus2}};pidrunnginx。pid;server{listen{{s。port}}defaultserver;servername{{s。name}}。{{s。domain}};root{{s。path}};}{endfor}查看生成后的nginx2。conf第一个server不包含s。user变量所以userroot;第二个server不包含s。user变量所以userroot;第三个server包含s。user变量所以usernginx;等于变量值catnginx2。confuserroot;workerprocesses4;pidrunnginx。pid;server{listen90defaultserver;servernameweb1。deniss。wang;rootvarwwwhtml;}userroot;workerprocesses4;pidrunnginx。pid;server{listen91defaultserver;servernameweb2。deniss。wang;rootvarwwwhtml;}usernginx;workerprocesses4;pidrunnginx。pid;server{listen92defaultserver;servernameweb3。deniss。wang;rootvarwwwhtml;}tasks示范定义一组执行任务,可以包含多个模块的集合。 Demo指定主机组hosts:k3scluster开启提权,指定用户become:yesbecomeuser:root任务tasks:任务的名称name:pingserverping:name:echohostnameshell为模块名,后面等同于a参数shell:hostnamename:touchfilefile:nametmpfile。txtstatetouchname:echofileshell:lsltmpfile。txtname:writefileshell:echohelloworldtmpfile。txtname:copymodulewritefilecopy:contenthellodenissdesttmpdeniss。txtname:displayfilecontentshell:cattmpfile。txtregister:displaycontent1name:showdebug:vardisplaycontent1。stdoutverbosity0name:displaycopymodulefilecontentshell:cattmpdeniss。txtregister:displaycontent2name:showdebug:vardisplaycontent2。stdoutverbosity0ansibleplaybookhello。yamlPLAY〔k3scluster〕TASK〔GatheringFacts〕ok:〔ubuntu20bj03〕TASK〔pingserver〕ok:〔ubuntu20bj03〕TASK〔echohostname〕changed:〔ubuntu20bj03〕TASK〔touchfile〕changed:〔ubuntu20bj03〕TASK〔echofile〕changed:〔ubuntu20bj03〕TASK〔writefile〕changed:〔ubuntu20bj03〕TASK〔copymodulewritefile〕ok:〔ubuntu20bj03〕TASK〔displayfilecontent〕changed:〔ubuntu20bj03〕TASK〔show〕ok:〔ubuntu20bj03〕{displaycontent1。stdout:helloworld}TASK〔displaycopymodulefilecontent〕changed:〔ubuntu20bj03〕TASK〔show〕ok:〔ubuntu20bj03〕{displaycontent2。stdout:hellodeniss}PLAYRECAPubuntu20bj03:ok11changed6unreachable0failed0skipped0rescued0ignored0状态释义:ok:ok未修改文件元数据,绿色changed:数据有修改,黄色handles示范handles与notity结合的例子同一个name下可以定义多个notify配置关联到不同的handlers中。指定主机组hosts:k3scluster开启提权,指定用户become:yesbecomeuser:roottasks:name:copyhttpd。confcopy:srca2020imgdataimg。jpgdatasrcansiblehttpd。confdestetchttpdconfhttpd。confbackupyes关联多个触发器的写法notify:restarthttpdcheckstatushttpdchecknetworkport Demo Centos指定主机组hosts:k3scluster开启提权,指定用户become:yesbecomeuser:roottasks:name:installhttpdyum:namehttpdname:copyhttpd。confcopy:srca2020imgdataimg。jpgdatasrcoptansibleconfhttpd。confdestetchttpdconfhttpd。confbackupyes此任务如果有变动会触发如下定义名称的触发器notify:restarthttpdname:starthttpdservice:namehttpdstatestartedenabledyes触发器,需要配置notify触发handlers:name:restarthttpdservice:namehttpdstaterestarted Ubuntu指定主机组hosts:k3scluster开启提权,指定用户become:yesbecomeuser:roottasks:name:Updateaptgetrepoandcacheapt:updatecacheyesforceaptgetyescachevalidtime3600name:InstallVsftpdapt:name:vsftpdname:copyvsftpd。confcopy:srca2020imgdataimg。jpgdatasrcoptansibleconfvsftpd。confdestetcvsftpd。confbackupyesnotify:restartvsftpdname:startvsftpdservice:namevsftpdstatestartedenabledyes配置notify触发,修改配置文件的时候生效。handlers:name:restartvsftpdservice:namevsftpdstaterestarted执行安装vsftpdPlayBookansibleplaybookinstallvsftpd。yamlPLAY〔k3scluster〕TASK〔GatheringFacts〕ok:〔ubuntu20bj03〕TASK〔Updateaptgetrepoandcache〕ok:〔ubuntu20bj03〕TASK〔InstallVsftpd〕ok:〔ubuntu20bj03〕TASK〔copyvsftpd。conf〕ok:〔ubuntu20bj03〕TASK〔startvsftpd〕ok:〔ubuntu20bj03〕PLAYRECAPubuntu20bj03:ok5changed0unreachable0failed0skipped0rescued0ignored0修改vsftpd文件以后会触发重启操作。ansibleplaybookinstallpkg。yamlPLAY〔k3scluster〕TASK〔GatheringFacts〕ok:〔ubuntu20bj03〕TASK〔Updateaptgetrepoandcache〕ok:〔ubuntu20bj03〕TASK〔InstallVsftpd〕ok:〔ubuntu20bj03〕TASK〔copyvsftpd。conf〕changed:〔ubuntu20bj03〕TASK〔startvsftpd〕ok:〔ubuntu20bj03〕RUNNINGHANDLER〔restartvsftpd〕changed:〔ubuntu20bj03〕PLAYRECAPubuntu20bj03:ok6changed2unreachable0failed0skipped0rescued0ignored0Tags示范tags定义了tags后可通过定义的tags单独运行该tags来执行指定的tasks,运行多个可用,号分隔。多个不同的任务中可以定义相同的tags。指定主机组hosts:k3scluster开启提权,指定用户become:yesbecomeuser:roottasks:name:Updateaptgetrepoandcacheapt:updatecacheyesforceaptgetyescachevalidtime3600name:InstallVsftpdapt:name:vsftpdname:copyvsftpd。confcopy:srca2020imgdataimg。jpgdatasrcconfvsftpd。confdestetcvsftpd。confbackupyesnotify:restartvsftpd定义标签tags:cpconfname:startvsftpdservice:namevsftpdstatestartedenabledyes定义标签tags:upvsftpd配置notify触发,修改配置文件的时候生效。handlers:name:restartvsftpdservice:namevsftpdstaterestartedt指定标签执行ansibleplaybooktupvsftpdinstallvsftpd。yamlPLAY〔k3scluster〕TASK〔GatheringFacts〕ok:〔ubuntu20bj03〕TASK〔startvsftpd〕ok:〔ubuntu20bj03〕PLAYRECAPubuntu20bj03:ok2changed0unreachable0failed0skipped0rescued0ignored0ansibleplaybooktcpconfinstallvsftpd。yamlPLAY〔k3scluster〕TASK〔GatheringFacts〕ok:〔ubuntu20bj03〕TASK〔copyvsftpd。conf〕changed:〔ubuntu20bj03〕RUNNINGHANDLER〔restartvsftpd〕changed:〔ubuntu20bj03〕PLAYRECAPubuntu20bj03:ok3changed2unreachable0failed0skipped0rescued0ignored0ansiblevaultplaybook文件加密工具。ansiblevaultencrypthello。yamlencrypt:AES256加密(会提示输入密码)。view:加密的情况下查看原来的内容。edit:编辑加密的playbook文件。decrypt:解密。rekey:修改加密密码。ansibleconsoleansibleconsole:可交互执行命令,支持Tab键。ansibleconsoleWelcometotheansibleconsole。Typehelpor?tolistcommands。deniss。wangall(10)〔f:5〕rootall(10)〔f:5〕root当前执行用户。all表示当前主机列表。(10)表示当前主机清单下包含10台主机。〔f:5〕:表示并发执行任务数为5个ansibleRolesRoles角色是Ansiblev1。2版本新加入特性,用于层次性、结构化的组织playbook。Roles能够根据层次结构自动加载变量文件、tasks、handler、template文件等。简单来讲就是将这些文件归类到各自单独的文件目录中,使playbook文件可以更好的通过include这些文件目录。Roles一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景。Roles默认的目录为etcansibleroles。 目录结构说明playbook。yml剧本文件app具体的角色项目名称,比如Nginx、PHP、Apachefiles用于存放由copy或script模块调用的文件templates用于存放Jinja2模板,template模块会自动在此目录中寻找Jinja2模板文件tasksmain。yml文件为入口,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件handlersmain。yml文件为入口,用于定义此角色中触发条件时执行的动作varsmain。yml文件为入口,用于定义此角色用到的变量defaultsmain。yml文件为入口,用于为当前角色设定默认变量metamain。yml文件为入口,用于定义此角色的特殊设定及其依赖关系roles:所有的角色必须放在roles目录下,这个目录可以自定义位置,默认的位置在etcansiblerolesnginxrolestree。nginxdefaultsfileshandlersmetataskstemplatesvars创建对应的文件treerolesrolesnginxdefaultsfileshandlersmetatasksgroup。yamlmain。yamlrestart。yamlstart。yamltemplate。yamluser。yamlyum。yamltemplatesnginx。conf。j2varsetcansiblenginxroles。yml与roles存放位置在同一目录。hosts:k3sclusterbecome:yesbecomeuser:root选择调用的roles属性roles:调用定义好的role,存放在roles目录中。role:nginxetcansiblerolesnginxtasksmain。yml入口文件配置task执行顺序。include:roleshttpdtaskscopyfile。yml跨roles调用tasks,需要写roles目录级的全路径。如:include:group。ymlinclude:user。ymlinclude:yum。ymlinclude:template。ymlinclude:start。ymletcansiblerolesnginxtasksgroup。yml单独的tasks文件只写单独的内容如下:name:creategroupgroup:namenginxgid80执行nginxroles。yml文件ansibleplaybooknginxroles。ymlPLAY〔k3scluster〕TASK〔GatheringFacts〕ok:〔10。0。8。2〕TASK〔nginx:creategroup〕changed:〔10。0。8。2〕TASK〔nginx:createuser〕changed:〔10。0。8。2〕TASK〔nginx:installpackage〕changed:〔10。0。8。2〕TASK〔nginx:copyconf〕changed:〔10。0。8。2〕TASK〔nginx:startservice〕changed:〔10。0。8。2〕PLAYRECAP10。0。8。2:ok6changed5unreachable0failed0skipped0rescued0ignored0 rolestags标签在playbook文件中对roles配置相应的tags。hosts:k3sclusterbecome:yesbecomeuser:root选择roles属性roles:配置相应的tags用{}引用{role:nginx,tags:〔web,nginx〕}{role:mysql,tags:〔db,mysql〕}{role:redis,tags:〔db,redis〕}{role:golang,tags:〔web,golang〕}{role:vue,tags:〔web,vue〕}{role:appdemo,tags:appdemo}跟上面的用法一样,通过ansibleplaybookt参数指定tags进行单独调用如下指定tags为web的role执行,其中会依次执行nginx、golang、vue的roles。ansibleplaybooktwebplaybook。yml roleswhen语句对role进行条件的判断。ansibledistributionmajorversion7hosts:allbecome:yesbecomeuser:root选择roles属性roles:配置相应的tags用{}引用{role:nginx,tags:〔web,nginx〕}{role:mysql,tags:〔db,mysql〕}{role:redis,tags:〔db,redis〕}只针对操作系统为Centos7的执行{role:golang,tags:〔web,golang〕,when:ansibledistributionmajorversion7}只针对操作系统为Ubuntu20的执行{role:vue,tags:〔web,vue〕,when:(ansibledistributionUbuntuandansibledistributionmajorversion20)}{role:app,tags:app}extravarsextravars执行playboook的时候以参数方式传入变量。以变量方式传参ansibleplaybookdeploy。yamlextravarshostsk3sclusteruserubuntu以json格式传参ansibleplaybookdeploy。yamlextravars{appname:nginx,pkgname:vsftpd}以json文件方式传参ansibleplaybookdeploy。ymlextravarstestvars。json附上2个Demo Ubuntu安装软件,传入参数即可安装软件。定义集群,并设置提权root,hosts:allbecome:yesbecomeuser:rootvars:传入参数DEPLOYUSER:ubuntuAPPNAME:{{appname}}tasks:name:更新aptget仓库以及缓存apt:updatecacheyesforceaptgetyescachevalidtime3600name:安装{{APPNAME}}程序apt:name:{{APPNAME}}name:复制{{APPNAME}}配置文件copy:srca2020imgdataimg。jpgdatasrc。confvsftpd。confdestetc{{APPNAME}}。confbackupyesnotify:restart{{APPNAME}}此处必须与handlers一致定义标签tags:copyconfname:启动{{APPNAME}}服务service:name{{APPNAME}}statestartedenabledyes定义标签tags:startvsftpd配置notify触发,修改配置文件的时候生效。handlers:name:restart{{APPNAME}}service:name{{APPNAME}}staterestarted 发布流程,Demo中的具体实现逻辑,需要根据自己的环境来定义,此处仅做参考,如果你有什么好的建议和意见,可以扫描下面的二维码,加我微信,一起交流。hosts:allgatherfacts:novars:OSS参数OSSURL:https:repo。opendevops。cnOSSPATH:codocodoapicclibproductionOSSFILE:xxxxx20211020181130dispatchservice0。0。7。jarOSSFILEKEY:?xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx部署参数DEPLOYUSER:{{deployuser}}ubuntuAPPNAME:{{appname}}tomcatAPPDIR:{{appdir}}tmpDINGURL:{{dingurl}}DINGTOKEN:{{dingtoken}}tasks:name:验证{{inventoryhostname}}SSH端口localaction:waitforport22host{{inventoryhostname}}searchregexOpenSSHname:gatherfactssetup:name:钉钉{{dingurl}}{{dingtoken}}shell:echo{{dingurl}}register:printdingurlname:获取当前发布主机IPshell:curlhttp:ip。meregister:getipaddrname:获取当前发布主机IPSDTOUTdebug:vargetipaddr。stdoutname:获取当前发布主机名称shell:hostnameregister:gethostnamename:获取当前发布主机名称SDTOUTdebug:vargethostname发布的一些动作name:发布主机:{{gethostname。stdout}}验证{{APPNAME}}目录file:path:{{APPDIR}}{{APPNAME}}state:directorymode:0755register:createdirname:发布主机:{{gethostname。stdout}}验证{{APPNAME}}目录STDOUTdebug:varcreatedirname:发布主机:{{gethostname。stdout}}APP{{APPNAME}}程序包下载shell:wget{{OSSURL}}{{OSSPATH}}{{OSSFILE}}{{OSSFILEKEY}}O{{APPDIR}}{{APPNAME}}{{OSSFILE}}args:chdir:optcreates:opt{{OSSURL}}{{OSSFILE}}register:downloadfilenotify:restart{{APPNAME}}name:发布主机:{{gethostname。stdout}}APP{{APPNAME}}程序包下载CMDdebug:vardownloadfile。cmdname:发布主机:{{gethostname。stdout}}APP{{APPNAME}}改名shell:newfilenamels{{APPDIR}}{{APPNAME}}{{OSSFILE}}awkF{print3}echo{newfilename}mv{{APPDIR}}{{APPNAME}}{{OSSFILE}}{{APPDIR}}{{APPNAME}}{newfilename}args:chdir:optcreates:opt{{OSSURL}}{{OSSFILE}}register:movefilename:发布主机:{{gethostname。stdout}}APP{{APPNAME}}改名STDOUTdebug:varmovefile。stdoutname:发布主机:{{gethostname。stdout}}APP{{APPNAME}}权限修改file:path:{{APPDIR}}{{APPNAME}}state:directoryowner:{{DEPLOYUSER}}group:{{DEPLOYUSER}}recurse:yesregister:changedpermissionsname:APP{{APPNAME}}权限修改STDOUTdebug:varchangedpermissionsname:发布主机:{{gethostname。stdout}}APP{{APPNAME}}服务重启shell:echo{{OSSURL}}{{OSSPATH}}{{OSSFILE}}O{{APPDIR}}{{APPNAME}}{{OSSFILE}}register:restartservicenotify:restart{{APPNAME}}name:发布主机:{{gethostname。stdout}}APP{{APPNAME}}服务重启SDTOUTdebug:varrestartservice。cmd发布完成后的验证name:发布主机:{{gethostname。stdout}}验证{{APPNAME}}进程状态shell:echo{{OSSURL}}{{OSSPATH}}{{OSSFILE}}O{{APPDIR}}{{APPNAME}}{{OSSFILE}}args:chdir:optcreates:opt{{OSSURL}}{{OSSFILE}}register:processstatusname:发布主机:{{gethostname。stdout}}验证{{APPNAME}}进程状态STDOUTdebug:varprocessstatus。stdoutname:发布主机:{{gethostname。stdout}}验证{{APPNAME}}服务状态shell:echo{{OSSURL}}{{OSSPATH}}{{OSSFILE}}O{{APPDIR}}{{APPNAME}}{{OSSFILE}}args:chdir:optcreates:opt{{OSSURL}}{{OSSFILE}}register:servicestatusname:发布主机:{{gethostname。stdout}}验证{{APPNAME}}服务状态STDOUTdebug:varservicestatus。stdoutname:发布主机:{{gethostname。stdout}}验证{{APPNAME}}接口状态shell:curlsL{httpcode}{{OSSURL}}grepWelcome!awk{print1}args:chdir:optcreates:opt{{OSSURL}}{{OSSFILE}}register:interfacestatusname:发布主机:{{gethostname。stdout}}验证{{APPNAME}}接口状态STDOUTdebug:varinterfacestatus。stdout重启服务handlers:name:restart{{APPNAME}}service:name{{APPNAME}}staterestarted 执行参数变量ansibleplaybookCdeploy。yamledingurlding。opendevops。cnappnametomcatappdirtmpdenissdeployuserubuntu,dingtokenqwertyFDSFBSNFXZjsonansibleplaybookCdeploy。yamlextravars{appname:tomcat,deployuser:ubuntu,appdir:tmpdeniss,dingurl:ding。opendevops。cn,dingtoken:qwertyFDSFBSNFXZ} 至此,Ansible的基础篇与进阶篇已经完结,如果你认真的阅读学习并动手实践,你一定可以写出高效的AnsiblePlayBook脚本!敬请期待下一篇如何基于AnsibleAPI二次开发任务中心之AnsibleAPI篇。