5 Commits

39 changed files with 540 additions and 1094 deletions

2
.idea/alpina.iml generated
View File

@@ -4,7 +4,7 @@
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/venv" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="jdk" jdkName="Poetry (alpina) (4)" jdkType="Python SDK" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
<component name="PyDocumentationSettings">

37
.idea/jsonSchemas.xml generated
View File

@@ -31,7 +31,7 @@
<list>
<Item>
<option name="directory" value="true" />
<option name="path" value="roles/alpina/templates/services/authentik/blueprints" />
<option name="path" value="roles/alpina/collections/services/authentik/templates/blueprints" />
<option name="mappingKind" value="Directory" />
</Item>
</list>
@@ -39,22 +39,6 @@
</SchemaInfo>
</value>
</entry>
<entry key="Loki">
<value>
<SchemaInfo>
<option name="name" value="Loki" />
<option name="relativePathToSchema" value="https://json.schemastore.org/loki.json" />
<option name="applicationDefined" value="true" />
<option name="patterns">
<list>
<Item>
<option name="path" value="roles/alpina/templates/services/monitoring/loki_config/loki-config.yaml.j2" />
</Item>
</list>
</option>
</SchemaInfo>
</value>
</entry>
<entry key="Traefik v2">
<value>
<SchemaInfo>
@@ -140,6 +124,25 @@
</SchemaInfo>
</value>
</entry>
<entry key="prometheus.rules.json">
<value>
<SchemaInfo>
<option name="name" value="prometheus.rules.json" />
<option name="relativePathToSchema" value="https://json.schemastore.org/prometheus.rules.json" />
<option name="applicationDefined" value="true" />
<option name="patterns">
<list>
<Item>
<option name="path" value="roles/alpina/templates/services/monitoring/prometheus_config/container-alerts.yml" />
</Item>
<Item>
<option name="path" value="roles/alpina/templates/services/monitoring/prometheus_config/container.alerts.yml" />
</Item>
</list>
</option>
</SchemaInfo>
</value>
</entry>
</map>
</state>
</component>

2
.idea/misc.xml generated
View File

@@ -3,5 +3,5 @@
<component name="Black">
<option name="sdkName" value="Poetry (alpina) (2)" />
</component>
<component name="ProjectRootManager" version="2" project-jdk-name="Poetry (alpina)" project-jdk-type="Python SDK" />
<component name="ProjectRootManager" version="2" project-jdk-name="Poetry (alpina) (4)" project-jdk-type="Python SDK" />
</project>

View File

@@ -8,22 +8,6 @@ running on top of TrueNAS SCALE, separating all the docker stuff from the applia
# Notes
## Monitoring
The monitoring stack is set up to monitor all the containers and the host.
This is a work in progress, Grafana is set up with grafanalib, a Python library that generates Grafana dashboards.
The dashboards are generated from Python scripts in
[grafana_config/dashboards](roles/alpina/templates/services/monitoring/grafana_config/dashboards).
This requires a custom grafana image, which is built from the
[Dockerfile](roles/alpina/templates/services/monitoring/Dockerfile).
This also means it has to be manually rebuilt whenever the dashboards are updated.
From the services/monitoring directory, run:
```bash
docker compose up -d --build --force-recreate grafana
```
## IPv6
The current configuration is designed to work with IPv6.
However, because of how (not properly) I'm doing the subnetting

View File

@@ -14,20 +14,18 @@ authentik_secret_key: "{{ vault_authentik_secret_key }}"
authentik_sendgrid_api_key: "{{ vault_authentik_sendgrid_api_key }}"
auth_grafana_client_secret: "{{ vault_auth_grafana_client_secret }}"
auth_minio_client_secret: "{{ vault_auth_minio_client_secret }}"
auth_gitea_client_secret: "{{ vault_auth_gitea_client_secret }}"
auth_nextcloud_client_secret: "{{ vault_auth_nextcloud_client_secret }}"
arrstack_password: "{{ vault_arrstack_password }}"
auth_vpgen_client_id: "vpgen"
auth_vpgen_client_secret: "{{ vault_auth_vpgen_client_secret }}"
# Minio
minio_password: "{{ vault_minio_password }}"
# Monitoring
## auth_grafana_client_secret:
influxdb_admin_password: "{{ vault_influxdb_admin_password }}"
influxdb_admin_token: "{{ vault_influxdb_admin_token }}"
alertmanager_discord_webhook: "{{ vault_alertmanager_discord_webhook }}"
# Traefik
acme_email: "{{ vault_acme_email }}"
cloudflare_api_token: "{{ vault_cloudflare_api_token }}"
@@ -50,15 +48,3 @@ jwt_secret: "{{ vault_jwt_secret }}"
nextcloud_db_password: "{{ vault_nextcloud_db_password }}"
redis_password: "{{ vault_redis_password }}"
nextcloud_sendgrid_api_key: "{{ vault_nextcloud_sendgrid_api_key }}"
# VPGen
vpgen_opnsense_api_url: https://opnsense.cazzzer.com
vpgen_opnsense_api_key: "{{ vault_vpgen_opnsense_api_key }}"
vpgen_opnsense_api_secret: "{{ vault_vpgen_opnsense_api_secret }}"
vpgen_opnsense_wg_ifname: wg2
vpgen_ipv6_client_prefix_size: 112
vpgen_ip_max_index: 100
vpgen_vpn_endpoint: "{{ vault_vpgen_vpn_endpoint }}"
vpgen_vpn_dns: "{{ vault_vpgen_vpn_dns }}"
vpgen_max_clients_per_user: 20

View File

