Ansible deployed via boilerplates and playbooks

This commit is contained in:
2026-03-22 18:15:55 -05:00
parent 836ef66cf0
commit 307413f3f2
16 changed files with 760 additions and 274 deletions

View File

@@ -1,217 +1,252 @@
$ANSIBLE_VAULT;1.1;AES256 $ANSIBLE_VAULT;1.1;AES256
30386133633263613032383565326536626539353036313638383635623737356636643565366566 63636261313935343763663833386261356237343435326535383634373830393664383632656231
3563653933613063333537636166613661666663646234330a643731336366306564626135626165 6266353261613865333336383335316136336266383934300a306634626139626263623933363335
38386663353234643066376365653862396462393063396633613436356566616338353339626165 36366539373734373936626463333534333139303664303662333364363232313834313635346532
3131346263633531660a346634623165323136663039313565336661393861373930633234336336 6434383839336566310a623131656336393739376137366564316461623737623835373033393864
62633932663730646435343738353463373939363665303662653865386432653632666562353439 65303139643034633039306335633530383831363538326435336338633430323038626665356439
38356661316534343263613561633362326564626362623763643663363736303832326161356339 30333061373437323937343335656363396639393736336237663061353362613432643563343261
65366530386165383635303365613933623062623937333434303335363830313538336636343937 36343734636136626337313461383938613331656634663764353838396532613461616636653361
66316264363063363036656532376461633831366361396232326264666361386266643837386666 61633735346331633764303339653566343132326537656233366637323238366234343232363336
65666566636638316133613464613839306161636665356266346665336139616664356335343434 66313734646232616332326634396233373831303162343964633139366564663062333565343736
37613039346437633934656432643234663564616365653633323734666537656666306235633461 38636238643636616238643037366537353831333033626562363164363334626335613832353035
39316137333033363833626363386231626138613161383132386438613239346430393464633165 38616361346438656535316566316632653239373665646136326130363538313836653061363736
32393864643538323830303162363765386662303661343737376462616532346464333533633231 37653062343039353931386132616330313864366364396461373936353131393764393137323362
65643334666665353533643564656534373039323638393339386466316661646438626463643538 36326635326261353263663435396566643063383238373362393831636666333461303031623264
34396535343966326533333133353430393766633065303961396664336165353962613432376133 61653863666262333862323336663064376535643735663131386162376561363037316361663239
38616363396664383364623536373363353430323261303639316466393139333332366431666638 64316664363666323962343033353834326362313864353665613031343231656461353330613438
34626233343366366563373030356538636238343938656463643864653566353466643437613739 64366335333961356363663934636534303361343864363639396364653234663862643830636439
66313935613235353239306566303265316338386662653634633564663137353539663866383362 36666330326638353163383038306461326534613836326235366162633965636537393265646366
38663335643636613336353030626563376638393234326536656562323164646465356162393233 66393537366661666166396165373636633534366134373632306637653533613761383664383238
64343834633961613036343330373436316664316536343063333964623433666336303237363139 31616661333063303061623864373837383235623065373431313064396165386665363431393330
37326631666661623139376164666430633664343761366463383366346437376166633630306631 33366665363062616463623664656362386238653435613037376362303938663036373864343036
66303964373336613930663730336233383132393138343637636130306530656537363836626266 66313835323635323865613265313133383235643161336637646265316634383361376464633162
37383135613865363634623436323339336161343536393936653039326631336366363165303837 63373236373238626333376164616333303664636363303063666330623666663765646438366461
39343365373338373961623561366362653632646131386661613662386336326664313737326463 37363362643263366361613334393866356662323439313861373434313864333261636434333166
63636665356464656533613366393939393334396339303062643133653434376431343237633763 31643832653463613765333162373635333463366365306463323364353965336561363363643737
63663939363562373533386233326265393161653762363861393065653637373463366664356338 64643535313065353036386638636134643037626538353332376136393430326338383233373864
38626536316262623035303863333532373938396266646165313533316434396437666138363831 37336435626536303030323164316432656533343430336665363633396439623636653864396638
38396564376332343264343365336461633662326531356531643064306632306166383462666466 30336564313230373161376435393265333637333039663939653438386133663238633463663762
38343566623330366262333637626261626231396163636566326136303062623266623534343939 63636362666266376330383739356138643334636263353137613065373034383463386463373231
39343433626635616666303638646431616434363665346465646361353361353239643663303663 34393863626532313132333333653963613532313035376365613635353831666135323164653365
36343731343561626136343432363639373831346331366163653166303432323761616165653838 35633665396666613166333561376265646533613262353865623665626565353061373764643963
30636332343361326461656231663433373836303666316261623430333661343335656437393136 31393737623537636538306365356334353562383334623033623666363162636230383630643862
62303166626331363434383939346166393161336165346661633032363436393735613461376234 37633038383962343337373630363162346230373835623237393136323566653733613465343866
66643534353066396262356233373462373362623336343834613437636332343764393439653162 62643436346530346639376432316563656631306634643830373634623734656333666632646530
32353366313534373265336362623165383730356161316238336532633533646330336435326534 66633034646335343031313662653439303162633533363164666530386632656235363835316431
61643466643835623733303538316166646233643136653664653530376664333464393863366365 32313033656561333762353136656464613365666263373565383336646463323630623738666563
63613738393732393739393762613638383239303537353236636463663033396530376465333932 39363931373964313732306535616139623637353165363330663566396232646336303039623066
37326135336238396631333930373561646438313430323733353638356336636338656462613139 39346133326437333664366561316466306336333532363164373839336535646265613633636438
36373432633439613931656562316336653965313066386332643432653435643034376466343031 64366465346536613862636136363634353831353439353833393339343032626565373466623835
39633136656433336233393730356263376538656130353762303034336339356633656464393837 39383862306430353131323438656437383332363037393765626561393238313331333237336239
37623233613932383536623536653435396661313336326331653064616635316238373136623533 39623262613862333038393338666237643830326432656266336235326237396561373035656563
39653763393739373234346136353861383938353232336366336165333139323435636333656335 64613632393665653866353037396330346161386133643665336233616330393237643836363737
65373631396438633936643865323665653465666434373166363863626534323566663663323561 65396638646431326134623961316564313730353637653138646134306565326332346532363836
30353238636437653635386363363263376330323732613630613266343530393734383565643435 35663035346238383963376634393062663761653035636639653632643466346266623965303865
62356133633662393165313766323732386231333737613236373533383932623634336435363235 36393865326362316434616166393835643136663565373231626437333334336464343661363765
62353964636266336562353736386665646539323564633666316265313438326333653632313564 38376538616138626261313935333231376566306262613034323535383139623162353837356334
36356334386132393562663566386365623765363633313937333062393238393735383731653165 38666637613466623930306535313439373965653235343830336237306366303161336666376566
61646364633537363065366633646165643930353532633433656564333336376335353864623766 31376637393033363636663330613861633862636664653933623039376633323363636330633365
30316536613635373733303163326662363435336165346134303036383161396366636135623562 36386637376336336631376437623233643537383333623334303166626139363936376163616265
31393036323339373865633163643330393731386433613930633866393731373133383835346236 66373163306365626461373239333533656237376265303865633138633463396233333738396662
62356363663062373938636532343239366438396337313632616636333961306234663830313866 64316464653137373332633233663031346633353139313533633638333465656232636433623464
62646337353037666564653336376138326439633533396531393936313030333435383630316631 38366637353031636166353561666262643035343636663736386333323235376131633534663432
35353634663131343235616635386138306435303432653363363930656136356361663136376131 62393837353035646237613136333530346131303931653961633238316235313361323731646138
33373434616433366436326365616163313563343664623734306564623162623266326537636165 32383363326136636235373237306230633737346130633266643035636666373435663236396139
31633336366438343363393032323838383237323664653038376362643565653361646466623438 36386231393562386233643634363435663639383765653335623531616331383136333538303636
62323833386331323264616633653836343764663662646166383163653234333266353531343137 62363833626531626333386332376236326361313465316261646566393938323331326331616264
39613962316335326435356632626430363065316439623861303930643462666662663839643263 64666439383565613239333334333134623233316533316432376630633834353033386239396662
36666233373034363262656138626662383532393733396432363964653839303463376561306433 34333332646666353965643539353238656430666138316563373530373739363839323564373632
35643036633731613565323439643637336566396632663335393036663432653664333232346338 35313837323864663737306431643961653330656463613238626564303333313230386165366564
36343338333236663764643136373164373931653630626639306663333562323231643630343539 31313965363234613564646663336463633231396238383532343236616363323230346563343363
37303965393537636130356437393164366435633734613037306664346464663935346165373461 31636437396634363037303661303432313766333032303134646265313233323737316437366663
35313330316232333664356162383235653135623361386363643235366134373162633739393531 32613933303633303432613862333135313363303062616134643963353133613736626331646530
32613134633331376236373636636639333331353037343134346232636432306230346139343631 66356464656162313034633530393533313432633735313435623437633361623334373663353131
37613431616565363735656166333437343433306535613732653866653635633432353166313834 64306136316464376131393539333233386364613831383930633963333736363339393134373538
32623133363664653131636466343361616130353635303663663837396664626338393239343938 34633762636337366231323561306562303833356163356431646437363662356132306666656139
64383534316265623836316162383164636636306631373739313263653664306437313932316166 39313532333139383861313230373330373430623835636530326339383036323038363665663934
62363936613230316638643762366231653931643461323539613964346138366539303865303334 38346566613937356362616365663237373730326337646535373233313837613138386134653561
64393238306439616161316539346632626262653734383239343135323732653731333763656634 65613238313730646133386339653731383739643232633238653561666539653866623233343466
34306661613065633137643966333334666531653862623933383937646136343339323866383361 34306261636263616363346235613166633439326131623231393931663539333962373961363231
35366637373930613165646537653231343266613338373363303334316136633565383732373865 38393062613338353439643936313632316238333438386666303164346331306639626335393332
39373636373635626231666130343335323265626632303239393334643963616666343930323461 36623535343862383963393937333430646339633335323735663262373638616130316239373632
62393937643533376230313937663032326664636532616333623763326461363638303930666234 35303139613966613561313133653463636264623430396562646464323230636166326362363365
31663362393333356565343230633239646130356530623137333332383332316261646531633336 32343630626238396661313864346163356339623565613361356635633961623163623734363465
35393038386332353230633635353465616630306465613766636366613833376661633961623733 63646237343637646630613465656535313964613861653336616335346137306161343733653162
32316134323062366436363661343931306135316631666339313439653035613239383265386438 34306435663963373030383334333766656661643934376634313535373131356261626632356334
33363864366330626264643731663439303662646562396431373231353138363330663238313562 30396163653530656165633361383635363634366431383963376566353165393962636434636132
35663330303338633234653736386364346135616536613939366330343838616330613162303565 32316638653237623965623934616662623736613534343132373965336234343032316431643263
61356666376534636465323266396162383538636230616337656464343339353732386665393261 64306165343238636432613161366632633166313666616135383234636364663561363536346462
35303834653666616530393730626237386164343835613538333230636163653935353537623931 65363863623931346134663834663635303665633230386164653039643566313234303339383665
39613062323337353133653932326633633833396639633239346330613934626164333336353730 34633234386630376239313661383862306131386161623339643035373661306561316538646239
39613639386161393436356162633334643663623461323932633662336236363334373935613164 63643338386663633364366336646336356530363465386138343930376432336337313366613036
35313832653033356634316663396533386133353663383163333934376633393033613037353439 34663966633037373364376663653131326361333063616665326233623736626436643963306465
64643765366136643166343563646232386566636635363766616339386530346134323366666438 30363432383531333637313365333436346664613535313730656332316261666238623165653431
62623139663632373534353731326636386138393936316266393634383234613063633036366663 38656661326430633435393538633036313438326464626265313030613233653239346166636539
63346230373134626362323438656535393434666638306136356639303931313163613963623137 33383934373634356561396235616565623865616362626534663536666562386539663063613963
34366332646135633133316638323434653033633964356430626564666130633633613165373762 39393230643465316133663931313436666666376434386564323063353038333964653537383566
39613337663634373433633637653534643164636330396630313861316563663963363238333531 32326663666136653338326535313963313661623765623035393030326566383633313532346635
61613432373366396637643239613935636436353433323132663165633934353063623830363262 37363065653430363632353762303230646238653533383631336631613833363230333936336264
37613733613561623165383734313037303730346237626163616535313934616139373431613034 61663463303333303739303830343534663865363732383130373735633234323530386665346234
31333239653632643163366562373164386366343464393138303364343735643331633538373334 32356636633839376130316161643433306637653234373238343063386237376433666262656135
36343930663334366231363563316531313866616232643664633533343739306462323661313464 36363362386538613736653132396334656331393139343533393634626634333532316366353036
30313533356333333131656366643161373134613164303831636363306435336263363733303535 33653165386630626234623435323865353435616663363162643736313964303538303661643434
33383730626337343963323663313432646437323237363035376633613361313762356137636336 62633131373137383135643639386431316139393230623764356431336538313538313933376638
63383132363566303930306332363563303362333232313462326434643361643738373938663732 34363336373234666632636462306238366235336133373335353037613136383037343131623239
66663438666264383038346563306365363730323236613037376566303430353330613866646338 30373162643861356266663431626566316439643362333731366632646663626238613831343739
32386430636339663863623439323831656565373735666130616439316137373632326364613538 63643664353030343331656566656139383366333730636234653264643330366131646666376166
31623037386464313830336638646531633031623666313965323266373337643433643739643638 30633331393966373166313163396532396238393338363432656466636434313232353863343532
31663432653263636266666161636134643865383466366163303230653635383266346163643335 61663366346232646433393536393565633339633034306135393063646161323361363662646137
30333365616337323163363430323661383464613135376661623662346665623135373430333362 32353330666664343233336531326566363131633533636630303335663662383936363436356161
31346632333835653364633431616439633930303937643837633937663766656461326536613931 32633337323735323563323565333564613761646336383663373964373239306533336338313539
35323964393030363666353836316436343533393030653433353162366463326635396436363631 61346137643434326235383034323039316138343735316634636132323039383865383866326561
33333238646131343635313234353939393766656162313933353038313961343561653932353037 35323733633939313535303637303634323638386361656133346532336338326464653030386131
61356162633362386530376464663038343263383631343730343937326334333964623339316334 31626334396131393763353832393938346139636631656531646365636432376431666233616136
36323330333237643231646666626635646365383337323361336563663264643161643165363830 61303437383031363836316336363835613237666433303737616365386235373261623566386164
37323736353566316634396662663032633438386632333764663534306662383530316139393537 37326238333036306266393861303961336266626434653361623230366161633234663361653835
36633432613635346633656336626238346665646566313435393261333632336661383536656265 62346335303965323263613536363662623531316537306636313862336433363032613466646463
36326231626432656233363866646539363538393162623361333238396234393266653631353236 38313262306336353565663831663363393735353339613430656635623438643265613164366532
39383461326132663566306262623934313437663036386233316635343737346637623639323535 63363561636664343034386634653861333262393164386234616331316132396562643730356531
64326361313034376636366335383963643833353231353835303237343834303061343162363632 39663537643937633631663135313164366563303063343565323564303366623030303762356162
63393836363762643136666433353739393763663431656366336664383531323936323162623837 34313264333537393462363839343737653632653137666436646333326664653265323835333336
35323361623666356461623164373531363665343630316662343266323933333463653834336566 63333136383338313631636530303863363334363835333565663033373132613961313734666433
65333234363235333838316662383738333238363064373361333834316332636438613431363538 66313933383334623762373731316238663030323662636532633761633737623936336161323033
38333435643136353861666634373066346139336433303962313438613038326361653864343932 30316633666134643163393834666337633036353234346230313263313565643433663838346565
33396138663532646165653361653333393734626662343562666438363338383135323339386331 32336636333563663639363961636230336666313939333137393434633338636434373235326464
34616338346639376431303932333836363863343730383066383561393661626137343230363163 38666635396431623835393463613366616632656330653233363061343835616134663538396661
31663737333936396333636536643736356232666465373436306232323733353865393630303861 64663838623330616635393136353862306331323761376262653130306366373037363866376365
31356164643631643635323530633936323735643437613737383231326532373233396334616366 37383265663532383032373834623234616539343839353531373862393937653834343332303535
32663832626631636262326461663436353231366230313365353735363736626539643262393862 61363264663530366161666265663065383038313634376138373335663631353632646534643930
36636437663338356137303165613461663062646134303062616265613033363366303437616334 34613366313538373565383332613863333130613538363065346437316466666131616465366265
33353239303133613464376363383132373339306634313033663431636631393361643362343230 34363663663439663430396361353164363338386232626432613831616531376637613431656461
33353031393233363736313938643564376338303364343437656264633065356438386539633761 61343237323533333563363130333864386536343937613636353639663235303663653838306563
33346131303461616437303731373166303538323136373939366362616434393634383637353563 63313035356230336338343630333365656536346637306161393339666238366139353863633231
30303961316630623939663862623361386361666435303931626237393930313833333239393939 37653333643938633463346232326430343332666136633835316464666165333239356132333032
31376235346461353661363232616264656561333339633062623438613934313837653939643665 61366130383435396165383930393735393635653366363962326663633639343265373566313635
33653861373732393832343736646364343831323938386432643534313938393235323533633465 32326538343637623561663734356635353363643863393639656638376339616365343731353734
66623434613134303036636436383638666137623532306139346666623764623566393436333661 34666462383231356665376565363634353364383537636131306561373438616532313539323165
36336136656134316561666539323237646362616436346464656264666331613730623734393030 33623662666335343133386562663434323963383731383633316434626662346136373235356264
63626130303235633835633262373633363735346165303262306539663339663163343365353730 61316135613839316365336166376235643466653436623065313766376565323732626537656336
39386437623030643532306337373330613839393631653232666661613066393439646664306431 32376239633039393830643539643537396533326264353135373062303537356439303532643537
33616265356361613138333635613536336639326661653434353031323265636438343466353366 38326131323635613062366635303264633239633861333336643237386631393665323833303962
31666237646265373961663764313236663432373834616136363135353366666534336631636431 32313964666363346533353961666135626262623034343261643461643137653934636232306136
30353033393432366130313936363565323161316639343135613030373039383933376237303733 36313137626266326339376639613031356331393763663836613363616536613937313835613763
64396661376463626134333365623033306235353533303336643366366633306564626431346531 32646332323435306466303238663533393566333930633539303765646430333737373932326639
39393735363961356163666465396134653639626665353861626531333464373365653539303339 65633339303865623538353865346533633338393836386530393236316435623263646431616636
31643834373161373665383366336139313431366163343363626263333363626139646238313035 32363636643137323530336532333166656231346161663864363562646562376631653037326364
66343463336336376139333663303332626233356337653361616437363736313137303162666133 35643261623130363839623032616432646164373538373131653932363162613361666432643064
61656530646533353763316562363538333435636366653137303333666463646430333265626334 33373361393535343766626331303133366435643366613733363661396463303430616439643336
30313062393936393032323466396232643734383631656631393931393233346539373435323935 62653262393366353263393232303931373864323534396530623464623138333365336331386230
38303739353535656661333037616639313965393733316339316130626136383132323437373836 66393535613365656466363565333536363032306562373031636263333732383465626533383537
37356539663037646335376639303837393433613238636136633762616362366538383337343138 64663538333837376232313063623961396635356138356236303062386461663165663765353232
30613337653631303938363430326566613536653839363362633631306361386530646362343030 64336632343530356432616265666237623965333532333563646364323435336561303066333063
65663637306663383731646566626462376631303137383839363962376435623861616463623035 36613661383730383533333036306464633865653539313939383637353031613330343162383632
30353635663633653462373664326130396432393238663938393037383136303662366262376166 30313164333264376266353536343738656137326332636361326562333764393961373365333234
63613334653934656263396562643032646630333536633861336337306236313663653932646232 31356566646231353236663365356166656164313263663335343633336437306463343131623735
62346264393932323532373865643966393031303731663033383738393466366632373464376131 38393264393464303832633964393831303432363362653939316462303964343565383330616232
35336265626639336633323531636563376335386632376265333431363932633961326536336331 33316261376137643866636461393662386661636632626235616634396161333935633033306430
64656161393130613134646664656437383030613437646438383835663063313565613932383231 39316233333230623061303238303935323833393065373364393733303831313339346230656434
30626334313332363466333935343064613836623766353130336662383431623139333264393431 38353966306632663865316637346263323836633339623265393464393664646636373136656238
38343565613639636236393730643961623432316531663361383832313166396561393434356131 32306539386338346438343166353034316266326161653738346666346337623864316632333861
35366436616530313265346165653830323463323963663637366566613664666362333462356262 61323861313965343439383636306438666539396531313833306333306136333563643265333961
32646237663465306365313130386462356530343737306337623135303166373963613863326263 30643133616366333463316130303661373630623537363931303137343537626266316137333064
64323832663366346363326161313331316439313633643066326166626639373962393139383432 39643665386139666339623032386133333932376535323638626630363764326538633136366663
33643533666531666539663638613732346134633765333031626362336366666666633135313031 36653163653138393863396135343139333764393635336138653464383836353434633531626534
65633264396532363462373339366463383564646137663864386230343661633866353431623632 66316166356637333335623861333235343231323531663561393062336332376633333661663066
34376638343837306331356463626663376462316132396164643265346334346463393933393734 63343930343830346365323530303030396538666334653231336637353033633435386637306264
33313039333036616562643064396433666464326536393230393364343539306630323833653730 31663535313839383561353335316462386166386233653431363630643630376334643735636535
63626566366436626661656436613737376231346631646639326534643537636136616434316232 31633431383139303663646464383834303537343330373930393438356463303234363963616337
36306131636138663630646138326463623936623532303839623165623137363732343363383930 33613834373032346533653266346663316131343464386261336564363163333066353037643661
66333736336563616462346533393837396637663937376631346431373533316561356664383263 63323730353364316164653534333435636261643565303835336262616336336230353165653966
61663635663131666436373539646166373934333863323338626238633635396362663038623639 35343638616463336634333139396234663836393837383234633231376434663264633733343035
30396165353437663130613537313464333030353836346632313232353837626231303835666266 66643037633666326236663237303239353936633164656536336638323134356462363731373262
32633766323365303564313436346561626165386165623830393164333038306433316563323236 31666165383463633135613730656237336234666232656334663461316266353131376161376133
34343435306236386532346235643961343538383435333430366433346163353862366161613464 33363034383833313030656234666633636337333065636434323363323637376166626633663561
30316634313933613061636532353432626539316134636330623362613534376239643133363136 35613338623235393838626361356363653266626536663462363463356135633830383364386436
39613931303731333633646436623438363362386163643236613963313131383466306461366436 35613262366632366536643864653862353836383763323566323639313030306131343666643334
32353265643533636238646431353466306530303238323131653336396361303262356262613230 39306634373730656131666666623836616632366634346231313638393531363462353535343433
35353739653530646231313062643235623230363465333763333966356534373565326334306336 30363637396539393562616166386662663236636139623465653937316232656562303333343832
30336433363036626566613634303162376264333838653932396561383438316466383966343663 32653636646135383865343234383266336135616133666364306338353566356133663266396537
31626331623332316139376361366231343334356630653236333135626463336664323637306638 36613161663538316664613838313131326635303365313132383364646162346136623464383362
37303134666232303966613638616361613961356365613538323164343337386261643133393634 39393138666431356530373061393236633965326365653636303237393435366235393132393363
31306565373639323031346236633837306132373264643462613433393961303931376538356339 33613761353835643234356661363163306431613931626433353833326334336238663766396237
38633066313833383664393036333939333066633463333065396633313936306131366364303135 66316638343765363730393331623639303634316139623639346632313032613536323433303331
31613761616131616362633639363764376464646266323530616265363339363036653662643439 39393331636136636438323939326338336461653565393732633061623336363238653736663832
31313536646333393639346433336562643938646164636662316132326436616135303432386334 61353166663732383965396562343061323039313532323766623063633932363239383733313838
65663062653931643663636666313835646138323432373138353939613330613461643133613138 31636566303039663238323934346531323661633861613535396434363434366663366330333533
66636361643533386630316133356331623466663636333961633438613233353036666635376534 30333031393465303538623530343037363034323235663334353763343233343265633930376466
35383365376265383939303636316265663630333935623131303738376631656537656138343765 32666563623635616461366639616164666265363561313966623264616535636566666634366638
36643431623939633632323535363837363331323331393035366664316232343861626665633061 31613034353230336631353734333034386535366562666430626336666333613966333738313031
34346434666638393934643162653733323935646262396661363966643062346562613336333061 30353031393333353132656465326239326432373364643662343839653263323961323164363861
38363336366339633661666165383436663031306631643831643463663937653031393061306438 66653736353961336163333230663862326333653634663438346665333335343063626663303366
63656338323363336332353232373966363436646538343562393932653539316565656163386634 65653138633433313133303931636533646663316362666333366561633434386563306631336266
35306265393662326361393166373935356633323638663465616233376534646131353132663866 66356434666230353936326163363265303163633134353665666335393631363838616330626338
38346163613131326239636365343937653833356138393838316137313063653238376631346461 37316466326133313832663832353533633066626165323031636230616336373931643963303237
32323331626365323130613866653465353565343863636630366465383962623238636434663565 64643765363766386331613731356633323531386230626634316464376533623462316134343138
64343762623530623365383739326562616632626166613635383937343839626666306135333934 34366332303232646432343563396637356133313732663864613833613031633635356463313032
38336461373730633233373131323365613139616439636365383762663237383631353165336232 64393136353031373739333534396231363565316265353935616339353161626264383234316334
61613464386630396437393162653530396139636632393336623562303536353233633034366365 38633636353530323432613362633764363161373738363638616131643234366365363233333064
31396139646334376631316265393663316537643737383630643262613036326137366463623161 38373636336430376231633538336163616232393438366634336466663034393738653462353033
30346361383132373336616132383665333265363231303334623661336537343837656331613561 34633565323832633366373035343039643635643866356133626339336332306435653832356534
32343135383635356463663065346561303034663262643735646664303536363833383630623461 65623832363461313062653636626232366230623361383564373261646334346634616237306462
37616336386432313535373233386433663363623761313331633438363563396563626631336662 63643434366238316432623234353963383231613537386562343537396430373338333065326663
38653235633838613630623438373661333563623436383833333235326334386163663037386636 30373563636331663634613461653962393131666564353130353330363966323662373839373565
33303631616135396130663735353333346564656537393937613638616239663161313962613631 34326564623662383264616363663665643238363565303965613034613036326238326532306462
38386537653466353966346430633361303136643836326332633631336232646265613034326161 62353936666136643962643536353561363830656666633334343261663465363463303161343832
65633033393337363336326633306262316636663461346162633234376232646563363032343632 30333130326333646635653631643665643336616334616332353266653539316261366431636134
39643062313532646633343133313330316537343936646561613430303034303765633565396132 66626135383265666562306264636361613430303266633137386666343562666562646132656330
37636165373335303133316233363132303339626635663461366263366162643736616533313338 65643333386565303766303562616262373137666130653866313362373137346165373930653539
31353433363937343465346530306630393236636138643231393761623661326336356263306634 32666238663865616136326538383431313130316331353264636136383534613031313337343266
36643234326538316432363864666138643139313334393265623761626162306632386135336161 38646565376535356636336538323833373464323535626466643430386433366665326564616431
34326266306565343731626161643937663665366537643536636135613532643862353633333836 31623631353032656632613738393865343133303663353563376436393562353763613331343338
64356337313064663339333163613862393761356339633033346338353865303038323833373461 61366161633562353835323938616435663535316438366361343963323636653732313665653939
31346364663662316134383061313930323033356538626630373761613737343133303337613036 39663438663235303932373865616261643133393530376432666132636161326261386132316537
37373261303066313035663139653237336236643036323732313763343866393736383937363733 39616232666465633866303437383762623465623765363939363531343636363461376365623632
30393135653662666630353666316532303538366138386264663161656362633135343333613134 65653866346666666166386263326264393233666564646538303663653137366234373863643065
62633139613130666566383361366637633632663166643336303730616237626430623863363963 32646439343336666233623662626334343530353137376236373964616661656231336638376661
62316366633130343061366636393037323433643739646331306539376564666364383934383935 34346639323865636537316636393165303665336438653535363434326662346666326631613333
63376633343364326430373130316264393866373438653964373663653737633533393139363564 39393262343937663635643864616134613632376132393239386336356564376131363733366131
39336635386433343766353166323531633731616333666463323538393135636538383230633939 33616565383838393561396162373861613463636365353435643736656532666635346262663864
63363061623432346437303565626637326561306162613830363835373830383631636338376538 34396366613535353538626661613631333463646462396537383538366133303561663337316438
33343931353631393538306138393039626635666366363836333438663333323636623037303331 39626365303937336465353232353234643937396565383835303364393339623834666163653338
31663237343965663364643139306632666166616138316363316334613134343864316335383631 61613131333364613037666461616136383865393465373833633162366434633236323666663965
33323331336462656566613039313631643137363336643833646637383430363863373633633738 32643864653439386235303138326261303965386264323463646163643261666538653837373135
63666336643938663064613538373434636234373935383736373739363430343765393463626231 62363538366231643030386439326166643438393431363664353431313735613361393932623033
31643131636633386135366563316232343132376662643364626537656333643736626530653036 64326439663238353234323438396539613738663235653262643639363833633562353962313933
37653636646534353634633734373463313031626363376538316634383863393035353835643836 32306439303631383033353534343539663734333132633534366337646634616263383335623761
63353036633933323932646135396337393735383931373638643064626334366139623133386662 32643039383733313538393130333063333438343335616465663964356338383937626338366535
35626464653162396132 66393034633364363862613530666138326332313436303934616639386634373765663166343739
32303963306235663264643332343063313139346239663461316234366163343335643632663033
66656162373436346538356162376266333763393866663965396533343939373733306465613135
35313836303064663336623564376230366231353130373237643064333539323066353362343463
65656534623438383738656234303034626133643431313035303762636336666335363236393163
66336666623465666130343732383463316531373235353063653630343330333064666365633864
65323266336233626239376338336430333834623835663064373534633233396131353338643563
39376534393730666335383438633561633433333030343435306533623563313463373138306463
64613066656338316466343464363365303366636463616239656262393639303738356637363464
34313332623466323135383562316566386535373265343539643665353531663231303739613837
36326633663432313333376237373230353039326461333331333430633737353066353433636633
31383736633535343465623461666638313337666435393535393666363266623866363566336635
64393232633032383963643830646138623630626536336164626663366131653038343437373965
31663039383339383039656438396539366234396664636461313636613362333832303265326634
65326234303162666131323065656237336635636236643139323337653033646232343537316631
64653636306236383661323238396232336433323530393266316564373430633939643233316237
64653034626636393365356438323165363265346235303734316334353136323439313830663136
64643232653137633833643235346561633763316232623566653065353431626637633732396530
65613765336461653165323266663662316431643361393261313263613765343139343038386637
64323863646430356264353230313165623338656332346430376266376134313236623832306134
62393033333136613637363239653334323531383234376261363038313465333466336538383737
61316637633232363230366135636265633339323465643039366238626439656134333962383664
62393632313436363866613236393461366262613135663039653136323038343061343166626536
66303461323962626361326465616231313134393636343437376566306438663437653234613639
31356563393338653561386235386562323038633630313932643162366631646534316334623638
36613366303435336365623939376166396334346264646133323338353234316234343463623630
66646437333461363766623339656233363434633538343033393237346239313536383763666430
33613266626135613833616433326461313764376334623833346530343063333338663461646134
64613030363339633738333338386261366361313037323034613561633766613933623030393131
37636266323562326437613839656332643630663337326163373865356337363534623833316336
63623461643832303163643133333938653864666639613761303461646533376138336562656166
36626334323135373864636666636562643030356332306534613334313030363337643864306666
31393039336665366138306361626232303662636432663464383361656537393037323266623736
61383031346539383932653462373562303035303462666432643330643632666263313439316230
37383664313439383035343266383138383765393363373565653739343036363661373731613433
323130373039366635353462613536643830

