feat: provision precipitation storage directory
Create managed StorageBox directories from Ansible and document the precipitation image bind mount required by the test Swarm deployment.
This commit is contained in:
parent
bf64c2964c
commit
49ea69d805
@ -38,3 +38,12 @@
|
|||||||
content: "mounted by ansible"
|
content: "mounted by ansible"
|
||||||
dest: "{{ storagebox_mount_point }}/.mounted_marker"
|
dest: "{{ storagebox_mount_point }}/.mounted_marker"
|
||||||
mode: '0644'
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Create managed StorageBox directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ item.owner | default(omit) }}"
|
||||||
|
group: "{{ item.group | default(omit) }}"
|
||||||
|
mode: "{{ item.mode | default('0755') }}"
|
||||||
|
loop: "{{ storagebox_managed_directories | default([]) }}"
|
||||||
|
|||||||
@ -3,6 +3,9 @@ storagebox_user: "{{ storagebox_account }}-sub4"
|
|||||||
storagebox_url: "https://{{ storagebox_user }}.your-storagebox.de/"
|
storagebox_url: "https://{{ storagebox_user }}.your-storagebox.de/"
|
||||||
storagebox_mount_point: "/mnt/storagebox"
|
storagebox_mount_point: "/mnt/storagebox"
|
||||||
storagebox_password: "{{ vault_storagebox_password }}"
|
storagebox_password: "{{ vault_storagebox_password }}"
|
||||||
|
storagebox_managed_directories:
|
||||||
|
- path: "{{ storagebox_mount_point }}/precipitation/images"
|
||||||
|
mode: "0755"
|
||||||
iklim_password: "{{ vault_iklim_password }}"
|
iklim_password: "{{ vault_iklim_password }}"
|
||||||
swarm_manager_ip: "10.10.10.11"
|
swarm_manager_ip: "10.10.10.11"
|
||||||
admin_allowed_cidrs: "78.187.87.109/32 95.70.151.248/32"
|
admin_allowed_cidrs: "78.187.87.109/32 95.70.151.248/32"
|
||||||
|
|||||||
@ -151,3 +151,7 @@ Final step order in the pipeline:
|
|||||||
`test/secrets/iklim.co/.env` before the first deploy.
|
`test/secrets/iklim.co/.env` before the first deploy.
|
||||||
- `RESTRICTED_IP_1` and `RESTRICTED_IP_2` are hardcoded in the pipeline step above.
|
- `RESTRICTED_IP_1` and `RESTRICTED_IP_2` are hardcoded in the pipeline step above.
|
||||||
Move to `.env` if they change often.
|
Move to `.env` if they change often.
|
||||||
|
- Precipitation service expects its image-data bind mount at
|
||||||
|
`/mnt/storagebox/precipitation/images`. This directory is provisioned by the
|
||||||
|
test Ansible bootstrap through `storagebox_managed_directories`; do not rely on
|
||||||
|
the deploy pipeline to create it.
|
||||||
|
|||||||
@ -20,7 +20,22 @@ docker service ps iklimco_apisix
|
|||||||
|
|
||||||
No tasks in `Failed` or `Rejected` state.
|
No tasks in `Failed` or `Rejected` state.
|
||||||
|
|
||||||
## 2 — SWAG obtained the cert
|
## 2 — Precipitation image directory exists
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ls -ld /mnt/storagebox/precipitation/images
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: directory exists with `0755` permissions or stricter service-approved
|
||||||
|
permissions before `iklimco_precipitation-service` is deployed.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker volume inspect iklimco_image-data
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: `Options.device` is `/mnt/storagebox/precipitation/images`.
|
||||||
|
|
||||||
|
## 3 — SWAG obtained the cert
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec $(docker ps -q -f name=iklimco_swag) \
|
docker exec $(docker ps -q -f name=iklimco_swag) \
|
||||||
@ -36,7 +51,7 @@ docker exec $(docker ps -q -f name=iklimco_swag) \
|
|||||||
|
|
||||||
Expected: `fullchain.pem`, `privkey.pem`, `cert.pem`, `chain.pem`.
|
Expected: `fullchain.pem`, `privkey.pem`, `cert.pem`, `chain.pem`.
|
||||||
|
|
||||||
## 3 — Nginx config is valid
|
## 4 — Nginx config is valid
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec $(docker ps -q -f name=iklimco_swag) nginx -t
|
docker exec $(docker ps -q -f name=iklimco_swag) nginx -t
|
||||||
@ -44,7 +59,7 @@ docker exec $(docker ps -q -f name=iklimco_swag) nginx -t
|
|||||||
|
|
||||||
Expected: `syntax is ok` and `test is successful`.
|
Expected: `syntax is ok` and `test is successful`.
|
||||||
|
|
||||||
## 4 — Public API endpoint
|
## 5 — Public API endpoint
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -si https://api-test.iklim.co/health
|
curl -si https://api-test.iklim.co/health
|
||||||
@ -60,7 +75,7 @@ echo | openssl s_client -connect api-test.iklim.co:443 -servername api-test.ikli
|
|||||||
|
|
||||||
Expected: `subject=CN=*.iklim.co`, dates valid, `notAfter` > today.
|
Expected: `subject=CN=*.iklim.co`, dates valid, `notAfter` > today.
|
||||||
|
|
||||||
## 5 — IP-restricted subdomains block non-whitelisted IPs
|
## 6 — IP-restricted subdomains block non-whitelisted IPs
|
||||||
|
|
||||||
From a non-whitelisted IP:
|
From a non-whitelisted IP:
|
||||||
```bash
|
```bash
|
||||||
@ -74,7 +89,7 @@ curl -si https://grafana-test.iklim.co
|
|||||||
```
|
```
|
||||||
Expected: HTTP 200 (Grafana login page).
|
Expected: HTTP 200 (Grafana login page).
|
||||||
|
|
||||||
## 6 — Vault is reachable internally (not externally)
|
## 7 — Vault is reachable internally (not externally)
|
||||||
|
|
||||||
From outside the server:
|
From outside the server:
|
||||||
```bash
|
```bash
|
||||||
@ -91,14 +106,14 @@ docker exec $(docker ps -q -f name=iklimco_apisix | head -1) \
|
|||||||
```
|
```
|
||||||
Expected: JSON response `{"sealed":false,...}`.
|
Expected: JSON response `{"sealed":false,...}`.
|
||||||
|
|
||||||
## 7 — cert-reloader is watching
|
## 8 — cert-reloader is watching
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker service logs iklimco_cert-reloader --tail 10
|
docker service logs iklimco_cert-reloader --tail 10
|
||||||
```
|
```
|
||||||
Expected: `[cert-reloader] started` — no errors.
|
Expected: `[cert-reloader] started` — no errors.
|
||||||
|
|
||||||
## 8 — Vault cert path is correct
|
## 9 — Vault cert path is correct
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
VAULT_CTR=$(docker ps -q -f name=iklimco_vault)
|
VAULT_CTR=$(docker ps -q -f name=iklimco_vault)
|
||||||
@ -106,7 +121,7 @@ docker exec "$VAULT_CTR" ls /vault/certs/
|
|||||||
```
|
```
|
||||||
Expected: `STAR.iklim.co.full.crt` and `STAR.iklim.co_key.txt`.
|
Expected: `STAR.iklim.co.full.crt` and `STAR.iklim.co_key.txt`.
|
||||||
|
|
||||||
## 9 — fail2ban is active (SWAG)
|
## 10 — fail2ban is active (SWAG)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker exec $(docker ps -q -f name=iklimco_swag) \
|
docker exec $(docker ps -q -f name=iklimco_swag) \
|
||||||
@ -114,7 +129,7 @@ docker exec $(docker ps -q -f name=iklimco_swag) \
|
|||||||
```
|
```
|
||||||
Expected: list of jails including `nginx-http-auth`, `nginx-botsearch`, etc.
|
Expected: list of jails including `nginx-http-auth`, `nginx-botsearch`, etc.
|
||||||
|
|
||||||
## 10 — No services have published unexpected ports
|
## 11 — No services have published unexpected ports
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
docker service ls --format "{{.Name}}\t{{.Ports}}" \
|
docker service ls --format "{{.Name}}\t{{.Ports}}" \
|
||||||
|
|||||||
@ -317,6 +317,9 @@ storagebox_user: "{{ storagebox_account }}-sub4"
|
|||||||
storagebox_url: "https://{{ storagebox_user }}.your-storagebox.de/"
|
storagebox_url: "https://{{ storagebox_user }}.your-storagebox.de/"
|
||||||
storagebox_password: "{{ vault_storagebox_password }}"
|
storagebox_password: "{{ vault_storagebox_password }}"
|
||||||
storagebox_mount_point: "/mnt/storagebox"
|
storagebox_mount_point: "/mnt/storagebox"
|
||||||
|
storagebox_managed_directories:
|
||||||
|
- path: "{{ storagebox_mount_point }}/precipitation/images"
|
||||||
|
mode: "0755"
|
||||||
```
|
```
|
||||||
|
|
||||||
Prod ortamında suffix `sub4` → `sub5` olarak değişir.
|
Prod ortamında suffix `sub4` → `sub5` olarak değişir.
|
||||||
@ -398,12 +401,31 @@ vault_iklim_password: "IKLIM_KULLANICI_PAROLASI"
|
|||||||
dest: "{{ storagebox_mount_point }}/.mounted_marker"
|
dest: "{{ storagebox_mount_point }}/.mounted_marker"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
6. **Servis bind mount dizinlerini oluştur**
|
||||||
|
|
||||||
|
Test ortamında precipitation servisinin `image-data` volume'u host üzerinde
|
||||||
|
`/mnt/storagebox/precipitation/images` dizinine bind mount edilir. Dizin
|
||||||
|
StorageBox mount edildikten sonra Ansible tarafından oluşturulur ve `0755`
|
||||||
|
izinle bırakılır.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
- name: Create managed StorageBox directories
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: directory
|
||||||
|
owner: "{{ item.owner | default(omit) }}"
|
||||||
|
group: "{{ item.group | default(omit) }}"
|
||||||
|
mode: "{{ item.mode | default('0755') }}"
|
||||||
|
loop: "{{ storagebox_managed_directories | default([]) }}"
|
||||||
|
```
|
||||||
|
|
||||||
### Notlar
|
### Notlar
|
||||||
|
|
||||||
- `davfs2` paketi EPEL repository'sinde bulunur; base role `epel-release`'i zaten kurar.
|
- `davfs2` paketi EPEL repository'sinde bulunur; base role `epel-release`'i zaten kurar.
|
||||||
- StorageBox şifreleri asla plaintext olarak repository'e eklenmez; Ansible Vault zorunludur.
|
- StorageBox şifreleri asla plaintext olarak repository'e eklenmez; Ansible Vault zorunludur.
|
||||||
- Mount noktası reboot'ta `_netdev` flag'ı sayesinde network hazır olduktan sonra otomatik mount edilir.
|
- Mount noktası reboot'ta `_netdev` flag'ı sayesinde network hazır olduktan sonra otomatik mount edilir.
|
||||||
- Docker Swarm servisleri `/mnt/storagebox/<env>/<service>/` altındaki dizinleri bind mount olarak kullanır.
|
- Docker Swarm servisleri StorageBox altındaki servis dizinlerini bind mount olarak kullanır.
|
||||||
|
- Precipitation servisinin test ortamı image dizini `/mnt/storagebox/precipitation/images` olmalıdır; bu path `BE-Precipitation/docker-stack-service.yml` içindeki `device` değeriyle birebir eşleşmelidir.
|
||||||
|
|
||||||
## StorageBox SSH Key Role
|
## StorageBox SSH Key Role
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user