@@ -1,138 +1,96 @@
$ANSIBLE_VAULT;1.1;AES256
38376439643766303237356563616337663731366435613930393135383962666435313530663632
3432326162343632613565393737363335306263653032300a643539393562376162333761376631
62343731316430316638363338343966326635383930623339383339653936343765316439393233
6562323634383363300a323233346338393764623363346139313661386433656337363332656230
31306233643735333033316139363165373062363334363933396563366234316330646230353261
62326539663337323036346533303031333730373061656563613535376162633138306634626462
37313038356466336138643834643863393333373939616362636365366231383762633030313831
33393139313336623437396161623437323163633362363137626262653462633737373062643735
63353561313639393166306466346134623933323532636438656263663338376337376434356163
64343239616632313566656664393136363337386464613932383961343134363233653039336137
65656566306463313264646163646130323533666464323464643433313030346535346535323264
34356433343739343166383034313935666139663239653662663734343139343035616134303730
39643136623735666333646234346239303337333961343261383834393963386633633030633962
61376132313532643730633865326130666565303631386262396366306565613665363934383335
37376139616165396436663135373932653064656136356662363137653036383537613665393634
38313063656637353630373634316564383362663335356364626161663163323362333937316461
64336636386234623438613766316430353261346339313863306462393335636131363966363038
66393561323335393063663838393466656331323433376461653838313638303564666662636438
38663735616261656338626437336433613730353236636266316536656165303534353538316232
62363063376464323932383261663537393263333266633461326536656533653661303335646431
36616436396137343634373563386439653833306537373735353764346430616231313538636362
30363430613839373761363032316137636432643339383561313637376339323836353161343639
36316665656164396236383538346561306432333637393431393566333566633434393961663330
32383833396238633966393837336564626135653733383863346161663364353062303931303931
39653662373734643037393832643439653437353935666430373337643532346161376661633738
61643431633431666535333463636461613166363238373138306565643533623039353031646634
62383662663435346635373865633731393362623761313834393964623930646364366534333236
35393138346433366435313066633436393561643263343534393034373161343834633261363933
65376636393263663566653436633762643331336139653565663334373561353130653065653935
31616337313764313532303934376236623833363433336335303262643135643339613839623231
37343730616166323239653537313137373136626337333665633134363830626131353030393662
31643366386365353336326133636434303636343637643539653131316133306132643133643364
64636464373564383938663838613031626563613362626435383832346661306562343165643539
66353431393032313262393566353833343632366139656234306561366139633431653133356165
32363332636433626132666462626137653337646234646565303831646330333133353964626461
37333265623865376562663365336339353036346135363062663534643537353331623630356264
66386665333633383534313062623533383239383231333163663565633531666236306465633135
36363164636165343863363866343437636630353863316633623761373232643262623762316162
32613665306535626139366564616362393536336364666663333761383362393631316134373138
32616665363164363639303538373539346239663261373731613464333734326436666433666539
31656264326535626134323231646535656563363231633434636337323538343038303233363765
61393164316237323533313336316530316431653731343261636265393361616464323536333130
65346538306664663566666435393738323832396365363764333637613331356661306535376332
62313533306365373737643835396364363737306631346161353031633531383364636563383237
64633432386565356137333730313736393737303665326531356265376333663636393430386233
33666532616632373061633063656136646533363034363330366231653936396166663134396139
66393131653963386365656364666263666362316136333561326566626562616138383739346139
62343035646435393136656434646138376331346164663562306166646132363230333538323536
38643934613633373734653337666261356639353235326539356264633232343834633062336539
31616536663730656163626437653932313564633938643163313765393731386533323465303831
34353663363862363761643565633635373834623665653131613531373637386361636661376532
64386435643966343034643763393461373961626134346539653865636161333962333463393734
62343838363432396133326235323636613239326139376365353930373835313531326433326234
66396537636162363865663433626230316362343334653735646637613130636436633132663538
64623230303266373965616533346464373661363233613837613765343463306136623063313139
31383039343462363536646636653736316362356565326538636331646235373162663332313961
64623061636638666234623336656365383165626461323561343930316432313632316332306334
61376430303835383934396266303564363230313735366464386134393265326334663633663632
38643034393737303963643733656333316137646435653666353239373738373632383561646333
65363865353362383832643238363332613931343038366563316163303764323936316466666364
31373439383661656336653431666164393833643266656133383137376133636134643137663532
33353531663336346562653339616430333133363232336461353937303435346337363932306133
37623164343462363830323263323664303334633563313439376232303031633633316636383164
66306238333432333635653435383138383339343837346134613630353335656335663062326132
65323638343963623062663638366538363162343230323262616138373239653163623832313366
65323834383631646164316363383636643437346435313030656362653332653635343066666232
39346235383265326262306434383861653138393835663863383032363664323565316165646566
61646238393062373131346536343533663839313831383335316363343465663130633133393436
66333465633636353639663836376561353839613533346164366238353833636534633338313262
30656433376362346333303630643639353262323532666238633764363132303161326638643761
36616131636538613539383935613337643930333334613566393031646630383330656164363361
37306536356164633831626362653364313164356235653464333633313263383032333439626434
65376531396661636661303831393062666362623966353739303330393631323963373564353265
61343862323737336238356231626561396333386264666563356235333339653538626130623936
63326431316538346534313764356333396565666431633833613337323136643137306166623238
66393561333137373964353935323930636237366433613038383761643665363330323865386133
37623339613733353366656637383030623663313639363334656361623035643232626633313864
36346564653766646333613763616163363462613937656534363461376235613064373039326165
32666265383065636232613632333830633439653066653666663261646536663434393535613131
30373062313765663038313534623165653833623330383032363063393239373234636630646561
38633962363530666638666630316434613462656335613236363831313863613030636539356133
66386133383433663964306661636131633236633935633236623530373864646363383534383735
63633165626464333332303331333338313838393832626637626137316338643136336333633930
61346436336635656639616261383666336330333862303139633137373362303033653432613039
35623663353538323761623839623438646363313164356631386364356533346133333334326565
32303837663261386463313535373765356166376165386535623838326431616564346632363732
62373231356530346632373134343865303532326136653731633038353066623435336462303138
37363039343433613939363663623135396636396433653362666164323237393664623564393532
61376463336564396537366365373936333666373432376566323864343735636264643139643063
66396230303336633438666234336434353866323637316334313162363734623763666338336234
39303330343035333864396631323231363134646238323065356138633131323135613133356237
34373562633430613062313261363939373632313838333934303165336562663839663833383763
39316632656561653033613933373861366361353761346539306234366538373461373930306535
66623430343336333033306135303639646566393336663538313430616364653933663536386535
64323962353734356134656361663131376564626461386233643731393664353038626464313763
64396265373737313134613962376334373965353338303363303935353538643561336461393032
37356434343837376534663938366434343063643966643965346465636166363235643635333466
38323664366366663363616664336165653264633437393636363866316262303432356461386330
63326539626363333331366162363230626462656633653866383331333164663734633630353265
63303832376230646136346261383965626633613739616330666232376366613332663839336531
32343031336363663865643165666435623462376130326433316562363530343662366432313031
63626538656633346563663735323030363231643933326337613634376531636235333339373633
66353362333265343964353966383363613336636536393734363363623363316532653533633434
39333162303834353362323362656630343733653336613065333462626637303264653361393462
32336238326535383662636465383832346438333230666662633430303964343236626331623536
65383666316431646538396661386332323037383666336138666135613763363633343934663836
32656362323631303732613235663135633939643165626231373162643963613637626235613365
32326266323431636434633234333730373836373039666137663232323539396364373061393232
30646432666365333336333836313333363537363163383034656136383164663331373632313564
34353731363338323438366464663938393632626530323537306233613866356234323364373766
34326662656263383864613538326536626133386532303932326362376632363631356535393937
33346462336636656165316166363364343330383337636361656438383661333366633532616131
37313033623430663039626131303933316561666233613666636433363537373264653331323136
66663532653233373735326333333738663931343735306262353831303330633136623966316431
39316462313066336536623438626163383139343532313932316435356431323865373035343465
30346237393531353833616136323431376530333635633632666431313938643539363831313539
38396338336136363165323135663836336139623865666631663237616664636233653663383965
39623665656563316334323738323730306631636565393662313536353565383033653365663461
38326432353166376438356238386161396638666131636536356333393563613461373263346538
36656138353762323662363061613764633466303566353338626666646533616137393336333333
30393733316636353266653039346237363830333831383535646531616130353534633062643135
64373533646462313035383236333866313866366130663863363162613234393762646662666233
30653666353333366365343036643462346361303536363935396133343166303339623461376563
39333163636466646534356337656431376663623833303235303534633634386665636162346634
34646665633639663763316339663539663261333436363935316334656330313835616138626237
35623363393532633937653132303635396536646635633062393661616538303631663136363038
35623539303963383063343338653130643233636537356264323238633839303337383665393333
36303330393638643464646535653833626531343634626531396261363139326336623765623039
32613237636366376463343766303964336661363432646436373963626537373137396661633766
63633830663035663764303634643662333464353234646232343066306131336533396435313239
66366630643564313665306130656463633065646430373334336664633264353336376439666137
65366537366462623136353539373961333238373733663837373430663865643334393565333861
35363035343561633164613631633532623164376339633630393633396437333034376339656538
32653030626434326632386635383739663932393331333062656565303939373566653031613839
31363162666330393232646562333833633266643165316464623533623539356339333365623966
65323638396531346261303835373138333262323466656263643737343734303237303638353036
3733
32653863663065353431636364373163613536643238613961666561653663633530646165643766
3833323937353331313136633965393061616135366534660a333037383066303431623830313464
65346431633238666534373033663138353438313762326361666233353866663534363536643034
3636323439316261630a623262336331663431633266336235653034323234383566323963623365
32626363626164373536663464643632393761346137623866633237643038306265636362626561
61313634353634373530383061393364613461303132326335316566326436633635633131643433
31376539396639326464333233643933373737313064363262323639363964643862633035396161
35643037636535623966626131393538643432396536643365383736636262356135373434376433
32316361343330303431376234323632323932376635343964383733633761326639393966383039
35646131343034663962363335373661323065663764396631343461383661663738386163323633
36303464646532633235663662666663343238633465663334326463383133643239666634653739
35396130393961303230396236303766336666643930626161333338326137663235323066663032
33376564373563323635356233616264313663373534333636643236393866613062656338353864
66386132663362363832366661646462316139353132626662663934336530386534376538633235
62653131653835323261373435373631396466353738306362616266616532313435323633613933
61646132346536323632643865326234356535346566346532383162393265613931343962303463
31636334343736666434353835633734396465653862613234386431306463326134613931646232
32353535663133623434643866336165616232613662336533383432633338373763643337616637
38323237646461376433316164646366383438316639633162303739383263656265633364303565
36643339356136653332666230633939636264306431636562323864373037623138363739616561
37613364653737353638646564323439646138646536636564303866636233616264383466656439
33646232653061616437656162353036313834616162313936353533393833313432656534343363
35636638326236646163323463356634326534623165306461316530353936646162323435633862
64396464303363323837316162353734626663643962303534336637336632333463393734383532
66616534666466393333386337363238383432643764373864613461363766333932333862363332
61313364613031376334326635636432346532613462613265643462636436663963323862353733
38396261613332396633666130653262313234633132353264363266336231373535306532383661
65323530653531646339626537653433303332656535346639393466353133363833326236656231
33336265373463396135653730616266346331376461346433343464326238323034653330393732
36643432316662333633333036633761653031393433333338663633386264656535623534653463
36363565303333356361616539376532353066336137336134656465383364636361656664356439
65326334643631663665376530646433323439653864623964323363396561313663636538356536
63626336303862333364363166353437353163656238303765636662636137383337623563666264
66326633343230386638616438393436633431343264343231386563613935626430306337343533
66656366333332326131343661356236396430303832303834653530623639353036663436373862
61336437386338343965653563646664643438353232306231316564616462643236646239333062
38643461346639623964626438396631396139383332666130316635656530653136333662353566
36313261646330373963663032316662383137366436636534383366636362366435393036373264
34646537666462363531343335336638343038333633663862666163306662643634326533316561
61613235366233636530663462353066646530386265623534663336376364323237343936646134
31616563653864383565306439613932396562613835613562326264326535636630646666366335
36653631353961353933386236636534393636356334633336313333383238353838336335646630
63633365666530623562323634303935326362643762616532303531303139333565643835396163
36353130656365326435343130613234336637346461313639653133623933376163393935366266
66653337353732363038663164363663623266356366663637343466393836353965343730666362
38663636336265383331666666616535366334616431306164303738306436333364653765356662
37316433323563323431623164386337343563663538333435616333343433396236356363333262
61396664326234343136666331356465333233663135613839616334623033316362336162613731
38646530326538643337323838326563303130643934623939346635343331356531373235663937
62396530383365666439373632613633633233376139616138323033613135383330333132643839
65363833616337656662653462323436303531653635663739633366616532333761323238353764
39373836303735393165393435323139346661346135636138613731373165386533386333393364
32336265386334386338653734353565343733393931373436336233333031356531313739636666
61376234393631343236643137616631373564376132623534333939346162353662306661393438
32326566373934653463653737383131386431363664333535626361646637613632383132623533
32343465366562363765353366333330633631353936613930376631336538306230626632303966
31343936386535663165663066663862656439306363326337313561396132316338363930323632
33313061623534373338623931663934396339633564353533626639373837323832366132343538
63373862663137306665383732303863343564343830636233613139666631626532373938386663
35646331646462356639383964373732393866653963643832633661323430323430613330633364
35343262366362646165383032333236623863656264353964623136643631326135623538306261
37393839343331653665356131343063316232303963636462653238333466636334616435666463
65636662383930353238623130363834616137643830633261646338363435343839633565303562
37623231396163346464303464333962336261353634396236613132306464643764356265656137
32373263613964396430646332666235303634373431643939623963633334326135626565656662
30646166303732643562653166633232666635343665616665653566316632303861613861313333
38393636663137333231613239353661656338333536656563616237343234623031363535666637
61343662663965663161666436366630366432363733663537613064386130326466343366383232
32363662343561666665323565356163383932336361656132373263363239636666613461366339
31323264393866386239353333386161643330343262366666323533303737373163313262313766
61303638366263346232353134333431613730386431623235323537323962666133613939353762
63326361633630323937353163383930626336663365626532613031623532393932316138353335
32363262393764663135393466616639373965313238323935383531633434633038663437646662
31633265373937316533373332316132363061386133356231623230393739326464333761336338
38626234646164616265633061346239363164376532383834356435346232653065326362343363
39613532356166633133626563643238373661323937353635343464666339323561326136623366
62633637656462376136633963653263346565366563646533373431613761616231653739613537
32343332356435393635363837396463613165626337346235303363613764306132343539333836
63386633626332396339383165303166653334663239313066666632356165643161356262346230
32636365636364663466343939663538386439343336303537636230306263643534653339313538
31373165363962373337636138336561336638633762373363646139366339323031313664306534
30623130663037323839666166323162393065643535663866383062356330633137343239316436
32303132393739653363376138633430313832383165663366626436653033663637616664346632
63633439663734393236343265323533633639316133323336373064633138363266316135363335
31336637666331333139306537333565333064666433653730633430336261656665613263663937
64313230656333373838346439623061393164393239393934306336373063303934663334353532
31313637623466313835313566616161376230343532653561343364383133653736646338303631
36356164303630303433356332343630616465383831623036383833393330663566616333653161
63393361643266323336393962663263323338633634633033393762656139393665353630633637
39386462303731396261613961613238616237373332656361303139633763303837653765623464
64333565666532653864383861333433353731343161613231383836353966353636373762306132
35333536373939656638356333383135313231306433656536383933623634653263353434393238
32323037666135316337633465666335376332326633346665643333656139386465353134356636
36333434303538326135346539313734393939353163316666366438613133333464623732666438
663934323030303937623038343662646163