View File

@@ -25,21 +25,28 @@ ntp_servers:
load_balancers: load_balancers:
hosts: hosts:
lightning_lane: lightning_lane:
ansible_host: 10.1.71.35
ansible_become: true ansible_become: true
step_ca_server: step_ca_server:
hosts: hosts:
turnstile: turnstile:
ansible_host: 10.1.71.34
ansible_become: true ansible_become: true
authentik_server: authentik_server:
hosts: hosts:
guest-relations: guest-relations:
ansible_host: 10.1.71.40
ansible_become: true ansible_become: true
semaphore_server:
hosts:
imagineering:
ansible_host: 10.1.71.37
ansible_become: true
n8n_server:
hosts:
tiki-room:
prometheus_server: prometheus_server:
hosts: hosts:
cinderella-castle: cinderella-castle:
@@ -69,14 +76,6 @@ dev_servers:
hosts: hosts:
scrim: scrim:
semaphore_server:
hosts:
imagineering:
n8n_server:
hosts:
tiki-room:
# dhcp_server: # dhcp_server:
# hosts: # hosts:
# matchbox: # matchbox:

View File

@@ -0,0 +1,23 @@
---
# ------------------------------------------------------------------------------
# FILE: playbooks/day1_deploy_semaphore.yml
# DESCRIPTION: Deploys Semaphore on imagineering
# Runs: common → docker-host → semaphore
#
# USAGE:
# ansible-playbook -i inventory.yml playbooks/day1_deploy_semaphore.yml
#
# SECRETS REQUIRED IN VAULT (group_vars/all/vault):
# vault_semaphore_database_password
# vault_semaphore_admin_password
# vault_semaphore_access_key_encryption
# ------------------------------------------------------------------------------
- name: Deploy Semaphore
hosts: semaphore_server
become: true
roles:
- common
- docker-host
- semaphore

