commit ebab5d44f0147a69daa53b6fc683802de102f8c8 Author: xbazzi Date: Thu Jul 10 21:24:28 2025 -0600 Initial commit :rocket: :monkey: diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..b1e5280 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "ansible.python.interpreterPath": "/run/current-system/sw/bin/python", + "ansible.validation.lint.path": "", + "ansible.validation.lint.enabled": false +} \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..7f6c6df --- /dev/null +++ b/README.md @@ -0,0 +1,150 @@ +# Ansible Starter Kit + +Easy way for my homies to start up an ansible project for their homelab or local machine. + +# Prerequisites + +The ideal setup for a homelab is to have: + +- The same username/password in all vms/hosts so you don't have to type a different password for each host +- SSH key auth on each host so you don't have to type a password at all + +# Ansible basics + +I'll explain the basic units of an ansible project. For this example we're going to assume you want to mount +an NFS share in all your hosts. + +From bottom to top we have: + +## Tasks + +A task is the lowest unit in an ansible project. + +A task could be: + +- Creating a directory +- Installing an os package (curl, docker, nfs-common, etc) +- Starting a docker container + +### Examples + +```yml +- name: Add SSH key for remote user + ansible.posix.authorized_key: + user: javi + state: present + key: "{{ lookup('file', '/home/javi/.ssh/homelab_keypair_ed25519.pub') }}" +``` + +```yml +- name: Ensure NFS client is installed + ansible.builtin.package: + name: nfs-common + state: present + become: true +``` + +## Role + +A role is a self contained, re-usable unit that will give a meaningful result. Think of it like a class in a program. + +Roles have a list of tasks, as well as variables and files associated with those tasks. All contained in a folder. + +A role can look like: + +``` +roles/ + portainer/ + ├── defaults/ + │ └── main.yml # Default variables + ├── files/ + │ └── ... # Static files to be copied (e.g., configs, scripts) + ├── handlers/ + │ └── main.yml # Handlers (e.g., service restart) + ├── meta/ + │ └── main.yml # Role metadata (e.g., dependencies) + ├── tasks/ + │ └── main.yml # Main list of tasks to execute + ├── templates/ + │ └── ... # Jinja2 templates + ├── vars/ + │ └── main.yml # Non-overridable variables + └── README.md # Optional: Document what this role does + sshkey/ + ├── defaults/ + │ └── main.yml # Default variables + ├── files/ + │ └── ... # Static files to be copied (e.g., configs, scripts) + ├── handlers/ + │ └── main.yml # Handlers (e.g., service restart) + ├── meta/ + │ └── main.yml # Role metadata (e.g., dependencies) + ├── tasks/ + │ └── main.yml # Main list of tasks to execute + ├── templates/ + │ └── ... # Jinja2 templates + ├── vars/ + │ └── main.yml # Non-overridable variables + └── README.md # Optional: Document what this role does + +``` + +However, only the `defaults` and `tasks` subfolders and subsequent `main.yml` are required. Everything else is optional. + +A role can be: + +- Mounting a share +- Deploying a docker container with all its requirements like a database and mapped volumes + +# Playbook + +A playbook combines roles and task to create a final state in a host or group of hosts. + +A playbook can be: + +- Make sure all your hosts have sshkey auth, portainer, docker and an nfs share mounted. +- Deploy a suite of apps to a host or multiple hosts + +## Example + +```yml +--- +- name: Deploy apps to apps-1 node + hosts: apps + become: true + roles: + - role: apps/kan + vars: + port: 7070 + - role: apps/memos + vars: + port: 7071 + - role: apps/vaultwarden + vars: + port: 7072 + - role: apps/erugo + vars: + port: 7073 + - role: apps/tianji + vars: + port: 7074 + - role: apps/stirling-pdf o + vars: + port: 7075 + - role: apps/dumbware-todo + vars: + port: 7076 + pin: 8989 + - role: apps/dumbware-drop + vars: + port: 7077 + pin: "8989" +``` + +# Setup + +1. Clone this repo `git clone git@gitgud.foo:javif89/ansible-starter-kit.git [your project name]` +2. Run `setup.sh` to set up the vault password and become password +3. Set up your hosts in `hosts.yml` +4. Start making your roles and playbooks + diff --git a/ansible.cfg b/ansible.cfg new file mode 100755 index 0000000..0b0a949 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,5 @@ +[defaults] +remote_user = ansible +inventory = inventory/hosts.yml +roles_path = ./roles +vault_password_file = ~/.ansible-vault-key \ No newline at end of file diff --git a/inventory/group_vars/all.yml b/inventory/group_vars/all.yml new file mode 100644 index 0000000..8f7e471 --- /dev/null +++ b/inventory/group_vars/all.yml @@ -0,0 +1,96 @@ +$ANSIBLE_VAULT;1.1;AES256 +38333861353432643165366435353534316564346533666439376631373562366530386636623333 +6130343936376163336432366437623062643161636466640a383232343564636234376330323138 +37393731643030313230613363343639363737393364346231643835613532636530363964383933 +3834343936353965390a313439663463626461376461636462316237366430356437346164393034 +38633331646465666165343365616366623636613264663062613238656466326537373135393234 +38623034306461386132373262666532633562376532303762356663343930623464376661366238 +33373638386366643030366632636138653032633436373932613261656331633663643839306633 +39613136306130626635393333366136646665393932383563373739323730396633363334643639 +36323337336563616165626463306637653865643931613731636233313061616130623662393465 +63366131643135623337313735386566616663343263353561316132343138653761303436386433 +64653736616439623331373865383439343637343737313466363265333033663836633635623732 +30643137633738356665326138363734623766613462323831623931633163373933353661653434 +35343466363132663765623739336136656332333932303332363164366630376638353166316636 +31653133386461323532666661363865383430653230636233616238356431623462316133633239 +34316561333530353166626632653566333966326663383635323165356231386232346263363666 +61366430353239353732663437353165353562313438383063393935306534646165336232333861 +32633138323036323334343866333963353965303536373930336164323565333862353032336566 +39613263303966343337393165633866323233653132626264316238313131663961613037643865 +35376138643934383435636534343231303933396138643231613336613536333961333562343963 +31376438366438346231656364303535336465623237336263383761363630623632356335326231 +61366132613062353833613162623634383134666334366435646238343462396535336534316264 +35326461653331636462366536653430646438626562373635613464313031666434333732616239 +61383536623762653463363031343332393166646264663031656531363761666364653866326230 +33363264663366653930616133363539633463306434653732383435613430626439313935633162 +62323366653639343063353662383265626538646361383030396533366635353830383365636435 +36636433393635633237316131616630383464313535303137376131646566383366333935303830 +34663630613438613836393333626463623466393831303833626666636338356533616436636331 +32393665346538353539633634303161616662366433386139343034333963336630353634346232 +63333561326532336533326333613961643134306264373730346137653962663930326261333763 +32353264616333313263343964663465636235333438343334393963653530663130366133353031 +64626537663362316239643436646236636361656365373232663931613634333465643137313964 +31323464303432346337616530333135346166623561623531313561633533643161363930323265 +32363538323134383434316332383064663437653161316162636339663036316139633636646131 +34343939383935623333613835613431346532323530366331613065666566323731663336623137 +36653165623235343832653438393836353630663063613337346364393439303738656564626432 +64613863376463343433303933656163666532326430383863383636386331643265623963653730 +31666430303666373030343831383436376666346236646231346565643564656339326231383337 +32386239646634643261393531636666666637386633396136653661373835636237323031333434 +31633237633566313131306261613834356139306436393862333533336534383662663837626464 +63653831373235373638303864323531623965333662386239396637636562373632393365663062 +61333934613865626639393236303562643165316466386461636239373336623965333531303335 +63393030326230303537383431663634616133353734353835636565326261386165633730386665 +61363736653762326634316634663530306163366165303464373833633363613338383330353062 +62313331343830323063663363386566373964356566313638653331336366343236356565656331 +61326466653362326337626532353637636535373762383034653464313961353430666132376163 +63323636393331376565343037613631323130646466656531663335373461653063353166346336 +32613564373634663863343036623038656462643532653539396538646532383161333535313164 +66306532393137393736316330383466646265633539326437643039643037393735306136383337 +35353465643762313762653938376331356232356131336131616531303162383737623736363130 +38336634653564363564323964356564313665396461623836633533633534653961323632653766 +39383236663664643666333730623731663438326539346135326564326666396463323661393132 +35343862653264323564343730313938663664663035303332333163633137323661323431343138 +66336666386635643662323431626636636231666561396438336234366331616138323636336664 +36396133323937306463386261363766623366663965623361313264663861626161366166366237 +36393962613135326339623261333635326138336466306132333230643536376334386166346364 +61643231363737656131363935626433373164363161646365633536383563343936653333333832 +33383565346366616365363030646432363633663537316335376333313236616637633066333664 +63313039656664663664393633353466376264356161343532353838373366393835653134353438 +61396164636566313535656533396332316565336664363034353235643635616564663563633338 +32313662666566336437366666376630336466373831343431636662323431393061326139326537 +35303362366338383230643734333533323535303534303637623136613634333436656131376635 +30623736356634616366323563636535633530623435613634636662636436303337373762393734 +63363637323733306532343239303030626135663366333763623933613034333339323636653338 +37646665343632363466383762623763363238633265333166396165633461666662303332373164 +30356231356132323037396231613939353463656333613735376562323837323430623665373364 +63656238356161303462366130636236633238623861373830323237376563353934356239656539 +62346638643263383636666437646466393361366465366362336634663636306230373466366266 +38353133383937336336633239373739663731666162643037623630323739363464623763353163 +36653733663138386432323465383537383137623333333933366232323934623730613139656536 +39623564316135373830316238396664323663663137653130326163356566653630613662613638 +32626261383533393833633539633330383537323534346134366333346438323232336337623861 +35306632356165313063373738303130386436396532616365313633656637373362313639626338 +36616665386663303636323264623839303562303064306139333263343839323436333930393136 +36663531643363643537636437646266643032616437656239666539653163343935633366646534 +36623935356565653831366462653830393465353065386130303065626365663235366530303431 +63353635653163303138383163663931356139626264383331346532663961316261393832626430 +66303435393739303461363731363733646534363766626462333761623537343734343833393634 +31356537653630363563313539356535663032613538303264633864396365613366386366656336 +37643666636436626162636234333938303266393162393933393038366437613165366630386438 +37313634656632653238383134653039323739643366343631343530386237336139313164393133 +64653638363662333461323365333861396266653238306530613064316362663131633461366161 +32633835393832646530623033346238343761393036353137626463613139393839616432626263 +35663232323734333631613139666366666436653566653064393666356165336439303937326637 +36633438623933323964303065313332373762346463343263386439646533306332363136386434 +34363236383733323232306264613137383831633534666337356137316433656238363864646138 +39303661383963313833323330656666373536303931383464343036663035616630343063383139 +63653263323533303933653138666138336530633162653533336466353235366333643835313365 +38303462623430356339323731646238636663393838653466323030653866646435323636343337 +37316336383234323336383061666235663539616631663936613430313138643061393439383636 +31656535366361326566666264656465633337643365393765303732633238653231623735313638 +36303537393038306165393365343334373333393933356133313264396236623936343763366330 +37373262393230326132393237633335353964346434616137636662343635306632373532663830 +66333039613330306231363364323861363964313336666165616635363166623435636366343364 +64356364373832366435656539613238646538623035346434346364386434623461653763656135 +646161643166613037303031663863666465 diff --git a/inventory/group_vars/cluster_prep.yml b/inventory/group_vars/cluster_prep.yml new file mode 100644 index 0000000..96d1b46 --- /dev/null +++ b/inventory/group_vars/cluster_prep.yml @@ -0,0 +1,2 @@ +iscsi_target_ip: nas.lan.xbazzi.com # TrueNAS IP +iscsi_target_iqn: iqn.2005-10.org.freenas.ctl:pve-iscsi \ No newline at end of file diff --git a/inventory/host_vars/pve1.yml b/inventory/host_vars/pve1.yml new file mode 100644 index 0000000..57d1b8d --- /dev/null +++ b/inventory/host_vars/pve1.yml @@ -0,0 +1,11 @@ +$ANSIBLE_VAULT;1.1;AES256 +61636264373765333930663036663164363332363765353836326361383438303065623938353338 +3861383264346132613466666363623562383437643464640a343830356164323732313631666532 +61646636633062333539393266366537613037646137376463343638356562383538376534376533 +6361373233623565310a343466666233623138316439616239376266343932616366636232633735 +32623335633732653637336163666265383066303565386261353539656333656337393530323639 +65313233376434343761653264626563653031623236616362396262643463656535613237383435 +35343439643330343362333362396338646162313063623334326264316235636333376434626535 +34353332653138653765323936346536323038366238323932393335363762623237653962616664 +37653963633936653866656537663435333731343937616237353734383537316361633836363666 +3064366264653335663331383332656638323335633731353531 diff --git a/inventory/host_vars/pve2.yml b/inventory/host_vars/pve2.yml new file mode 100644 index 0000000..4fe1c80 --- /dev/null +++ b/inventory/host_vars/pve2.yml @@ -0,0 +1,11 @@ +$ANSIBLE_VAULT;1.1;AES256 +64366635666462636332636564316263363561326366646531626365633431373934306334373432 +6635396564336238383563613231373339616164326630330a333031643734653738666537386337 +34366264356237613534356330393130376262383361636638316562636463633239643264343564 +6236663764623439360a333165363430373561336334663739353738343364656432363939383234 +32343363373164303130376133633265656564363532663336326263636464623339353966366430 +33313339343534386664663361616438346136643361346264393563633630333562346338366530 +33666261633236363833343931353535366565363733326661626338363030383365383332373837 +62623537396666363265346333366661396139363732666261343132333237636335363338303033 +61376630333263313166356334383931326665383631363961633066396539393963313433373763 +6362323162346164633639623064376265313764353032663434 diff --git a/inventory/host_vars/pve3.yml b/inventory/host_vars/pve3.yml new file mode 100644 index 0000000..39e2b04 --- /dev/null +++ b/inventory/host_vars/pve3.yml @@ -0,0 +1,11 @@ +$ANSIBLE_VAULT;1.1;AES256 +34386433623163393561646137313364663363363138336164363561666533323565653464373961 +3061643566303432623963636530303530306433343666350a663933663935643635366561336630 +37653433666364366431363032633738646436626336323037343730376662363266333038613064 +6131363532623766320a656330613439363562653263666138336639663965303236356139336630 +33663961393438316333333030663236623934666632346566363739316262346538626434393066 +37663563363038393137353336393233316630323734346439663836313065386536326465626632 +30636165626132376138326331663965623965353561616536376266313430373839353230653332 +30653866323231333335313261636336333161363334663734633534343561623764393531386239 +62343136336332666237353863623330336564313130336239323639303766303361616664623331 +3638656138333862366138366539666232376164666239323132 diff --git a/inventory/hosts.yml b/inventory/hosts.yml new file mode 100644 index 0000000..f271aea --- /dev/null +++ b/inventory/hosts.yml @@ -0,0 +1,36 @@ +$ANSIBLE_VAULT;1.1;AES256 +64363164666338376439386465623133383736636361353661303464666164616232366431626333 +3437666365663839343866613537323366333564646234350a363434303639333535643039313039 +61306663306134666139303061316163323033353366386233643039613365386536333336663864 +6463316237376364660a313639623233326634366635313962373830393165343130363337353135 +39616535373561353064373139356362663739363138326237393630326535353961623733323766 +61366665346365626637626531666434336366643061663363323237613065613638353731663834 +63386361646161303339653433316232323135323561363161643833373865366162316465383930 +66346466346433643264633162326665613731383036616437643537383833616262646331356638 +61336331636334343465316366323861326365386136303565363564343438613866326162613930 +35643230316237383865616164653038306339306130316534303230383966353934356366633961 +64623761646138633931356230633961353361376239656364326338646436663831323631346531 +37633261646635633665663037663733313332396666636435383166343262663834383633646335 +39383137383436643865383065613533636132326331303731306465636465613136646462643336 +63386635346534343961626339393330633638633263326131313065353164353833333833326164 +36613462393334333166613765343938393132363165316532396237636137323262616631393930 +32323437316430306532653937613937663963613738323231366565313838656434656532623062 +36633561376536373036323330623539383763306561383136633434623062376266333361306266 +35333431626230316630626663376462653838656330376266396664323238323234306362343633 +66333463646665306561313033313464633231316366633031303863636264333363366666376163 +31663464643331666461353331663936656539616235353530366238326333663966386639353334 +65626330613330303930643835393365383739313831333235633261356331346161333765323335 +39393534393166383161376530623739336635303363393633653666633363656334653961643964 +65373237333338313162626636366264356663616261633734613330626562666538313165663562 +33393336613963353330336238656433613363306535323930623037663463613136643735613337 +63396334626334373737663461386663653865626136353761666531623563643465356366666266 +32393536643638303862353234366233323566623862316636323866323336366434376463306661 +31313133313639313635333335643836373437306535383734373031306539643738326238373366 +31393734383738636333643437393238336365376332643861636435303036653065613164363031 +63373632343634303236653036636134306237663462633861366630633034333832646362303236 +32636166366430343063316333636134616236373866373865316261626239376639366537306461 +33636265313262366264306331313039363734633766323932363465353032633764373332326466 +31363034326161643062343230333435343435623336653163323365363233643231306538373939 +35643338396661356332343431383232376238626434613462306437653537343530643030333735 +38393532303533323430373066343938396533656564663731393738363863663864356462663565 +656438663662326136393134643136663737 diff --git a/playbooks/apply-firewalld.yml b/playbooks/apply-firewalld.yml new file mode 100644 index 0000000..0cac4bb --- /dev/null +++ b/playbooks/apply-firewalld.yml @@ -0,0 +1,5 @@ +- name: Apply firewalld config + hosts: staging-vm + become: yes + roles: + - role: provision/alma/firewall \ No newline at end of file diff --git a/playbooks/backup-pve.yml b/playbooks/backup-pve.yml new file mode 100644 index 0000000..73866bf --- /dev/null +++ b/playbooks/backup-pve.yml @@ -0,0 +1,6 @@ +--- +- name: Backup /etc/pve from all Proxmox nodes + hosts: pve-nodes + become: yes + roles: + - role: utility/pve_backup diff --git a/playbooks/backups/pve1.tar.gz b/playbooks/backups/pve1.tar.gz new file mode 100644 index 0000000..ab4d6f5 Binary files /dev/null and b/playbooks/backups/pve1.tar.gz differ diff --git a/playbooks/backups/pve2.tar.gz b/playbooks/backups/pve2.tar.gz new file mode 100644 index 0000000..b1c2430 Binary files /dev/null and b/playbooks/backups/pve2.tar.gz differ diff --git a/playbooks/backups/pve3.tar.gz b/playbooks/backups/pve3.tar.gz new file mode 100644 index 0000000..5aaac1f Binary files /dev/null and b/playbooks/backups/pve3.tar.gz differ diff --git a/playbooks/configure-pve.yml b/playbooks/configure-pve.yml new file mode 100644 index 0000000..c2c531a --- /dev/null +++ b/playbooks/configure-pve.yml @@ -0,0 +1,6 @@ +--- +- name: Configure networking for a new node + hosts: pve-nodes + become: true + roles: + - role: pve/setup_networking \ No newline at end of file diff --git a/playbooks/deploy-dbgate.yml b/playbooks/deploy-dbgate.yml new file mode 100644 index 0000000..6a70f57 --- /dev/null +++ b/playbooks/deploy-dbgate.yml @@ -0,0 +1,15 @@ +--- +- name: Deploy DBGate container + hosts: prod1 + become: true + roles: + - role: apps/dbgate + vars: + directory: "pg-dev" + container_name: "postgres-dev" + port: 7000 + - role: services/postgres + vars: + directory: "pg-beta" + container_name: "postgres-beta" + port: 7001 \ No newline at end of file diff --git a/playbooks/deploy-postgres.yml b/playbooks/deploy-postgres.yml new file mode 100644 index 0000000..2ed19f5 --- /dev/null +++ b/playbooks/deploy-postgres.yml @@ -0,0 +1,16 @@ +--- +- name: Deploy PostgreSQL container + hosts: prod1 + become: true + roles: + - role: services/postgres + - role: services/postgres + vars: + directory: "pg-dev" + container_name: "postgres-dev" + port: 7000 + - role: services/postgres + vars: + directory: "pg-beta" + container_name: "postgres-beta" + port: 7001 \ No newline at end of file diff --git a/playbooks/example.yml b/playbooks/example.yml new file mode 100644 index 0000000..d0cce9d --- /dev/null +++ b/playbooks/example.yml @@ -0,0 +1,6 @@ +--- +- name: Example playbook + hosts: vms + become: true + roles: + - role: server/sshkey \ No newline at end of file diff --git a/playbooks/prep-pve-for-cluster.yml b/playbooks/prep-pve-for-cluster.yml new file mode 100644 index 0000000..b4d3bc5 --- /dev/null +++ b/playbooks/prep-pve-for-cluster.yml @@ -0,0 +1,5 @@ +- name: Prep all Proxmox nodes for clustering + hosts: pve-nodes + become: yes + roles: + - role: utility/cluster_prep diff --git a/playbooks/provision-alma.yml b/playbooks/provision-alma.yml new file mode 100644 index 0000000..b4bbcff --- /dev/null +++ b/playbooks/provision-alma.yml @@ -0,0 +1,13 @@ +--- +- name: Provision AlmaLinux 9 VM + hosts: staging-vm + become: yes + roles: + - role: server/users + - role: server/sshkey + # - role: server/network + # - role: server/firewall + # - role: provision/alma/common + # - role: provision/alma/nfs + # - role: docker/install + # - role: server/reboot \ No newline at end of file diff --git a/playbooks/sysprep-alma.yml b/playbooks/sysprep-alma.yml new file mode 100644 index 0000000..4802778 --- /dev/null +++ b/playbooks/sysprep-alma.yml @@ -0,0 +1,9 @@ +- name: Sysprep Alma Linux machine + hosts: staging-vm + become: yes + roles: + - role: server/users + - role: server/sysprep + - role: server/sshkey + - role: server/network + - role: server/reboot \ No newline at end of file diff --git a/roles/app/database/defaults/main.yml b/roles/app/database/defaults/main.yml new file mode 100755 index 0000000..e69de29 diff --git a/roles/app/database/tasks/main.yml b/roles/app/database/tasks/main.yml new file mode 100755 index 0000000..1fb4cf8 --- /dev/null +++ b/roles/app/database/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: Create app database + ansible.builtin.include_role: + name: postgres/database + vars: + database: "{{ app_name }}" + +- name: Create app db user + ansible.builtin.include_role: + name: postgres/user + vars: + user: "{{ app_name }}" + password: "password" + +- name: Give app user full priviledges on DB + ansible.builtin.include_role: + name: postgres/priviledges + vars: + database: "{{ app_name }}" + user: "{{ app_name }}" \ No newline at end of file diff --git a/roles/apps/dbgate/defaults/main.yml b/roles/apps/dbgate/defaults/main.yml new file mode 100644 index 0000000..8676a24 --- /dev/null +++ b/roles/apps/dbgate/defaults/main.yml @@ -0,0 +1,4 @@ +docker_dir: "/data/docker/dbgate" +port: "6001" +app_port: "3000" +container_name: "postgres" \ No newline at end of file diff --git a/roles/apps/dbgate/tasks/main.yml b/roles/apps/dbgate/tasks/main.yml new file mode 100644 index 0000000..706d28a --- /dev/null +++ b/roles/apps/dbgate/tasks/main.yml @@ -0,0 +1,19 @@ +- name: Create docker folder + ansible.builtin.file: + dest: "{{ docker_dir }}" + state: directory + mode: '0770' + +- name: Put up the postgres container + community.docker.docker_container: + name: "{{container_name}}" + image: postgres:17.4 + restart_policy: always + state: started + pull: true + ports: + - "{{ port }}:{{ app_port }}" + env: + CONNECTIONS: postgres_con + volumes: + - "dbgate-data:/root/.dbgate" \ No newline at end of file diff --git a/roles/docker/install/defaults/main.yml b/roles/docker/install/defaults/main.yml new file mode 100755 index 0000000..e69de29 diff --git a/roles/docker/install/tasks/main.yml b/roles/docker/install/tasks/main.yml new file mode 100755 index 0000000..c4195ec --- /dev/null +++ b/roles/docker/install/tasks/main.yml @@ -0,0 +1,40 @@ +--- +- name: Install plugins-core to manage DNF repos + ansible.builtin.dnf: + name: + - dnf-plugins-core + state: present +# - name: Install plugins-core to manage DNF repos +# ansible.builtin.command: dnf -y install dnf-plugins-core + +- name: Add Docker repo + ansible.builtin.command: dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo + register: docker_repo + +- name: Verify Docker repo added + ansible.builtin.debug: + var: docker_repo.stdout + +- name: Install Docker Engine + ansible.builtin.dnf: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + state: present + +- name: Enable and start Docker Engine + ansible.builtin.systemd_service: + name: docker + state: started + enabled: true + +- name: Verify with Hello World + ansible.builtin.command: docker run hello-world + register: docker_hello + +- name: Test + ansible.builtin.debug: + var: docker_hello.stdout_lines diff --git a/roles/docker/install/tasks/main2.yml b/roles/docker/install/tasks/main2.yml new file mode 100644 index 0000000..86b2c7c --- /dev/null +++ b/roles/docker/install/tasks/main2.yml @@ -0,0 +1,45 @@ +--- +- name: Update apt cache + ansible.builtin.apt: + update_cache: yes + +- name: Install prerequisite packages + ansible.builtin.apt: + name: + - ca-certificates + - curl + state: present + +- name: Create apt keyrings directory + ansible.builtin.file: + path: /etc/apt/keyrings + state: directory + mode: '0755' + +- name: Download Docker GPG key + ansible.builtin.get_url: + url: "https://download.docker.com/linux/ubuntu/gpg" + dest: /etc/apt/keyrings/docker.asc + mode: '0644' + +- name: Add Docker apt repository + ansible.builtin.apt_repository: + repo: "deb [arch={{ docker_arch }} signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable" + filename: docker + state: present + vars: + docker_arch: "{{ ansible_architecture | regex_replace('x86_64', 'amd64') }}" + +- name: Update apt cache after adding Docker repository + ansible.builtin.apt: + update_cache: true + +- name: Install Docker packages + ansible.builtin.apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-buildx-plugin + - docker-compose-plugin + state: present \ No newline at end of file diff --git a/roles/docker/portainer/defaults/main.yml b/roles/docker/portainer/defaults/main.yml new file mode 100755 index 0000000..e69de29 diff --git a/roles/docker/portainer/tasks/main.yml b/roles/docker/portainer/tasks/main.yml new file mode 100755 index 0000000..a18e91d --- /dev/null +++ b/roles/docker/portainer/tasks/main.yml @@ -0,0 +1,22 @@ +- name: Pull Portainer Agent image + become: true + community.docker.docker_image: + name: portainer/agent + tag: latest + source: pull + +- name: Deploy Portainer Agent container + become: true + community.docker.docker_container: + name: portainer_agent + image: portainer/agent + pull: false # we already pulled above + state: started + restart_policy: always + ports: + - "9001:9001" + volumes: + - /var/run/docker.sock:/var/run/docker.sock + - /var/lib/docker/volumes:/var/lib/docker/volumes + - /:/host + timeout: 120 # wait up to 2m for it to come up diff --git a/roles/docker/remove/defaults/main.yml b/roles/docker/remove/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/docker/remove/handlers/main.yml b/roles/docker/remove/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/docker/remove/tasks/main.yml b/roles/docker/remove/tasks/main.yml new file mode 100644 index 0000000..530f0a4 --- /dev/null +++ b/roles/docker/remove/tasks/main.yml @@ -0,0 +1,13 @@ +--- +- name: Remove old docker stuff + ansible.builtin.dnf: + name: + - docker + - docker-client + - docker-client-latest + - docker-common + - docker-latest + - docker-latest-logrotate + - docker-logrotate + - docker-engine + state: absent \ No newline at end of file diff --git a/roles/docker/remove/templates/main.yml b/roles/docker/remove/templates/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/docker/stack/defaults/main.yml b/roles/docker/stack/defaults/main.yml new file mode 100755 index 0000000..6b7f1a5 --- /dev/null +++ b/roles/docker/stack/defaults/main.yml @@ -0,0 +1,2 @@ +apps: [] +stack_name: "willneverexist" \ No newline at end of file diff --git a/roles/docker/stack/tasks/main.yml b/roles/docker/stack/tasks/main.yml new file mode 100755 index 0000000..ab0863b --- /dev/null +++ b/roles/docker/stack/tasks/main.yml @@ -0,0 +1,27 @@ +--- +- name: Create app mount directories + ansible.builtin.file: + path: "{{ remote_app_mounts }}/{{ item }}" + state: directory + mode: '0777' + loop: "{{ apps }}" + +- name: Create stack directory + ansible.builtin.file: + path: "{{ remote_stacks }}/{{ stack_name }}" + state: directory + mode: '0777' + +- name: Copy docker-compose.yml to server + ansible.builtin.copy: + src: '{{ docker_stacks }}/{{ stack_name }}/docker-compose.yml' + dest: '{{ remote_stacks }}/{{ stack_name }}/docker-compose.yml' + owner: javi + group: javi + mode: '0777' + +- name: Start up the containers + ansible.builtin.command: docker compose up -d + become: true + args: + chdir: "{{ remote_stacks }}/{{ stack_name }}" \ No newline at end of file diff --git a/roles/postgres/database/defaults/main.yml b/roles/postgres/database/defaults/main.yml new file mode 100755 index 0000000..e69de29 diff --git a/roles/postgres/database/tasks/main.yml b/roles/postgres/database/tasks/main.yml new file mode 100755 index 0000000..b54e09e --- /dev/null +++ b/roles/postgres/database/tasks/main.yml @@ -0,0 +1,10 @@ +--- +- name: Create database + delegate_to: localhost + community.postgresql.postgresql_db: + name: "{{ database }}" + state: present + login_host: "{{ pg_host }}" + login_port: "{{ pg_port }}" + login_user: "{{ pg_user }}" + login_password: "{{ pg_password }}" diff --git a/roles/postgres/priviledges/defaults/main.yml b/roles/postgres/priviledges/defaults/main.yml new file mode 100755 index 0000000..84dc138 --- /dev/null +++ b/roles/postgres/priviledges/defaults/main.yml @@ -0,0 +1 @@ +priviledges: ALL \ No newline at end of file diff --git a/roles/postgres/priviledges/tasks/main.yml b/roles/postgres/priviledges/tasks/main.yml new file mode 100755 index 0000000..b47041a --- /dev/null +++ b/roles/postgres/priviledges/tasks/main.yml @@ -0,0 +1,28 @@ +--- +- name: Grant database-level privileges on "{{ database }}" + delegate_to: localhost + community.postgresql.postgresql_privs: + db: "{{ database }}" + type: database + objs: "{{ database }}" + privs: "CREATE" + role: "{{ user }}" + state: present + login_host: "{{ pg_host }}" + login_port: "{{ pg_port }}" + login_user: "{{ pg_user }}" + login_password: "{{ pg_password }}" + +- name: Give user full priviledges on database + delegate_to: localhost + community.postgresql.postgresql_privs: + db: "{{ database }}" + type: schema + objs: public + privs: "{{ priviledges }}" + role: "{{ user }}" + state: present + login_host: "{{ pg_host }}" + login_port: "{{ pg_port }}" + login_user: "{{ pg_user }}" + login_password: "{{ pg_password }}" \ No newline at end of file diff --git a/roles/postgres/user/defaults/main.yml b/roles/postgres/user/defaults/main.yml new file mode 100755 index 0000000..3fab93f --- /dev/null +++ b/roles/postgres/user/defaults/main.yml @@ -0,0 +1 @@ +password: "password" \ No newline at end of file diff --git a/roles/postgres/user/tasks/main.yml b/roles/postgres/user/tasks/main.yml new file mode 100755 index 0000000..bbdd928 --- /dev/null +++ b/roles/postgres/user/tasks/main.yml @@ -0,0 +1,11 @@ +--- +- name: Create postgres user + delegate_to: localhost + community.postgresql.postgresql_user: + name: "{{ user }}" + password: "{{ password }}" + state: present + login_host: "{{ pg_host }}" + login_port: "{{ pg_port }}" + login_user: "{{ pg_user }}" + login_password: "{{ pg_password }}" \ No newline at end of file diff --git a/roles/provision/alma/common/defaults/main.yml b/roles/provision/alma/common/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/provision/alma/common/handlers/main.yml b/roles/provision/alma/common/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/provision/alma/common/tasks/main.yml b/roles/provision/alma/common/tasks/main.yml new file mode 100644 index 0000000..6a700bc --- /dev/null +++ b/roles/provision/alma/common/tasks/main.yml @@ -0,0 +1,56 @@ +--- +- name: Set system timezone + ansible.builtin.command: timedatectl set-timezone "{{ timezone }}" + register: output + changed_when: output.rc != 0 + +- name: Set hostname + ansible.builtin.hostname: + name: "{{ provision_hostname }}" + use: systemd + +- name: Upgrade all packages + ansible.builtin.dnf: + name: "*" + update_only: true + +- name: Add CodeReady Builder repo + ansible.builtin.command: dnf config-manager --set-enabled crb + register: output + changed_when: output.rc != 0 + +- name: Install QEMU Guest Agent + ansible.builtin.dnf: + name: + - 'qemu-guest-agent' + +- name: Enable and start QEMU Guest Agent + ansible.builtin.service: + name: qemu-guest-agent + enabled: yes + state: started + +- name: Install EPEL + ansible.builtin.dnf: + name: + - 'epel-release' + update_cache: true + +- name: Install Dev Tools + ansible.builtin.dnf: + name: + - '@Development tools' + update_cache: true + +- name: Install baseline packages + ansible.builtin.dnf: + name: + - vim + - curl + - git + - bash-completion + - firewalld + - fastfetch + - btop + state: latest + update_cache: true diff --git a/roles/provision/alma/common/templates/main.yml b/roles/provision/alma/common/templates/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/provision/alma/docker/defaults/main.yml b/roles/provision/alma/docker/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/provision/alma/docker/handlers/main.yml b/roles/provision/alma/docker/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/provision/alma/docker/tasks/main.yml b/roles/provision/alma/docker/tasks/main.yml new file mode 100644 index 0000000..301767e --- /dev/null +++ b/roles/provision/alma/docker/tasks/main.yml @@ -0,0 +1,18 @@ +- name: Add Docker repository + ansible.builtin.get_url: + url: https://download.docker.com/linux/centos/docker-ce.repo + dest: /etc/yum.repos.d/docker-ce.repo + +- name: Install Docker packages + ansible.builtin.dnf: + name: + - docker-ce + - docker-ce-cli + - containerd.io + state: present + +- name: Enable and start Docker + ansible.builtin.service: + name: docker + enabled: yes + state: started diff --git a/roles/provision/alma/docker/templates/main.yml b/roles/provision/alma/docker/templates/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/provision/alma/nfs/defaults/main.yml b/roles/provision/alma/nfs/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/provision/alma/nfs/handlers/main.yml b/roles/provision/alma/nfs/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/provision/alma/nfs/tasks/main.yml b/roles/provision/alma/nfs/tasks/main.yml new file mode 100644 index 0000000..05602e7 --- /dev/null +++ b/roles/provision/alma/nfs/tasks/main.yml @@ -0,0 +1,23 @@ +--- +- name: Install NFS client + ansible.builtin.dnf: + name: nfs-utils + state: present + +- name: Create mount points + ansible.builtin.file: + path: "{{ item.path }}" + state: directory + owner: nfsuser + group: nfsuser + mode: '0755' + loop: "{{ nfs_mounts }}" + +- name: Mount NFS shares + ansible.posix.mount: + src: "{{ item.src }}" + path: "{{ item.path }}" + fstype: nfs + opts: "{{ item.opts }}" + state: mounted + loop: "{{ nfs_mounts }}" diff --git a/roles/provision/alma/nfs/templates/main.yml b/roles/provision/alma/nfs/templates/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/pve/cluster_prep/defaults/main.yml b/roles/pve/cluster_prep/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/pve/cluster_prep/tasks/main.yml b/roles/pve/cluster_prep/tasks/main.yml new file mode 100644 index 0000000..6bb6e39 --- /dev/null +++ b/roles/pve/cluster_prep/tasks/main.yml @@ -0,0 +1,107 @@ +--- +# - name: Set hostname +# hostname: +# name: "{{ inventory_hostname }}" +# - name: Disable Proxmox Enterprise repo +# lineinfile: +# path: /etc/apt/sources.list.d/pve-enterprise.list +# regexp: '^deb' +# line: '# deb ...' +# state: present +# ignore_errors: yes # In case the file doesn't exist + +- name: Find all sources.list.d files + find: + paths: /etc/apt/sources.list.d + patterns: "*.list" + file_type: file + register: list_files + +- name: Comment out any line with 'enterprise' in each file + lineinfile: + path: "{{ item.path }}" + regexp: '^(?!#).*enterprise' + line: '# \g<0>' + backrefs: yes + state: present + loop: "{{ list_files.files }}" + +- name: Overwrite sources.list with Proxmox-recommended repos + copy: + dest: /etc/apt/sources.list + content: | + deb http://ftp.debian.org/debian bookworm main contrib + deb http://ftp.debian.org/debian bookworm-updates main contrib + + # Proxmox VE pve-no-subscription repository provided by proxmox.com, + # NOT recommended for production use + deb http://download.proxmox.com/debian/pve bookworm pve-no-subscription + + # security updates + deb http://security.debian.org/debian-security bookworm-security main contrib + mode: '0644' + +- name: Add Proxmox no-subscription repo to sources.list.d + copy: + dest: /etc/apt/sources.list.d/pve-no-subscription.list + content: | + deb http://download.proxmox.com/debian/pve bullseye pve-no-subscription + owner: root + group: root + mode: '0644' + + +- name: Update apt cache + apt: + update_cache: yes + +- name: Update /etc/hosts with all PVE nodes + template: + src: hosts.j2 + dest: /etc/hosts + mode: "0644" + +- name: Ensure search domain and nameserver set properly + template: + src: resolv.j2 + dest: /etc/resolv.conf + mode: "0644" + +- name: Ensure chrony is installed + apt: + name: chrony + state: present + update_cache: yes + +- name: Enable and start chronyd + service: + name: chrony + state: started + enabled: yes + +- name: Discover iSCSI targets from TrueNAS + shell: | + iscsiadm -m discovery -t st -p {{ iscsi_target_ip }} + register: iscsi_discovery + changed_when: false + +- name: Login to discovered iSCSI target (unauthenticated) + shell: | + iscsiadm -m node -T {{ iscsi_target_iqn }} -p {{ iscsi_target_ip }} --login + register: iscsi_login + changed_when: "'Login to' in iscsi_login.stdout or 'already present' in iscsi_login.stdout" + +- name: Make iSCSI login persistent across reboots + shell: | + iscsiadm -m node -T {{ iscsi_target_iqn }} -p {{ iscsi_target_ip }} --op update -n node.startup -v automatic + changed_when: false + +# - name: Ensure vg_ha exists +# command: vgs vg_ha +# register: vg_result +# failed_when: vg_result.rc != 0 +# changed_when: false + +# - name: Debug VG presence +# debug: +# msg: "VG 'vg_ha' found on {{ inventory_hostname }}" diff --git a/roles/pve/cluster_prep/templates/hosts.j2 b/roles/pve/cluster_prep/templates/hosts.j2 new file mode 100644 index 0000000..a65756c --- /dev/null +++ b/roles/pve/cluster_prep/templates/hosts.j2 @@ -0,0 +1,6 @@ +127.0.0.1 localhost +{% for host in groups['pve-nodes'] %} +{{ hostvars[host]['ansible_default_ipv4']['address'] }} {{ host }} {{ host }}.lan.xbazzi.com +{{ hostvars[host]['cluster_ip'] }} {{ host }}-cluster +{% endfor %} + diff --git a/roles/pve/cluster_prep/templates/resolv.j2 b/roles/pve/cluster_prep/templates/resolv.j2 new file mode 100644 index 0000000..e2b3300 --- /dev/null +++ b/roles/pve/cluster_prep/templates/resolv.j2 @@ -0,0 +1,2 @@ +search lan.xbazzi.com +nameserver 10.133.7.1 \ No newline at end of file diff --git a/roles/pve/pve_backup/defaults/main.yml b/roles/pve/pve_backup/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/pve/pve_backup/tasks/main.yml b/roles/pve/pve_backup/tasks/main.yml new file mode 100644 index 0000000..20a1bab --- /dev/null +++ b/roles/pve/pve_backup/tasks/main.yml @@ -0,0 +1,26 @@ +--- +- name: Copy /etc/ backup script to PVE node + template: + src: backup_pve_config.sh.j2 + dest: /home/xbazzi/backup_pve.sh + mode: '0755' + +- name: Run backup script + shell: /home/xbazzi/backup_pve.sh + +- name: Find most recent backup directory + shell: "ls -td /home/xbazzi/pve_backup_* | head -1" + register: latest_backup_dir + changed_when: false + +- name: Archive backup folder + archive: + path: "{{ latest_backup_dir.stdout }}" + dest: "{{ latest_backup_dir.stdout }}.tar.gz" + format: gz + +- name: Fetch backup archive to control machine + fetch: + src: "{{ latest_backup_dir.stdout }}.tar.gz" + dest: "backups/{{ inventory_hostname }}.tar.gz" + flat: yes diff --git a/roles/pve/pve_backup/templates/backup_pve_config.sh.j2 b/roles/pve/pve_backup/templates/backup_pve_config.sh.j2 new file mode 100644 index 0000000..0e1d96e --- /dev/null +++ b/roles/pve/pve_backup/templates/backup_pve_config.sh.j2 @@ -0,0 +1,23 @@ +#!/bin/bash +set -e + +TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S") +BACKUP_DIR="/home/xbazzi/pve_backup_${TIMESTAMP}" +NODE_NAME=$(hostname) + +echo "🔒 Creating backup directory at $BACKUP_DIR..." +mkdir -p "$BACKUP_DIR" + +echo "📁 Backing up /etc/pve..." +cp -a /etc/pve "$BACKUP_DIR/etc_pve" + +echo "📄 Saving VM and container config files..." +mkdir -p "$BACKUP_DIR/qemu-server" "$BACKUP_DIR/lxc" +cp -a /etc/pve/qemu-server/*.conf "$BACKUP_DIR/qemu-server/" 2>/dev/null || true +cp -a /etc/pve/lxc/*.conf "$BACKUP_DIR/lxc/" 2>/dev/null || true + +echo "💽 Saving storage.cfg..." +cp -a /etc/pve/storage.cfg "$BACKUP_DIR/" 2>/dev/null || true + +echo "📦 Backup complete on $NODE_NAME." +echo "🗃️ Location: $BACKUP_DIR" diff --git a/roles/pve/setup_networking/defaults/main.yml b/roles/pve/setup_networking/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/pve/setup_networking/handlers/main.yml b/roles/pve/setup_networking/handlers/main.yml new file mode 100644 index 0000000..eb3f4ff --- /dev/null +++ b/roles/pve/setup_networking/handlers/main.yml @@ -0,0 +1,5 @@ +# - name: Restart networking +# ansible.builtin.systemd: +# name: networking +# state: restarted + \ No newline at end of file diff --git a/roles/pve/setup_networking/tasks/main.yml b/roles/pve/setup_networking/tasks/main.yml new file mode 100644 index 0000000..91d62bc --- /dev/null +++ b/roles/pve/setup_networking/tasks/main.yml @@ -0,0 +1,46 @@ +--- +- name: Set up network interfaces for new PVE node + template: + src: interfaces-xbazzi.j2 + # dest: /etc/network/interfaces.d/interfaces-xbazzi + dest: /etc/network/interfaces + owner: root + group: root + mode: "0644" + +- name: Apply correct permissions to interfaces.d + file: + path: "/etc/network/interfaces.d" + owner: root + group: root + mode: '0644' + +- name: Find all files in the directory + ansible.builtin.find: + paths: /etc/network/interfaces.d/ + file_type: file + register: files_to_delete + +- name: Delete all files + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + loop: "{{ files_to_delete.files }}" + +- name: Update /etc/hosts with all PVE nodes + template: + src: hosts.j2 + dest: /etc/hosts + mode: "0644" + +- name: Ensure search domain and nameserver set properly + template: + src: resolv.j2 + dest: /etc/resolv.conf + mode: "0644" + + +- name: Restart networking + ansible.builtin.systemd: + name: networking + state: restarted diff --git a/roles/pve/setup_networking/templates/hosts.j2 b/roles/pve/setup_networking/templates/hosts.j2 new file mode 100644 index 0000000..a65756c --- /dev/null +++ b/roles/pve/setup_networking/templates/hosts.j2 @@ -0,0 +1,6 @@ +127.0.0.1 localhost +{% for host in groups['pve-nodes'] %} +{{ hostvars[host]['ansible_default_ipv4']['address'] }} {{ host }} {{ host }}.lan.xbazzi.com +{{ hostvars[host]['cluster_ip'] }} {{ host }}-cluster +{% endfor %} + diff --git a/roles/pve/setup_networking/templates/interfaces-xbazzi.j2 b/roles/pve/setup_networking/templates/interfaces-xbazzi.j2 new file mode 100644 index 0000000..e3f38ff --- /dev/null +++ b/roles/pve/setup_networking/templates/interfaces-xbazzi.j2 @@ -0,0 +1,48 @@ +auto eno1 +iface eno1 inet manual + mtu 1500 + +auto enp1s0f0 +iface enp1s0f0 inet manual + mtu 9000 + +iface enp1s0f1 inet manual + mtu 9000 + +# Mgmt interface +auto vmbr0 +iface vmbr0 inet static + address {{ vmbr0_ip }}/22 + bridge-ports eno1 + bridge-stp off + bridge-fd 0 + mtu 1500 + +auto vmbr1 +iface vmbr1 inet manual + bridge-ports enp1s0f0 + bridge-stp off + bridge-fd 0 + bridge-vlan-aware yes + bridge-vids 2-4094 + mtu 9000 + +# Prod interface +auto vmbr1.1337 +iface vmbr1.1337 inet static + address {{ vmbr1_1337_ip }}/22 + gateway 10.133.7.1 + mtu 9000 + +# DMZ interface +auto vmbr1.666 +iface vmbr1.666 inet static + address {{ vmbr1_666_ip }}/22 + mtu 1500 + +# Cluster network +auto {{ cluster_iface }} +iface {{ cluster_iface }} inet static + address {{ cluster_ip }}/28 + mtu 1500 + diff --git a/roles/pve/setup_networking/templates/resolv.j2 b/roles/pve/setup_networking/templates/resolv.j2 new file mode 100644 index 0000000..e2b3300 --- /dev/null +++ b/roles/pve/setup_networking/templates/resolv.j2 @@ -0,0 +1,2 @@ +search lan.xbazzi.com +nameserver 10.133.7.1 \ No newline at end of file diff --git a/roles/server/firewall/defaults/main.yml b/roles/server/firewall/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/firewall/handlers/main.yml b/roles/server/firewall/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/firewall/tasks/main.yml b/roles/server/firewall/tasks/main.yml new file mode 100644 index 0000000..a742df0 --- /dev/null +++ b/roles/server/firewall/tasks/main.yml @@ -0,0 +1,43 @@ +--- +- name: Enable and start firewalld + ansible.builtin.systemd: + name: firewalld + enabled: yes + state: started + +- name: Assign interface ens18 to core zone + ansible.posix.firewalld: + interface: ens18 + zone: core + state: enabled + permanent: true + +- name: Assign interface ens19 to mgmt zone + ansible.posix.firewalld: + interface: ens19 + zone: mgmt + state: enabled + permanent: true + +- name: Assign interface ens20 to dmz zone + ansible.posix.firewalld: + interface: ens20 + zone: dmz + state: enabled + permanent: true + +- name: Set core to default + ansible.builtin.command: firewall-cmd --set-default-zone=core + +# - name: Remove ens18 from public +# ansible.builtin.command: firewall-cmd --zone=public --remove-interface=ens18 + +# - name: Assign interface ens18 to "internal" zone +# ansible.posix.firewalld: +# interface: ens18 +# zone: internal +# state: enabled +# permanent: true + +- name: Reload firewalld to apply changes + ansible.builtin.command: firewall-cmd --reload diff --git a/roles/server/firewall/templates/main.yml b/roles/server/firewall/templates/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/ftp/defaults/main.yml b/roles/server/ftp/defaults/main.yml new file mode 100755 index 0000000..e69de29 diff --git a/roles/server/ftp/tasks/main.yml b/roles/server/ftp/tasks/main.yml new file mode 100755 index 0000000..a710115 --- /dev/null +++ b/roles/server/ftp/tasks/main.yml @@ -0,0 +1,23 @@ +--- +- name: Update apt cache + ansible.builtin.apt: + update_cache: true + +- name: Install proftpd package + ansible.builtin.apt: + name: proftpd + state: present + +- name: Ensure proftpd is enabled and started + ansible.builtin.service: + name: proftpd + state: started + enabled: true + become: true + +- name: Allow FTP through UFW firewall (if UFW is enabled) + community.general.ufw: + rule: allow + port: 21 + proto: tcp + ignore_errors: false \ No newline at end of file diff --git a/roles/server/network/defaults/main.yml b/roles/server/network/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/network/handlers/main.yml b/roles/server/network/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/network/tasks/main.yml b/roles/server/network/tasks/main.yml new file mode 100644 index 0000000..05daa35 --- /dev/null +++ b/roles/server/network/tasks/main.yml @@ -0,0 +1,136 @@ +--- +- name: Enable and start firewalld + ansible.builtin.systemd: + name: firewalld + enabled: yes + state: started + +- name: Enable and start NetworkManager + ansible.builtin.systemd: + name: NetworkManager + enabled: yes + state: started + +- name: Check existing zones + ansible.builtin.command: firewall-cmd --get-zones + register: firewalld_zones + +- name: Debug output + ansible.builtin.debug: + var: firewalld_zones.stdout + +# - name: Create zone "core" +# ansible.builtin.command: firewall-cmd --permanent --new-zone="{{ item }}" +# loop: ["core", "mgmt"] +# # loop: "{{ firewalld_zones.stdout | split }}" +# when: item in firewalld_zones.stdout.split() + # (item != "core" and + # item != "dmz") + +- name: Create firewalld core zone + ansible.posix.firewalld: + zone: core + state: present + permanent: true + +- name: Create firewalld mgmt zone + ansible.posix.firewalld: + zone: mgmt + state: present + permanent: true + +- name: Create firewalld dmz zone + ansible.posix.firewalld: + zone: dmz + state: present + permanent: true + +- name: Reload firewalld to apply changes + ansible.builtin.command: firewall-cmd --reload + +- name: Enable ssh rule in core for initial ansible config + ansible.posix.firewalld: + zone: core + service: ssh + state: enabled + permanent: true + +# - name: Ensure all other zones are disabled +# ansible.posix.firewalld: +# zone: "{{ item }}" +# state: disabled +# permanent: true +# when: item not in zones +# loop: "{{ firewalld_zones.stdout | split }}" + +- name: Set up CORE interface manually + nmcli: + conn_name: CORE + zone: core + type: ethernet + ip4: "{{ provision_core_ip4 }}" + gw4: "{{ core_gw4 }}" + dns4: "{{ core_gw4 }}" + method4: "manual" + ifname: ens18 + dns4_search: lan.xbazzi.com + state: present + # delegate_to: "{{ provision_core_ip4_no_subnet }}" + +- name: Set up mgmt interface manually + nmcli: + conn_name: MGMT + zone: mgmt + type: ethernet + ip4: "{{ provision_mgmt_ip4 }}" + routes4: "0.0.0.0/0 {{ mgmt_gw4 }}" + routing_rules4: + - "priority 2 from {{ mgmt_net }} table 200" + route_metric4: 102 + dns4: "{{ mgmt_gw4 }}" + method4: "manual" + ifname: "ens19" + dns4_search: "lan.xbazzi.com" + state: present + # delegate_to: "{{ provision_core_ip4_no_subnet }}" + +- name: Set up dmz interface manually + nmcli: + conn_name: DMZ + zone: dmz + type: ethernet + ip4: "{{ provision_dmz_ip4 }}" + routes4: "0.0.0.0/0 {{ dmz_gw4 }}" + routing_rules4: + - "priority 3 from {{ dmz_net }} table 300" + route_metric4: 103 + dns4: "{{ dmz_gw4 }}" + method4: "manual" + ifname: "ens20" + dns4_search: "lan.xbazzi.com" + state: present + # delegate_to: "{{ provision_core_ip4_no_subnet }}" + +- name: Remove ens18 default connection + nmcli: + conn_name: ens18 + state: absent + # delegate_to: "{{ provision_core_ip4_no_subnet }}" + +- name: Remove ens19 default connection + nmcli: + conn_name: ens19 + state: absent + # delegate_to: "{{ provision_core_ip4_no_subnet }}" + +- name: Remove ens20 default connection + nmcli: + conn_name: ens20 + state: absent + # delegate_to: "{{ provision_core_ip4_no_subnet }}" + +- name: Remove "Wired connection 1" + nmcli: + conn_name: Wired connection 1 + state: absent + # delegate_to: "{{ provision_core_ip4_no_subnet }}" diff --git a/roles/server/network/templates/ifcfg-template.j2 b/roles/server/network/templates/ifcfg-template.j2 new file mode 100644 index 0000000..89715b7 --- /dev/null +++ b/roles/server/network/templates/ifcfg-template.j2 @@ -0,0 +1,6 @@ +DEVICE={{ network_config.interface }} +BOOTPROTO=none +ONBOOT=yes +IPADDR={{ network_config.address }} +NETMASK={{ network_config.netmask }} +GATEWAY={{ network_config.gateway }} diff --git a/roles/server/network/templates/main.yml b/roles/server/network/templates/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/reboot/defaults/main.yml b/roles/server/reboot/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/reboot/handlers/main.yml b/roles/server/reboot/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/reboot/tasks/main.yml b/roles/server/reboot/tasks/main.yml new file mode 100644 index 0000000..f814796 --- /dev/null +++ b/roles/server/reboot/tasks/main.yml @@ -0,0 +1,5 @@ +--- +- name: Reboot machine and send a message + ansible.builtin.shell: "reboot" + async: 1 + poll: 0 \ No newline at end of file diff --git a/roles/server/reboot/templates/main.yml b/roles/server/reboot/templates/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/sshkey/defaults/main.yml b/roles/server/sshkey/defaults/main.yml new file mode 100755 index 0000000..e69de29 diff --git a/roles/server/sshkey/tasks/main.yml b/roles/server/sshkey/tasks/main.yml new file mode 100644 index 0000000..f2484c4 --- /dev/null +++ b/roles/server/sshkey/tasks/main.yml @@ -0,0 +1,12 @@ +--- +- name: Add ansible user SSH public key + ansible.posix.authorized_key: + user: ansible + key: "{{ lookup('file', '/home/xbazzi/.ssh/ansible_ed25519.pub') }}" + state: present + +- name: Add xbazzi user SSH public key + ansible.posix.authorized_key: + user: xbazzi + key: "{{ lookup('file', '/home/xbazzi/.ssh/lan_id_ed25519.pub') }}" + state: present \ No newline at end of file diff --git a/roles/server/sysprep/defaults/main.yml b/roles/server/sysprep/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/sysprep/handlers/main.yml b/roles/server/sysprep/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/sysprep/tasks/main.yml b/roles/server/sysprep/tasks/main.yml new file mode 100644 index 0000000..b3f8f0e --- /dev/null +++ b/roles/server/sysprep/tasks/main.yml @@ -0,0 +1,115 @@ +--- +- name: Set hostname to generic localhost + ansible.builtin.hostname: + name: localhost.localdomain + # use: systemd + +- name: Ensure IPv4 localhost entry exists in /etc/hosts + ansible.builtin.lineinfile: + path: /etc/hosts + line: "127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4" + state: present + create: yes + regexp: '^127\.0\.0\.1\s+localhost' + +- name: Remove IPv6 localhost entry (::1) from /etc/hosts + ansible.builtin.lineinfile: + path: /etc/hosts + regexp: '^::1\s+localhost' + state: absent + +# - name: Remove xbazzi user +# ansible.builtin.user: +# name: xbazzi +# state: absent +# remove: true + +# - name: Truncate machine-id +# ansible.builtin.command: truncate -s 0 /etc/machine-id + +- name: Remove DBus machine-id if exists + ansible.builtin.file: + path: /var/lib/dbus/machine-id + state: absent + +- name: Remove root SSH folder + ansible.builtin.file: + path: /root/.ssh + state: absent + +- name: Remove anaconda kickstart config + ansible.builtin.file: + path: /root/anaconda-ks.cfg + state: absent + +- name: Clear logs + ansible.builtin.file: + path: "{{ item }}" + state: absent + loop: + - /var/log/boot.log + - /var/log/cron + - /var/log/dmesg + - /var/log/grubby + - /var/log/lastlog + - /var/log/maillog + - /var/log/messages + - /var/log/secure + - /var/log/spooler + - /var/log/tallylog + - /var/log/wtmp + - /var/log/yum.log + - /var/log/audit/audit.log + - /var/log/tuned/tuned.log + - /var/log/wpa_supplicant.log + - /var/log/ovirt-guest-agent/ovirt-guest-agent.log + +- name: Rotate and vacuum journal logs + ansible.builtin.shell: | + journalctl --rotate + journalctl --vacuum-time=1s + when: ansible_facts['distribution_major_version'] is version('8', '>=') + +- name: Clear shell history + ansible.builtin.copy: + content: "" + dest: /root/.bash_history + force: true + +- name: Find all SSH keys + ansible.builtin.find: + paths: + - /etc/ssh + - /home/ + patterns: + - "ssh_host*" + - "id_*" + - "authorized_keys" + - "known_hosts" + - "config" + use_regex: false + recurse: true + file_type: file + register: ssh_files + +- name: Debug found SSH keys + debug: + msg: "{{ item.path }}" + loop: "{{ ssh_files.files }}" + +- name: Remove SSH keys + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + loop: "{{ ssh_files.files }}" + # loop: "{{ ssh_keys.results | map(attribute='files') | flatten }}" + +- name: Sync changes to disk + ansible.builtin.command: sync + +- name: Remove old local SSH known_hosts entry (necessary to avoid fingerprint warning) + become_user: xbazzi + local_action: + module: command + args: + cmd: ssh-keygen -R "{{ hostvars['staging-vm'].ansible_host }}" diff --git a/roles/server/sysprep/templates/main.yml b/roles/server/sysprep/templates/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/users/defaults/main.yml b/roles/server/users/defaults/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/users/handlers/main.yml b/roles/server/users/handlers/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/server/users/tasks/main.yml b/roles/server/users/tasks/main.yml new file mode 100644 index 0000000..365b9cf --- /dev/null +++ b/roles/server/users/tasks/main.yml @@ -0,0 +1,45 @@ +--- +- name: Add xbazzi group + ansible.builtin.group: + name: xbazzi + state: present + gid: 1337 + +- name: Add xbazzi user + ansible.builtin.user: + name: xbazzi + create_home: true + shell: /bin/bash + groups: wheel,xbazzi + uid: 1337 + state: present + +# - name: Add ansible group +# ansible.builtin.group: +# name: ansible +# state: present +# gid: 1001 + +# - name: Add ansible user +# ansible.builtin.user: +# name: ansible +# create_home: true +# shell: /bin/bash +# groups: wheel,ansible +# state: present +# uid: 1001 + +- name: Add nfsuser group + ansible.builtin.group: + name: nfsuser + state: present + gid: 3005 + +- name: Add nfsuser user + ansible.builtin.user: + name: nfsuser + create_home: true + shell: /bin/bash + groups: wheel + state: present + uid: 3005 diff --git a/roles/server/users/templates/main.yml b/roles/server/users/templates/main.yml new file mode 100644 index 0000000..e69de29 diff --git a/roles/services/postgres/defaults/main.yml b/roles/services/postgres/defaults/main.yml new file mode 100644 index 0000000..8ca4c28 --- /dev/null +++ b/roles/services/postgres/defaults/main.yml @@ -0,0 +1,5 @@ +directory: "postgres" +default_user: "postgres" +default_password: "password" +port: "5432" +container_name: "postgres" \ No newline at end of file diff --git a/roles/services/postgres/tasks/main.yml b/roles/services/postgres/tasks/main.yml new file mode 100644 index 0000000..7df3f06 --- /dev/null +++ b/roles/services/postgres/tasks/main.yml @@ -0,0 +1,23 @@ +- name: Create data folder + ansible.builtin.file: + dest: "{{ docker_dir }}/{{ directory }}" + state: directory + owner: root + group: docker + mode: '0770' + recurse: yes + +- name: Put up the postgres container + community.docker.docker_container: + name: "{{container_name}}" + image: postgres:17.4 + restart_policy: always + state: started + pull: true + ports: + - "{{ port }}:5432" + env: + POSTGRES_USER: "{{ default_user }}" + POSTGRES_PASSWORD: "{{ default_password }}" + volumes: + - "{{ docker_dir }}/{{ directory }}/data:/var/lib/postgresql/data/" \ No newline at end of file diff --git a/roles/util/mount_nfs/defaults/main.yml b/roles/util/mount_nfs/defaults/main.yml new file mode 100755 index 0000000..771dc8d --- /dev/null +++ b/roles/util/mount_nfs/defaults/main.yml @@ -0,0 +1,3 @@ +mount_host: "{{ hostvars['nas'].ansible_host }}" +share: "/mnt/ALEXANDRIA/" +mount_path: "/mnt/unspecifiedshare" \ No newline at end of file diff --git a/roles/util/mount_nfs/tasks/main.yml b/roles/util/mount_nfs/tasks/main.yml new file mode 100755 index 0000000..9173c44 --- /dev/null +++ b/roles/util/mount_nfs/tasks/main.yml @@ -0,0 +1,21 @@ +--- +- name: Ensure NFS client is installed + ansible.builtin.package: + name: nfs-common + state: present + become: true + +- name: Create mount point directory + ansible.builtin.file: + path: "{{ mount_path }}" + state: directory + mode: '0777' + become: true + +- name: Mount share + ansible.posix.mount: + src: "{{ mount_host }}:{{ share }}" + path: "{{ mount_path }}" + fstype: nfs + state: mounted + become: true \ No newline at end of file diff --git a/setup.sh b/setup.sh new file mode 100755 index 0000000..bd30ef7 --- /dev/null +++ b/setup.sh @@ -0,0 +1,28 @@ +echo "**Deleting .git so you can start your own repo" +rm -rf .git +echo "***Ansible vault password***" +echo "This is used to encrypt/descrypt secrets in your vault" +echo "We'll save it to a file in ~/.[file name] so it doesn't have to be typed every time" +echo +read -p "File name (no . prefix): " ansible_vault_pass_filename +read -s -p "Password: " ansible_vault_pass + +echo $ansible_vault_pass > ~/.$ansible_vault_pass_filename +echo "vault_password_file = ~/.$ansible_vault_pass_filename" >>ansible.cfg + +echo +echo + +echo "***Ansible become password***" +echo "A lot of actions need sudo. This password will be stored in group_vars/all.yml encrypted" +read -s -p "Password: " ansible_become_pass +echo "# Sudo password for your servers" >>./group_vars/all.yml +ansible-vault encrypt_string "$ansible_become_pass" --name 'ansible_become_pass' >>./group_vars/all.yml + +echo +echo + +echo "Setup complete" +echo "You can delete setup.sh since running it again would cause issues" +echo "Config for vault password was output to ./ansible.cfg" +echo "Config for sudo (become) password was output to ./group_vars/all.yml"