View File

@@ -12,7 +12,3 @@ fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}"
# Authentik GitHub OAuth
github_consumer_key: 32d5cae58d744c56fcc9
github_consumer_secret: "{{ vault_github_consumer_secret }}"
# VPGen
vpgen_ipv4_starting_addr: 10.18.11.100
vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}"

View File

@@ -1,24 +1,21 @@
$ANSIBLE_VAULT;1.1;AES256
63353634643462306366336162646431616335613961343464626166303837363565393136373433
3663373337303837353564383531393462343064353534370a666333363166636137396634613139
62313762373332303334666530333731653231663263663930633265333665383661643037303737
3239666139623937390a373066376363663865373266623831653964366565623138643138353866
35343633323032326331393263316434396335643732363337643262373663646339663836623235
61356534393435303336313636646665366238303539343835343761633230383261333864396465
34336166346261613061616336633166383338623561626662333665323462623064666531633833
34333735343934356365306135386430646539366561666334393065363532393636653031393237
38633437383961376162366430393761366231636437316139373334623964396236643761306363
33653761356632643334333932346664353037366638363835663435363162396333616535363730
61623539363130633330303462613861393965643066303338353531346433363962373761623235
36313838323830333966326331656435653837363530353837636465333434666266373639626534
37663633353962336237316433653763616333333165343630346637346137613338333363653231
36326163343839363936613334373430326531646464626230616634663530343265356166346165
61306263613937626565626165616336626131636234643062306530326235646532313962626438
61363333373034313563373831633339653365663831376463663839333233616635656137333561
36396639393835316133393737313164353939336134623666396265396535353861643263366235
62323137306235633061386630636235613636393033333631633231316337393430383438643462
63343630353134363633383331373437623631333532663536643937616636666433623861643639
63653532626337333136313932396164393733333038396235313133326338356234363363633962
34336562396138333535363165343764363336316238323364326539343738633831636536306139
38653766656430353035396166616133343666303231363039386635363536306531343932656261
623162633233343566376630303538636664
61656162363565633436373135333536623561663136303736393865623830633539376362363363
3938333137343336626634346262363964316563643261310a366538363037343965363766646535
61636239326464373039333462653562373933396665393039633266326234663335363337666439
6137323332303533640a383062383135633762323561313666636566306531306636633466316536
66623731626266333731303336323733343336626366343833633365616330343565363035323039
35313961383131616133386663376331336639633137383137346164353632653939363266613562
36316631366661353632386230306532633862393963663465383862653964646462666334396666
66626636353539316266343937623662613336616331626439306538363764636366656635356639
30663535393366383261333832356237373230663037373638303161303534636230616464636265
37623938303638646233346338616239393838396433313063343065386666323264646461373032
63376661646139316430303533643063336634333364643231336130613638626431623732646434
63643833353164313465633333646232653761356333323933396666323837656334343866363762
39646263653137356632323534356631366531636530613736343438393136363835373435636230
30313163386335353935663432323033326235653963653930396235373863373232666334326661
34336632666365666563326366376461386130343965363832343430396537323734363533353065
64313837623366356261383437306465633730353332636561333462356363326132313933653234
66363634333664333433613466396639306436353035346134373430663532373934343861323262
30666664336336393835346234316238613839326436363162626439376530306133343530303365
65393030633237333166336637363435646435323736353461333932366638333264333239373733
30623062643336643431