View File

@@ -0,0 +1,4 @@
---
# file: roles/semaphore/defaults/main.yml
semaphore_compose_dir: /opt/docker/semaphore

View File

@@ -0,0 +1,7 @@
---
# file: roles/semaphore/handlers/main.yml
- name: Restart Semaphore
community.docker.docker_compose_v2:
project_src: "{{ semaphore_compose_dir }}"
state: restarted

View File

@@ -0,0 +1,212 @@
---
# file: roles/semaphore/tasks/main.yml
- name: Create Semaphore directory
ansible.builtin.file:
path: "{{ semaphore_compose_dir }}"
state: directory
owner: wed
group: docker
mode: '0755'
- name: Copy Compose file from boilerplate
ansible.builtin.copy:
src: "{{ playbook_dir }}/../../boilerplates/semaphore/compose.yaml"
dest: "{{ semaphore_compose_dir }}/compose.yaml"
owner: wed
group: docker
mode: '0644'
- name: Deploy Semaphore .env file
ansible.builtin.template:
src: env.j2
dest: "{{ semaphore_compose_dir }}/.env"
owner: wed
group: docker
mode: '0600'
- name: Start Semaphore containers
community.docker.docker_compose_v2:
project_src: "{{ semaphore_compose_dir }}"
state: present
register: semaphore_compose
- name: Wait for Semaphore to be ready
ansible.builtin.uri:
url: "http://localhost:3000/api/ping"
method: GET
status_code: 200
register: semaphore_health
retries: 24
delay: 5
until: semaphore_health.status == 200
# ── Post-deploy: Restore project config via API ──
- name: Authenticate to Semaphore API
ansible.builtin.uri:
url: "http://localhost:3000/api/auth/login"
method: POST
body_format: json
body:
auth: "admin"
password: "{{ vault_semaphore_admin_password }}"
status_code: 204
return_content: false
register: semaphore_auth
no_log: true
- name: Set auth cookie fact
ansible.builtin.set_fact:
semaphore_cookie: "{{ semaphore_auth.cookies_string }}"
no_log: true
- name: Check if mk-labs project already exists
ansible.builtin.uri:
url: "http://localhost:3000/api/projects"
method: GET
headers:
Cookie: "{{ semaphore_cookie }}"
return_content: true
register: semaphore_projects
- name: Set project exists flag
ansible.builtin.set_fact:
project_exists: "{{ semaphore_projects.json | selectattr('name', 'equalto', 'mk-labs') | list | length > 0 }}"
- name: Read project config from boilerplate
ansible.builtin.slurp:
src: "{{ playbook_dir }}/../../boilerplates/semaphore/project-config.json"
delegate_to: localhost
become: false
register: project_config_raw
when: not project_exists
- name: Restore project via API
ansible.builtin.uri:
url: "http://localhost:3000/api/projects/restore"
method: POST
headers:
Cookie: "{{ semaphore_cookie }}"
Content-Type: "application/json"
body: "{{ project_config_raw.content | b64decode | string }}"
body_format: raw
status_code: [200, 201]
return_content: true
register: restore_result
when: not project_exists
- name: Display restore result
ansible.builtin.debug:
msg: "Project '{{ restore_result.json.name | default('mk-labs') }}' restored successfully (ID: {{ restore_result.json.id | default('unknown') }})"
when: not project_exists and restore_result is defined
- name: Skip restore — project already exists
ansible.builtin.debug:
msg: "Project 'mk-labs' already exists, skipping restore"
when: project_exists
# ── Push secrets: DELETE empty shells, POST with actual values ──
- name: Get project ID
ansible.builtin.set_fact:
semaphore_project_id: >-
{{ (semaphore_projects.json | selectattr('name', 'equalto', 'mk-labs') | first).id
if project_exists else restore_result.json.id }}
- name: Get existing keys
ansible.builtin.uri:
url: "http://localhost:3000/api/project/{{ semaphore_project_id }}/keys"
method: GET
headers:
Cookie: "{{ semaphore_cookie }}"
return_content: true
register: semaphore_keys
- name: Find wed-ssh-key ID (if exists)
ansible.builtin.set_fact:
wed_ssh_key_id: "{{ (semaphore_keys.json | selectattr('name', 'equalto', 'wed-ssh-key') | first).id | default(omit) }}"
ignore_errors: true
- name: Find ansible-vault-password ID (if exists)
ansible.builtin.set_fact:
vault_password_key_id: "{{ (semaphore_keys.json | selectattr('name', 'equalto', 'ansible-vault-password') | first).id | default(omit) }}"
ignore_errors: true
- name: Check if wed-ssh-key is empty
ansible.builtin.set_fact:
wed_ssh_key_empty: "{{ (semaphore_keys.json | selectattr('name', 'equalto', 'wed-ssh-key') | first).empty | default(true) }}"
ignore_errors: true
- name: Check if ansible-vault-password is empty
ansible.builtin.set_fact:
vault_password_empty: "{{ (semaphore_keys.json | selectattr('name', 'equalto', 'ansible-vault-password') | first).empty | default(true) }}"
ignore_errors: true
# -- wed-ssh-key: delete empty shell if needed, then create with value --
- name: Delete empty wed-ssh-key shell
ansible.builtin.uri:
url: "http://localhost:3000/api/project/{{ semaphore_project_id }}/keys/{{ wed_ssh_key_id }}"
method: DELETE
headers:
Cookie: "{{ semaphore_cookie }}"
status_code: [200, 204]
when: wed_ssh_key_id is defined and wed_ssh_key_empty | bool
- name: Build wed-ssh-key payload
ansible.builtin.set_fact:
wed_key_payload: >-
{{ {"name": "wed-ssh-key",
"type": "ssh",
"project_id": semaphore_project_id | int,
"ssh": {"login": "", "passphrase": "", "private_key": vault_wed_ssh_private_key}} | to_json }}
no_log: true
when: wed_ssh_key_empty | bool
- name: Create wed-ssh-key with private key
ansible.builtin.uri:
url: "http://localhost:3000/api/project/{{ semaphore_project_id }}/keys"
method: POST
headers:
Cookie: "{{ semaphore_cookie }}"
Content-Type: "application/json"
body: "{{ wed_key_payload }}"
body_format: raw
status_code: [200, 201]
no_log: true
when: wed_ssh_key_empty | bool
# -- ansible-vault-password: delete empty shell if needed, then create with value --
- name: Delete empty ansible-vault-password shell
ansible.builtin.uri:
url: "http://localhost:3000/api/project/{{ semaphore_project_id }}/keys/{{ vault_password_key_id }}"
method: DELETE
headers:
Cookie: "{{ semaphore_cookie }}"
status_code: [200, 204]
when: vault_password_key_id is defined and vault_password_empty | bool
- name: Build ansible-vault-password payload
ansible.builtin.set_fact:
vault_key_payload: >-
{{ {"name": "ansible-vault-password",
"type": "login_password",
"project_id": semaphore_project_id | int,
"login_password": {"login": "", "password": vault_ansible_vault_password}} | to_json }}
no_log: true
when: vault_password_empty | bool
- name: Create ansible-vault-password with value
ansible.builtin.uri:
url: "http://localhost:3000/api/project/{{ semaphore_project_id }}/keys"
method: POST
headers:
Cookie: "{{ semaphore_cookie }}"
Content-Type: "application/json"
body: "{{ vault_key_payload }}"
body_format: raw
status_code: [200, 201]
no_log: true
when: vault_password_empty | bool

