feat: backup appwritefix: CORS error by adding platforms
This commit is contained in:
@@ -40,4 +40,17 @@ File is now only downloaded if absent. Upgrade playbook handles re-downloads.
|
|||||||
- Appwrite console loads without error ✅
|
- Appwrite console loads without error ✅
|
||||||
- Stack running on bab1.mgmt.toal.ca ✅
|
- Stack running on bab1.mgmt.toal.ca ✅
|
||||||
- install_appwrite.yml is idempotent ✅
|
- install_appwrite.yml is idempotent ✅
|
||||||
- node_exporter install: complete, metrics confirmed ✅
|
- node_exporter install: complete, metrics confirmed ✅
|
||||||
|
- bootstrap_appwrite.yml: project + API key creation working ✅
|
||||||
|
- API key stored at kv/oys/bab-appwrite-api-key
|
||||||
|
|
||||||
|
## bootstrap_appwrite.yml — Key Decisions
|
||||||
|
|
||||||
|
| Decision | Rationale |
|
||||||
|
|----------|-----------|
|
||||||
|
| No account creation task | Appwrite only grants console owner role via web UI signup, not REST API |
|
||||||
|
| JWT required for console API | Session cookie alone gives `role: users`; JWT carries team membership claims including `projects.write` |
|
||||||
|
| teamId fetched dynamically | Appwrite 1.8.x requires teamId in POST /v1/projects; use teams[0]['$id'] from GET /v1/teams |
|
||||||
|
| `$id` via bracket notation | Jinja2 treats `$` as special; dot notation fails |
|
||||||
|
| vault_kv2_write (not vault_kv2_put) | No put module in community.hashi_vault; no patch operation — dedicated path avoids clobbering other secrets |
|
||||||
|
| Dedicated Vault path kv/oys/bab-appwrite-api-key | Separate from env config secrets to avoid full-overwrite on re-run |
|
||||||
110
docs/summaries/handoff-2026-03-14-appwrite-bootstrap-backup.md
Normal file
110
docs/summaries/handoff-2026-03-14-appwrite-bootstrap-backup.md
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
# Session Handoff: Appwrite Bootstrap, Backup, and Bug Fixes
|
||||||
|
**Date:** 2026-03-14
|
||||||
|
**Session Duration:** ~3 hours
|
||||||
|
**Session Focus:** Fix Appwrite console crash, add bootstrap and backup playbooks
|
||||||
|
**Context Usage at Handoff:** ~85%
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What Was Accomplished
|
||||||
|
|
||||||
|
1. Fixed `_APP_DOMAIN_TARGET_CNAME` null crash → `playbooks/templates/appwrite.env.j2`
|
||||||
|
2. Fixed idempotency: removed `force: true` from compose download → `playbooks/install_appwrite.yml`
|
||||||
|
3. Fixed `appwrite_response_format` undefined error → `playbooks/provision_database.yml`, `playbooks/provision_users.yml`
|
||||||
|
4. Created Appwrite bootstrap playbook → `playbooks/bootstrap_appwrite.yml`
|
||||||
|
5. Created Appwrite backup playbook → `playbooks/backup_appwrite.yml`
|
||||||
|
6. Diagnosed nginx CORS 405 on `apidev.bab.toal.ca` — **not fixed, open**
|
||||||
|
7. Written decision record → `docs/summaries/decisions-2026-03-14-domain-target-fix.md`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Exact State of Work in Progress
|
||||||
|
|
||||||
|
- **CORS / nginx**: `apidev.bab.toal.ca` returns HTTP 405 on OPTIONS preflight from nginx/1.20.1. Root cause: nginx config does not pass OPTIONS to backend. `appwrite.toal.ca` works fine. nginx config is managed by `nginxinc.nginx_core` role; no config templates exist in this repo yet.
|
||||||
|
- **backup_appwrite.yml**: Written and structurally correct but **not yet run successfully end-to-end**. Needs a test run and restore verification.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Decisions Made This Session
|
||||||
|
|
||||||
|
| Decision | Rationale | Status |
|
||||||
|
|----------|-----------|--------|
|
||||||
|
| `_APP_DOMAIN_TARGET_CNAME` replaces `_APP_DOMAIN_TARGET` | Deprecated since Appwrite 1.7.0; compose `environment:` blocks list the new var, not the old one — old var silently never reached containers | CONFIRMED |
|
||||||
|
| `appwrite_response_format \| default('1.6')` | Var undefined at module_defaults evaluation time; `1.6` is correct format for Appwrite 1.8.x | CONFIRMED |
|
||||||
|
| bootstrap: no account creation task | Appwrite only grants console `owner` role via web UI signup; REST API creates `role: users` which lacks `projects.write` | CONFIRMED |
|
||||||
|
| bootstrap: JWT required for console API | Session cookie alone gives `role: users`; JWT carries team membership claims including `projects.write` | CONFIRMED |
|
||||||
|
| bootstrap: `teamId` fetched from `GET /v1/teams` | Required field in `POST /v1/projects` for Appwrite 1.8.x; discovered from browser network capture | CONFIRMED |
|
||||||
|
| bootstrap: `['$id']` bracket notation | Jinja2 rejects `.$id` — `$` is a special character | CONFIRMED |
|
||||||
|
| bootstrap: `vault_kv2_write` at `kv/oys/bab-appwrite-api-key` | `vault_kv2_put` does not exist; no PATCH operation — dedicated path avoids full-overwrite of other secrets | CONFIRMED |
|
||||||
|
| backup: mysqldump runs while service UP | `--single-transaction` gives consistent InnoDB snapshot; service must be up for `docker compose exec` | CONFIRMED |
|
||||||
|
| backup: `block/rescue/always` | Ensures `systemctl start appwrite` fires even if volume backup fails | CONFIRMED |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Key Numbers
|
||||||
|
|
||||||
|
- `appwrite_response_format` default: `1.6`
|
||||||
|
- Vault path for API key: `kv/oys/bab-appwrite-api-key`, key: `appwrite_api_key`
|
||||||
|
- Backup destination: `/var/backups/appwrite/YYYYMMDDTHHMMSS/`
|
||||||
|
- Volumes backed up (8): `appwrite-uploads`, `appwrite-functions`, `appwrite-builds`, `appwrite-sites`, `appwrite-certificates`, `appwrite-config`, `appwrite-cache`, `appwrite-redis`
|
||||||
|
- Volume excluded: `appwrite-mariadb` (covered by mysqldump)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Conditional Logic Established
|
||||||
|
|
||||||
|
- IF `appwrite_compose_project` not set THEN `_compose_project` defaults to `basename(appwrite_dir)` = `appwrite` → Docker volume names are `appwrite_appwrite-uploads`, etc.
|
||||||
|
- IF bootstrap re-run THEN second API key created AND Vault entry overwritten — delete old key from console manually
|
||||||
|
- IF backup fails during volume tar THEN `always` block restarts Appwrite — playbook exits failed, partial backup remains in `backup_dir`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files Created or Modified
|
||||||
|
|
||||||
|
| File Path | Action | Description |
|
||||||
|
|-----------|--------|-------------|
|
||||||
|
| `playbooks/templates/appwrite.env.j2` | Modified | Replaced `_APP_DOMAIN_TARGET` with `_APP_DOMAIN_TARGET_CNAME`; added `_APP_DOMAIN_TARGET_CAA` |
|
||||||
|
| `playbooks/install_appwrite.yml` | Modified | Removed `force: true` from `get_url` |
|
||||||
|
| `playbooks/provision_database.yml` | Modified | `appwrite_response_format \| default('1.6')`; fixed long URL line |
|
||||||
|
| `playbooks/provision_users.yml` | Modified | `appwrite_response_format \| default('1.6')` |
|
||||||
|
| `playbooks/bootstrap_appwrite.yml` | Created | Session→JWT→teams→project→API key→Vault |
|
||||||
|
| `playbooks/backup_appwrite.yml` | Created | mysqldump + volume tar + .env, block/rescue/always |
|
||||||
|
| `docs/summaries/decisions-2026-03-14-domain-target-fix.md` | Created | Decision record for domain var fix and idempotency |
|
||||||
|
| `CLAUDE.md` | Modified | Added trailing newline rule |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What the NEXT Session Should Do
|
||||||
|
|
||||||
|
1. **Fix nginx CORS** — `apidev.bab.toal.ca` returns 405 on OPTIONS. Load `playbooks/install_nginx.yml`; find where `nginxinc.nginx_core.nginx_config` vars are defined in inventory and add OPTIONS passthrough.
|
||||||
|
2. **Test backup end-to-end** — run `ansible-navigator run playbooks/backup_appwrite.yml --mode stdout`, verify 8 volume tarballs + `mariadb-dump.sql` + `.env` in `/var/backups/appwrite/<timestamp>/`
|
||||||
|
3. **Validate volume name prefix** — run `docker volume ls | grep appwrite` on bab1 to confirm prefix is `appwrite_`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Open Questions Requiring User Input
|
||||||
|
|
||||||
|
- [ ] **CORS fix scope**: Should nginx config live in this repo as templates, or managed elsewhere? — impacts `install_nginx.yml` completion
|
||||||
|
- [ ] **Backup retention**: No rotation yet — each run adds a timestamped dir. Add cleanup task?
|
||||||
|
- [ ] **Backup offsite**: 3-2-1 rule — is S3/rsync in scope?
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Assumptions That Need Validation
|
||||||
|
|
||||||
|
- ASSUMED: Docker Compose project name for volumes is `appwrite` (basename of `/home/ptoal/appwrite`) — validate with `docker volume ls`
|
||||||
|
- ASSUMED: `teams[0]` in bootstrap is always the admin's personal team — valid only if admin has one team
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## What NOT to Re-Read
|
||||||
|
|
||||||
|
- `docs/summaries/handoff-2026-03-14-appwrite-setup-final.md` — superseded; moved to archive
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Files to Load Next Session
|
||||||
|
|
||||||
|
- `playbooks/install_nginx.yml` — if working on CORS fix
|
||||||
|
- `playbooks/backup_appwrite.yml` — if testing/fixing backup
|
||||||
|
- `docs/context/architecture.md` — for Appwrite API or EDA work
|
||||||
98
playbooks/backup_appwrite.yml
Normal file
98
playbooks/backup_appwrite.yml
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
---
|
||||||
|
# Backs up a running Appwrite instance per the official backup guide:
|
||||||
|
# https://appwrite.io/docs/advanced/self-hosting/production/backups
|
||||||
|
#
|
||||||
|
# What is backed up:
|
||||||
|
# - MariaDB: mysqldump (--single-transaction, consistent without downtime)
|
||||||
|
# - Docker volumes: all data volumes (tar.gz, requires service stop)
|
||||||
|
# - .env file
|
||||||
|
#
|
||||||
|
# Backup is written to: {{ appwrite_backup_root }}/YYYYMMDDTHHMMSS/
|
||||||
|
#
|
||||||
|
# Required vars (from inventory):
|
||||||
|
# appwrite_dir - e.g. /home/ptoal/appwrite
|
||||||
|
#
|
||||||
|
# Optional vars:
|
||||||
|
# appwrite_backup_root - destination parent dir (default: /var/backups/appwrite)
|
||||||
|
# appwrite_compose_project - compose project name (default: basename of appwrite_dir)
|
||||||
|
|
||||||
|
- name: Backup Appwrite
|
||||||
|
hosts: appwrite
|
||||||
|
gather_facts: true
|
||||||
|
become: true
|
||||||
|
|
||||||
|
vars:
|
||||||
|
_compose_project: "{{ appwrite_compose_project | default(appwrite_dir | basename) }}"
|
||||||
|
backup_root: "{{ appwrite_backup_root | default('/var/backups/appwrite') }}"
|
||||||
|
backup_dir: "{{ backup_root }}/{{ ansible_date_time.iso8601_basic_short }}"
|
||||||
|
# appwrite-mariadb volume excluded — covered by the mysqldump below.
|
||||||
|
# appwrite-cache and appwrite-redis are transient but included for
|
||||||
|
# completeness; they are safe to omit if backup size is a concern.
|
||||||
|
appwrite_volumes:
|
||||||
|
- appwrite-uploads
|
||||||
|
- appwrite-functions
|
||||||
|
- appwrite-builds
|
||||||
|
- appwrite-sites
|
||||||
|
- appwrite-certificates
|
||||||
|
- appwrite-config
|
||||||
|
- appwrite-cache
|
||||||
|
- appwrite-redis
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Create backup directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ backup_dir }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0700'
|
||||||
|
|
||||||
|
- name: Dump MariaDB
|
||||||
|
# --single-transaction gives a consistent InnoDB snapshot without locking.
|
||||||
|
# Runs while the service is still up so docker compose exec is available.
|
||||||
|
ansible.builtin.shell:
|
||||||
|
cmd: >
|
||||||
|
docker compose exec -T mariadb
|
||||||
|
sh -c 'exec mysqldump --all-databases --add-drop-database
|
||||||
|
--single-transaction --routines --triggers
|
||||||
|
-uroot -p"$MYSQL_ROOT_PASSWORD"'
|
||||||
|
> {{ backup_dir }}/mariadb-dump.sql
|
||||||
|
chdir: "{{ appwrite_dir }}"
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Stop, back up volumes, and restart
|
||||||
|
block:
|
||||||
|
- name: Stop Appwrite service
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: appwrite
|
||||||
|
state: stopped
|
||||||
|
|
||||||
|
- name: Back up Docker volumes
|
||||||
|
ansible.builtin.command:
|
||||||
|
cmd: >
|
||||||
|
docker run --rm
|
||||||
|
-v {{ _compose_project }}_{{ item }}:/data
|
||||||
|
-v {{ backup_dir }}:/backup
|
||||||
|
ubuntu tar czf /backup/{{ item }}.tar.gz -C /data .
|
||||||
|
loop: "{{ appwrite_volumes }}"
|
||||||
|
changed_when: true
|
||||||
|
|
||||||
|
- name: Back up .env
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ appwrite_dir }}/.env"
|
||||||
|
dest: "{{ backup_dir }}/.env"
|
||||||
|
remote_src: true
|
||||||
|
mode: '0600'
|
||||||
|
|
||||||
|
rescue:
|
||||||
|
- name: Notify that backup failed
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Backup failed — Appwrite will be restarted. Check {{ backup_dir }} for partial output."
|
||||||
|
|
||||||
|
always:
|
||||||
|
- name: Ensure Appwrite service is started
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
name: appwrite
|
||||||
|
state: started
|
||||||
|
|
||||||
|
- name: Report backup location
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Backup written to {{ backup_dir }}"
|
||||||
176
playbooks/bootstrap_appwrite.yml
Normal file
176
playbooks/bootstrap_appwrite.yml
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
---
|
||||||
|
# Bootstraps a fresh Appwrite instance:
|
||||||
|
# 1. Creates the console admin user
|
||||||
|
# 2. Creates the BAB project
|
||||||
|
# 3. Registers web platforms (CORS allowed origins)
|
||||||
|
# 4. Generates an Ansible automation API key
|
||||||
|
# 5. Stores the API key secret in Vault at kv/oys/bab-appwrite-api-key
|
||||||
|
#
|
||||||
|
# Run once per environment after install_appwrite.yml.
|
||||||
|
# Safe to re-run: account and project creation tolerate 409.
|
||||||
|
# Platform and API key creation are NOT idempotent — re-running creates
|
||||||
|
# duplicates. Delete stale entries from the console.
|
||||||
|
#
|
||||||
|
# Required vars (from inventory):
|
||||||
|
# appwrite_domain - e.g. appwrite.toal.ca (used to build admin URL)
|
||||||
|
# appwrite_project - project ID to create
|
||||||
|
# appwrite_project_name - human-readable project name (default: BAB)
|
||||||
|
# appwrite_web_platforms - list of {name, hostname} dicts for CORS origins
|
||||||
|
#
|
||||||
|
# Note: uses appwrite_domain directly, not appwrite_admin_uri, because
|
||||||
|
# appwrite_admin_uri may point to an app-layer proxy (e.g. nginx) that
|
||||||
|
# does not expose the Appwrite admin/console endpoints.
|
||||||
|
|
||||||
|
- name: Bootstrap Appwrite — Admin, Project, and API Key
|
||||||
|
hosts: appwrite
|
||||||
|
gather_facts: false
|
||||||
|
|
||||||
|
vars:
|
||||||
|
appwrite_admin_uri: "https://{{ appwrite_domain }}/v1"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
- name: Read admin credentials from Vault
|
||||||
|
community.hashi_vault.vault_kv2_get:
|
||||||
|
path: oys/bab_admin
|
||||||
|
engine_mount_point: kv
|
||||||
|
register: vault_admin
|
||||||
|
no_log: true
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Create Appwrite console admin account
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ appwrite_admin_uri }}/account"
|
||||||
|
method: POST
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
X-Appwrite-Project: console
|
||||||
|
X-Appwrite-Response-Format: "1.6"
|
||||||
|
body:
|
||||||
|
userId: "{{ appwrite_admin_user_id | default('bab-admin') }}"
|
||||||
|
email: "{{ vault_admin.secret.bab_admin_user }}"
|
||||||
|
password: "{{ vault_admin.secret.bab_admin_password }}"
|
||||||
|
status_code: [201, 409, 501]
|
||||||
|
return_content: true
|
||||||
|
delegate_to: localhost
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Create admin session
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ appwrite_admin_uri }}/account/sessions/email"
|
||||||
|
method: POST
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
X-Appwrite-Project: console
|
||||||
|
X-Appwrite-Response-Format: "1.6"
|
||||||
|
body:
|
||||||
|
email: "{{ vault_admin.secret.bab_admin_user }}"
|
||||||
|
password: "{{ vault_admin.secret.bab_admin_password }}"
|
||||||
|
status_code: [201]
|
||||||
|
return_content: true
|
||||||
|
register: admin_session
|
||||||
|
delegate_to: localhost
|
||||||
|
no_log: false
|
||||||
|
|
||||||
|
- name: Create JWT from admin session
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ appwrite_admin_uri }}/account/jwt"
|
||||||
|
method: POST
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
X-Appwrite-Project: console
|
||||||
|
X-Appwrite-Response-Format: "1.6"
|
||||||
|
Cookie: "{{ admin_session.cookies_string }}"
|
||||||
|
status_code: [201]
|
||||||
|
return_content: true
|
||||||
|
register: admin_jwt
|
||||||
|
delegate_to: localhost
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Get admin user teams
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ appwrite_admin_uri }}/teams"
|
||||||
|
method: GET
|
||||||
|
headers:
|
||||||
|
X-Appwrite-Project: console
|
||||||
|
X-Appwrite-Response-Format: "1.6"
|
||||||
|
X-Appwrite-JWT: "{{ admin_jwt.json.jwt }}"
|
||||||
|
status_code: [200]
|
||||||
|
return_content: true
|
||||||
|
register: admin_teams
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Create BAB project
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ appwrite_admin_uri }}/projects"
|
||||||
|
method: POST
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
X-Appwrite-Project: console
|
||||||
|
X-Appwrite-Response-Format: "1.6"
|
||||||
|
X-Appwrite-JWT: "{{ admin_jwt.json.jwt }}"
|
||||||
|
body:
|
||||||
|
projectId: "{{ appwrite_project }}"
|
||||||
|
name: "{{ appwrite_project_name | default('BAB') }}"
|
||||||
|
teamId: "{{ admin_teams.json.teams[0]['$id'] }}"
|
||||||
|
region: default
|
||||||
|
status_code: [201, 409]
|
||||||
|
return_content: true
|
||||||
|
delegate_to: localhost
|
||||||
|
no_log: false
|
||||||
|
|
||||||
|
- name: Register web platforms (CORS allowed origins)
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ appwrite_admin_uri }}/projects/{{ appwrite_project }}/platforms"
|
||||||
|
method: POST
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
X-Appwrite-Project: console
|
||||||
|
X-Appwrite-Response-Format: "1.6"
|
||||||
|
X-Appwrite-JWT: "{{ admin_jwt.json.jwt }}"
|
||||||
|
body:
|
||||||
|
type: web
|
||||||
|
name: "{{ item.name }}"
|
||||||
|
hostname: "{{ item.hostname }}"
|
||||||
|
status_code: [201]
|
||||||
|
return_content: true
|
||||||
|
loop: "{{ appwrite_web_platforms | default([]) }}"
|
||||||
|
delegate_to: localhost
|
||||||
|
|
||||||
|
- name: Create Ansible automation API key
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ appwrite_admin_uri }}/projects/{{ appwrite_project }}/keys"
|
||||||
|
method: POST
|
||||||
|
body_format: json
|
||||||
|
headers:
|
||||||
|
X-Appwrite-Project: console
|
||||||
|
X-Appwrite-Response-Format: "1.6"
|
||||||
|
X-Appwrite-JWT: "{{ admin_jwt.json.jwt }}"
|
||||||
|
body:
|
||||||
|
name: ansible-automation
|
||||||
|
scopes:
|
||||||
|
- databases.read
|
||||||
|
- databases.write
|
||||||
|
- collections.read
|
||||||
|
- collections.write
|
||||||
|
- attributes.read
|
||||||
|
- attributes.write
|
||||||
|
- indexes.read
|
||||||
|
- indexes.write
|
||||||
|
- documents.read
|
||||||
|
- documents.write
|
||||||
|
- users.read
|
||||||
|
- users.write
|
||||||
|
status_code: [201]
|
||||||
|
return_content: true
|
||||||
|
register: api_key
|
||||||
|
delegate_to: localhost
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
- name: Store API key secret in Vault
|
||||||
|
community.hashi_vault.vault_kv2_write:
|
||||||
|
path: oys/bab-appwrite-api-key
|
||||||
|
engine_mount_point: kv
|
||||||
|
data:
|
||||||
|
appwrite_api_key: "{{ api_key.json.secret }}"
|
||||||
|
delegate_to: localhost
|
||||||
|
no_log: true
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
ansible.builtin.uri:
|
ansible.builtin.uri:
|
||||||
body_format: json
|
body_format: json
|
||||||
headers:
|
headers:
|
||||||
X-Appwrite-Response-Format: '{{ appwrite_response_format }}'
|
X-Appwrite-Response-Format: '{{ appwrite_response_format | default("1.6") }}'
|
||||||
X-Appwrite-Project: '{{ appwrite_project }}'
|
X-Appwrite-Project: '{{ appwrite_project }}'
|
||||||
X-Appwrite-Key: '{{ appwrite_api_key }}'
|
X-Appwrite-Key: '{{ appwrite_api_key }}'
|
||||||
return_content: true
|
return_content: true
|
||||||
@@ -46,7 +46,9 @@
|
|||||||
|
|
||||||
- name: Create Attributes
|
- name: Create Attributes
|
||||||
ansible.builtin.uri:
|
ansible.builtin.uri:
|
||||||
url: "{{ appwrite_api_uri }}/databases/{{ bab_database.id }}/collections/{{ item[0].id }}/attributes/{{ ( item[1].format is defined and item[1].format != '' ) |ternary(item[1].format, item[1].type) }}"
|
url: >-
|
||||||
|
{{ appwrite_api_uri }}/databases/{{ bab_database.id }}/collections/{{ item[0].id }}/attributes/{{
|
||||||
|
(item[1].format is defined and item[1].format != '') | ternary(item[1].format, item[1].type) }}
|
||||||
method: POST
|
method: POST
|
||||||
body: "{{ lookup('ansible.builtin.template', 'appwrite_attribute_template.json.j2') }}"
|
body: "{{ lookup('ansible.builtin.template', 'appwrite_attribute_template.json.j2') }}"
|
||||||
status_code: [202, 409]
|
status_code: [202, 409]
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
body_format: json
|
body_format: json
|
||||||
headers:
|
headers:
|
||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
X-Appwrite-Response-Format: '{{ appwrite_response_format }}'
|
X-Appwrite-Response-Format: '{{ appwrite_response_format | default("1.6") }}'
|
||||||
X-Appwrite-Project: '{{ appwrite_project }}'
|
X-Appwrite-Project: '{{ appwrite_project }}'
|
||||||
X-Appwrite-Key: '{{ appwrite_api_key }}'
|
X-Appwrite-Key: '{{ appwrite_api_key }}'
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user