feat: Auto deploy stacks on komodo (no storage yet)
This commit is contained in:
@@ -242,4 +242,4 @@ komodo_db_password: "{{ vault_komodo_db_password }}"
|
|||||||
komodo_webhook_secret: "{{ vault_komodo_webhook_secret }}"
|
komodo_webhook_secret: "{{ vault_komodo_webhook_secret }}"
|
||||||
komodo_jwt_secret: "{{ vault_komodo_jwt_secret }}"
|
komodo_jwt_secret: "{{ vault_komodo_jwt_secret }}"
|
||||||
komodo_onboarding_key: "{{ vault_komodo_onboarding_key }}"
|
komodo_onboarding_key: "{{ vault_komodo_onboarding_key }}"
|
||||||
komodo_core_address: "10.0.4.10:9120"
|
komodo_core_host: "10.0.4.10:9120"
|
||||||
|
|||||||
@@ -1,46 +1,53 @@
|
|||||||
$ANSIBLE_VAULT;1.1;AES256
|
$ANSIBLE_VAULT;1.1;AES256
|
||||||
34633839643463656436373363623239343634393834353863336665613863663464316636343564
|
33346333343637663032363331303231316234346636353763653039383662343730356335353730
|
||||||
6561613766613735303865363339326563363961343739370a626535346366366261666131653565
|
6466653064643530393338663130613238343733646366350a666333636337356362393033393639
|
||||||
39653832326235353662656466626132383531613338653138363039633563313536313765333166
|
30636331653939323336313638623235393632663963303834613430386135633134343465383738
|
||||||
6265343938386332340a313230353564653739633939363031623130316265373538333237343133
|
6139633438383937320a353536643230383439323339316638366464336636353164646232373839
|
||||||
39303831303230323738383565303335363763353462353966643832626131646436336434323138
|
35323165636364363238366431383663303430316130653366643263376238316137666665376366
|
||||||
66636635326634383137376431323736613434656533633664383161393338326565336130303930
|
61653937626264396531356639373865393962616565353265353366666133386266623638613138
|
||||||
31303232393332623839323162373239616634356434643364323933613335363861343738313661
|
38316632363065613234306661313431663639393862316630323064376236663332313130633465
|
||||||
63306435303962323566346564383066636634663536646264383961343461623236386362336239
|
37396136313032613932616664653239346265323135316131323735306638356664373336376231
|
||||||
36316536346533626438366430363664383135346337303239643335656261626639323433313765
|
34376565343531393831323438303563333463373437636535636162373830386135346164333264
|
||||||
33613564626235323337343164346235336663613238323966346331623266613832633234393232
|
37633264653932636639316161306637326361313530313365633335633937333832326130343532
|
||||||
39393565383235373365353538373764333433386439333132643064373839643963376333373032
|
39333739313364353539313262646364323931346436393633343063666238623363646338663862
|
||||||
34613361663630323937333162373534356263373861363163303062363232663731316164653966
|
37376565663636663166323030626133313065346135666439613032616135663136663062653032
|
||||||
39346163353635663738316262363465643639313766346339333963333964336265303666643064
|
34616433646266313462326261323166313566386266653962663435656232303036363235373632
|
||||||
62643366613034663838326436313739363863316666393238306564306539623162636266393033
|
32626461663936353236623564633366383366636666386236633766646439333161393438653661
|
||||||
39653438663938346233656630366130316161373363393561663631663737373131383736666136
|
39633362313337616139373663326364353534386231636561366664363862363833613133373031
|
||||||
66346231663338643735313739343361643431396638613837303833616539373261346163306132
|
30626664336166373938643935343138326564343036333266336331626638613238306262326261
|
||||||
39656436626635633733396138303963343135343437313637346565643835613739653839343938
|
30666265643435633565303365623633326466653837643633653934646638383736653365653730
|
||||||
61623561303930306335383963393561393735316331323639373536616236383532366136653134
|
66613365343730643635323032646363633934313263316534313263303533383865613636616266
|
||||||
63366661363332366338656234386139363066363239656136383634623430303262626465356536
|
66323435363037336239643366373534653434343063623130393437393633306130356666333339
|
||||||
34303862303763613761616134323236316232373931386336653034633230396633363965313331
|
30633533353563643832633064653165363563356436626637353833643064323432346131373230
|
||||||
31666234363064323331666535316134623461663433366538613133396633353161323766363437
|
32346433653332623535343366306662623638326462616463376333663830663039366235313766
|
||||||
66396439303235313137393135383837323737663731386331376362613964323737366633623733
|
31323665393964363262363366313764363965353439363865323464623632313833333235306237
|
||||||
31353261306163356333303333393466643338343765323637656565333762386133363031396638
|
30363937646335303066343934306130313330653266383239646462636364306439636163393634
|
||||||
34386639393133303134383034316439363262386461346534326236326135623964363461646430
|
65653638666239363737653632316536333535333134616664343665343030313637643333393963
|
||||||
33623433306130393232353135623332396136653230383439333665303737343137383864356433
|
38306338333033313064333339393239343631643563623765663362353764323661366161636138
|
||||||
37313262383961656133393731656162316433356336336530333862363561353238663433343131
|
30366166353364373139616562623634316432613662363539613765336335326266666666356332
|
||||||
32353862363863343666383766363135663736613332313438356366303332326632653961313762
|
34653263316663636530323431353562643833373935306264333565363832643030646433326263
|
||||||
34363230633461616461373536366239313962616565396566316139393466303332643265353835
|
38643462666237376331643037316232623664653333386433636566656366666430363337616130
|
||||||
35356364343734663963303839363733393730633262643438336562643733623966663130353635
|
31383730306563386465383531366462363266333437323831393561363665663231346362363665
|
||||||
38363833633936363164313239323265623332643539356532623636383232323538386431653165
|
35333836653931343161653261656265643732353837666337393835363536353937646561396365
|
||||||
31353138666537616565646239303165376439373063356663316664356564323961613039663061
|
64363463326435386330343937323934356366343434323964306131363133633434303266636563
|
||||||
62336261306532386136616465383265613262363936633164373236353238633463303939623133
|
39393463333539306262323239663033633830336433663931653433393030626633316564343737
|
||||||
65313335653935346364383232373261666334663634373938353861383561613936393339366530
|
31626461316234623965316339343434646561636164343037356566623366626636326663623533
|
||||||
34303961373561303031323834663466346436383966373530633430333536373833383166313938
|
63646166383835306430333965346234363334646534323566623430633865373837353763626663
|
||||||
31376531366166333762623233646433323134663366323730613932393333333737623463653634
|
37363461656430623739366664613832346135333535393531623762656566616137303439323039
|
||||||
31356466646465333666363034343730313164353039646236393564326536323330363639343664
|
63613436366161616263396464316231333535346561666631366464666433643031653231316464
|
||||||
39363836663332333234396239336339356532626430653861373137333562623830653936323432
|
62626363346335663639623366396634373664643965393339636336616139616431653830306331
|
||||||
34306238623137313232333033356266303564376163333065653137616661643537373831666136
|
37633439306365333961356336653637656661643763353032653063336430393638653830313439
|
||||||
39303037383661313064396364363639346564643564303638623661356235336162633633616531
|
62396632316166356131316438643164386466623162663661383834346633656265396438666231
|
||||||
34626331393564363564613937346165333936366231333462633561356362616434306165343130
|
61663332366634623032323836366235613933363964366665643330366466306434356232396330
|
||||||
62346665653532663434396238366562336264656130643566666466313964303066373462373034
|
39636163653536396365336631366633313830633631383333383338333964613034623935666663
|
||||||
32613434363832626265636234343535313438313532643631363633363335653364393564356632
|
66346434326630333630326333663462376431306432633466356166306532616530633262626231
|
||||||
37613135343632613433616630333163323230333235363531343966333232646664393163386238
|
36653936333134643832343865366333623939656539386534346430646330616431376366363265
|
||||||
36613731656666663236316133353237636363663336656162316163393230346565366536376236
|
33353132336562613139383264396462353234303533353263343433626566366263393134356666
|
||||||
6336
|
65343633663261626138333665323238623239363364646436336639333636663236396162376164
|
||||||
|
62356534323663353832653466393837353931636232353331386534323934633336623039316662
|
||||||
|
30646432613761623966623033393533633235396431353631663364653461393464353738663031
|
||||||
|
63653931366633323966313664333562613263663239333937626536333662666538643736663034
|
||||||
|
38316365333033333130643931333331373662326639316266363436656365646262613433376336
|
||||||
|
31376663326563323637313339396263376231333230643238326339663239633463303435653035
|
||||||
|
39343533636234326262323330663736326431353637343663636165663935313236316337336463
|
||||||
|
33373033653435313235
|
||||||
|
|||||||
@@ -0,0 +1,45 @@
|
|||||||
|
---
|
||||||
|
# Playbook to provision Komodo stacks from git repository
|
||||||
|
# Automatically discovers stacks from docker-compose folder structure
|
||||||
|
# Structure: docker-compose/{server}/{app}/compose.yaml
|
||||||
|
# Usage: ansible-playbook -i inventories/production.yml playbooks/provision_komodo_stacks.yml
|
||||||
|
|
||||||
|
- name: Provision Komodo stacks
|
||||||
|
hosts: localhost
|
||||||
|
connection: local
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
docker_compose_root: "{{ playbook_dir }}/../../docker-compose"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Find all compose.yaml files in docker-compose directory
|
||||||
|
find:
|
||||||
|
paths: "{{ docker_compose_root }}"
|
||||||
|
patterns: "compose.yaml"
|
||||||
|
recurse: true
|
||||||
|
register: compose_files
|
||||||
|
|
||||||
|
- name: Build stack list from discovered compose files
|
||||||
|
set_fact:
|
||||||
|
komodo_stacks: "{{ komodo_stacks | default([]) + [{'server': path_parts[0], 'app': path_parts[1]}] }}"
|
||||||
|
loop: "{{ compose_files.files }}"
|
||||||
|
vars:
|
||||||
|
path_parts: "{{ item.path | regex_replace('^.*/docker-compose/', '') | split('/') }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ path_parts[0] }}/{{ path_parts[1] }}"
|
||||||
|
|
||||||
|
- name: Display discovered stacks
|
||||||
|
debug:
|
||||||
|
msg: "Found {{ komodo_stacks | length }} stacks: {{ komodo_stacks | map(attribute='app') | list | join(', ') }}"
|
||||||
|
|
||||||
|
- name: Create Komodo stacks
|
||||||
|
include_role:
|
||||||
|
name: komodo_stack
|
||||||
|
vars:
|
||||||
|
komodo_stack_name: "{{ item.app }}"
|
||||||
|
komodo_server_name: "{{ item.server }}"
|
||||||
|
komodo_run_directory: "docker-compose/{{ item.server }}/{{ item.app }}"
|
||||||
|
loop: "{{ komodo_stacks }}"
|
||||||
|
loop_control:
|
||||||
|
label: "{{ item.app }} (on {{ item.server }})"
|
||||||
@@ -5,7 +5,7 @@ services:
|
|||||||
container_name: komodo-periphery
|
container_name: komodo-periphery
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
environment:
|
environment:
|
||||||
PERIPHERY_CORE_ADDRESS: {{ komodo_core_address }}
|
PERIPHERY_CORE_ADDRESS: {{ komodo_core_host }}
|
||||||
PERIPHERY_CONNECT_AS: {{ inventory_hostname }}
|
PERIPHERY_CONNECT_AS: {{ inventory_hostname }}
|
||||||
PERIPHERY_CORE_PUBLIC_KEYS: file:/config/keys/core.pub
|
PERIPHERY_CORE_PUBLIC_KEYS: file:/config/keys/core.pub
|
||||||
PERIPHERY_ROOT_DIRECTORY: /etc/komodo
|
PERIPHERY_ROOT_DIRECTORY: /etc/komodo
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
# Komodo Stack Role
|
||||||
|
|
||||||
|
This role automates the creation of stacks in Komodo via its REST API.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
The included `provision_komodo_stacks.yml` playbook automatically discovers all stacks from your `docker-compose/` folder structure and creates them in Komodo:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook -i inventories/production.yml playbooks/provision_komodo_stacks.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
This will scan for all `compose.yaml` files in the structure: `docker-compose/{server}/{app}/compose.yaml` and create corresponding stacks in Komodo.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- A running Komodo instance with API access
|
||||||
|
- Valid Komodo API token stored in `vault_komodo_api_token`
|
||||||
|
- Existing server and repository configured in Komodo
|
||||||
|
|
||||||
|
## Role Variables
|
||||||
|
|
||||||
|
### Required Variables
|
||||||
|
|
||||||
|
- `komodo_stack_name`: Name for the stack (typically the app name, e.g., "changedetection")
|
||||||
|
- `komodo_server_name`: Name of the server in Komodo where the stack should deploy
|
||||||
|
- `komodo_repo_name`: Name of the repository in Komodo containing the stack definition
|
||||||
|
- `komodo_run_directory`: Path within the repository to the compose.yaml file (e.g., `docker-compose/apps-1/changedetection`)
|
||||||
|
|
||||||
|
### Optional Variables
|
||||||
|
|
||||||
|
- `komodo_host`: Komodo instance URL (default: `https://komodo.{{ domain }}`)
|
||||||
|
- `komodo_api_token`: API token for authentication (default: `{{ vault_komodo_api_token }}`)
|
||||||
|
|
||||||
|
## Example Usage
|
||||||
|
|
||||||
|
### Automatic Discovery (Recommended)
|
||||||
|
|
||||||
|
Use the provided playbook to automatically discover and create all stacks from your repository:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook -i inventories/production.yml playbooks/provision_komodo_stacks.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
This scans the `docker-compose/` directory and creates stacks for each app found in the structure:
|
||||||
|
|
||||||
|
- `docker-compose/{server}/{app}/compose.yaml`
|
||||||
|
|
||||||
|
Example structure:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker-compose/
|
||||||
|
apps-1/
|
||||||
|
changedetection/
|
||||||
|
compose.yaml
|
||||||
|
turn/
|
||||||
|
compose.yaml
|
||||||
|
media-1/
|
||||||
|
arr/
|
||||||
|
compose.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## How It Works
|
||||||
|
|
||||||
|
1. Validates all required variables are provided
|
||||||
|
2. Fetches list of servers from Komodo API and finds the server ID by name
|
||||||
|
3. Fetches list of repositories from Komodo API and finds the repo ID by name
|
||||||
|
4. Checks if a stack with the same name already exists
|
||||||
|
5. Creates the stack if it doesn't exist (skips if it does)
|
||||||
|
|
||||||
|
## API Token Setup
|
||||||
|
|
||||||
|
Store your Komodo API token in an Ansible vault file:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# inventories/group_vars/all/vault.yml
|
||||||
|
vault_komodo_api_token: 'your-api-token-here'
|
||||||
|
```
|
||||||
|
|
||||||
|
Generate an API token in Komodo: Settings → API Keys → Create New Token
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- The role is idempotent - it won't create duplicate stacks
|
||||||
|
- Server and repo must already exist in Komodo before running this role
|
||||||
|
- Uses retry logic for API calls to handle temporary network issues
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
---
|
||||||
|
# Komodo API configuration
|
||||||
|
komodo_core_address: "http://{{ komodo_core_host }}"
|
||||||
|
|
||||||
|
komodo_api_key: "{{ vault_komodo_api_key }}"
|
||||||
|
komodo_api_secret: "{{ vault_komodo_api_secret }}"
|
||||||
|
|
||||||
|
# Stack configuration
|
||||||
|
komodo_repo_name: "homelab"
|
||||||
|
|
||||||
|
# Optional stack configuration
|
||||||
|
komodo_stack_environment: []
|
||||||
|
komodo_stack_labels: {}
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
---
|
||||||
|
- name: Validate required variables
|
||||||
|
assert:
|
||||||
|
that:
|
||||||
|
- komodo_stack_name is defined and komodo_stack_name | length > 0
|
||||||
|
- komodo_server_name is defined and komodo_server_name | length > 0
|
||||||
|
- komodo_repo_name is defined and komodo_repo_name | length > 0
|
||||||
|
- komodo_run_directory is defined and komodo_run_directory | length > 0
|
||||||
|
- komodo_api_key is defined and komodo_api_key | length > 0
|
||||||
|
- komodo_api_secret is defined and komodo_api_secret | length > 0
|
||||||
|
fail_msg: "Missing required variables: komodo_stack_name, komodo_server_name, komodo_repo_name, komodo_run_directory, komodo_api_key, or komodo_api_secret"
|
||||||
|
|
||||||
|
- name: Get Komodo server by name
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/read/GetServer"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
server: "{{ komodo_server_name }}"
|
||||||
|
status_code: 200
|
||||||
|
validate_certs: false
|
||||||
|
register: komodo_server
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
|
|
||||||
|
- name: Extract server ID
|
||||||
|
set_fact:
|
||||||
|
komodo_server_id: "{{ komodo_server.json._id['$oid'] }}"
|
||||||
|
|
||||||
|
- name: Debug server response
|
||||||
|
debug:
|
||||||
|
msg: "Server ID: {{ komodo_server_id }}"
|
||||||
|
|
||||||
|
- name: Get Komodo repo by name
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/read/GetRepo"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
repo: "{{ komodo_repo_name }}"
|
||||||
|
status_code: 200
|
||||||
|
validate_certs: false
|
||||||
|
register: komodo_repo
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
|
|
||||||
|
- name: Extract repo ID
|
||||||
|
set_fact:
|
||||||
|
komodo_repo_id: "{{ komodo_repo.json._id['$oid'] }}"
|
||||||
|
|
||||||
|
- name: Debug repo response
|
||||||
|
debug:
|
||||||
|
msg: "Repo ID: {{ komodo_repo_id }}"
|
||||||
|
|
||||||
|
- name: Check if stack already exists
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/read/GetStack"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
stack: "{{ komodo_stack_name }}"
|
||||||
|
status_code: [200, 500]
|
||||||
|
validate_certs: false
|
||||||
|
register: existing_stack
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Create Komodo stack
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/write/CreateStack"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
name: "{{ komodo_stack_name }}"
|
||||||
|
config:
|
||||||
|
server_id: "{{ komodo_server_id }}"
|
||||||
|
linked_repo: "{{ komodo_repo_id }}"
|
||||||
|
run_directory: "{{ komodo_run_directory }}"
|
||||||
|
status_code: [200, 201]
|
||||||
|
validate_certs: false
|
||||||
|
register: stack_result
|
||||||
|
when: existing_stack.status == 500
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
|
|
||||||
|
- name: Display stack creation result
|
||||||
|
debug:
|
||||||
|
msg: "Stack '{{ komodo_stack_name }}' created successfully with ID: {{ stack_result.json._id }}"
|
||||||
|
when: existing_stack.status == 500 and stack_result is succeeded
|
||||||
|
|
||||||
|
- name: Display stack already exists message
|
||||||
|
debug:
|
||||||
|
msg: "Stack '{{ komodo_stack_name }}' already exists with ID: {{ existing_stack.json._id }}"
|
||||||
|
when: existing_stack.status == 200
|
||||||
|
|
||||||
|
- name: Deploy stack
|
||||||
|
uri:
|
||||||
|
url: "{{ komodo_core_address }}/execute/DeployStack"
|
||||||
|
method: POST
|
||||||
|
headers:
|
||||||
|
"X-Api-Key": "{{ komodo_api_key }}"
|
||||||
|
"X-Api-Secret": "{{ komodo_api_secret }}"
|
||||||
|
"Content-Type": "application/json"
|
||||||
|
body_format: json
|
||||||
|
body:
|
||||||
|
stack: "{{ komodo_stack_name }}"
|
||||||
|
status_code: 200
|
||||||
|
validate_certs: false
|
||||||
|
register: start_result
|
||||||
|
retries: 3
|
||||||
|
delay: 2
|
||||||
Reference in New Issue
Block a user