View File

@@ -0,0 +1,3 @@
DATABASE_PASSWORD={{ vault_semaphore_database_password }}
SEMAPHORE_ADMIN_PASSWORD={{ vault_semaphore_admin_password }}
SEMAPHORE_ACCESS_KEY_ENCRYPTION={{ vault_semaphore_access_key_encryption }}

View File

@@ -0,0 +1,3 @@
DATABASE_PASSWORD=cVMGmtkCcOsMReHi99GHBIWNmNTUQPfZ
SEMAPHORE_ADMIN_PASSWORD=4U+gEcm0aUby+5q5
SEMAPHORE_ACCESS_KEY_ENCRYPTION=6APgfDAgWtqg0XBXPKPyG7N3evwksB6u

View File

@@ -0,0 +1,44 @@
services:
semaphore:
image: docker.io/semaphoreui/semaphore:v2.17.2
restart: unless-stopped
environment:
- SEMAPHORE_DB_DIALECT=mysql
- SEMAPHORE_DB_HOST=semaphore_db
- SEMAPHORE_DB=semaphore
- SEMAPHORE_DB_USER=semaphore
- SEMAPHORE_DB_PASS=${DATABASE_PASSWORD}
- SEMAPHORE_ADMIN=admin
- SEMAPHORE_ADMIN_NAME=Administrator
- SEMAPHORE_ADMIN_EMAIL=ryan.blundon@protonmail.com
- SEMAPHORE_ADMIN_PASSWORD=${SEMAPHORE_ADMIN_PASSWORD}
- SEMAPHORE_PLAYBOOK_PATH=/tmp/semaphore/
- SEMAPHORE_ACCESS_KEY_ENCRYPTION=${SEMAPHORE_ACCESS_KEY_ENCRYPTION}
- ANSIBLE_HOST_KEY_CHECKING=False
networks:
- semaphore_backend
ports:
- "3000:3000"
depends_on:
- semaphore_db
semaphore_db:
image: docker.io/library/mysql:8.1
restart: unless-stopped
environment:
- MYSQL_USER=semaphore
- MYSQL_PASSWORD=${DATABASE_PASSWORD}
- MYSQL_DATABASE=semaphore
- MYSQL_ROOT_PASSWORD=${DATABASE_PASSWORD}
networks:
- semaphore_backend
volumes:
- semaphore_db:/var/lib/mysql
volumes:
semaphore_db:
driver: local
networks:
semaphore_backend:
driver: bridge

