Sync before Archive
This commit is contained in:
@@ -1,162 +1,170 @@
|
|||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
35616466656362396235346561343838343634666539663537353635316361353566383531623266
|
64393362643437353731353234643535366431613861636131613139636435633465306333656161
|
||||||
3934346664633933666162376430626165626132376637630a356261613130306538633933653931
|
3365306632386330373862363637363435633235643336610a663736396537313032336162633334
|
||||||
34383032376664306663353836356165373861383932333737336633366362373962663533366235
|
32626233346233323565383030393130316532653062373730376163326134616239663865363862
|
||||||
6663393939396563660a373031353531646165336239656534613330663266666361613834326532
|
3365316365643534610a343932623566356637663136336338386534373532383863363662326438
|
||||||
64313632643565666139303464356339383834303262323933326133663163386465323431633332
|
37393331356632313163643138613330366631643465623633386433663236636334666264383033
|
||||||
38616266353430316133313135643164366464346134316462343536636532323432356362623366
|
34333935633131363364626333313336353733373562326636343633653838616532643737366435
|
||||||
63383331663535663739386338376561383962316462613432323938373437646136613564393464
|
36366330633263613938323566393063373233363538643531636131316335316461656631616362
|
||||||
64633530633635633634366135353730343037306437383861363230333036396164656637373864
|
30343965356363383139366534363664313831363132383337636266316538393139383232386230
|
||||||
39383963623865303630376437663861303935363234383539323263303031373865386539346431
|
65353364313534333632306465393264386466346365303232356263653563653338306131376131
|
||||||
64323335663134333738653732613761353938373830376261353737613865653537326561303964
|
66343764643639396663623330623332333466633737343738386230626463386137373536343430
|
||||||
34613134323963663362303235613962303966323163316535386139366161363831656638383665
|
36636430616132363161303338353033343963643338656639643662636664613965636263366135
|
||||||
31376561303733393464303039636565393537616363333431633863356135353038346562323930
|
64353134376162633162316166316239333963653930363830646165636537653238623537323238
|
||||||
35376462623632633632303533313138373630393331616239656365626164613166663837373938
|
39376338636335336338323935333439306534386539336331613961663261623962383237303632
|
||||||
37393064323761303434333265323039356265356532636133383362656634313431333262633566
|
34326139626366303331363337353432623636626231373731646665623831353865303130663533
|
||||||
31363439656433333562316636636431326564346633623862383463613735396563343164326339
|
37326639626237653361316666616161363531303961613538636663633063396363346337663239
|
||||||
39356337623264353363336538646366356631303438353236656234383836356363303436393137
|
64313333653766383736303161636530316538633033323063323662336335666264646564643465
|
||||||
32633665636266623035616264393463363036373530386431653536306431366234353936373464
|
64396436366131373061326233643562626335376263623031376532313730653363343038356135
|
||||||
64666133303734636135616636393165373530663031396139636561306336366636663335363139
|
30336131646635636638353934636139343662623265336338386535663536393935343132306335
|
||||||
65356130666164353564343733623337393137326463306333323338386536333363313337363234
|
33626632613663353661313061623732643539323637336433666330313463666661623836303462
|
||||||
39383666336535386331316162326264343966646562303030363766623936616263646364316432
|
61383732613139343434363662616539373837633139393764353864613062346237346661633033
|
||||||
31326138323031356235316366313361353235346132383965623431353364623331326162663437
|
61393639326535366266643664653439383238646132306636656130333733316638363830346433
|
||||||
37373630323232343662376437653337663166663562343066623363343064336230373964326132
|
38643430346263663639653762393935356662363533323766343362366532626532633530323630
|
||||||
64383965626533663036616261303039663838623030396633393730336334373236366638633339
|
30643436653130363066373665666434383732663837643839356539366432316539613863623839
|
||||||
61613561626664383063373530393130376539316637363964316532313034313065353530373761
|
35323930383437383535373330326239663966383234663233643337623330353236626464636530
|
||||||
30386338386333323633333961636434316330613065643662356131623536323865393933326537
|
36393735646664366235363831656262383333626265383066393363346165656265363438306135
|
||||||
61633231636638396164373635313434376533613334346238396462656334363036643235333839
|
34633530653837346638636665666162363062663333623263356131646661373234333939333536
|
||||||
36643962353662373439366236333363343432643666363561633931323564316664316538363733
|
30643639333836373439613561346130623239363737626238663436356365633562366465643561
|
||||||
30326632393638313665643562616230373335363831656136633633343234336465616361363537
|
32643039376234323963653733353138643138626430383639313765353035646539653466623539
|
||||||
35623666303636303837623430373832663532323430383330313530646636316535336434613466
|
32366135366266323261333938373837386636626232323661393035613638643335383564663462
|
||||||
35373666363665643536363863663161653330646462633239623466346265376231653363393366
|
31383663663063373935396439653231353962303630346338623938343064643037396562626637
|
||||||
61343233326638386633343135316563653234336538613939623938366164326561323861373166
|
63363363343739626639633934393734396434653262373137373539316536306663336466626639
|
||||||
39323462646530333737663039336530656534333332616661373037636336346137643861613930
|
34646465306439313239323365333761663161313461613766343463666134303036376338366663
|
||||||
35613066346262346232643362373835333337626361316339636564663235323939633234363866
|
64356364653462383534343438343933623766396232336434653765613864376235363735343032
|
||||||
38616662623665373139323031343462393135653463306333373665666431613264666661643434
|
32313133383731333366626534363065333738346230393636393938366633363561346436363338
|
||||||
33393666633464636562393335323064636332656336373661353461323830386166656231383639
|
33393932626333636166313431633339386564616466653165383962656633303161393935366635
|
||||||
33373631396439313265383063613638643633343861323733306335366163653332373865663863
|
65396464326333396433303966316231376432363335643732303438663131653932636564363264
|
||||||
61653532643838636137353031323663613933656462333364656331373763323366316339653038
|
36356663623436643835373538363662643134313030656236326335393334626634663136333137
|
||||||
36323831643566323039653566643635303232313137653130393165613633343364646366366532
|
38363432346663393435366536636335636465343131666562396334636530346235366365396431
|
||||||
31386565366438613866346263653166343934323863303839303531346363663234343265393162
|
64623739373130623436356161666139656330646661396430633264393632663366353037643130
|
||||||
31613936333138616237393065656430303436653466613632633335613136616534396434653235
|
35373839373430643065616630613433646536356563353133633361623235623733313234306435
|
||||||
66373834363764333366343933333362363138303663333932643531363863313136633630343063
|
64356635343361633462376131636362386433373339383365313436333332613333316237323632
|
||||||
36326336313733636564356235303664336131653639393964383132663230613264626131353037
|
33633362376331323930376130393838633333316330363362396131306230643161373636303034
|
||||||
36363866636238353430396461616530356435386265393864343164613434376139333038336339
|
37303738306233363937316332313830396336323639333634666364633566386261373031383563
|
||||||
35313964336462626365343135656466316562613935353431326332313461663937326338393536
|
36633865643634363234613463636437306236376435613034623537356162353235396665636338
|
||||||
61663732313464383734323664663566313732323536666237653662393738333835613831623434
|
31613733363430313532643235343438393137313136653730643364623662336236323464656465
|
||||||
38306430616333356436633330626537356265343936343764633638393262356266313130623632
|
65636431633464613437396561643638346565313937303731633837623930333538383335633938
|
||||||
31616131356461656636396539636134616138306239653232613166333765326364666165623334
|
62666461323033303937653366646432623764653566626333333766656235633662623631636636
|
||||||
62663533313064396635333830616362303332643163646138393761366139626363346537333235
|
35626161653736303261303233643236393038303063386532643563663065303331616637386661
|
||||||
61616130366334366437633039343533626664343538396638633833336136336662643937366636
|
33326637393633616430643665623431616336336666383236326538383535633364613135653131
|
||||||
66356665623361386362643237646464326566323865343437336130353031373663643132333630
|
38383961383264313130383263613763326666663033626338313762376336353866646634323537
|
||||||
65656461643733643534363362336364613164383266393136343830663037313365343632363934
|
39393565643265633437396535643165626165646537373039613061613936356434366238636562
|
||||||
32386335303638313734623633323564373163666465336563653934346435353766303331333032
|
61393639316531316564646334663863383836656261623230646461323566316664653965336136
|
||||||
34303037626266366638663435663532633232343361306636303166373437376439653437626537
|
62353839363664396632306231363031303265343131343739633835353338386335343737326633
|
||||||
65373532386332366530616537363334383362653434333162323533376165376533353263396338
|
36656433616135653663353166636461623337653138613435646663663939323631373063373136
|
||||||
31653338383363316537366334613137666365646237303235303731633362383536353564663535
|
63396331313538636437383635643831643935303932313964336532643366623434316662376632
|
||||||
65653864396465333438323532363731643431373666633830316566343537633337366465376138
|
63666464333736333162373461333563393138366638643039393865613238616531356165346236
|
||||||
35663139303761383935316261636461353936653966303738313130626130613130326332386137
|
65313432383533353738396530356465386263313939393962333637306138653939646638353235
|
||||||
38326464356637333933316264663032303161643034303363326665373163656238663364643233
|
37393733333032623763333632353866633866613162663833346534666237383430663838383965
|
||||||
61373461393330316366373135383532323436313535333535623338353332346364613262616539
|
66663332616164353539323261383364363237383064306132633530326134383561346536346636
|
||||||
32383866636233313461323466336538613165316565646431633632353331383237303437306636
|
32393365316435626464386631663037663934313533663030313466323134336439303362626365
|
||||||
35653566386437333536656630323761636262333333396563303264653166656663636264633933
|
30613764346362326130353333353663316539306437376465306332353464343530663933363562
|
||||||
65343435373038366163386464353562303161613162633330633630306566646430613736396266
|
39646333323631353835336461326233623963353535316633353236353236636462313163633638
|
||||||
38396432646637623837356662626639623361356163346564353238353263363434326465306637
|
35366538366336663534353739353231306164626664383737333565666337636164386539316632
|
||||||
62343464623365633133633539383933313633333664316438313830346335326161393138333139
|
64323966336637626538303830323535373533306362636236303065663161353734653633393064
|
||||||
32363237343133386436396537333639623537656362643134356566326439353237313939376637
|
66353938306238646238313037323163343935643863653632336462363834326634363433383338
|
||||||
35336134383035396637383637356536353064636163333639393763616538313264373930366563
|
35646364353834376439633136313939393064633539643462623562333832303261386331636533
|
||||||
32333933373466336465643030663765373164363732656231626261336665633238623830313163
|
37373837396461373064353565353438633938616162363138323561343662383330346633323133
|
||||||
62343438303936383738303737363338333864666135356336313964626131653663393933653130
|
36626665343636343739353732366133313434623230353732323037633236303237656364323763
|
||||||
33313435653364623531323038393962616432636265666437356365323963636431613136633463
|
30363530306131303630386131623866323861633636313431376161336536373436656334303036
|
||||||
64376235393462633162386366666266353234383936306637663136383830663438636637376532
|
61316639666136313338396233326234386634343863633632626264363336376531363461626564
|
||||||
61313134623233626230653931653131356265353836303064326563303936363734656166386133
|
35336335396561626339616234373265663032353432363832306666353339376338396366383839
|
||||||
38303230366562376566376337376164373335303566386638613839353637323563366463396661
|
62633063326135323539653133626538613331613334353430623232376336633334666433316638
|
||||||
31623134666231316337373539356332616136663761303834373831663433316339363630396131
|
61326563366432333632666436363761376237636434356231613061626633303737626531626236
|
||||||
64303066643063666165326439633133383966663265653133346635636634313135636463343835
|
62373166363432616666616630616565373934356564363266396662323963636434313735626161
|
||||||
36383733383561626239363561653034373636373134633934376437316231323433623733393537
|
61373738623966363032313632376465356235363834633639663733653131636531363563326662
|
||||||
32323330366262383463316564373930663634363231636635353137636330393630333930653439
|
62663365323934363761653536356162336463646566393838346134356536303264323065396534
|
||||||
38663066613139343761353164636537356331656534613637356463633561336663393033333331
|
63346531303764613634646336313530326663373433396436663162343530306131386265303137
|
||||||
38636436646162343630393431316664303738373834326165666366396330316366663838376133
|
32333432383966363735343331646233613631373165346131323632366165346235656330323939
|
||||||
61386631646338653761646432613432383763326537393136616662633135323336643330663938
|
34393030313466666265346163323561353734613434386239333630623762616566616562316265
|
||||||
65373234336136643462363939653734613464393830333566643764313834363836356531386363
|
38633263323339396462336166646431363336616462366463383663313839613638383663303133
|
||||||
39386536323864373863666135633039653966333531633030633362343938313138373764643865
|
32333835623531366236643530623961656631336139313037353962323937666465343430666336
|
||||||
31353437363830633363623861643164333631343431663832663564613161363165373561383533
|
33383464363930663630333164636361326334396163376661666564663538623732663839613237
|
||||||
65373234356337373732303038393364326430646131653536646536393139326138373533663761
|
35623237613761356235383130633733333766333236363537383862306539373665383461386534
|
||||||
34626464663563396631393565626431363066303632306561316336373737313937396563396534
|
32646432363339306433646139393732366464336339346161323736363937383566656663356230
|
||||||
65366337353232616361323963303263343235383432323261373564356261663632623836313266
|
65316562383562366366653466646461613235353061623363386331636139386136306131633232
|
||||||
34326163363562343064623265373562316432663839303662613661616265386263336462633163
|
32326238353861613236373964383131363537653632663532376364336166303662663336623161
|
||||||
63643264303062643264396362353864306562323364323361366463333061366439373339363262
|
37623838616664376561663763393534323931343163376535396662626333383730363232653036
|
||||||
35353331393265316631323039623334616638356439346335333864616132363562373334323039
|
39626266623666346635373630343135333532353866363234396265356631333265663432326235
|
||||||
38363161613261363562623032383263303930383538653365393864663266306130613638333131
|
37346439613363313334633964386632336138316662616661356637363730306164646439643765
|
||||||
32666135643831666531343266386365663563393639656635306338366431313563616632653739
|
62343137663137633031316665363362643165643731326464323962616330383164353861366462
|
||||||
61643263616530383466656265316630386537356438653063643832373464376162643831323836
|
31663965626338636534356461366362333831396464376134613331393664306639386632396236
|
||||||
38376338326239326632616262356366396538656666393365383366393237633361333536326434
|
66633066663831646361333730356361646133383834376230356336613038303665323732663162
|
||||||
31366538396337306632663937343064383836653831383538353037343366393534386437643530
|
37643130313739306638636262656632353431316531336438363636363833626237346363326461
|
||||||
30356237393739353437323438623664376338323865656439313231313062313766383363616530
|
31636262396632666335303566633161333937626330373835613236656130383132663863636364
|
||||||
30336363633437643539663037666331346335373639633539613466666231653131316535326439
|
34383661353966346362386461303062303138626536323163376362326639356336396437333530
|
||||||
32353066393064636262633166643832653938633432633762376435616466336363643131383532
|
66623765313638616430383838396164336565646338636430363262396636663965383531383139
|
||||||
62353337336133666530383865326537623932373163643131353034623964396462633936613630
|
35356663363437383132333566336131666139643639663662633363616133323031353032663438
|
||||||
30353566316531313135353965353130646463343539303031353130633536613835383565643932
|
39393266633639306363313530643239303132303264323063306335346233363233373865653863
|
||||||
33383236656433363762653663383961613164633533303061386334656165366337386235656632
|
65396430346630626566383963356264313630623336316236393730343437656435656664663266
|
||||||
36353537383635633631323161636535643733313366613435313632373230326337616165323838
|
32643639363536396266626435373363303234623230383035326536633631633737653739366563
|
||||||
63383038396663303230666337333264613762393066336134653063663562313130303966643238
|
65653932663539353436366139313635663962663330343461353864323166323733366163653162
|
||||||
37336431666265643231376139386138306261636638616466366461373666393531316139373564
|
66353866376134633534323366656265633930356132316137616235343866653265666161363266
|
||||||
61363631633866396531653336363365656236613266373933376535656565623461653465346333
|
30386638343739353965643466613639303666316432323634383464633431363566333831643134
|
||||||
62376566343530366466613536393938343263303437383334373863626138383764656561333662
|
65363138313439366430613837396337323436636530313664303964353966306565663630323662
|
||||||
37613764353639653838633533316462653165663037376134613730323661383364343438353035
|
33643639623935336235373332633739306539656235323439343331376632373538613534386430
|
||||||
39363634623034633263383063653437613339313762333234643062613035373264326233383935
|
30633832656532623262326662376237393262333764623937343232383861636563633730393765
|
||||||
66643134373735383135353763306165303063383161313135343435386163356466656163636366
|
39663032373132323735633361343933333332623465343863636263363161303165656234313338
|
||||||
35323037303562633863346138616530333932313633343162666662333930663535633661633934
|
65383462626465376162306639626531366161396531643364656539366233306166386234313761
|
||||||
36376637396532313265323066626637333061353165633036333739663632346337643137343165
|
30633666303832636561323236373363373137353032613637353637386238353234646431333661
|
||||||
34653561303864613335396233626130363436353764666365356230316534316365613436323639
|
32313834666237626333626437663562646438363561393364373565313536363535323536363537
|
||||||
32613662353438333362363565346432303333356361653065303236626133353961343834333661
|
35633834616136656261643130656131306264333131326431626439343765393031313964616639
|
||||||
31633238666165633561303639626630323235346635356264323934353034316361636331333461
|
33643933653033336436616635346335383335333334343836343638613264396462633530623866
|
||||||
35356138616332656161343434653638653861373962386436323061356263353064613934656663
|
30303462653130353430663862623261343866383335343239393435633962383864396430313536
|
||||||
34653062383434666462623732386337393038313339626463376631623336666133633663643835
|
66643535303437383232323564326266356636376464623563636139633237313661356330633931
|
||||||
31613438376431613862333564396330346635656231333835383433343832613663643163396334
|
66376631373366613731633863666132626366393532666331343361323764626539666238656262
|
||||||
35653739386264326530393261633864656462636264663832303537333833373037323039373731
|
66356332383235353864303562356638636130343938383530376432663866316238333434616233
|
||||||
65393837656234383530353335343730353535393561346137313436383966396632326437343562
|
32316432333064663764363831343464326334353737346632383565643737366233396139333639
|
||||||
31316237396336666233656637383461303737363565356136396336393864383238396164333163
|
35656435346335323030636363356633633332376138653930613037313537373038353433363532
|
||||||
32646238303430626261646236306664396533313136623764303962333836623933666562663439
|
39346161336261353463656430663033623036396365346638323832313361633866363134396165
|
||||||
35666465613738326165626365343734623131356238616162386233376333663764363038636635
|
65356632366463393435386366643232383162623536653965643235323934633464373061333237
|
||||||
63643531323164323634316130326265623966323033356338663261636136373035303665346537
|
32636564386662626365613235333664323563633466383238343336343063376531396161343530
|
||||||
64663065373366636637303237333666396266636535326563653130613237363833626365623331
|
61306632646133626133343132666534666337336239306137663931623637643164326538646138
|
||||||
66363264353831343264306336313532646637343631656230393466396633336639356431313839
|
63313037336235316164316232636262316331356363356438653235346539643065636537366661
|
||||||
39643630626462616336333166333062373231613039313661646231393834386561373431643561
|
37313437386432316336663366633366666434346135356462623635313531333530653866663863
|
||||||
64313933636430343132613263663936313732343233646631616163366633386164653763313333
|
31646438316435373637303733646564316261336233623035353564363664303437373132353166
|
||||||
62383563303434303830363338666465306463643262623637363939623136366639306330636331
|
33646534663130356330663565656663333765653961663835623235633665623464353862616138
|
||||||
33633462643234656636656634663664616338636332393231343932383363643331396635303466
|
37343531366462616439333539306265626164636233616262616563386566396536386264343137
|
||||||
31353935626461396431626336343466623163323730656131313432313635366365653063623537
|
30396434303231366664656334656635616334633066323062313738363431646335643132626331
|
||||||
61306466393938636261363032353330353134383430363164353230323630363864393234356238
|
33663038316165626365346366363731323639653837616163653561623034393064303563353232
|
||||||
32333865663063353566663038316633666464636433626236343632643864656635373833386338
|
30613939353336396365613662393938663933363662656634663465303134393964623738633765
|
||||||
61366136303863343430393661653738626331343366333965616135663339633334623762373266
|
37633832626631363736383436666263356531366237356261666538303863343033356333656138
|
||||||
36383564663337353935626534366365626238306232633534326266656333613664643736356637
|
64366537363939346535313732643965623332396265386636353364316630333130643833383331
|
||||||
64323030626361356338356165326336626365636666343131306236366630653534376333373037
|
34643563386539383235386130323065353835376564613835313934333636316464636463376537
|
||||||
35623062653032666431643936393337623830646134653034336139363863373931653132663165
|
32363565333038643230656266393761313064616537393830343163643535646436616230626166
|
||||||
65333536343535343463373662373937663133616437636137373632373332323632363465613663
|
36373531646536363664663330353864636533656261353331316364633361633934326436323933
|
||||||
36326636666435353062383433373562643464376365623530663836356663336338346565386535
|
39636631623430313934393033373630656132623734363835353735353935393063356261323764
|
||||||
35643136396130326634386632333739663632616538356434376336393664396332623562356164
|
66346265376339623265376666343865343763393833323564643161613861303065346137653339
|
||||||
39636262323563313862303266663035346132323765613732316434353631383234323036323630
|
34326432383230656638303963373832316438666131623539613464636631653365353331346262
|
||||||
34336165306436633434306333313534333238623963306338616363303632613934393732653962
|
37626130343831636133646135323564306538353439636265313239326235343232633136383663
|
||||||
38323331396664336163346236396536333361376431313461383032363733316133343437376637
|
62306561616564623038393631373862346535366135633836353363323330346430613466393463
|
||||||
30376230366666346363383235333836616539626465636539616131373437336332633633316437
|
39313766613064306566316561303761626135613063326536363761626635646134303732356130
|
||||||
31626538326137656262633332623631643737656632653036376432653333643031663266316338
|
38333266363639636565393737323938663938633662653231366164316262666538356162323665
|
||||||
38353734343761656533383133386634343331383338343333363438386231393332653330303631
|
38383263366133326333636466343835373737613333623464383139343863336234373932393239
|
||||||
30643363346538393532373533376537313831633764366566373539346337623135323161323039
|
36653736393732353466656334613364626339356533343363353731353033363730376565353236
|
||||||
36326139306364326663353233343133356165326362666535336138653663613131363835376533
|
66343332306330303662373363326236393333663565383661643763363662396265313037643432
|
||||||
30366566613265346232323062636435373733646461646639306539323762613932313166666331
|
63343336623663326237326365333565346335346630356439303534363561626362363833313239
|
||||||
37643431363961643832336464646433656664613137303062613037346335323230626464383461
|
62366436313466633534343430306461313266376363336536666162306135363434643266373338
|
||||||
61363535616266626364333633333061633234646638383335616232373166346233306139363239
|
65323866323537636465306636646533316466303735386336663234386538303939343661653562
|
||||||
62373363343836623162313638383434363530343134666666346630363630643633616639356231
|
34353564313738643665636337336536343735336436626438653335376532343137613837356363
|
||||||
35336365376437353935353630333835633033306235653964656163613166643136363165396263
|
31353861363733373232363865323164663532646235623533336536333932363133613830373937
|
||||||
35333732373665346362336333356538313161633032653931393465306430396536333735383237
|
38616137646332303934303839633336313239653064626331383432633935353538636132633134
|
||||||
62313361616530623630653762613430393837366431656139393437643837623135333666393231
|
61393230663536633335393330386363333162636661373938343837323736663539393636366532
|
||||||
31323566663366376666663362656630366135633336323462643936343433613938316432653638
|
35623637623262373332373335303833373239323430393766633939633665643236623139363834
|
||||||
64343637383039373265643963653037343530386465363936343438346538633266663762366536
|
30636135303634643765393433393962303138666630343936653234333730336234356234396566
|
||||||
39393732653637343166336663323363653131653035376464643934353963353935386364376336
|
35346331336639333237323136616337623938666561343861393563393633313261633333333434
|
||||||
35633533346632396237346534303665383365633565663939623438343463613938633863323864
|
38633064633538396566373730636632346234653339303533343431643266373266633836633139
|
||||||
36633538643830373964373864323235393865366364303166653739376563616364303936623733
|
33313234366236626338636331346565336138313136623632343735363132623964353066346233
|
||||||
32333935313537643231653232643463303634366366386534363562333635623730316638346661
|
66363833383432316238353364363963323762666562303030663939303162656261663664616632
|
||||||
37663936366330666463623263326134353331613661363863383361643965316635353663396639
|
66396466643763393130313831313438356635346230646335306237363262366132323133646535
|
||||||
38323538333165623666333933393966343763323536663163383133663362383665616237633239
|
30313338653262636136393133306663653331333830626534356536303532633031356435663734
|
||||||
6665
|
32383035643637313863653537656665366138333933333364646561353333653661306133646361
|
||||||
|
32326535393333383033313765383031353233323138386365623132646636383037633537386361
|
||||||
|
65306166613030353033666438343530333330306532323135306363653764613638383461633964
|
||||||
|
63666239366638663537643636373432303164623735626634383636643836343436346161393365
|
||||||
|
62336462636534383766656632653833333832393263316633356235373335643436363333393335
|
||||||
|
62643838303131643265613861373964653464623766363664383330343138653632396365633533
|
||||||
|
39383535616630663564326536623537323966616436353439343630363738626131326365656132
|
||||||
|
32383737303733623830353366383062313134396531303831323336326137396335353763353631
|
||||||
|
36663336353865303562316233643762643563386665393664623138643836633165
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ proxmox_clone_node: "fantasyland"
|
|||||||
# VM Configuration
|
# VM Configuration
|
||||||
vm_os_distribution: "ubuntu"
|
vm_os_distribution: "ubuntu"
|
||||||
vm_os_version: "24.04"
|
vm_os_version: "24.04"
|
||||||
vm_size: "medium"
|
vm_size: "small"
|
||||||
vm_storage: "general"
|
vm_storage: "general"
|
||||||
|
|
||||||
# Proxmox HA Configuration
|
# Proxmox HA Configuration
|
||||||
@@ -22,12 +22,12 @@ proxmox_host_target: "pve02"
|
|||||||
|
|
||||||
# Network Configuration
|
# Network Configuration
|
||||||
# IP address for the Traefik load balancer
|
# IP address for the Traefik load balancer
|
||||||
ip_address: 10.1.71.80
|
ip_address: 10.1.71.24
|
||||||
vm_mac_address: 'BC:24:11:50:00:80'
|
#vm_mac_address: 'BC:24:11:50:00:80'
|
||||||
|
|
||||||
# Software Configuration
|
# Software Configuration
|
||||||
# Traefik will be installed and configured on this host
|
# Traefik will be installed and configured on this host
|
||||||
|
|
||||||
# VM Template Configuration
|
# VM Template Configuration
|
||||||
vm_clone_source: "{{ vm_os_distribution }}-{{ vm_os_version }}-{{ vm_size }}"
|
#vm_clone_source: "{{ vm_os_distribution }}-{{ vm_os_version }}-{{ vm_size }}"
|
||||||
hostname: "{{ inventory_hostname }}.{{ base_domain }}"
|
hostname: "{{ inventory_hostname }}.{{ base_domain }}"
|
||||||
@@ -25,6 +25,11 @@ prometheus_nodes:
|
|||||||
hosts:
|
hosts:
|
||||||
cinderella-castle:
|
cinderella-castle:
|
||||||
|
|
||||||
|
load_balancers:
|
||||||
|
hosts:
|
||||||
|
lightning-lane:
|
||||||
|
ansible_host: 10.1.71.24
|
||||||
|
ansible_become: true
|
||||||
# node_explorer:
|
# node_explorer:
|
||||||
# hosts:
|
# hosts:
|
||||||
# cinderella-castle:
|
# cinderella-castle:
|
||||||
@@ -78,37 +83,37 @@ terraform_server:
|
|||||||
hosts:
|
hosts:
|
||||||
infra01:
|
infra01:
|
||||||
|
|
||||||
hub_cluster:
|
# hub_cluster:
|
||||||
hosts:
|
# hosts:
|
||||||
ocp-hub:
|
# ocp-hub:
|
||||||
|
|
||||||
internal_cluster:
|
# internal_cluster:
|
||||||
hosts:
|
# hosts:
|
||||||
int-master01:
|
# int-master01:
|
||||||
int-master02:
|
# int-master02:
|
||||||
int-master03:
|
# int-master03:
|
||||||
# int-worker01:
|
# # int-worker01:
|
||||||
int-worker02:
|
# int-worker02:
|
||||||
|
|
||||||
talos_cluster:
|
# talos_cluster:
|
||||||
hosts:
|
# hosts:
|
||||||
splash:
|
# splash:
|
||||||
|
|
||||||
fastpass_control_plane:
|
# fastpass_control_plane:
|
||||||
hosts:
|
# hosts:
|
||||||
space-mountain:
|
# space-mountain:
|
||||||
big-thunder-mountain:
|
# big-thunder-mountain:
|
||||||
splash-mountain:
|
# splash-mountain:
|
||||||
|
|
||||||
fastpass_workers:
|
# fastpass_workers:
|
||||||
hosts:
|
# hosts:
|
||||||
haunted-mansion: # backstage
|
# haunted-mansion: # backstage
|
||||||
peter-pans-flight: # backstage
|
# peter-pans-flight: # backstage
|
||||||
|
|
||||||
fastpass:
|
# fastpass:
|
||||||
children:
|
# children:
|
||||||
fastpass_control_plane:
|
# fastpass_control_plane:
|
||||||
fastpass_workers:
|
# fastpass_workers:
|
||||||
|
|
||||||
# sql_servers:
|
# sql_servers:
|
||||||
# hosts:
|
# hosts:
|
||||||
|
|||||||
177
ansible/playbooks/deploy-haproxy-cloudflare.yml
Normal file
177
ansible/playbooks/deploy-haproxy-cloudflare.yml
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
---
|
||||||
|
# ansible/playbooks/deploy-haproxy-cloudflare.yml
|
||||||
|
|
||||||
|
- name: Deploy HAProxy with Cloudflare DNS certificates
|
||||||
|
hosts: lightning-lane
|
||||||
|
become: true
|
||||||
|
|
||||||
|
vars:
|
||||||
|
# Certbot Cloudflare configuration
|
||||||
|
haproxy_certbot_enable: true
|
||||||
|
haproxy_certbot_challenge_method: "dns-cloudflare"
|
||||||
|
haproxy_certbot_email: "ryan@mk-labs.cloud"
|
||||||
|
haproxy_certbot_staging: false # Set to true for testing
|
||||||
|
haproxy_certbot_cloudflare_api_token: "{{ vault_cloudflare_api_token }}"
|
||||||
|
|
||||||
|
# Request wildcard certificate
|
||||||
|
haproxy_certbot_domains:
|
||||||
|
- domain: "*.local.mk-labs.cloud"
|
||||||
|
include_base: true # Also include local.mk-labs.cloud
|
||||||
|
|
||||||
|
# HAProxy Stats
|
||||||
|
haproxy_stats_password: "{{ vault_haproxy_stats_password }}"
|
||||||
|
|
||||||
|
# Frontend configuration
|
||||||
|
haproxy_frontends:
|
||||||
|
- name: https_front
|
||||||
|
bind: "*:443 ssl crt {{ haproxy_ssl_cert_dir }}/live crt {{ haproxy_ssl_default_crt }} alpn h2,http/1.1"
|
||||||
|
mode: http
|
||||||
|
options:
|
||||||
|
- "http-server-close"
|
||||||
|
- "forwardfor"
|
||||||
|
acls:
|
||||||
|
- "netbox hdr(host) -i fire-station.local.mk-labs.cloud"
|
||||||
|
- "wordpress hdr(host) -i be-our-guest.local.mk-labs.cloud"
|
||||||
|
- "plane hdr(host) -i people-mover.local.mk-labs.cloud"
|
||||||
|
- "minecraft hdr(host) -i arcade.local.mk-labs.cloud"
|
||||||
|
use_backends:
|
||||||
|
- "netbox_back if netbox"
|
||||||
|
- "wordpress_back if wordpress"
|
||||||
|
- "plane_back if plane"
|
||||||
|
- "minecraft_back if minecraft"
|
||||||
|
|
||||||
|
# Backend configuration
|
||||||
|
haproxy_backends:
|
||||||
|
- name: netbox_back
|
||||||
|
mode: http
|
||||||
|
balance: roundrobin
|
||||||
|
options:
|
||||||
|
- "httpchk GET /api/"
|
||||||
|
servers:
|
||||||
|
- name: fire-station
|
||||||
|
address: 10.1.71.102:8000
|
||||||
|
check: true
|
||||||
|
|
||||||
|
- name: wordpress_back
|
||||||
|
mode: http
|
||||||
|
balance: roundrobin
|
||||||
|
servers:
|
||||||
|
- name: be-our-guest
|
||||||
|
address: 10.1.71.101:80
|
||||||
|
check: true
|
||||||
|
|
||||||
|
- name: plane_back
|
||||||
|
mode: http
|
||||||
|
balance: roundrobin
|
||||||
|
servers:
|
||||||
|
- name: people-mover
|
||||||
|
address: 10.1.71.112:8080
|
||||||
|
check: true
|
||||||
|
|
||||||
|
- name: minecraft_back
|
||||||
|
mode: http
|
||||||
|
balance: roundrobin
|
||||||
|
servers:
|
||||||
|
- name: arcade
|
||||||
|
address: 10.1.71.111:25565
|
||||||
|
check: true
|
||||||
|
|
||||||
|
# TCP services
|
||||||
|
haproxy_tcp_services:
|
||||||
|
- name: postgres
|
||||||
|
frontend_port: 5432
|
||||||
|
backend_port: 5432
|
||||||
|
balance: leastconn
|
||||||
|
timeout_client: 1h
|
||||||
|
timeout_server: 1h
|
||||||
|
servers:
|
||||||
|
- name: netbox-db
|
||||||
|
address: 10.1.71.102
|
||||||
|
check: true
|
||||||
|
|
||||||
|
- name: ssh_jump
|
||||||
|
frontend_port: 2222
|
||||||
|
backend_port: 22
|
||||||
|
balance: source
|
||||||
|
servers:
|
||||||
|
- name: main-street-usa
|
||||||
|
address: 10.1.71.11
|
||||||
|
check: true
|
||||||
|
- name: tomorrowland
|
||||||
|
address: 10.1.71.12
|
||||||
|
check: true
|
||||||
|
- name: fantasyland
|
||||||
|
address: 10.1.71.13
|
||||||
|
check: true
|
||||||
|
|
||||||
|
- name: minecraft_java
|
||||||
|
frontend_port: 25565
|
||||||
|
backend_port: 25565
|
||||||
|
balance: roundrobin
|
||||||
|
servers:
|
||||||
|
- name: arcade
|
||||||
|
address: 10.1.71.111
|
||||||
|
check: true
|
||||||
|
|
||||||
|
# Firewall configuration
|
||||||
|
haproxy_firewall_allowed_ports:
|
||||||
|
- 80/tcp
|
||||||
|
- 443/tcp
|
||||||
|
- 2222/tcp
|
||||||
|
- 5432/tcp
|
||||||
|
- 8404/tcp
|
||||||
|
- 25565/tcp
|
||||||
|
|
||||||
|
pre_tasks:
|
||||||
|
- name: Ensure required groups exist
|
||||||
|
ansible.builtin.group:
|
||||||
|
name: "{{ item }}"
|
||||||
|
state: present
|
||||||
|
loop:
|
||||||
|
- haproxy
|
||||||
|
|
||||||
|
roles:
|
||||||
|
- haproxy
|
||||||
|
|
||||||
|
post_tasks:
|
||||||
|
- name: Wait for HAProxy to be ready
|
||||||
|
ansible.builtin.wait_for:
|
||||||
|
host: "{{ ansible_default_ipv4.address }}"
|
||||||
|
port: 443
|
||||||
|
timeout: 60
|
||||||
|
|
||||||
|
- name: Display deployment summary
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: |
|
||||||
|
╔════════════════════════════════════════════════════════════╗
|
||||||
|
║ HAProxy Deployment Complete - lightning-lane ║
|
||||||
|
╚════════════════════════════════════════════════════════════╝
|
||||||
|
|
||||||
|
Stats Interface: http://{{ ansible_default_ipv4.address }}:8404/stats
|
||||||
|
Username: {{ haproxy_stats_username }}
|
||||||
|
|
||||||
|
HTTPS Services:
|
||||||
|
{% for frontend in haproxy_frontends %}
|
||||||
|
{% if frontend.acls is defined %}
|
||||||
|
{% for acl in frontend.acls %}
|
||||||
|
- {{ acl.split()[1] | regex_replace('hdr\\(host\\)', '') | regex_replace('-i', '') | trim }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
TCP Services:
|
||||||
|
{% for tcp in haproxy_tcp_services %}
|
||||||
|
- {{ tcp.name }}: {{ ansible_default_ipv4.address }}:{{ tcp.frontend_port }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
Certificates:
|
||||||
|
{% for domain in haproxy_certbot_domains %}
|
||||||
|
- {{ domain.domain }}{% if domain.include_base | default(false) %} + base domain{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
Next steps:
|
||||||
|
1. Verify certificate: certbot certificates
|
||||||
|
2. Test renewal: certbot renew --dry-run
|
||||||
|
3. Check HAProxy stats interface
|
||||||
|
4. Test HTTPS endpoints
|
||||||
0
ansible/playbooks/roles/haproxy/README.md
Normal file
0
ansible/playbooks/roles/haproxy/README.md
Normal file
147
ansible/playbooks/roles/haproxy/defaults/main.yml
Normal file
147
ansible/playbooks/roles/haproxy/defaults/main.yml
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
---
|
||||||
|
# ansible/roles/haproxy/defaults/main.yml
|
||||||
|
|
||||||
|
# HAProxy version and installation
|
||||||
|
haproxy_version: "3.2"
|
||||||
|
haproxy_install_method: "package" # package or source
|
||||||
|
|
||||||
|
# System configuration
|
||||||
|
haproxy_user: haproxy
|
||||||
|
haproxy_group: haproxy
|
||||||
|
haproxy_chroot_dir: /var/lib/haproxy
|
||||||
|
haproxy_config_dir: /etc/haproxy
|
||||||
|
haproxy_log_dir: /var/log/haproxy
|
||||||
|
|
||||||
|
# Global settings
|
||||||
|
haproxy_global_maxconn: 4096
|
||||||
|
haproxy_global_log_facility: local0
|
||||||
|
haproxy_global_log_level: info
|
||||||
|
haproxy_global_nbthread: "{{ ansible_processor_vcpus }}"
|
||||||
|
|
||||||
|
# Default timeouts (milliseconds)
|
||||||
|
haproxy_timeout_connect: 5000
|
||||||
|
haproxy_timeout_client: 50000
|
||||||
|
haproxy_timeout_server: 50000
|
||||||
|
|
||||||
|
# Stats interface
|
||||||
|
haproxy_stats_enable: true
|
||||||
|
haproxy_stats_port: 8404
|
||||||
|
haproxy_stats_uri: /stats
|
||||||
|
haproxy_stats_refresh: 30s
|
||||||
|
haproxy_stats_username: admin
|
||||||
|
haproxy_stats_password: "{{ vault_haproxy_stats_password | default('changeme') }}"
|
||||||
|
|
||||||
|
# SSL/TLS configuration
|
||||||
|
haproxy_ssl_cert_dir: "{{ haproxy_config_dir }}/certs"
|
||||||
|
haproxy_ssl_default_crt: "{{ haproxy_ssl_cert_dir }}/default.pem"
|
||||||
|
haproxy_ssl_ciphers: "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384"
|
||||||
|
haproxy_ssl_options: "ssl-min-ver TLSv1.2 no-tls-tickets"
|
||||||
|
|
||||||
|
# Health check defaults
|
||||||
|
haproxy_health_check_interval: 2000
|
||||||
|
haproxy_health_check_timeout: 1000
|
||||||
|
haproxy_health_check_rise: 2
|
||||||
|
haproxy_health_check_fall: 3
|
||||||
|
|
||||||
|
# Service discovery integration
|
||||||
|
haproxy_netbox_integration: false # true
|
||||||
|
haproxy_netbox_url: "http://fire-station.local.mk-labs.cloud:8000"
|
||||||
|
haproxy_netbox_token: "{{ vault_netbox_token | default('') }}"
|
||||||
|
|
||||||
|
# Frontends configuration
|
||||||
|
haproxy_frontends: []
|
||||||
|
# - name: http_front
|
||||||
|
# bind: "*:80"
|
||||||
|
# mode: http
|
||||||
|
# redirect: "scheme https code 301"
|
||||||
|
#
|
||||||
|
# - name: https_front
|
||||||
|
# bind: "*:443 ssl crt {{ haproxy_ssl_cert_dir }}"
|
||||||
|
# mode: http
|
||||||
|
# options:
|
||||||
|
# - "http-server-close"
|
||||||
|
# - "forwardfor"
|
||||||
|
# acls:
|
||||||
|
# - "netbox hdr(host) -i fire-station.local.mk-labs.cloud"
|
||||||
|
# - "wordpress hdr(host) -i be-our-guest.local.mk-labs.cloud"
|
||||||
|
# use_backends:
|
||||||
|
# - "netbox_back if netbox"
|
||||||
|
# - "wordpress_back if wordpress"
|
||||||
|
|
||||||
|
# Backends configuration
|
||||||
|
haproxy_backends: []
|
||||||
|
# - name: netbox_back
|
||||||
|
# mode: http
|
||||||
|
# balance: roundrobin
|
||||||
|
# options:
|
||||||
|
# - "httpchk GET /"
|
||||||
|
# servers:
|
||||||
|
# - name: fire-station
|
||||||
|
# address: 10.1.71.102:8000
|
||||||
|
# check: true
|
||||||
|
|
||||||
|
# TCP services configuration
|
||||||
|
haproxy_tcp_services: []
|
||||||
|
# - name: postgres
|
||||||
|
# frontend_port: 5432
|
||||||
|
# backend_port: 5432
|
||||||
|
# balance: leastconn
|
||||||
|
# servers:
|
||||||
|
# - name: netbox-db
|
||||||
|
# address: 10.1.71.102
|
||||||
|
|
||||||
|
# Firewall configuration
|
||||||
|
haproxy_configure_firewall: true
|
||||||
|
haproxy_firewall_allowed_ports:
|
||||||
|
- 80/tcp
|
||||||
|
- 443/tcp
|
||||||
|
- 8404/tcp
|
||||||
|
|
||||||
|
# Monitoring and observability
|
||||||
|
haproxy_prometheus_exporter: false
|
||||||
|
haproxy_prometheus_port: 9101
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
haproxy_rsyslog_config: true
|
||||||
|
haproxy_log_rotation: true
|
||||||
|
|
||||||
|
# Certificate management - Certbot with Cloudflare DNS
|
||||||
|
haproxy_certbot_enable: true
|
||||||
|
haproxy_certbot_challenge_method: "dns-cloudflare" # or "webroot" for HTTP-01
|
||||||
|
haproxy_certbot_email: "ryan.blundon@protonmail.com"
|
||||||
|
haproxy_certbot_staging: false # Set to true for testing with Let's Encrypt staging
|
||||||
|
|
||||||
|
# Cloudflare DNS configuration
|
||||||
|
haproxy_certbot_cloudflare_api_token: "{{ vault_cloudflare_api_token }}"
|
||||||
|
haproxy_certbot_cloudflare_credentials_file: "/etc/letsencrypt/cloudflare.ini"
|
||||||
|
|
||||||
|
# Certificate domains - DNS-01 supports wildcards
|
||||||
|
haproxy_certbot_domains:
|
||||||
|
- domain: "*.mk-labs.cloud"
|
||||||
|
include_base: true
|
||||||
|
- domain: "*.local.mk-labs.cloud"
|
||||||
|
include_base: true # Also include local.mk-labs.cloud
|
||||||
|
- domain: "lightning-lane.local.mk-labs.cloud"
|
||||||
|
include_base: false
|
||||||
|
|
||||||
|
# Alternative: specific domains without wildcard
|
||||||
|
# haproxy_certbot_domains:
|
||||||
|
# - domain: "lightning-lane.local.mk-labs.cloud"
|
||||||
|
# - domain: "fire-station.local.mk-labs.cloud"
|
||||||
|
# - domain: "be-our-guest.local.mk-labs.cloud"
|
||||||
|
|
||||||
|
# Certbot renewal settings
|
||||||
|
haproxy_certbot_renewal_cron_minute: "0"
|
||||||
|
haproxy_certbot_renewal_cron_hour: "3" # 3 AM daily
|
||||||
|
haproxy_certbot_renewal_cron_day: "*"
|
||||||
|
haproxy_certbot_post_hook: "{{ haproxy_config_dir }}/certbot-post-hook.sh"
|
||||||
|
|
||||||
|
# Certificate storage
|
||||||
|
haproxy_certbot_cert_dir: "/etc/letsencrypt/live"
|
||||||
|
haproxy_certbot_archive_dir: "/etc/letsencrypt/archive"
|
||||||
|
|
||||||
|
# DNS propagation wait time (seconds)
|
||||||
|
haproxy_certbot_dns_propagation_seconds: 60
|
||||||
|
|
||||||
|
# Fallback to self-signed if Certbot fails
|
||||||
|
haproxy_certbot_fallback_selfsigned: true
|
||||||
26
ansible/playbooks/roles/haproxy/handlers/main.yml
Normal file
26
ansible/playbooks/roles/haproxy/handlers/main.yml
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
---
|
||||||
|
# ansible/roles/haproxy/handlers/main.yml
|
||||||
|
|
||||||
|
- name: Reload haproxy
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: haproxy
|
||||||
|
state: reloaded
|
||||||
|
listen: reload haproxy
|
||||||
|
|
||||||
|
- name: Restart haproxy
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: haproxy
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
listen: restart haproxy
|
||||||
|
|
||||||
|
- name: Reload systemd
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
daemon_reload: true
|
||||||
|
listen: reload systemd
|
||||||
|
|
||||||
|
- name: Restart rsyslog
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: rsyslog
|
||||||
|
state: restarted
|
||||||
|
listen: restart rsyslog
|
||||||
202
ansible/playbooks/roles/haproxy/tasks/certbot-cloudflare.yml
Normal file
202
ansible/playbooks/roles/haproxy/tasks/certbot-cloudflare.yml
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
---
|
||||||
|
# ansible/roles/haproxy/tasks/certbot-cloudflare.yml
|
||||||
|
|
||||||
|
- name: Install Certbot and Cloudflare DNS plugin
|
||||||
|
ansible.builtin.package:
|
||||||
|
name:
|
||||||
|
- certbot
|
||||||
|
- python3-certbot-dns-cloudflare
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create Let's Encrypt configuration directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/letsencrypt
|
||||||
|
state: directory
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Create Cloudflare credentials file
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: cloudflare-credentials.ini.j2
|
||||||
|
dest: "{{ haproxy_certbot_cloudflare_credentials_file }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0600'
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Create Certbot post-renewal hook script
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: certbot-post-hook.sh.j2
|
||||||
|
dest: "{{ haproxy_certbot_post_hook }}"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Create Certbot renewal hooks directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/letsencrypt/renewal-hooks/deploy
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Link post-hook to renewal hooks directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
src: "{{ haproxy_certbot_post_hook }}"
|
||||||
|
dest: /etc/letsencrypt/renewal-hooks/deploy/haproxy-reload.sh
|
||||||
|
state: link
|
||||||
|
force: true
|
||||||
|
|
||||||
|
- name: Check for existing certificates
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ haproxy_certbot_cert_dir }}/{{ item.domain | regex_replace('\\*\\.', '') }}"
|
||||||
|
register: existing_certs
|
||||||
|
loop: "{{ haproxy_certbot_domains }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.domain }}"
|
||||||
|
|
||||||
|
- name: Build certificate request commands
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
certbot_commands: "{{ certbot_commands | default([]) + [command_item] }}"
|
||||||
|
vars:
|
||||||
|
cert_name: "{{ item.item.domain | regex_replace('\\*\\.', '') }}"
|
||||||
|
domain_list: >-
|
||||||
|
{{ [item.item.domain] +
|
||||||
|
(item.item.include_base | default(false) | ternary(
|
||||||
|
[item.item.domain | regex_replace('\\*\\.', '')],
|
||||||
|
[]
|
||||||
|
))
|
||||||
|
}}
|
||||||
|
command_item:
|
||||||
|
domain: "{{ item.item.domain }}"
|
||||||
|
cert_name: "{{ cert_name }}"
|
||||||
|
domains: "{{ domain_list }}"
|
||||||
|
exists: "{{ item.stat.exists }}"
|
||||||
|
loop: "{{ existing_certs.results }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.item.domain }}"
|
||||||
|
|
||||||
|
- name: Display certificate request plan
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: |
|
||||||
|
Will request certificates for:
|
||||||
|
{% for cmd in certbot_commands %}
|
||||||
|
- {{ cmd.cert_name }} ({{ cmd.domains | join(', ') }}) - {{ 'EXISTS' if cmd.exists else 'NEW' }}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
- name: Request certificates from Let's Encrypt via Cloudflare DNS
|
||||||
|
ansible.builtin.command: >
|
||||||
|
certbot certonly
|
||||||
|
--non-interactive
|
||||||
|
--agree-tos
|
||||||
|
--email {{ haproxy_certbot_email }}
|
||||||
|
--dns-cloudflare
|
||||||
|
--dns-cloudflare-credentials {{ haproxy_certbot_cloudflare_credentials_file }}
|
||||||
|
--dns-cloudflare-propagation-seconds {{ haproxy_certbot_dns_propagation_seconds }}
|
||||||
|
--cert-name {{ item.cert_name }}
|
||||||
|
{% for domain in item.domains %}
|
||||||
|
--domain {{ domain }}
|
||||||
|
{% endfor %}
|
||||||
|
{% if haproxy_certbot_staging %}
|
||||||
|
--staging
|
||||||
|
{% endif %}
|
||||||
|
--deploy-hook {{ haproxy_certbot_post_hook }}
|
||||||
|
loop: "{{ certbot_commands }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.cert_name }}"
|
||||||
|
when: not item.exists
|
||||||
|
register: certbot_result
|
||||||
|
failed_when:
|
||||||
|
- certbot_result.rc != 0
|
||||||
|
- "'Certificate not yet due for renewal' not in certbot_result.stdout"
|
||||||
|
- "'too many certificates already issued' not in certbot_result.stderr"
|
||||||
|
|
||||||
|
- name: Display certificate request results
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Certificate for {{ item.item.cert_name }}: {{ 'SUCCESS' if item.rc == 0 else 'SKIPPED/FAILED' }}"
|
||||||
|
loop: "{{ certbot_result.results }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.item.cert_name }}"
|
||||||
|
when: certbot_result.results is defined
|
||||||
|
|
||||||
|
- name: Run post-hook to combine certificates for HAProxy
|
||||||
|
ansible.builtin.command: "{{ haproxy_certbot_post_hook }}"
|
||||||
|
changed_when: true
|
||||||
|
when: certbot_result.changed
|
||||||
|
|
||||||
|
- name: Setup automatic certificate renewal via cron
|
||||||
|
ansible.builtin.cron:
|
||||||
|
name: "Certbot certificate renewal"
|
||||||
|
minute: "{{ haproxy_certbot_renewal_cron_minute }}"
|
||||||
|
hour: "{{ haproxy_certbot_renewal_cron_hour }}"
|
||||||
|
day: "{{ haproxy_certbot_renewal_cron_day }}"
|
||||||
|
job: "/usr/bin/certbot renew --quiet --deploy-hook {{ haproxy_certbot_post_hook }} 2>&1 | logger -t certbot"
|
||||||
|
user: root
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create systemd timer for certificate renewal (alternative to cron)
|
||||||
|
when: ansible_service_mgr == "systemd"
|
||||||
|
block:
|
||||||
|
- name: Create certbot renewal service
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
[Unit]
|
||||||
|
Description=Certbot Renewal
|
||||||
|
After=network-online.target
|
||||||
|
Wants=network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=oneshot
|
||||||
|
ExecStart=/usr/bin/certbot renew --quiet --deploy-hook {{ haproxy_certbot_post_hook }}
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
dest: /etc/systemd/system/certbot-renewal.service
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Create certbot renewal timer
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
[Unit]
|
||||||
|
Description=Certbot Renewal Timer
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
OnCalendar=daily
|
||||||
|
RandomizedDelaySec=1h
|
||||||
|
Persistent=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
||||||
|
dest: /etc/systemd/system/certbot-renewal.timer
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Enable and start certbot renewal timer
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: certbot-renewal.timer
|
||||||
|
enabled: true
|
||||||
|
state: started
|
||||||
|
daemon_reload: true
|
||||||
|
|
||||||
|
- name: Test certificate renewal (dry-run)
|
||||||
|
ansible.builtin.command: certbot renew --dry-run --dns-cloudflare --dns-cloudflare-credentials {{ haproxy_certbot_cloudflare_credentials_file }}
|
||||||
|
register: renewal_test
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Display renewal test results
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: |
|
||||||
|
Certificate renewal dry-run: {{ 'SUCCESS ✓' if renewal_test.rc == 0 else 'FAILED ✗' }}
|
||||||
|
|
||||||
|
{% if renewal_test.rc == 0 %}
|
||||||
|
Your certificates will renew automatically.
|
||||||
|
{% else %}
|
||||||
|
Please check the output above for errors.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- name: List all certificates
|
||||||
|
ansible.builtin.command: certbot certificates
|
||||||
|
register: cert_list
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Display certificate information
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "{{ cert_list.stdout_lines }}"
|
||||||
78
ansible/playbooks/roles/haproxy/tasks/certificates.yml
Normal file
78
ansible/playbooks/roles/haproxy/tasks/certificates.yml
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
---
|
||||||
|
# ansible/roles/haproxy/tasks/certificates.yml
|
||||||
|
|
||||||
|
- name: Check if default certificate exists
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ haproxy_ssl_default_crt }}"
|
||||||
|
register: default_cert
|
||||||
|
|
||||||
|
- name: Generate self-signed certificate for development
|
||||||
|
when: not default_cert.stat.exists
|
||||||
|
block:
|
||||||
|
- name: Generate private key
|
||||||
|
openssl_privatekey:
|
||||||
|
path: "{{ haproxy_ssl_cert_dir }}/default.key"
|
||||||
|
size: 2048
|
||||||
|
mode: '0600'
|
||||||
|
owner: "{{ haproxy_user }}"
|
||||||
|
group: "{{ haproxy_group }}"
|
||||||
|
|
||||||
|
- name: Generate certificate signing request
|
||||||
|
openssl_csr:
|
||||||
|
path: "{{ haproxy_ssl_cert_dir }}/default.csr"
|
||||||
|
privatekey_path: "{{ haproxy_ssl_cert_dir }}/default.key"
|
||||||
|
common_name: "lightning-lane.local.mk-labs.cloud"
|
||||||
|
subject_alt_name:
|
||||||
|
- "DNS:lightning-lane.local.mk-labs.cloud"
|
||||||
|
- "DNS:*.local.mk-labs.cloud"
|
||||||
|
owner: "{{ haproxy_user }}"
|
||||||
|
group: "{{ haproxy_group }}"
|
||||||
|
|
||||||
|
- name: Generate self-signed certificate
|
||||||
|
openssl_certificate:
|
||||||
|
path: "{{ haproxy_ssl_cert_dir }}/default.crt"
|
||||||
|
privatekey_path: "{{ haproxy_ssl_cert_dir }}/default.key"
|
||||||
|
csr_path: "{{ haproxy_ssl_cert_dir }}/default.csr"
|
||||||
|
provider: selfsigned
|
||||||
|
selfsigned_not_after: "+3650d"
|
||||||
|
owner: "{{ haproxy_user }}"
|
||||||
|
group: "{{ haproxy_group }}"
|
||||||
|
|
||||||
|
- name: Combine certificate and key for HAProxy
|
||||||
|
ansible.builtin.shell: |
|
||||||
|
cat {{ haproxy_ssl_cert_dir }}/default.crt \
|
||||||
|
{{ haproxy_ssl_cert_dir }}/default.key \
|
||||||
|
> {{ haproxy_ssl_default_crt }}
|
||||||
|
args:
|
||||||
|
creates: "{{ haproxy_ssl_default_crt }}"
|
||||||
|
|
||||||
|
- name: Set permissions on combined certificate
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ haproxy_ssl_default_crt }}"
|
||||||
|
owner: "{{ haproxy_user }}"
|
||||||
|
group: "{{ haproxy_group }}"
|
||||||
|
mode: '0600'
|
||||||
|
|
||||||
|
- name: Create certificate directory structure
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ haproxy_ssl_cert_dir }}/{{ item }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ haproxy_user }}"
|
||||||
|
group: "{{ haproxy_group }}"
|
||||||
|
mode: '0755'
|
||||||
|
loop:
|
||||||
|
- live
|
||||||
|
- archive
|
||||||
|
|
||||||
|
- name: Deploy additional certificates
|
||||||
|
when: haproxy_ssl_certificates is defined
|
||||||
|
block:
|
||||||
|
- name: Copy certificate files
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ haproxy_ssl_cert_dir }}/live/{{ item.name }}.pem"
|
||||||
|
owner: "{{ haproxy_user }}"
|
||||||
|
group: "{{ haproxy_group }}"
|
||||||
|
mode: '0600'
|
||||||
|
loop: "{{ haproxy_ssl_certificates }}"
|
||||||
|
notify: Reload haproxy
|
||||||
94
ansible/playbooks/roles/haproxy/tasks/configure.yml
Normal file
94
ansible/playbooks/roles/haproxy/tasks/configure.yml
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
---
|
||||||
|
# ansible/roles/haproxy/tasks/configure.yml
|
||||||
|
|
||||||
|
- name: Fetch services from NetBox
|
||||||
|
when: haproxy_netbox_integration
|
||||||
|
block:
|
||||||
|
- name: Query NetBox for service configurations
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ haproxy_netbox_url }}/api/ipam/services/"
|
||||||
|
method: GET
|
||||||
|
headers:
|
||||||
|
Authorization: "Token {{ haproxy_netbox_token }}"
|
||||||
|
Accept: "application/json"
|
||||||
|
return_content: true
|
||||||
|
register: netbox_services
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Parse NetBox services
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
haproxy_frontends: "{{ haproxy_frontends | default([]) + netbox_parsed_frontends }}"
|
||||||
|
haproxy_backends: "{{ haproxy_backends | default([]) + netbox_parsed_backends }}"
|
||||||
|
vars:
|
||||||
|
netbox_parsed_frontends: "{{ netbox_services.json.results | map(attribute='custom_fields') | list }}"
|
||||||
|
netbox_parsed_backends: "{{ netbox_services.json.results | map(attribute='custom_fields') | list }}"
|
||||||
|
when: netbox_services.json.results is defined
|
||||||
|
|
||||||
|
- name: Generate HAProxy main configuration
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: haproxy.cfg.j2
|
||||||
|
dest: "{{ haproxy_config_dir }}/haproxy.cfg"
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
mode: '0644'
|
||||||
|
backup: true
|
||||||
|
validate: 'haproxy -c -f %s'
|
||||||
|
notify: reload haproxy
|
||||||
|
|
||||||
|
- name: Configure rsyslog for HAProxy
|
||||||
|
when: haproxy_rsyslog_config
|
||||||
|
block:
|
||||||
|
- name: Create rsyslog configuration for HAProxy
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
# HAProxy logging configuration
|
||||||
|
$ModLoad imudp
|
||||||
|
$UDPServerRun 514
|
||||||
|
|
||||||
|
# Create separate log files for HAProxy
|
||||||
|
local0.* {{ haproxy_log_dir }}/haproxy.log
|
||||||
|
local0.info {{ haproxy_log_dir }}/haproxy-info.log
|
||||||
|
local0.notice {{ haproxy_log_dir }}/haproxy-notice.log
|
||||||
|
local0.err {{ haproxy_log_dir }}/haproxy-error.log
|
||||||
|
|
||||||
|
# Stop processing HAProxy logs
|
||||||
|
& stop
|
||||||
|
dest: /etc/rsyslog.d/49-haproxy.conf
|
||||||
|
mode: '0644'
|
||||||
|
notify: restart rsyslog
|
||||||
|
|
||||||
|
- name: Configure logrotate for HAProxy
|
||||||
|
when: haproxy_log_rotation
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: logrotate.j2
|
||||||
|
dest: /etc/logrotate.d/haproxy
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Create HAProxy systemd override directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /etc/systemd/system/haproxy.service.d
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Configure HAProxy systemd service overrides
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
[Service]
|
||||||
|
# Increase file descriptor limits
|
||||||
|
LimitNOFILE=65536
|
||||||
|
|
||||||
|
# Runtime directory
|
||||||
|
RuntimeDirectory=haproxy
|
||||||
|
RuntimeDirectoryMode=0755
|
||||||
|
|
||||||
|
# Security hardening
|
||||||
|
NoNewPrivileges=true
|
||||||
|
ProtectSystem=strict
|
||||||
|
ProtectHome=true
|
||||||
|
PrivateTmp=true
|
||||||
|
ReadWritePaths={{ haproxy_log_dir }}
|
||||||
|
dest: /etc/systemd/system/haproxy.service.d/override.conf
|
||||||
|
mode: '0644'
|
||||||
|
notify:
|
||||||
|
- Reload systemd
|
||||||
|
- Restart haproxy
|
||||||
128
ansible/playbooks/roles/haproxy/tasks/install.yml
Normal file
128
ansible/playbooks/roles/haproxy/tasks/install.yml
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
---
|
||||||
|
# ansible/roles/haproxy/tasks/install.yml
|
||||||
|
|
||||||
|
- name: Install HAProxy repository (Ubuntu)
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
block:
|
||||||
|
- name: Add HAProxy PPA
|
||||||
|
ansible.builtin.apt_repository:
|
||||||
|
repo: "ppa:vbernat/haproxy-{{ haproxy_version }}"
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Install HAProxy
|
||||||
|
ansible.builtin.apt:
|
||||||
|
name: haproxy
|
||||||
|
state: present
|
||||||
|
update_cache: true
|
||||||
|
|
||||||
|
- name: Install HAProxy (Fedora/RHEL)
|
||||||
|
when: ansible_os_family == "RedHat"
|
||||||
|
block:
|
||||||
|
- name: Install HAProxy
|
||||||
|
ansible.builtin.dnf:
|
||||||
|
name: haproxy
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Install additional packages
|
||||||
|
ansible.builtin.package:
|
||||||
|
name:
|
||||||
|
- rsyslog
|
||||||
|
- logrotate
|
||||||
|
- socat # For HAProxy socket communication
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create HAProxy system user
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ haproxy_user }}"
|
||||||
|
group: "{{ haproxy_group }}"
|
||||||
|
system: true
|
||||||
|
shell: /usr/sbin/nologin
|
||||||
|
home: "{{ haproxy_chroot_dir }}"
|
||||||
|
create_home: true
|
||||||
|
|
||||||
|
- name: Create required directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ haproxy_user }}"
|
||||||
|
group: "{{ haproxy_group }}"
|
||||||
|
mode: '0755'
|
||||||
|
loop:
|
||||||
|
- "{{ haproxy_config_dir }}"
|
||||||
|
- "{{ haproxy_ssl_cert_dir }}"
|
||||||
|
- "{{ haproxy_log_dir }}"
|
||||||
|
- "{{ haproxy_chroot_dir }}"
|
||||||
|
- /var/lib/haproxy/dev
|
||||||
|
|
||||||
|
- name: Create HAProxy socket directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: /run/haproxy
|
||||||
|
state: directory
|
||||||
|
owner: "{{ haproxy_user }}"
|
||||||
|
group: "{{ haproxy_group }}"
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Configure firewall rules
|
||||||
|
when: haproxy_configure_firewall
|
||||||
|
block:
|
||||||
|
- name: Open HAProxy ports (UFW)
|
||||||
|
when: ansible_os_family == "Debian"
|
||||||
|
community.general.ufw:
|
||||||
|
rule: allow
|
||||||
|
port: "{{ item.split('/')[0] }}"
|
||||||
|
proto: "{{ item.split('/')[1] }}"
|
||||||
|
loop: "{{ haproxy_firewall_allowed_ports }}"
|
||||||
|
|
||||||
|
- name: Open HAProxy ports (firewalld)
|
||||||
|
when: ansible_os_family == "RedHat"
|
||||||
|
ansible.posix.firewalld:
|
||||||
|
port: "{{ item }}"
|
||||||
|
permanent: true
|
||||||
|
state: enabled
|
||||||
|
immediate: true
|
||||||
|
loop: "{{ haproxy_firewall_allowed_ports }}"
|
||||||
|
|
||||||
|
- name: Install Prometheus HAProxy exporter
|
||||||
|
when: haproxy_prometheus_exporter
|
||||||
|
block:
|
||||||
|
- name: Download HAProxy exporter
|
||||||
|
ansible.builtin.get_url:
|
||||||
|
url: "https://github.com/prometheus/haproxy_exporter/releases/download/v0.15.0/haproxy_exporter-0.15.0.linux-amd64.tar.gz"
|
||||||
|
dest: /tmp/haproxy_exporter.tar.gz
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Extract HAProxy exporter
|
||||||
|
ansible.builtin.unarchive:
|
||||||
|
src: /tmp/haproxy_exporter.tar.gz
|
||||||
|
dest: /usr/local/bin/
|
||||||
|
remote_src: true
|
||||||
|
extra_opts:
|
||||||
|
- --strip-components=1
|
||||||
|
- --wildcards
|
||||||
|
- '*/haproxy_exporter'
|
||||||
|
|
||||||
|
- name: Create HAProxy exporter systemd service
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: |
|
||||||
|
[Unit]
|
||||||
|
Description=HAProxy Exporter
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User={{ haproxy_user }}
|
||||||
|
ExecStart=/usr/local/bin/haproxy_exporter --haproxy.scrape-uri=unix:/run/haproxy/admin.sock
|
||||||
|
Restart=on-failure
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
dest: /etc/systemd/system/haproxy-exporter.service
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Enable and start HAProxy exporter
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: haproxy-exporter
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
40
ansible/playbooks/roles/haproxy/tasks/main.yml
Normal file
40
ansible/playbooks/roles/haproxy/tasks/main.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
# ansible/roles/haproxy/tasks/main.yml
|
||||||
|
|
||||||
|
# - name: Include OS-specific variables
|
||||||
|
# include_vars: "{{ ansible_os_family }}.yml"
|
||||||
|
# tags: [haproxy, always]
|
||||||
|
|
||||||
|
- name: Include installation tasks
|
||||||
|
ansible.builtin.include_tasks: install.yml
|
||||||
|
tags: [haproxy, install]
|
||||||
|
|
||||||
|
- name: Include Certbot with Cloudflare DNS tasks
|
||||||
|
ansible.builtin.include_tasks: certbot-cloudflare.yml
|
||||||
|
when:
|
||||||
|
- haproxy_certbot_enable
|
||||||
|
- haproxy_certbot_challenge_method == "dns-cloudflare"
|
||||||
|
tags: [haproxy, certificates, certbot, cloudflare]
|
||||||
|
|
||||||
|
- name: Include fallback self-signed certificate tasks
|
||||||
|
ansible.builtin.include_tasks: certificates.yml
|
||||||
|
when:
|
||||||
|
- not haproxy_certbot_enable
|
||||||
|
- haproxy_certbot_fallback_selfsigned | default(false)
|
||||||
|
tags: [haproxy, certificates, selfsigned]
|
||||||
|
|
||||||
|
- name: Include configuration tasks
|
||||||
|
ansible.builtin.include_tasks: configure.yml
|
||||||
|
tags: [haproxy, configure]
|
||||||
|
|
||||||
|
- name: Include validation tasks
|
||||||
|
ansible.builtin.include_tasks: validate.yml
|
||||||
|
tags: [haproxy, validate]
|
||||||
|
|
||||||
|
- name: Ensure HAProxy is started and enabled
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: haproxy
|
||||||
|
state: started
|
||||||
|
enabled: true
|
||||||
|
daemon_reload: true
|
||||||
|
tags: [haproxy, service]
|
||||||
47
ansible/playbooks/roles/haproxy/tasks/validate.yml
Normal file
47
ansible/playbooks/roles/haproxy/tasks/validate.yml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
---
|
||||||
|
# ansible/roles/haproxy/tasks/validate.yml
|
||||||
|
|
||||||
|
- name: Validate HAProxy configuration syntax
|
||||||
|
command: haproxy -c -f {{ haproxy_config_dir }}/haproxy.cfg
|
||||||
|
register: haproxy_validation
|
||||||
|
changed_when: false
|
||||||
|
failed_when: haproxy_validation.rc != 0
|
||||||
|
|
||||||
|
- name: Display validation results
|
||||||
|
debug:
|
||||||
|
msg: "{{ haproxy_validation.stdout_lines }}"
|
||||||
|
when: haproxy_validation.stdout_lines is defined
|
||||||
|
|
||||||
|
- name: Check HAProxy service status
|
||||||
|
systemd:
|
||||||
|
name: haproxy
|
||||||
|
state: started
|
||||||
|
register: haproxy_status
|
||||||
|
changed_when: false
|
||||||
|
|
||||||
|
- name: Verify HAProxy is listening on configured ports
|
||||||
|
wait_for:
|
||||||
|
host: "{{ ansible_default_ipv4.address }}"
|
||||||
|
port: "{{ item }}"
|
||||||
|
timeout: 10
|
||||||
|
loop:
|
||||||
|
- 80
|
||||||
|
- 443
|
||||||
|
- "{{ haproxy_stats_port }}"
|
||||||
|
when: haproxy_status.status.ActiveState == "active"
|
||||||
|
|
||||||
|
- name: Test stats interface accessibility
|
||||||
|
uri:
|
||||||
|
url: "http://localhost:{{ haproxy_stats_port }}{{ haproxy_stats_uri }}"
|
||||||
|
user: "{{ haproxy_stats_username }}"
|
||||||
|
password: "{{ haproxy_stats_password }}"
|
||||||
|
force_basic_auth: true
|
||||||
|
status_code: 200
|
||||||
|
register: stats_test
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Display stats interface status
|
||||||
|
debug:
|
||||||
|
msg: "Stats interface is {{ 'accessible' if stats_test.status == 200 else 'not accessible' }}"
|
||||||
|
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# {{ ansible_managed }}
|
||||||
|
# Certbot post-renewal hook for HAProxy
|
||||||
|
# Combines certificate and private key for HAProxy consumption
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
LETSENCRYPT_LIVE="/etc/letsencrypt/live"
|
||||||
|
HAPROXY_CERT_DIR="{{ haproxy_ssl_cert_dir }}/live"
|
||||||
|
HAPROXY_USER="{{ haproxy_user }}"
|
||||||
|
HAPROXY_GROUP="{{ haproxy_group }}"
|
||||||
|
LOG_FILE="{{ haproxy_log_dir }}/certbot-hook.log"
|
||||||
|
|
||||||
|
# Ensure HAProxy cert directory exists
|
||||||
|
mkdir -p "$HAPROXY_CERT_DIR"
|
||||||
|
|
||||||
|
# Logging function
|
||||||
|
log() {
|
||||||
|
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
log "Starting certificate deployment for HAProxy"
|
||||||
|
|
||||||
|
# Track if any certificates were updated
|
||||||
|
CERTS_UPDATED=false
|
||||||
|
|
||||||
|
# Process each certificate in Let's Encrypt live directory
|
||||||
|
for cert_dir in "$LETSENCRYPT_LIVE"/*; do
|
||||||
|
if [ ! -d "$cert_dir" ] || [ "$(basename "$cert_dir")" = "README" ]; then
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
CERT_NAME=$(basename "$cert_dir")
|
||||||
|
|
||||||
|
# Check if certificate files exist
|
||||||
|
if [ ! -f "$cert_dir/fullchain.pem" ] || [ ! -f "$cert_dir/privkey.pem" ]; then
|
||||||
|
log "WARNING: Missing certificate files for $CERT_NAME, skipping"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Processing certificate: $CERT_NAME"
|
||||||
|
|
||||||
|
# Create combined PEM file (fullchain + privkey)
|
||||||
|
# HAProxy requires the certificate chain and private key in a single file
|
||||||
|
COMBINED_PEM="$HAPROXY_CERT_DIR/${CERT_NAME}.pem"
|
||||||
|
|
||||||
|
# Combine certificates
|
||||||
|
cat "$cert_dir/fullchain.pem" "$cert_dir/privkey.pem" > "$COMBINED_PEM.tmp"
|
||||||
|
|
||||||
|
# Check if certificate actually changed
|
||||||
|
if [ -f "$COMBINED_PEM" ] && cmp -s "$COMBINED_PEM" "$COMBINED_PEM.tmp"; then
|
||||||
|
log "Certificate $CERT_NAME unchanged, skipping"
|
||||||
|
rm "$COMBINED_PEM.tmp"
|
||||||
|
continue
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Move new certificate into place
|
||||||
|
mv "$COMBINED_PEM.tmp" "$COMBINED_PEM"
|
||||||
|
|
||||||
|
# Set proper permissions
|
||||||
|
chown "$HAPROXY_USER:$HAPROXY_GROUP" "$COMBINED_PEM"
|
||||||
|
chmod 600 "$COMBINED_PEM"
|
||||||
|
|
||||||
|
log "Created/Updated: $COMBINED_PEM"
|
||||||
|
CERTS_UPDATED=true
|
||||||
|
done
|
||||||
|
|
||||||
|
# Create/update default certificate symlink
|
||||||
|
# Use the first wildcard cert or the first available cert as default
|
||||||
|
DEFAULT_CERT="{{ haproxy_ssl_default_crt }}"
|
||||||
|
WILDCARD_CERT="$HAPROXY_CERT_DIR/local.mk-labs.cloud.pem"
|
||||||
|
|
||||||
|
if [ -f "$WILDCARD_CERT" ]; then
|
||||||
|
ln -sf "$WILDCARD_CERT" "$DEFAULT_CERT"
|
||||||
|
log "Updated default certificate symlink to wildcard cert"
|
||||||
|
elif [ -n "$(ls -A "$HAPROXY_CERT_DIR" 2>/dev/null)" ]; then
|
||||||
|
FIRST_CERT=$(ls "$HAPROXY_CERT_DIR"/*.pem 2>/dev/null | head -n1)
|
||||||
|
ln -sf "$FIRST_CERT" "$DEFAULT_CERT"
|
||||||
|
log "Updated default certificate symlink to $FIRST_CERT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Only reload HAProxy if certificates were actually updated
|
||||||
|
if [ "$CERTS_UPDATED" = true ]; then
|
||||||
|
log "Certificates updated, validating HAProxy configuration"
|
||||||
|
|
||||||
|
# Validate HAProxy configuration
|
||||||
|
if haproxy -c -f {{ haproxy_config_dir }}/haproxy.cfg >/dev/null 2>&1; then
|
||||||
|
log "HAProxy configuration valid, reloading service"
|
||||||
|
|
||||||
|
if systemctl reload haproxy; then
|
||||||
|
log "HAProxy reloaded successfully"
|
||||||
|
else
|
||||||
|
log "ERROR: Failed to reload HAProxy"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "ERROR: HAProxy configuration validation failed"
|
||||||
|
haproxy -c -f {{ haproxy_config_dir }}/haproxy.cfg 2>&1 | tee -a "$LOG_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log "No certificates were updated, skipping HAProxy reload"
|
||||||
|
fi
|
||||||
|
|
||||||
|
log "Certificate deployment complete"
|
||||||
|
exit 0
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# {{ ansible_managed }}
|
||||||
|
# Cloudflare API credentials for Certbot DNS-01 challenge
|
||||||
|
# This file contains sensitive information and should be protected
|
||||||
|
|
||||||
|
# Cloudflare API Token (RECOMMENDED)
|
||||||
|
# Create at: https://dash.cloudflare.com/profile/api-tokens
|
||||||
|
# Required permissions: Zone:DNS:Edit for specific zone
|
||||||
|
dns_cloudflare_api_token = {{ haproxy_certbot_cloudflare_api_token }}
|
||||||
|
|
||||||
|
# Alternative: Global API Key (NOT RECOMMENDED - too permissive)
|
||||||
|
# dns_cloudflare_email = your-email@example.com
|
||||||
|
# dns_cloudflare_api_key = your-global-api-key
|
||||||
188
ansible/playbooks/roles/haproxy/templates/haproxy.cfg.j2
Normal file
188
ansible/playbooks/roles/haproxy/templates/haproxy.cfg.j2
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
{# ansible/roles/haproxy/templates/haproxy.cfg.j2 #}
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# HAProxy Configuration for {{ inventory_hostname }}
|
||||||
|
# Generated by Ansible - DO NOT EDIT MANUALLY
|
||||||
|
# Magic Kingdom Labs - lightning-lane load balancer
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Global settings
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
global
|
||||||
|
log 127.0.0.1 {{ haproxy_global_log_facility }} {{ haproxy_global_log_level }}
|
||||||
|
chroot {{ haproxy_chroot_dir }}
|
||||||
|
pidfile /var/run/haproxy.pid
|
||||||
|
maxconn {{ haproxy_global_maxconn }}
|
||||||
|
user {{ haproxy_user }}
|
||||||
|
group {{ haproxy_group }}
|
||||||
|
daemon
|
||||||
|
nbthread {{ haproxy_global_nbthread }}
|
||||||
|
|
||||||
|
# Runtime socket for management
|
||||||
|
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
|
||||||
|
stats timeout 30s
|
||||||
|
|
||||||
|
# SSL/TLS configuration
|
||||||
|
ssl-default-bind-ciphers {{ haproxy_ssl_ciphers }}
|
||||||
|
ssl-default-bind-options {{ haproxy_ssl_options }}
|
||||||
|
ssl-default-server-ciphers {{ haproxy_ssl_ciphers }}
|
||||||
|
ssl-default-server-options {{ haproxy_ssl_options }}
|
||||||
|
|
||||||
|
# Performance tuning
|
||||||
|
tune.ssl.default-dh-param 2048
|
||||||
|
tune.ssl.cachesize 100000
|
||||||
|
tune.ssl.lifetime 600
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Common defaults
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
defaults
|
||||||
|
mode http
|
||||||
|
log global
|
||||||
|
option httplog
|
||||||
|
option dontlognull
|
||||||
|
option http-server-close
|
||||||
|
option redispatch
|
||||||
|
retries 3
|
||||||
|
timeout connect {{ haproxy_timeout_connect }}
|
||||||
|
timeout client {{ haproxy_timeout_client }}
|
||||||
|
timeout server {{ haproxy_timeout_server }}
|
||||||
|
timeout http-request 10s
|
||||||
|
timeout http-keep-alive 10s
|
||||||
|
timeout check 10s
|
||||||
|
maxconn 3000
|
||||||
|
|
||||||
|
# Error pages
|
||||||
|
errorfile 400 /etc/haproxy/errors/400.http
|
||||||
|
errorfile 403 /etc/haproxy/errors/403.http
|
||||||
|
errorfile 408 /etc/haproxy/errors/408.http
|
||||||
|
errorfile 500 /etc/haproxy/errors/500.http
|
||||||
|
errorfile 502 /etc/haproxy/errors/502.http
|
||||||
|
errorfile 503 /etc/haproxy/errors/503.http
|
||||||
|
errorfile 504 /etc/haproxy/errors/504.http
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Stats interface
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
{% if haproxy_stats_enable %}
|
||||||
|
listen stats
|
||||||
|
bind *:{{ haproxy_stats_port }}
|
||||||
|
mode http
|
||||||
|
stats enable
|
||||||
|
stats uri {{ haproxy_stats_uri }}
|
||||||
|
stats refresh {{ haproxy_stats_refresh }}
|
||||||
|
stats realm Magic\ Kingdom\ Labs\ -\ HAProxy\ Statistics
|
||||||
|
stats auth {{ haproxy_stats_username }}:{{ haproxy_stats_password }}
|
||||||
|
stats admin if TRUE
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# HTTP Redirect Frontend (HTTP -> HTTPS)
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
frontend http_front
|
||||||
|
bind *:80
|
||||||
|
mode http
|
||||||
|
|
||||||
|
# Redirect all HTTP traffic to HTTPS
|
||||||
|
redirect scheme https code 301
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# HTTPS Frontend with SNI
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
frontend https_front
|
||||||
|
bind *:443 ssl crt {{ haproxy_ssl_cert_dir }}/live crt {{ haproxy_ssl_default_crt }} alpn h2,http/1.1
|
||||||
|
mode http
|
||||||
|
|
||||||
|
# Security headers
|
||||||
|
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
|
||||||
|
http-response set-header X-Frame-Options "SAMEORIGIN"
|
||||||
|
http-response set-header X-Content-Type-Options "nosniff"
|
||||||
|
http-response set-header X-XSS-Protection "1; mode=block"
|
||||||
|
|
||||||
|
# Logging
|
||||||
|
option httplog
|
||||||
|
option forwardfor
|
||||||
|
|
||||||
|
{% if haproxy_frontends is defined and haproxy_frontends | length > 0 %}
|
||||||
|
{% for frontend in haproxy_frontends %}
|
||||||
|
{% if frontend.acls is defined %}
|
||||||
|
# ACLs for {{ frontend.name }}
|
||||||
|
{% for acl in frontend.acls %}
|
||||||
|
acl {{ acl }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
{% for frontend in haproxy_frontends %}
|
||||||
|
{% if frontend.use_backends is defined %}
|
||||||
|
# Backend routing for {{ frontend.name }}
|
||||||
|
{% for use_backend in frontend.use_backends %}
|
||||||
|
use_backend {{ use_backend }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
# Default backend
|
||||||
|
default_backend no_match_back
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# Backends
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
{% for backend in haproxy_backends %}
|
||||||
|
backend {{ backend.name }}
|
||||||
|
mode {{ backend.mode | default('http') }}
|
||||||
|
balance {{ backend.balance | default('roundrobin') }}
|
||||||
|
{% if backend.options is defined %}
|
||||||
|
{% for option in backend.options %}
|
||||||
|
option {{ option }}
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
{% if backend.http_check is defined %}
|
||||||
|
option httpchk {{ backend.http_check }}
|
||||||
|
{% endif %}
|
||||||
|
{% if backend.servers is defined %}
|
||||||
|
{% for server in backend.servers %}
|
||||||
|
server {{ server.name }} {{ server.address }}{% if server.check | default(false) %} check{% endif %}{% if server.backup | default(false) %} backup{% endif %}{% if server.weight is defined %} weight {{ server.weight }}{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
|
||||||
|
# Default backend for unmatched requests
|
||||||
|
backend no_match_back
|
||||||
|
mode http
|
||||||
|
http-request deny deny_status 404
|
||||||
|
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
# TCP Services
|
||||||
|
#---------------------------------------------------------------------
|
||||||
|
{% for tcp_service in haproxy_tcp_services %}
|
||||||
|
# {{ tcp_service.name | upper }} Service (TCP)
|
||||||
|
frontend {{ tcp_service.name }}_front
|
||||||
|
bind *:{{ tcp_service.frontend_port }}
|
||||||
|
mode tcp
|
||||||
|
option tcplog
|
||||||
|
{% if tcp_service.timeout_client is defined %}
|
||||||
|
timeout client {{ tcp_service.timeout_client }}
|
||||||
|
{% endif %}
|
||||||
|
default_backend {{ tcp_service.name }}_back
|
||||||
|
|
||||||
|
backend {{ tcp_service.name }}_back
|
||||||
|
mode tcp
|
||||||
|
balance {{ tcp_service.balance | default('roundrobin') }}
|
||||||
|
{% if tcp_service.timeout_server is defined %}
|
||||||
|
timeout server {{ tcp_service.timeout_server }}
|
||||||
|
{% endif %}
|
||||||
|
{% if tcp_service.timeout_connect is defined %}
|
||||||
|
timeout connect {{ tcp_service.timeout_connect }}
|
||||||
|
{% endif %}
|
||||||
|
{% if tcp_service.servers is defined %}
|
||||||
|
{% for server in tcp_service.servers %}
|
||||||
|
server {{ server.name }} {{ server.address }}:{{ tcp_service.backend_port }}{% if server.check | default(true) %} check{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endfor %}
|
||||||
14
ansible/playbooks/roles/haproxy/templates/logrotate.j2
Normal file
14
ansible/playbooks/roles/haproxy/templates/logrotate.j2
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{# ansible/roles/haproxy/templates/logrotate.j2 #}
|
||||||
|
{{ haproxy_log_dir }}/*.log {
|
||||||
|
daily
|
||||||
|
rotate 14
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
compress
|
||||||
|
delaycompress
|
||||||
|
sharedscripts
|
||||||
|
postrotate
|
||||||
|
/bin/kill -HUP `cat /var/run/rsyslog.pid 2> /dev/null` 2> /dev/null || true
|
||||||
|
/bin/kill -HUP `cat /var/run/haproxy.pid 2> /dev/null` 2> /dev/null || true
|
||||||
|
endscript
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user