View File

@@ -12,7 +12,3 @@ fw_vpn_input_ports: "{{ vault_fw_vpn_input_ports }}"
# Authentik GitHub OAuth
github_consumer_key: dbacb8621c37320eb745
github_consumer_secret: "{{ vault_github_consumer_secret }}"
# VPGen
vpgen_ipv4_starting_addr: 10.18.11.50
vpgen_ipv6_starting_addr: "{{ vault_vpgen_ipv6_starting_addr }}"

View File

@@ -1,24 +1,21 @@
$ANSIBLE_VAULT;1.1;AES256
63633035373836396362626539323363363132366230343762366437326339343535663361633430
3039646662343464303663313631313361306136613461340a313836363237376238343232613463
36633962613233386261366536333664346132396266383064353065353936653038346534343433
3734333932666436660a346539643637316432343761393635333265656165313464656631653236
37303637333564383036623664616237313466643836663632363461353462386638326361396535
34353639303734323633306266356134393832366132633132383361336138643961663362616132
65356338353837623531383566363666633565646537353937656463343832613031633630306462
62313335353065323939366536356161653339316265373362376138396636626361643435386234
61633732383963653935363137346466623163396231303430346338323761643237383461303932
36663263633730346362386366663135653735303161383166633631333862303261356132303461
34633432633663623136303337613335643636356530626336366361373736333336366230346265
31396463363639303431386439303163643037376262616437643438323162653134643837363430
66336331636466383063656632306566346531336161653136623938616564333333326566616364
62383935616637656132373664343730653239396634313530633665633736653365366136656265
39343833333836323133376465376164323530643438353234353938663733323433373531636335
64366232613637636537626139656130303663353266363064666464373665336238383763616436
30303032393830333730353837656237666564346430613531653466646534613536353433613634
62653538366638366565633261346431396639663435356531366537353737363761356530643635
61653438346434363834653131646661366338633431303862333732326262626366633034323137
30323636616333356430346365643630366162323133376135366663343265346234346161306431
35383736336664636561623262643162636130366162326536656231653165386230333562383466
66323863656566396639316263376233613162396265373235306662663665613663626565623761
663938383964623436306662666663303330
63633535633462326534626562373461373363643166383961303861623531663263323534366537
3263633238646439306430356365623233313838326639350a386633363434623737313565316535
33393734633937333637373432366132323366343836393538366339626235613937323066613666
3737393262646333390a623331333461373563313166323232343234616538623433376166313532
32323834346336336164343938303062336438643566343866316164643535663039326331646465
36666162393365323633646635333666613030386265306238633434303234336439646663356363
63323638373035326465633934326363316364616539613462653232393465633233366666373664
66616361646564303530356331323864343966633736643434653237316236363063613634646438
35303238646632616465643264316164363139393834626362326538613033656464323435396638
31346631653764303332386331663361623766333332366537313634636333346538653537346631
62363438303036386530633236376633326162336434343861346261373835653735323161323965
62353965373164616537346134303232363033323134323130316439386339613966646330666533
65346239383230646565346133663530613462363532663562326136376233303638323332326630
35656432363563653663616236393932663637323139666664636237336136366438656666633865
66353162656364356638313236643131613830393838636264663833343461373963613431656364
32303331623033303433333631313038316336653638656638373031653234356164333363336532
37316334353463376562643138346633613633353536653939376564333166323931353634333736
63616133663266383339323562343265613461623865623263623139396163343065623264366230
32633362336335396562366563363830636133376238646433386236666461333731353337386333
61323931643766326338

View File

@@ -31,5 +31,4 @@
- nextcloud
- jellyfin
- arrstack
- vpgen
import_tasks: deploy_collection.yml

View File

@@ -1 +1 @@
NEXTCLOUD_VERSION=30-apache
NEXTCLOUD_VERSION=29-apache

View File

@@ -1,21 +0,0 @@
DATABASE_URL=file:/data/vpgen.db
AUTH_DOMAIN=auth.{{ domain }}
AUTH_CLIENT_ID={{ auth_vpgen_client_id }}
AUTH_CLIENT_SECRET={{ auth_vpgen_client_secret }}
AUTH_REDIRECT_URL=https://vpgen.{{ domain }}/auth/authentik/callback
OPNSENSE_API_URL={{ vpgen_opnsense_api_url }}
OPNSENSE_API_KEY={{ vpgen_opnsense_api_key }}
OPNSENSE_API_SECRET={{ vpgen_opnsense_api_secret }}
OPNSENSE_WG_IFNAME={{ vpgen_opnsense_wg_ifname }}
IPV4_STARTING_ADDR={{ vpgen_ipv4_starting_addr }}
IPV6_STARTING_ADDR={{ vpgen_ipv6_starting_addr }}
IPV6_CLIENT_PREFIX_SIZE={{ vpgen_ipv6_client_prefix_size }}
IP_MAX_INDEX={{ vpgen_ip_max_index }}
VPN_ENDPOINT={{ vpgen_vpn_endpoint }}
VPN_DNS={{ vpgen_vpn_dns }}
MAX_CLIENTS_PER_USER={{ vpgen_max_clients_per_user }}
ORIGIN=https://vpgen.{{ domain }}

View File

@@ -1,16 +0,0 @@
{% import 'contrib/compose_helpers.j2' as helpers with context %}
networks:
{{ helpers.default_network(196) | indent(2) }}
services:
vpgen:
image: gitea.cazzzer.com/cazzzer/vpgen:develop
container_name: vpgen
labels:
- {{ helpers.traefik_labels('vpgen', port='3000') | indent(6) }}
restart: unless-stopped
env_file:
- .env.vpgen
volumes:
- {{ base_volume_path }}/vpgen:/data

View File