View File

@@ -0,0 +1,107 @@
{
"environments": [
{
"env": "{}",
"json": "{}",
"name": "Production"
}
],
"integration_aliases": [],
"integrations": [],
"inventories": [
{
"become_key": "wed-ssh-key",
"inventory": "ansible/inventory.yml",
"name": "foundation",
"ssh_key": "wed-ssh-key",
"type": "file"
}
],
"keys": [
{
"name": "git-public",
"owner": "",
"type": "none"
},
{
"name": "wed-ssh-key",
"owner": "",
"type": "ssh"
},
{
"name": "ansible-vault-password",
"owner": "",
"type": "login_password"
}
],
"meta": {
"alert": false,
"max_parallel_tasks": 0,
"name": "mk-labs",
"type": ""
},
"repositories": [
{
"git_branch": "main",
"git_url": "https://github.com/rblundon/homelab.git",
"name": "homelab",
"ssh_key": "git-public"
}
],
"roles": [],
"schedules": [],
"secret_storages": [],
"templates": [
{
"allow_override_args_in_task": true,
"autorun": false,
"description": "Post-provisioning OS baseline: common role, DNS registration, NetBox status update",
"environment": "Production",
"inventory": "foundation",
"name": "day0-baseline",
"playbook": "ansible/playbooks/day0_baseline.yml",
"repository": "homelab",
"suppress_success_alerts": false,
"survey_vars": [],
"type": "task",
"vault_key": "ansible-vault-password"
},
{
"allow_override_args_in_task": true,
"autorun": false,
"description": "Deploy Semaphore on imagineering",
"environment": "Production",
"inventory": "foundation",
"name": "day1-deploy-semaphore",
"playbook": "ansible/playbooks/day1_deploy_semaphore.yml",
"repository": "homelab",
"suppress_success_alerts": false,
"survey_vars": [],
"type": "task",
"vault_key": "ansible-vault-password"
},
{
"allow_override_args_in_task": false,
"autorun": false,
"description": "Sync Traefik dynamic configs and create DNS CNAMEs for all services",
"environment": "Production",
"inventory": "foundation",
"name": "add-service-route",
"playbook": "ansible/playbooks/add_service_route.yml",
"repository": "homelab",
"suppress_success_alerts": false,
"survey_vars": [],
"type": "task",
"vault_key": "ansible-vault-password"
}
],
"views": [
{
"hidden": false,
"position": 0,
"sort_reverse": false,
"title": "All",
"type": "all"
}
]
}

