Parameterize Zitadel deployment variables
This commit is contained in:
parent
2c820b3416
commit
6279b005b2
12
playbooks/deploy_zitadel_docker.yaml
Normal file
12
playbooks/deploy_zitadel_docker.yaml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
- name: setup zitadel
|
||||||
|
hosts: "{{ zitadel_target_host }}"
|
||||||
|
become: true
|
||||||
|
vars:
|
||||||
|
zitadel_target_host: auth.svc.plus
|
||||||
|
zitadel_domain: "{{ zitadel_target_host }}"
|
||||||
|
zitadel_masterkey: MasterkeyNeedsToHave32Characters
|
||||||
|
zitadel_workspace: /opt/zitadel
|
||||||
|
roles:
|
||||||
|
- roles/vhosts/common/
|
||||||
|
- roles/vhosts/docker/
|
||||||
|
- roles/docker/zitadel/
|
||||||
23
playbooks/roles/docker/zitadel/README.md
Normal file
23
playbooks/roles/docker/zitadel/README.md
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Zitadel Docker role
|
||||||
|
|
||||||
|
This role provisions a Zitadel stack with Postgres, optional TLS termination, login frontend, Nginx proxy, and Certbot assets. Templates from `templates/` and static assets from `files/` are rendered into `{{ zitadel_workspace }}` and the Docker Compose stack is started.
|
||||||
|
|
||||||
|
## Layout
|
||||||
|
```
|
||||||
|
files/
|
||||||
|
├── certbot/
|
||||||
|
│ ├── conf/
|
||||||
|
│ └── www/
|
||||||
|
├── docker-compose.yaml
|
||||||
|
├── nginx/
|
||||||
|
│ ├── conf.d/
|
||||||
|
│ │ └── default.conf
|
||||||
|
│ └── nginx.conf
|
||||||
|
└── run.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## Defaults
|
||||||
|
- `zitadel_deploy_dir`: `/opt/zitadel`
|
||||||
|
- `zitadel_workspace`: `{{ zitadel_deploy_dir }}`
|
||||||
|
- `zitadel_domain`: `auth.svc.plus`
|
||||||
|
- `zitadel_masterkey`: `MasterkeyNeedsToHave32Characters`
|
||||||
6
playbooks/roles/docker/zitadel/defaults/main.yml
Normal file
6
playbooks/roles/docker/zitadel/defaults/main.yml
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
# Default deployment directory for Zitadel Docker stack
|
||||||
|
zitadel_deploy_dir: /opt/zitadel
|
||||||
|
zitadel_workspace: "{{ zitadel_deploy_dir }}"
|
||||||
|
zitadel_domain: auth.svc.plus
|
||||||
|
zitadel_masterkey: MasterkeyNeedsToHave32Characters
|
||||||
5
playbooks/roles/docker/zitadel/files/nginx/nginx.conf
Normal file
5
playbooks/roles/docker/zitadel/files/nginx/nginx.conf
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
events {}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/conf.d/*.conf;
|
||||||
|
}
|
||||||
6
playbooks/roles/docker/zitadel/files/run.sh
Normal file
6
playbooks/roles/docker/zitadel/files/run.sh
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Helper script to start the Zitadel docker compose stack
|
||||||
|
cd "$(dirname "$0")"
|
||||||
|
docker-compose -f docker-compose.yaml up -d
|
||||||
40
playbooks/roles/docker/zitadel/tasks/main.yml
Normal file
40
playbooks/roles/docker/zitadel/tasks/main.yml
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
---
|
||||||
|
- name: Ensure Zitadel directories exist
|
||||||
|
become: true
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: directory
|
||||||
|
mode: "0755"
|
||||||
|
loop:
|
||||||
|
- "{{ zitadel_workspace }}"
|
||||||
|
- "{{ zitadel_workspace }}/certbot"
|
||||||
|
- "{{ zitadel_workspace }}/certbot/conf"
|
||||||
|
- "{{ zitadel_workspace }}/certbot/www"
|
||||||
|
- "{{ zitadel_workspace }}/nginx"
|
||||||
|
- "{{ zitadel_workspace }}/nginx/conf.d"
|
||||||
|
|
||||||
|
- name: Template Zitadel configuration files
|
||||||
|
become: true
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ zitadel_workspace }}/{{ item.dest }}"
|
||||||
|
mode: "{{ item.mode | default('0644') }}"
|
||||||
|
loop:
|
||||||
|
- { src: 'docker-compose.yaml', dest: 'docker-compose.yaml' }
|
||||||
|
- { src: 'nginx/conf.d/default.conf', dest: 'nginx/conf.d/default.conf' }
|
||||||
|
|
||||||
|
- name: Copy Zitadel static files
|
||||||
|
become: true
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ item.src }}"
|
||||||
|
dest: "{{ zitadel_workspace }}/{{ item.dest }}"
|
||||||
|
mode: "{{ item.mode | default('0644') }}"
|
||||||
|
loop:
|
||||||
|
- { src: 'run.sh', dest: 'run.sh', mode: '0755' }
|
||||||
|
- { src: 'nginx/nginx.conf', dest: 'nginx/nginx.conf' }
|
||||||
|
|
||||||
|
- name: Bring up Zitadel stack
|
||||||
|
become: true
|
||||||
|
ansible.builtin.command: docker-compose -f {{ zitadel_workspace }}/docker-compose.yaml up -d
|
||||||
|
args:
|
||||||
|
chdir: "{{ zitadel_workspace }}"
|
||||||
168
playbooks/roles/docker/zitadel/templates/docker-compose.yaml
Normal file
168
playbooks/roles/docker/zitadel/templates/docker-compose.yaml
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
services:
|
||||||
|
|
||||||
|
zitadel-external-tls:
|
||||||
|
extends:
|
||||||
|
service: zitadel-init
|
||||||
|
command: 'start-from-setup --masterkey "{{ zitadel_masterkey }}"'
|
||||||
|
environment:
|
||||||
|
ZITADEL_EXTERNALPORT: 443
|
||||||
|
ZITADEL_EXTERNALSECURE: true
|
||||||
|
ZITADEL_TLS_ENABLED: false
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
- db
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: 'service_healthy'
|
||||||
|
zitadel-init:
|
||||||
|
condition: 'service_completed_successfully'
|
||||||
|
|
||||||
|
zitadel-enabled-tls:
|
||||||
|
extends:
|
||||||
|
service: zitadel-init
|
||||||
|
command: 'start-from-setup --masterkey "{{ zitadel_masterkey }}"'
|
||||||
|
environment:
|
||||||
|
ZITADEL_EXTERNALPORT: 443
|
||||||
|
ZITADEL_EXTERNALSECURE: true
|
||||||
|
ZITADEL_TLS_ENABLED: true
|
||||||
|
ZITADEL_TLS_CERTPATH: /etc/letsencrypt/live/{{ zitadel_domain }}/fullchain.pem
|
||||||
|
ZITADEL_TLS_KEYPATH: /etc/letsencrypt/live/{{ zitadel_domain }}/privkey.pem
|
||||||
|
volumes:
|
||||||
|
- "{{ zitadel_workspace }}/certbot/conf:/etc/letsencrypt"
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
- db
|
||||||
|
depends_on:
|
||||||
|
zitadel-init:
|
||||||
|
condition: 'service_completed_successfully'
|
||||||
|
db:
|
||||||
|
condition: 'service_healthy'
|
||||||
|
|
||||||
|
zitadel-init:
|
||||||
|
image: '${ZITADEL_IMAGE:-ghcr.io/zitadel/zitadel:latest}'
|
||||||
|
command: 'init'
|
||||||
|
depends_on:
|
||||||
|
db:
|
||||||
|
condition: 'service_healthy'
|
||||||
|
environment:
|
||||||
|
# Using an external domain other than localhost proofs, that the proxy configuration works.
|
||||||
|
# If Zitadel can't resolve a requests original host to this domain,
|
||||||
|
# it will return a 404 Instance not found error.
|
||||||
|
ZITADEL_EXTERNALDOMAIN: {{ zitadel_domain }}
|
||||||
|
# In case something doesn't work as expected,
|
||||||
|
# it can be handy to be able to read the access logs.
|
||||||
|
ZITADEL_LOGSTORE_ACCESS_STDOUT_ENABLED: true
|
||||||
|
# For convenience, ZITADEL should not ask to change the initial admin users password.
|
||||||
|
ZITADEL_FIRSTINSTANCE_ORG_HUMAN_PASSWORDCHANGEREQUIRED: false
|
||||||
|
# database configuration
|
||||||
|
ZITADEL_DATABASE_POSTGRES_HOST: db
|
||||||
|
ZITADEL_DATABASE_POSTGRES_USER_PASSWORD: zitadel_pw
|
||||||
|
# Set up a service account with IAM_LOGIN_CLIENT role and write the PAT to the file ./login-client.pat
|
||||||
|
ZITADEL_FIRSTINSTANCE_LOGINCLIENTPATPATH: /current-dir/login-client.pat
|
||||||
|
ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_USERNAME: login-client
|
||||||
|
ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_MACHINE_NAME: Automatically Initialized IAM Login Client
|
||||||
|
ZITADEL_FIRSTINSTANCE_ORG_LOGINCLIENT_PAT_EXPIRATIONDATE: '2029-01-01T00:00:00Z'
|
||||||
|
# The master key is used to
|
||||||
|
networks:
|
||||||
|
- db
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD", "/app/zitadel", "ready" ]
|
||||||
|
interval: '10s'
|
||||||
|
timeout: '5s'
|
||||||
|
retries: 5
|
||||||
|
start_period: '10s'
|
||||||
|
volumes:
|
||||||
|
- "{{ zitadel_workspace }}:/current-dir:rw"
|
||||||
|
|
||||||
|
db:
|
||||||
|
restart: 'always'
|
||||||
|
image: postgres:17-alpine
|
||||||
|
environment:
|
||||||
|
POSTGRES_PASSWORD: postgres
|
||||||
|
healthcheck:
|
||||||
|
test: [ "CMD-SHELL", "pg_isready" ]
|
||||||
|
interval: 5s
|
||||||
|
timeout: 60s
|
||||||
|
retries: 10
|
||||||
|
start_period: 5s
|
||||||
|
networks:
|
||||||
|
- db
|
||||||
|
volumes:
|
||||||
|
- 'data:/var/lib/postgresql/data:rw'
|
||||||
|
|
||||||
|
login-external-tls:
|
||||||
|
restart: 'unless-stopped'
|
||||||
|
image: 'ghcr.io/zitadel/zitadel-login:latest'
|
||||||
|
environment:
|
||||||
|
- ZITADEL_API_URL=http://zitadel-external-tls:8080
|
||||||
|
- NEXT_PUBLIC_BASE_PATH=/ui/v2/login
|
||||||
|
- ZITADEL_SERVICE_USER_TOKEN_FILE=/current-dir/login-client.pat
|
||||||
|
- CUSTOM_REQUEST_HEADERS=Host:{{ zitadel_domain }}
|
||||||
|
volumes:
|
||||||
|
- "{{ zitadel_workspace }}:/current-dir:ro"
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
depends_on:
|
||||||
|
zitadel-external-tls:
|
||||||
|
condition: 'service_healthy'
|
||||||
|
|
||||||
|
login-enabled-tls:
|
||||||
|
restart: 'unless-stopped'
|
||||||
|
image: 'ghcr.io/zitadel/zitadel-login:latest'
|
||||||
|
environment:
|
||||||
|
- ZITADEL_API_URL=https://zitadel-enabled-tls:8080
|
||||||
|
- NEXT_PUBLIC_BASE_PATH=/ui/v2/login
|
||||||
|
- ZITADEL_SERVICE_USER_TOKEN_FILE=/current-dir/login-client.pat
|
||||||
|
- CUSTOM_REQUEST_HEADERS=Host:{{ zitadel_domain }}
|
||||||
|
- NODE_TLS_REJECT_UNAUTHORIZED=0
|
||||||
|
volumes:
|
||||||
|
- "{{ zitadel_workspace }}:/current-dir:ro"
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
depends_on:
|
||||||
|
zitadel-enabled-tls:
|
||||||
|
condition: 'service_healthy'
|
||||||
|
|
||||||
|
proxy-external-tls:
|
||||||
|
image: nginx:mainline-alpine
|
||||||
|
container_name: proxy-external-tls
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- "{{ zitadel_workspace }}/nginx/nginx.conf:/etc/nginx/nginx.conf"
|
||||||
|
- "{{ zitadel_workspace }}/nginx/conf.d:/etc/nginx/conf.d:ro"
|
||||||
|
- "{{ zitadel_workspace }}/certbot/conf:/etc/letsencrypt"
|
||||||
|
- "{{ zitadel_workspace }}/certbot/www:/var/www/certbot"
|
||||||
|
ports:
|
||||||
|
- "80:80"
|
||||||
|
- "443:443"
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
depends_on:
|
||||||
|
zitadel-external-tls:
|
||||||
|
condition: service_healthy
|
||||||
|
|
||||||
|
certbot:
|
||||||
|
image: certbot/certbot
|
||||||
|
container_name: certbot
|
||||||
|
command: >
|
||||||
|
certonly --webroot
|
||||||
|
--webroot-path=/var/www/certbot
|
||||||
|
--email manbuzhe2009@qq.com
|
||||||
|
--agree-tos
|
||||||
|
--no-eff-email
|
||||||
|
-d {{ zitadel_domain }}
|
||||||
|
volumes:
|
||||||
|
- "{{ zitadel_workspace }}/certbot/conf:/etc/letsencrypt"
|
||||||
|
- "{{ zitadel_workspace }}/certbot/www:/var/www/certbot"
|
||||||
|
depends_on:
|
||||||
|
proxy-external-tls:
|
||||||
|
condition: service_started
|
||||||
|
networks:
|
||||||
|
- app
|
||||||
|
|
||||||
|
networks:
|
||||||
|
app:
|
||||||
|
db:
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
data:
|
||||||
@ -0,0 +1,42 @@
|
|||||||
|
# ----------------------------------------------------
|
||||||
|
# 80 - ACME Challenge + Redirect to HTTPS
|
||||||
|
# ----------------------------------------------------
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name {{ zitadel_domain }};
|
||||||
|
|
||||||
|
# Certbot HTTP-01 challenge
|
||||||
|
location ^~ /.well-known/acme-challenge/ {
|
||||||
|
root /var/www/certbot;
|
||||||
|
}
|
||||||
|
|
||||||
|
# All HTTP → HTTPS
|
||||||
|
location / {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# ----------------------------------------------------
|
||||||
|
# 443 - TLS Termination
|
||||||
|
# ----------------------------------------------------
|
||||||
|
server {
|
||||||
|
listen 443 ssl http2;
|
||||||
|
server_name {{ zitadel_domain }};
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/{{ zitadel_domain }}/fullchain.pem;
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/{{ zitadel_domain }}/privkey.pem;
|
||||||
|
|
||||||
|
ssl_protocols TLSv1.2 TLSv1.3;
|
||||||
|
ssl_prefer_server_ciphers on;
|
||||||
|
|
||||||
|
location /ui/v2/login {
|
||||||
|
proxy_pass http://login-external-tls:3000;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Forwarded-Proto https;
|
||||||
|
}
|
||||||
|
location / {
|
||||||
|
grpc_pass grpc://zitadel-external-tls:8080;
|
||||||
|
grpc_set_header Host $host;
|
||||||
|
grpc_set_header X-Forwarded-Proto https;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user