@@ -5,80 +5,46 @@ metadata:
name: Alpina - OAuth2 Apps
entries:
{% set apps = {
"Grafana": {
"redirect_uri": "https://grafana."~ domain ~"/login/generic_oauth",
"icon": "https://grafana."~ domain ~"/public/img/grafana_icon.svg",
"client_secret": auth_grafana_client_secret,
"ui_group": "Services",
"allowed_for_groups": ["admins"],
},
"Minio": {
"redirect_uri": "https://minio."~ domain ~"/oauth_callback",
"icon": "https://minio."~ domain ~"/logo192.png",
"client_secret": auth_minio_client_secret,
"ui_group": "Services",
"allowed_for_groups": ["admins"],
},
"Gitea": {
"redirect_uri": "https://gitea."~ domain ~"/user/oauth2/Authentik/callback",
"redirect_uris": "https://gitea."~ domain ~"/user/oauth2/Authentik/callback",
"icon": "https://gitea."~ domain ~"/assets/img/logo.svg",
"client_secret": auth_gitea_client_secret,
"ui_group": "Apps",
"allowed_for_groups": ["admins", "users"],
},
"Nextcloud": {
"redirect_uri": "https://nc."~ domain ~"/apps/sociallogin/custom_oidc/authentik",
"redirect_uris": "https://nc."~ domain ~"/apps/sociallogin/custom_oidc/authentik",
"icon": "https://nc."~ domain ~"/apps/theming/favicon",
"client_secret": auth_nextcloud_client_secret,
"ui_group": "Apps",
"allowed_for_groups": ["admins", "users"],
},
} -%}
{% for app in apps.keys() -%}
- identifiers:
name: {{ app }}
model: authentik_providers_oauth2.oauth2provider
id: {{ app }}
id: {{ app | lower }}
attrs:
access_code_validity: minutes=1
access_token_validity: minutes=5
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
invalidation_flow: !Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
client_type: confidential
client_id: {{ app | lower }}
client_secret: {{ apps[app]["client_secret"] }}
issuer_mode: per_provider
sub_mode: hashed_user_id
property_mappings:
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
{% if app == "Minio" -%}
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, minio]]
{%- endif %}
redirect_uris:
- matching_mode: strict
url: {{ apps[app]["redirect_uri"] }}
# Necessary for JWKS to be generated correctly
redirect_uris: {{ apps[app]["redirect_uris"] }}
refresh_token_validity: days=30
signing_key: !Find [authentik_crypto.certificatekeypair, [name, "authentik Self-signed Certificate"]]
- identifiers:
slug: {{ app | lower }}
model: authentik_core.application
id: app-{{ app }}
id: {{ app | lower }}
attrs:
name: {{ app }}
group: "{{ apps[app]["ui_group"] }}"
group: "Apps"
meta_description: "Hello, I'm {{ app }}!"
meta_publisher: Alpina
icon: "{{ apps[app]["icon"] }}"
open_in_new_tab: true
provider: !KeyOf {{ app }}
{% for group in apps[app]["allowed_for_groups"] -%}
- identifiers:
group: !Find [authentik_core.group, [name, {{ group }}]]
target: !KeyOf app-{{ app }}
model: authentik_policies.policybinding
attrs:
order: 10
{% endfor %}
policy_engine_mode: any
provider: !KeyOf {{ app | lower }}
{% endfor %}

View File