View File

@@ -0,0 +1,17 @@
http:
routers:
semaphore:
rule: "Host(`semaphore.local.mk-labs.cloud`)"
entryPoints:
- websecure
service: semaphore
tls:
certResolver: cloudflare
middlewares:
- security-headers
services:
semaphore:
loadBalancer:
servers:
- url: "http://imagineering.local.mk-labs.cloud:3000"

View File

@@ -8,14 +8,14 @@
--- ---
## Phase 0: Repository Restructuring ## Phase 0: Repository Restructuring
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 0.1 | Create `archive/pre-mk-labs` branch from current `main` | — | `[ ]` | | 0.1 | ~~Create `archive/pre-mk-labs` branch from current `main`~~ | — | `[x]` |
| 0.2 | Restructure repo to new directory layout (terraform/, ansible/, n8n/, netbox/, boilerplates/) | — | `[ ]` | | 0.2 | ~~Restructure repo to new directory layout (terraform/, ansible/, n8n/, netbox/, boilerplates/, packer/, talos/, docs/)~~ | — | `[x]` |
| 0.3 | Validate existing Terraform modules and Ansible roles still work from new paths | — | `[ ]` | | 0.3 | ~~Validate existing Terraform modules and Ansible roles still work from new paths~~ | — | `[x]` |
| 0.4 | Update `ansible.cfg` roles_path for new directory structure | — | `[ ]` | | 0.4 | ~~Update `ansible.cfg` roles_path for new directory structure~~ | — | `[x]` |
--- ---
@@ -23,25 +23,29 @@
> **Depends on:** Phase 0 > **Depends on:** Phase 0
### 1A: Deploy NetBox (`fire-station`) ### 1A: Deploy NetBox (`fire-station`)
> **Note:** `fire-station` LXC deployed via Proxmox helper script. NetBox is configured and working.
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 1.1 | Provision `fire-station` VM (10.1.71.102) — manual for now (this is a pipeline prerequisite) | Terraform | `[ ]` | | 1.1 | ~~Provision `fire-station` (10.1.71.34)~~ — LXC already running | Helper script | `[x]` |
| 1.2 | Generate NetBox Compose stack via Boilerplates CLI | Boilerplates | `[ ]` | | 1.2 | ~~Deploy NetBox on `fire-station`~~ — installed via helper script | Helper script | `[x]` |
| 1.3 | Deploy NetBox containers on `fire-station` | Ansible | `[ ]` | | 1.3 | ~~NetBox configured and operational~~ | Manual | `[x]` |
| 1.4 | Add Traefik dynamic config for `netbox.local.mk-labs.cloud``fire-station` | Ansible | `[ ]` | | 1.4 | Add Traefik dynamic config for `netbox.local.mk-labs.cloud``fire-station` | Ansible | `[-]` |
| 1.5 | Create DNS record on `monorail` pointing to `lightning-lane` (10.1.71.35) | Ansible | `[ ]` | | 1.5 | Create DNS CNAME on `monorail` pointing to `lightning-lane` | Ansible | `[-]` |
| 1.6 | Verify NetBox accessible via `netbox.local.mk-labs.cloud` | Manual | `[ ]` | | 1.6 | Verify NetBox accessible via `netbox.local.mk-labs.cloud` | Manual | `[-]` |
> **Note:** Tasks 1.41.6 deferred. Helper-script Apache install conflicts with Traefik reverse proxy (double Host header issue). NetBox accessible directly at `fire-station.local.mk-labs.cloud`. Will resolve when NetBox is rebuilt as a Compose stack (see P.10).
### 1B: Configure NetBox Data Model ### 1B: Configure NetBox Data Model
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 1.7 | Create `netbox/initializers/custom_fields.yml` in repo | Manual | `[ ]` | | 1.7 | ~~Create `netbox/initializers/custom_fields.yml` in repo~~ | Manual | `[x]` |
| 1.8 | Add custom fields to VM object: `proxmox_template` (selection), `proxmox_node` (selection), `vm_role` (text) | NetBox | `[ ]` | | 1.8 | ~~Add custom fields to VM object: `proxmox_template` (selection), `proxmox_node` (selection), `vm_role` (text)~~ — applied from initializers | NetBox | `[x]` |
| 1.9 | Create `netbox/initializers/vlans.yml` — define all VLANs from master table | Manual | `[ ]` | | 1.9 | ~~Create `netbox/initializers/vlans.yml` — define all VLANs from master table~~ | Manual | `[x]` |
| 1.10 | Create `netbox/initializers/prefixes.yml` — define IP prefixes | Manual | `[ ]` | | 1.10 | ~~Create `netbox/initializers/prefixes.yml` — define IP prefixes~~ | Manual | `[x]` |
| 1.11 | Import existing infrastructure into NetBox (Proxmox hosts, existing VMs, IPs) | Manual | `[ ]` | | 1.11 | Import existing infrastructure into NetBox (Proxmox hosts, existing VMs, IPs) | Manual | `[ ]` |
| 1.12 | Configure NetBox webhook: `VM Staged Trigger` — POST to `http://tiki-room:5678/webhook/vm-provision` on VM status change to `Staged` | NetBox | `[ ]` | | 1.12 | Configure NetBox webhook: `VM Staged Trigger` — POST to `http://tiki-room:5678/webhook/vm-provision` on VM status change to `Staged` | NetBox | `[ ]` |
| 1.13 | Test webhook fires correctly on VM status change | Manual | `[ ]` | | 1.13 | Test webhook fires correctly on VM status change | Manual | `[ ]` |
@@ -51,12 +55,13 @@
## Phase 2: Terraform VM Module ## Phase 2: Terraform VM Module
> **Depends on:** Phase 0 (repo structure) > **Depends on:** Phase 0 (repo structure)
> **Note:** `terraform/proxmox/vm/` module exists with `main.tf`, `variables.tf`, `outputs.tf`, `providers.tf`. A `test-pipeline-vm` has been run. UDM DHCP module also exists at `terraform/unifi/dhcp/`.
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 2.1 | Write `variables.tf`: hostname, ip, vlan, template, proxmox_node | Manual | `[ ]` | | 2.1 | ~~Write `variables.tf`: hostname, ip, vlan, template, proxmox_node~~ | Manual | `[x]` |
| 2.2 | Write `main.tf` using bpg/proxmox provider for VM resource | Manual | `[ ]` | | 2.2 | ~~Write `main.tf` using bpg/proxmox provider for VM resource~~ | Manual | `[x]` |
| 2.3 | Test `terraform apply` manually with hardcoded values | Manual | `[ ]` | | 2.3 | ~~Test `terraform apply` manually with hardcoded values~~ (`test-pipeline-vm` state exists) | Manual | `[x]` |
| 2.4 | Validate cloud-init baseline config (hostname, SSH key, networking) | Manual | `[ ]` | | 2.4 | Validate cloud-init baseline config (hostname, SSH key, networking) | Manual | `[ ]` |
| 2.5 | Configure Terraform state backend on `city-hall` | Manual | `[ ]` | | 2.5 | Configure Terraform state backend on `city-hall` | Manual | `[ ]` |
@@ -65,15 +70,16 @@
## Phase 3: Ansible Baseline Role & Semaphore ## Phase 3: Ansible Baseline Role & Semaphore
> **Depends on:** Phase 0 (repo structure) > **Depends on:** Phase 0 (repo structure)
> **Note:** `common` role exists (hostname, chrony, packages, sudo). `dns-manager` role exists. `docker-host` role exists. Playbooks for DNS entry creation exist. Semaphore (`imagineering`) is deployed via helper script but not yet configured.
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 3.1 | Configure NetBox dynamic inventory plugin (`netbox.yml`) | Manual | `[ ]` | | 3.1 | Configure NetBox dynamic inventory plugin (`netbox.yml`) | Manual | `[ ]` |
| 3.2 | Write/update `vm-baseline` role: packages, SSH hardening, Chrony → `sundial` | Manual | `[ ]` | | 3.2 | ~~Write/update `vm-baseline` role: packages, SSH hardening, Chrony → `sundial`~~ (`common` role exists) | Manual | `[x]` |
| 3.3 | Add DNS registration task to role (Technitium API on `monorail`) | Manual | `[ ]` | | 3.3 | ~~Add DNS registration task to role (Technitium API on `monorail`)~~ (`dns-manager` role + `add_technitium_dns_entry` task exist) | Manual | `[x]` |
| 3.4 | Add NetBox status update task — set VM to `Active` via API on success | Manual | `[ ]` | | 3.4 | Add NetBox status update task — set VM to `Active` via API on success | Manual | `[ ]` |
| 3.5 | Add NetBox status update task — set VM to `Failed` via API on error | Manual | `[ ]` | | 3.5 | Add NetBox status update task — set VM to `Failed` via API on error | Manual | `[ ]` |
| 3.6 | Configure Semaphore (`imagineering`): connect to GitHub repo, create job template for `vm-baseline` | Manual | `[ ]` | | 3.6 | Redeploy Semaphore (`imagineering`) as VM with Boilerplates Compose stack, then configure: connect to GitHub repo, create job template for `day0_baseline` | Manual | `[ ]` |
| 3.7 | Test Ansible playbook end-to-end via Semaphore manual trigger | Manual | `[ ]` | | 3.7 | Test Ansible playbook end-to-end via Semaphore manual trigger | Manual | `[ ]` |
--- ---
@@ -82,16 +88,20 @@
> **Depends on:** Phases 1, 2, 3 > **Depends on:** Phases 1, 2, 3
### 4A: Deploy & Configure n8n (`tiki-room`) ### 4A: Deploy & Configure n8n (`tiki-room`)
> **Note:** `tiki-room` and n8n deployed via helper script, configured and working. `imagineering` (Semaphore) deployed via helper script but not yet configured.
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 4.1 | Provision `tiki-room` VM (10.1.71.23) if not already running | Terraform | `[ ]` | | 4.1 | ~~Provision `tiki-room` (10.1.71.36)~~ already running | Helper script | `[x]` |
| 4.2 | Deploy n8n containers on `tiki-room` | Ansible | `[ ]` | | 4.2 | ~~Deploy and configure n8n on `tiki-room`~~ — working | Helper script | `[x]` |
| 4.3 | Add Traefik dynamic config for `n8n.local.mk-labs.cloud``tiki-room` | Ansible | `[ ]` | | 4.3 | ~~Add Traefik dynamic config for `n8n.local.mk-labs.cloud` → `tiki-room`~~ | Ansible | `[x]` |
### 4B: Build the Provisioning Workflow ### 4B: Build the Provisioning Workflow
> **Note:** `n8n/workflows/VM Provisioning Pipeline.json` and `DNS: Create A Record.json` already exported to repo.
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 4.4 | Create n8n webhook node to receive NetBox payload | n8n | `[ ]` | | 4.4 | Create n8n webhook node to receive NetBox payload | n8n | `[ ]` |
@@ -99,7 +109,7 @@
| 4.6 | Add Terraform trigger: SSH to `city-hall`, run `terraform apply` with variables from payload | n8n | `[ ]` | | 4.6 | Add Terraform trigger: SSH to `city-hall`, run `terraform apply` with variables from payload | n8n | `[ ]` |
| 4.7 | Add Semaphore trigger: call Semaphore API to launch `vm-baseline` job template | n8n | `[ ]` | | 4.7 | Add Semaphore trigger: call Semaphore API to launch `vm-baseline` job template | n8n | `[ ]` |
| 4.8 | Add error handling: set NetBox VM status to `Failed` on any pipeline error | n8n | `[ ]` | | 4.8 | Add error handling: set NetBox VM status to `Failed` on any pipeline error | n8n | `[ ]` |
| 4.9 | Export n8n workflow JSON and commit to `n8n/workflows/vm-provisioning.json` | Manual | `[ ]` | | 4.9 | ~~Export n8n workflow JSON and commit to `n8n/workflows/vm-provisioning.json`~~ (initial export exists) | Manual | `[x]` |
--- ---
@@ -109,10 +119,12 @@
### 5A: Hostname & IP Allocation ### 5A: Hostname & IP Allocation
> **Decided:** Hostname `the-grid` · IP `10.1.71.128` · VM ID `71128` · DNS `the-grid.local.mk-labs.cloud` · External `the-grid.mk-labs.cloud`
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 5.1 | Select themed hostname for Nextcloud VM | Manual | `[ ]` | | 5.1 | ~~Select themed hostname for Nextcloud VM~~`the-grid` | Manual | `[x]` |
| 5.2 | Allocate IP address from General Applications block (10.1.71.128/25) | Manual | `[ ]` | | 5.2 | ~~Allocate IP address from General Applications block (10.1.71.128/25)~~`10.1.71.128` | Manual | `[x]` |
| 5.3 | Add hostname and IP to master allocation table in `Homelab_Technical_Decision_Points.md` | Manual | `[ ]` | | 5.3 | Add hostname and IP to master allocation table in `Homelab_Technical_Decision_Points.md` | Manual | `[ ]` |
### 5B: Pipeline Run ### 5B: Pipeline Run
@@ -147,9 +159,9 @@
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 6.6 | Add Traefik dynamic config for `nextcloud.local.mk-labs.cloud` → Nextcloud VM | Ansible | `[ ]` | | 6.6 | Add Traefik dynamic config for `the-grid.local.mk-labs.cloud` → Nextcloud VM | Ansible | `[ ]` |
| 6.7 | Create DNS record on `monorail` pointing `nextcloud.local.mk-labs.cloud` to `lightning-lane` (10.1.71.35) | Ansible | `[ ]` | | 6.7 | Create DNS record on `monorail` pointing `the-grid.local.mk-labs.cloud` to `lightning-lane` (10.1.71.35) | Ansible | `[ ]` |
| 6.8 | Verify Nextcloud accessible via `nextcloud.local.mk-labs.cloud` | Manual | `[ ]` | | 6.8 | Verify Nextcloud accessible via `the-grid.local.mk-labs.cloud` | Manual | `[ ]` |
### 6C: Authentik OIDC Integration ### 6C: Authentik OIDC Integration
@@ -187,7 +199,7 @@
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 7.4 | Add `cloudflared` container to Nextcloud's Compose stack (or deploy centrally — decide placement) | Manual | `[ ]` | | 7.4 | Add `cloudflared` container to Nextcloud's Compose stack (or deploy centrally — decide placement) | Manual | `[ ]` |
| 7.5 | Configure tunnel to route `nextcloud.mk-labs.cloud``http://localhost:80` (or Traefik) | Manual | `[ ]` | | 7.5 | Configure tunnel to route `the-grid.mk-labs.cloud``http://localhost:80` (or Traefik) | Manual | `[ ]` |
| 7.6 | Deploy `cloudflared` container | Ansible | `[ ]` | | 7.6 | Deploy `cloudflared` container | Ansible | `[ ]` |
| 7.7 | Verify tunnel status in Cloudflare dashboard (healthy/connected) | Manual | `[ ]` | | 7.7 | Verify tunnel status in Cloudflare dashboard (healthy/connected) | Manual | `[ ]` |
@@ -195,9 +207,9 @@
| # | Task | Done By | Status | | # | Task | Done By | Status |
|---|------|---------|--------| |---|------|---------|--------|
| 7.8 | Verify Cloudflare auto-creates CNAME for `nextcloud.mk-labs.cloud` → tunnel | Cloudflare | `[ ]` | | 7.8 | Verify Cloudflare auto-creates CNAME for `the-grid.mk-labs.cloud` → tunnel | Cloudflare | `[ ]` |
| 7.9 | Configure Cloudflare Access policy for `nextcloud.mk-labs.cloud` (optional: OIDC via Authentik, IP allowlist, or open) | Cloudflare | `[ ]` | | 7.9 | Configure Cloudflare Access policy for `the-grid.mk-labs.cloud` (optional: OIDC via Authentik, IP allowlist, or open) | Cloudflare | `[ ]` |
| 7.10 | Test external access to `nextcloud.mk-labs.cloud` from outside the network | Manual | `[ ]` | | 7.10 | Test external access to `the-grid.mk-labs.cloud` from outside the network | Manual | `[ ]` |
| 7.11 | Test Nextcloud desktop/mobile client sync via external URL | Manual | `[ ]` | | 7.11 | Test Nextcloud desktop/mobile client sync via external URL | Manual | `[ ]` |
--- ---
@@ -231,3 +243,7 @@
| P.7 | NetBox template auto-sync from Proxmox API | `proxmox_template` dropdown currently maintained manually | | P.7 | NetBox template auto-sync from Proxmox API | `proxmox_template` dropdown currently maintained manually |
| P.8 | Additional Cloudflare Tunnel services | Pattern established with Nextcloud; extend to other external-facing services | | P.8 | Additional Cloudflare Tunnel services | Pattern established with Nextcloud; extend to other external-facing services |
| P.9 | Nextcloud: Photos backup, Calendar & Contacts | Expand Nextcloud scope beyond file sync | | P.9 | Nextcloud: Photos backup, Calendar & Contacts | Expand Nextcloud scope beyond file sync |
| P.10 | Ansiblize NetBox LXC (`fire-station`) | Create Ansible role for NetBox Apache vhost config, `wed` user setup, and baseline config. Currently helper-script deployed with no `wed` user. Apache `ServerName` was manually changed from `netbox.example.com` to `netbox.local.mk-labs.cloud`. |
| P.11 | `add_service_route.yml` — remove stale CNAMEs | When a dynamic config is removed from `boilerplates/traefik/dynamic/`, the corresponding CNAME on `monorail` should be cleaned up. Currently the playbook only creates, never deletes. |
| P.12 | Rename existing deploy playbooks to day0/day1 convention | `deploy_authentik.yml``day1_deploy_authentik.yml`, `deploy_traefik.yml``day1_deploy_traefik.yml`, etc. New playbooks already follow the convention. |
| P.13 | Evaluate external secrets manager | Explore Infisical, HashiCorp Vault, or Doppler to replace Ansible Vault encrypted files. Would provide audit logging, rotation, access control. Consolidate centralized vs distributed vault question at the same time. |

View File

@@ -6,9 +6,7 @@
# cd terraform/proxmox/hosts # cd terraform/proxmox/hosts
# terraform apply \ # terraform apply \
# -var-file="tfvars/guest-relations.tfvars" \ # -var-file="tfvars/guest-relations.tfvars" \
# -state="states/guest-relations.tfstate" \ # -state="states/guest-relations.tfstate"
# -var="proxmox_api_url=https://main-street-usa.local.mk-labs.cloud:8006" \
# -var="proxmox_api_token=terraform@pve!terraform-token=<token>"
hostname = "guest-relations" hostname = "guest-relations"
vm_id = 71040 vm_id = 71040

View File

@@ -0,0 +1,24 @@
# ─── imagineering ──────────────────────────────────────────────────────────
# Semaphore Ansible Automation
# Provisioned manually (pre-pipeline bootstrap — NetBox not yet available)
#
# Apply:
# cd terraform/proxmox/hosts
# terraform apply \
# -var-file="tfvars/imagineering.tfvars" \
# -state="states/imagineering.tfstate"
hostname = "imagineering"
vm_id = 71037
ip_address = "10.1.71.37"
target_node = "main-street-usa"
clone_node = "fantasyland"
template_name = "ubuntu-24.04-medium"
datastore = "liberty-tree"
bridge = "vmbr0"
dns_servers = ["10.1.71.1"]
search_domain = "local.mk-labs.cloud"
# Bootstrap mode — no pipeline available yet
started = true
use_dhcp = false