@@ -4,47 +4,61 @@ metadata:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - Proxied Apps
entries:
# TODO: Possibly refactor this into a jinja macro (?)
- identifiers:
name: arrstack
model: authentik_core.group
id: arrstack
attrs:
arrstack_username: "arr"
arrstack_password: "{{ arrstack_password }}"
# TODO: Probably refactor this into a jinja macro
{% set apps = {
"Uptime Kuma": {
"uptime-kuma": {
"host": "uptime",
"name": "Uptime Kuma",
"icon": "https://uptime."~ domain ~"/icon.svg",
"unauthenticated_paths": "^/icon.svg$",
"ui_group": "Services",
"allowed_for_groups": ["admins"],
"group": "Services",
"create_admin_group": true,
},
"qBit": {
"qbit": {
"host": "qbit",
"name": "qBit",
"icon": "https://qbit."~ domain ~"/images/qbittorrent-tray.svg",
"unauthenticated_paths": "^/images/qbittorrent-tray.svg$",
"ui_group": "Arrstack",
"allowed_for_groups": ["arrstack"],
"group": "Arrstack",
"create_admin_group": false,
},
"Prowlarr": {
"prowlarr": {
"host": "prowlarr",
"name": "Prowlarr",
"icon": "https://prowlarr."~ domain ~"/Content/Images/logo.svg",
"unauthenticated_paths": "^/Content/Images/logo.svg$",
"ui_group": "Arrstack",
"allowed_for_groups": ["arrstack"],
"group": "Arrstack",
"create_admin_group": false,
},
"Sonarr": {
"sonarr": {
"host": "sonarr",
"name": "Sonarr",
"icon": "https://sonarr."~ domain ~"/Content/Images/logo.svg",
"unauthenticated_paths": "^/Content/Images/logo.svg$",
"ui_group": "Arrstack",
"allowed_for_groups": ["arrstack"],
"group": "Arrstack",
"create_admin_group": false,
},
"Radarr": {
"radarr": {
"host": "radarr",
"name": "Radarr",
"icon": "https://radarr."~ domain ~"/Content/Images/logo.svg",
"unauthenticated_paths": "^/Content/Images/logo.svg$",
"ui_group": "Arrstack",
"allowed_for_groups": ["arrstack"],
"group": "Arrstack",
"create_admin_group": false,
},
} -%}
{% for app in apps.keys() -%}
- identifiers:
name: {{ app }}
name: {{ apps[app]["name"] }}
model: authentik_providers_proxy.proxyprovider
id: {{ app }}
attrs:
@@ -54,26 +68,39 @@ entries:
skip_path_regex: "{{ apps[app]["unauthenticated_paths"] }}"
- identifiers:
slug: {{ app | lower | replace(" ", "-") }}
slug: {{ app }}
model: authentik_core.application
id: app-{{ app }}
attrs:
name: {{ app }}
group: {{ apps[app]["ui_group"] }}
meta_description: "Hello, I'm {{ app }}!"
name: {{ apps[app]["name"] }}
group: {{ apps[app]["group"] }}
meta_description: "Hello, I'm {{ apps[app]["name"] }}!"
meta_publisher: Alpina
icon: "{{ apps[app]["icon"] }}"
open_in_new_tab: true
provider: !KeyOf {{ app }}
{% for group in apps[app]["allowed_for_groups"] -%}
{% if apps[app]["create_admin_group"] -%}
- identifiers:
group: !Find [authentik_core.group, [name, {{ group }}]]
target: !KeyOf app-{{ app }}
name: "{{ apps[app]["name"] }} Admins"
model: authentik_core.group
id: "{{ app }} Admins"
- identifiers:
group: !KeyOf "{{ app }} Admins"
target: !Find [authentik_core.application, [ slug, {{ app }}] ]
model: authentik_policies.policybinding
attrs:
order: 10
{% endfor %}
order: 0
{% endif %}
{% if apps[app]["group"] == "Arrstack" -%}
- identifiers:
group: !KeyOf arrstack
target: !Find [authentik_core.application, [slug, {{ app }}]]
model: authentik_policies.policybinding
attrs:
order: 0
{% endif %}
{% endfor %}

View File

@@ -1,40 +0,0 @@
version: 1
metadata:
labels:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - Default Groups
entries:
- identifiers:
name: "admins"
model: authentik_core.group
id: "admins"
attrs:
is_superuser: true
- identifiers:
name: "users"
model: authentik_core.group
id: "users"
- identifiers:
name: "arrstack"
model: authentik_core.group
id: "arrstack"
attrs:
arrstack_username: "arr"
arrstack_password: "{{ arrstack_password }}"
- identifiers:
scope_name: "minio"
model: authentik_providers_oauth2.scopemapping
id: "scope-minio"
attrs:
name: "Minio Policy"
expression: |
policy = "default"
if ak_is_group_member(request.user, name="admins"):
policy = "consoleAdmin"
return {
"policy": policy,
}

View File

@@ -0,0 +1,56 @@
version: 1
metadata:
labels:
blueprints.goauthentik.io/instantiate: "true"
name: Alpina - OAuth2 Services
entries:
{% set apps = {
"Grafana": {
"redirect_uris": "https://grafana."~ domain ~"/login/generic_oauth",
"icon": "https://grafana."~ domain ~"/public/img/grafana_icon.svg",
"client_secret": auth_grafana_client_secret,
},
} -%}
# TODO: Add Minio
{% for app in apps.keys() -%}
- identifiers:
name: {{ app }}
model: authentik_providers_oauth2.oauth2provider
id: {{ app | lower }}
attrs:
authorization_flow: !Find [authentik_flows.flow, [slug, default-provider-authorization-implicit-consent]]
client_type: confidential
client_id: {{ app | lower }}
client_secret: {{ apps[app]["client_secret"] }}
property_mappings:
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, openid]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, email]]
- !Find [authentik_providers_oauth2.scopemapping, [scope_name, profile]]
redirect_uris: {{ apps[app]["redirect_uris"] }}
- identifiers:
slug: {{ app | lower }}
model: authentik_core.application
attrs:
name: {{ app }}
group: "Services"
meta_description: "Hello, I'm {{ app }}!"
meta_publisher: Alpina
icon: "{{ apps[app]["icon"] }}"
open_in_new_tab: true
provider: !KeyOf {{ app | lower }}
- identifiers:
name: "{{ app }} Admins"
model: authentik_core.group
id: "{{ app }} Admins"
- identifiers:
group: !KeyOf "{{ app }} Admins"
target: !Find [authentik_core.application, [slug, {{ app | lower }}]]
model: authentik_policies.policybinding
attrs:
order: 0
{% endfor %}

View File

@@ -5,16 +5,11 @@ MINIO_DOMAIN=s3.{{ domain }}
MINIO_SERVER_URL=https://s3.{{ domain }}
MINIO_BROWSER_REDIRECT_URL=https://minio.{{ domain }}
# https://min.io/docs/minio/linux/reference/minio-server/settings/iam/openid.html
MINIO_IDENTITY_OPENID_CONFIG_URL=https://auth.{{ domain }}/application/o/minio/.well-known/openid-configuration
MINIO_IDENTITY_OPENID_CLIENT_ID=minio
MINIO_IDENTITY_OPENID_CLIENT_SECRET={{ auth_minio_client_secret }}
# defaults to "policy"
#MINIO_IDENTITY_OPENID_CLAIM_NAME=policy
MINIO_IDENTITY_OPENID_DISPLAY_NAME=Authentik
# no need to specify scopes,
# as it defaults to the ones advertised at the discovery url
#MINIO_IDENTITY_OPENID_SCOPES=openid,profile,email,minio
#MINIO_IDENTITY_OPENID_REDIRECT_URI_DYNAMIC=off
#MINIO_IDENTITY_OPENID_CLAIM_USERINFO=on
#MINIO_IDENTITY_OPENID_CONFIG_URL=https://auth.{{ domain }}/application/o/minio/.well-known/openid-configuration
#MINIO_IDENTITY_OPENID_CLIENT_ID=
#MINIO_IDENTITY_OPENID_CLIENT_SECRET=
#MINIO_IDENTITY_OPENID_CLAIM_NAME=
#MINIO_IDENTITY_OPENID_CLAIM_PREFIX=
#MINIO_IDENTITY_OPENID_SCOPES=
#MINIO_IDENTITY_OPENID_REDIRECT_URI=
#MINIO_IDENTITY_OPENID_COMMENT=

View File

@@ -0,0 +1 @@
DISCORD_WEBHOOK={{ alertmanager_discord_webhook }}

View File

@@ -4,10 +4,6 @@ RUN pip install grafanalib
COPY ./grafana_config/dashboards /dashboards
# Required for grafanalib to find the shared python files like common.py
# https://github.com/weaveworks/grafanalib/issues/58
ENV PYTHONPATH=/dashboards
RUN generate-dashboards /dashboards/*.dashboard.py
FROM grafana/grafana:latest

View File

@@ -0,0 +1,68 @@
# The root route on which each incoming alert enters.
route:
group_by: ["alertname", "job"]
group_wait: 20s
group_interval: 5m
repeat_interval: 3h
receiver: discord_webhook
receivers:
- name: "discord_webhook"
discord_configs:
- webhook_url: "{{ alertmanager_discord_webhook }}"
{# - send_resolved: true#}
{# username: 'Alertmanager'#}
{# webhook_configs:#}
{# - send_resolved: true#}
{# url: '{{ alertmanager_discord_webhook }}'#}
{# username: 'Alertmanager'#}
{# icon_url: 'https://prometheus.io/assets/icon.png'#}
{# icon_emoji: ':alert:'#}
{# send_resolved: true#}
{# text: "{{ .CommonAnnotations.summary }}"#}
{# title: "{{ .CommonLabels.alertname }}"#}
{# color: '{{ if eq .Status "firing" }}#FF0000{{ else }}#00FF00{{ end }}'#}
{# footer: '{{ .CommonLabels.monitor }}'#}
{# footer_icon: 'https://prometheus.io/assets/icon.png'#}
{# actions:#}
{# - type: 'button'#}
{# text: 'Open in Grafana'#}
{# url: '{{ .ExternalURL }}'#}
{# style: 'primary'#}
{# send_resolved: true#}
{# confirm:#}
{# title: 'Are you sure?'#}
{# text: 'This will open Grafana in a new tab.'#}
{# ok_text: 'Yes'#}
{# dismiss_text: 'No'#}
{# fields:#}
{# - title: 'Description'#}
{# value: "{{ .CommonAnnotations.description }}"#}
{# short: false#}
{# - title: 'Details'#}
{# value: "{{ .CommonAnnotations.details }}"#}
{# short: false#}
{# - title: 'Severity'#}
{# value: '{{ if eq .Labels.severity "critical" }}Critical{{ else if eq .Labels.severity "warning" }}Warning{{ else }}Info{{ end }}'#}
{# short: true#}
{# - title: 'Host'#}
{# value: '{{ .CommonLabels.monitor }}'#}
{# short: true#}
{# - title: 'Starts At'#}
{# value: '{{ .StartsAt.Format "2006-01-02 15:04:05" }}'#}
{# short: true#}
{# - title: 'Ends At'#}
{# value: '{{ .EndsAt.Format "2006-01-02 15:04:05" }}'#}
{# short: true#}
{# - title: 'Runbook'#}
{# value: '{{ .CommonAnnotations.runbook_url }}'#}
{# short: true#}
{# - title: 'Dashboard'#}
{# value: '{{ .CommonAnnotations.dashboard_url }}'#}
{# short: true#}
{# - title: 'Alerting Rule'#}
{# value: '{{ .CommonLabels.alertname }}'#}
{# short: true#}
{# - title: 'Alerting Rule Description'#}
{# value: '{{ .CommonLabels.alertname }}'#}
{# short: true#}

View File

@@ -60,17 +60,33 @@ services:
prometheus:
image: prom/prometheus:latest
container_name: prometheus
labels:
- {{ helpers.traefik_labels('prom', port='9090') | indent(6) }}
restart: unless-stopped
# Needed to make config files readable (not anymore, TODO: remove)
user: "{{ remote_uid }}"
command:
- --config.file=/etc/prometheus/prometheus.yml
- --storage.tsdb.retention.time=30d
- --web.external-url=https://prom.{{ domain }}/
volumes:
- ./prometheus_config:/etc/prometheus:ro
- {{ base_volume_path }}/monitoring/prometheus_configs:/etc/prometheus/extra:ro
- {{ base_volume_path }}/monitoring/prometheus:/prometheus
alertmanager:
image: prom/alertmanager:latest
container_name: alertmanager
labels:
- {{ helpers.traefik_labels('alert', port='9093') | indent(6) }}
restart: unless-stopped
command:
- --config.file=/etc/alertmanager/alertmanager.yml
- --web.external-url=https://alert.{{ domain }}/
volumes:
- ./alertmanager_config:/etc/alertmanager:ro
- {{ base_volume_path }}/monitoring/alertmanager:/alertmanager
node-exporter:
image: prom/node-exporter:latest
container_name: node-exporter
@@ -84,11 +100,6 @@ services:
image: gcr.io/cadvisor/cadvisor:latest
container_name: cadvisor
restart: unless-stopped
command:
- --docker_only=true
- --store_container_labels=false
- --whitelisted_container_labels=com.docker.compose.project,com.docker.compose.service
- --enable_metrics=cpu,cpuLoad,diskIO,memory,network,oom_event,process
volumes:
- /:/rootfs:ro
- /var/run:/var/run:rw

View File

@@ -3,7 +3,7 @@ apiVersion: 1
providers:
- name: "Grafana"
org_id: 1
folder: "Alpina"
folder: "Services"
type: "file"
options:
path: "/etc/grafana/provisioning/dashboards"

View File

@@ -1,27 +0,0 @@
from grafanalib.core import Template
# TODO: consider default params for common params like line width, show points, tooltip
PrometheusTemplate = Template(
name='datasource',
type='datasource',
label='Prometheus',
query='prometheus',
)
# TODO: this slightly less (clown emoji), normal Target gave me errors in grafana
class LokiTarget(object):
def __init__(self, loki_datasource, expr, legendFormat, refId):
self.loki_datasource = loki_datasource
self.expr = expr
self.legendFormat = legendFormat
self.refId = refId
def to_json_data(self):
return {
'datasource': self.loki_datasource,
'expr': self.expr,
'legendFormat': self.legendFormat,
'refId': self.refId,
'queryType': 'range',
}

View File

@@ -5,21 +5,28 @@ from grafanalib.core import (
)
from grafanalib.formatunits import BYTES_IEC, SECONDS, BYTES_SEC_IEC
from common import LokiTarget, PrometheusTemplate
prom_datasource='${datasource}'
prom_datasource='prometheus'
loki_datasource='loki'
# TODO: this is (clown emoji), normal Target gave me errors in grafana
class LokiTarget(object):
def to_json_data(self):
return {
'datasource': loki_datasource,
'expr': '{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`',
'legendFormat': '{{ container_name }}',
'refId': 'A',
'queryType': 'range',
}
dashboard = Dashboard(
title='Containers',
uid='containers',
description='Data for compose projects from default Prometheus datasource collected by Cadvisor',
tags=[
'linux',
'docker',
'example'
],
templating=Templating(list=[
PrometheusTemplate,
Template(
name='compose_project',
label='Compose Project',
@@ -37,6 +44,7 @@ dashboard = Dashboard(
includeAll=True,
multi=True,
refresh=REFRESH_ON_TIME_RANGE_CHANGE,
),
Template(
name='logs_query',
@@ -48,6 +56,7 @@ dashboard = Dashboard(
timezone='browser',
panels=[
TimeSeries(
id=1,
title='Container Memory Usage',
unit=BYTES_IEC,
gridPos=GridPos(h=8, w=12, x=0, y=0),
@@ -67,14 +76,13 @@ dashboard = Dashboard(
],
),
TimeSeries(
id=2,
title='Container CPU Usage',
unit=SECONDS,
gridPos=GridPos(h=8, w=12, x=12, y=0),
lineWidth=2,
fillOpacity=10,
showPoints='never',
tooltipMode='all',
tooltipSort='desc',
targets=[
Target(
datasource=prom_datasource,
@@ -85,6 +93,7 @@ dashboard = Dashboard(
],
),
TimeSeries(
id=3,
title='Container Network Traffic',
unit=BYTES_SEC_IEC,
gridPos=GridPos(h=8, w=12, x=0, y=8),
@@ -109,6 +118,7 @@ dashboard = Dashboard(
],
),
Logs(
id=4,
title='',
gridPos=GridPos(h=8, w=12, x=12, y=8),
showLabels=True,
@@ -117,12 +127,13 @@ dashboard = Dashboard(
prettifyLogMessage=True,
dedupStrategy='numbers',
targets=[
LokiTarget(
loki_datasource=loki_datasource,
expr='{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`',
legendFormat='{{ container_name }}',
refId='A',
),
LokiTarget(),
# Target(
# datasource=loki_datasource,
# expr='{compose_project=~"$compose_project", container_name=~"$container_name"} |= `$logs_query`',
# legendFormat='{{ container_name }}',
# refId='A',
# ),
],
),
],

View File

@@ -0,0 +1,51 @@
from grafanalib.core import (
Dashboard, TimeSeries, GaugePanel,
Target, GridPos,
OPS_FORMAT
)
dashboard = Dashboard(
title="Python generated example dashboard",
description="Example dashboard using the Random Walk and default Prometheus datasource",
tags=[
'example'
],
timezone="browser",
panels=[
TimeSeries(
title="Random Walk",
dataSource='default',
targets=[
Target(
datasource='grafana',
expr='example',
),
],
gridPos=GridPos(h=8, w=16, x=0, y=0),
),
GaugePanel(
title="Random Walk",
dataSource='default',
targets=[
Target(
datasource='grafana',
expr='example',
),
],
gridPos=GridPos(h=4, w=4, x=17, y=0),
),
TimeSeries(
title="Prometheus http requests",
dataSource='prometheus',
targets=[
Target(
expr='rate(prometheus_http_requests_total[5m])',
legendFormat="{{ handler }}",
refId='A',
),
],
unit=OPS_FORMAT,
gridPos=GridPos(h=8, w=16, x=0, y=10),
),
],
).auto_panel_ids()

View File

@@ -1,139 +0,0 @@
from grafanalib.core import Dashboard, Templating, Template, TimeSeries, PERCENT_UNIT_FORMAT, GridPos, Target
from grafanalib.formatunits import BYTES_IEC
from common import PrometheusTemplate
from node_consts import CPU_BASIC_COLORS, MEMORY_BASIC_COLORS
dashboard = Dashboard(
title='Node Exporter',
uid='node',
description='Node Exporter (not quite full)',
tags=[
'linux',
],
timezone='browser',
templating=Templating(list=[
# Datasource
PrometheusTemplate,
# Job
Template(
name='job',
label='Job',
dataSource='${datasource}',
query='label_values(node_uname_info, job)',
),
# Instance
Template(
name='instance',
label='Instance',
dataSource='${datasource}',
query='label_values(node_uname_info{job="$job"}, instance)',
),
]),
panels=[
# CPU Basic
TimeSeries(
title='CPU Basic',
description='Basic CPU usage info',
unit=PERCENT_UNIT_FORMAT,
gridPos=GridPos(h=8, w=12, x=0, y=0),
lineWidth=1,
fillOpacity=30,
showPoints='never',
stacking={'mode': 'percent', 'group': 'A'},
tooltipMode='all',
tooltipSort='desc',
targets=[
Target(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="system"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy System',
refId='A',
),
Target(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="user"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy User',
refId='B',
),
Target(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="iowait"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy Iowait',
refId='C',
),
Target(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode=~".*irq"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy IRQs',
refId='D',
),
Target(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode!="idle",mode!="user",mode!="system",mode!="iowait",mode!="irq",mode!="softirq"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Busy Other',
refId='E',
),
Target(
datasource='${datasource}',
expr='sum(irate(node_cpu_seconds_total{instance="$instance",job="$job", mode="idle"}[$__rate_interval])) / scalar(count(count(node_cpu_seconds_total{instance="$instance",job="$job"}) by (cpu)))',
legendFormat='Idle',
refId='F',
),
],
# Extra JSON for the colors
extraJson=CPU_BASIC_COLORS,
),
# Memory Basic
TimeSeries(
title='Memory Basic',
description='Basic memory usage',
unit=BYTES_IEC,
gridPos=GridPos(h=8, w=12, x=12, y=0),
lineWidth=1,
fillOpacity=30,
showPoints='never',
stacking={'mode': 'normal', 'group': 'A'},
tooltipMode='all',
tooltipSort='desc',
targets=[
Target(
datasource='${datasource}',
expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"}',
format='time_series',
legendFormat='RAM Total',
refId='A',
),
Target(
datasource='${datasource}',
expr='node_memory_MemTotal_bytes{instance="$instance",job="$job"} - node_memory_MemFree_bytes{instance="$instance",job="$job"} - (node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"})',
format='time_series',
legendFormat='RAM Used',
refId='B',
),
Target(
datasource='${datasource}',
expr='node_memory_Cached_bytes{instance="$instance",job="$job"} + node_memory_Buffers_bytes{instance="$instance",job="$job"} + node_memory_SReclaimable_bytes{instance="$instance",job="$job"}',
legendFormat='RAM Cache + Buffer',
refId='C',
),
Target(
datasource='${datasource}',
expr='node_memory_MemFree_bytes{instance="$instance",job="$job"}',
legendFormat='RAM Free',
refId='D',
),
Target(
datasource='${datasource}',
expr='(node_memory_SwapTotal_bytes{instance="$instance",job="$job"} - node_memory_SwapFree_bytes{instance="$instance",job="$job"})',
legendFormat='SWAP Used',
refId='E',
),
],
# Extra JSON for the colors
extraJson=MEMORY_BASIC_COLORS,
),
# TODO: Network Basic
# TODO: Disk Basic
],
).auto_panel_ids()

View File

@@ -1,487 +0,0 @@
# TODO: Question life decisions (I'm not sure if this is good)
CPU_BASIC_COLORS = {
"fieldConfig": {
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Busy Iowait"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#890F02",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Idle"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#052B51",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Busy Iowait"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#890F02",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Idle"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#7EB26D",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Busy System"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#EAB839",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Busy User"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#0A437C",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Busy Other"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#6D1F62",
"mode": "fixed"
}
}
]
}
]
},
}
MEMORY_BASIC_COLORS = {
"fieldConfig": {
"overrides": [
{
"matcher": {
"id": "byName",
"options": "Apps"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#629E51",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Buffers"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#614D93",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Cache"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#6D1F62",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Cached"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#511749",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Committed"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#508642",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Free"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#0A437C",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Hardware Corrupted - Amount of RAM that the kernel identified as corrupted / not working"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#CFFAFF",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Inactive"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#584477",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "PageTables"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#0A50A1",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Page_Tables"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#0A50A1",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "RAM_Free"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#E0F9D7",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "SWAP Used"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#BF1B00",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Slab"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#806EB7",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Slab_Cache"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#E0752D",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Swap"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#BF1B00",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Swap Used"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#BF1B00",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Swap_Cache"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#C15C17",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Swap_Free"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#2F575E",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Unused"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#EAB839",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "RAM Total"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#E0F9D7",
"mode": "fixed"
}
},
{
"id": "custom.fillOpacity",
"value": 0
},
{
"id": "custom.stacking",
"value": {
"group": False,
"mode": "normal"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "RAM Cache + Buffer"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#052B51",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "RAM Free"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#7EB26D",
"mode": "fixed"
}
}
]
},
{
"matcher": {
"id": "byName",
"options": "Available"
},
"properties": [
{
"id": "color",
"value": {
"fixedColor": "#DEDAF7",
"mode": "fixed"
}
},
{
"id": "custom.fillOpacity",
"value": 0
},
{
"id": "custom.stacking",
"value": {
"group": False,
"mode": "normal"
}
}
]
}
]
}
}

View File

@@ -15,6 +15,18 @@ datasources:
url: http://prometheus:9090
editable: false
- name: Alertmanager
type: alertmanager
access: proxy
uid: alertmanager
url: http://alertmanager:9093
jsonData:
# Valid options for implementation include mimir, cortex and prometheus
implementation: prometheus
# Whether Grafana should send alert instances to this Alertmanager
handleGrafanaManagedAlerts: true
editable: false
- name: InfluxDB
type: influxdb
access: proxy

View File

@@ -31,4 +31,4 @@ name_attribute_path = name
# Optionally map user groups to Grafana roles
allow_assign_grafana_admin = true
role_attribute_path = contains(groups[*], 'admins') && 'GrafanaAdmin' || 'Viewer'
role_attribute_path = contains(groups[*], 'Grafana Admins') && 'GrafanaAdmin' || 'Viewer'

View File

@@ -17,6 +17,13 @@ common:
schema_config:
configs:
- from: 2020-10-24
store: boltdb-shipper
object_store: filesystem
schema: v12
index:
prefix: index_
period: 24h
- from: 2024-10-18
index:
period: 24h
@@ -26,5 +33,5 @@ schema_config:
store: tsdb
# TODO: Figure this out
# ruler:
# alertmanager_url: http://localhost:9093
ruler:
alertmanager_url: http://localhost:9093

View File

@@ -0,0 +1,23 @@
groups:
- name: qbit-low-traffic
interval: 1m
rules:
- alert: QbitLowTraffic
expr: |
rate(container_network_transmit_bytes_total{name=~"gluetun"}[1m]) < 1024
for: 2m
labels:
severity: warning
annotations:
title: 'Low traffic on qBit'
description: |
The traffic on qBittorrent is lower than 1KiB/s for 2 minutes.
Last value was x bytes/s.
[Grafana Dashboard](https://grafana.{{ domain }}/d/containers?orgId=1)
[View in Grafana](https://grafana.{{ domain }}/d/containers?orgId=1&viewPanel=3)
__dashboard__uid: 'containers'
__orgId__: 1
__panelId__: 3

View File

@@ -0,0 +1,20 @@
groups:
- name: demo-service-alerts
rules:
- alert: DemoServiceHighErrorRate
expr: |
(
sum without(status, instance) (
rate(demo_api_request_duration_seconds_count{status=~"5..",job="demo"}[1m])
)
/
sum without(status, instance) (
rate(demo_api_request_duration_seconds_count{job="demo"}[1m])
) * 100 > 0.5
)
for: 1m
labels:
severity: critical
annotations:
title: 'High 5xx rate for {{'{{ $labels.method }}'}} on {{'{{ $labels.path }}'}}'
description: 'The 5xx error rate for path {{'{{ $labels.path }}'}} with method {{'{{ $labels.method }}'}} in {{'{{ $labels.job }}'}} is {{'{{ printf "%.2f" $value }}'}}%.'

View File

@@ -5,6 +5,11 @@ global:
external_labels:
monitor: "{{ ansible_host }}"
alerting:
alertmanagers:
- static_configs:
- targets: ["alertmanager:9093"]
scrape_configs:
- job_name: "prometheus"
static_configs:
@@ -30,7 +35,15 @@ scrape_configs:
static_configs:
- targets: ["promtail:9080"]
- job_name: 'demo'
static_configs:
- targets:
- 'demo.promlabs.com:10000'
- 'demo.promlabs.com:10001'
- 'demo.promlabs.com:10002'
rule_files:
- "/etc/prometheus/container.alerts.yml"
- "/etc/prometheus/extra/rules/*.yml"
- "/etc/prometheus/extra/rules/*.json"

View File

@@ -12,7 +12,7 @@ networks:
services:
traefik:
image: traefik:v3.2
image: traefik:v3.0
container_name: traefik
restart: unless-stopped
env_file:
@@ -23,6 +23,7 @@ services:
- ./rules:/rules:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- {{ base_volume_path }}/traefik/rules:/rules/extra:ro
- {{ base_volume_path }}/traefik/logs:/logs
- {{ base_volume_path }}/traefik/acme:/acme
# This is mostly just so that the traefik network gets created

View File

@@ -2,8 +2,11 @@ api:
insecure: true
log:
filePath: /logs/traefik.log
level: INFO
accessLog:
filePath: /logs/access.log
bufferingSize: 100
entryPoints:
web:

View File

@@ -5,11 +5,10 @@
post_tasks:
- name: Docker prune objects
docker_prune:
containers: true
# Keep images for building grafana
images: true
containers: yes
images: yes
images_filters:
until: "720h"
dangling: false
networks: true
volumes: true
builder_cache: false
builder_cache: true