View File

@@ -6,9 +6,7 @@
# cd terraform/proxmox/hosts # cd terraform/proxmox/hosts
# terraform apply \ # terraform apply \
# -var-file="tfvars/lightning-lane.tfvars" \ # -var-file="tfvars/lightning-lane.tfvars" \
# -state="states/lightning-lane.tfstate" \ # -state="states/lightning-lane.tfstate"
# -var="proxmox_api_url=https://main-street-usa.local.mk-labs.cloud:8006" \
# -var="proxmox_api_token=terraform@pve!automation=<token>"
hostname = "lightning-lane" hostname = "lightning-lane"
vm_id = 71035 vm_id = 71035

View File

@@ -6,11 +6,7 @@
# cd terraform/proxmox/hosts # cd terraform/proxmox/hosts
# terraform apply \ # terraform apply \
# -var-file="tfvars/turnstile.tfvars" \ # -var-file="tfvars/turnstile.tfvars" \
# -state="states/turnstile.tfstate" \ # -state="states/turnstile.tfstate"
# -var="proxmox_api_url=https://main-street-usa.local.mk-labs.cloud:8006" \
# -var="proxmox_api_token=terraform@pve!terraform-token=<token>"
# turnstile — Smallstep step-ca SSH Certificate Authority
# Provisioned manually (pre-pipeline bootstrap)
hostname = "turnstile" hostname = "turnstile"
vm_id = 71034 vm_id = 71034