Skip to content

Commit bd3d8d5

Browse files
committed
feat: add prod environment deployment setup
- Add prod directory deployment with ArgoCD - Configure prod.directory.outshift environment - Ingress-based external access with TLS - External OCI registry with SSL passthrough - Production logging and federation endpoints - Update onboarding templates and federation examples Partial implementation of #6 Signed-off-by: Tibor Kircsi <tkircsi@cisco.com>
1 parent c004a27 commit bd3d8d5

File tree

16 files changed

+563
-28
lines changed

16 files changed

+563
-28
lines changed

Taskfile.yml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ tasks:
1616
gen:dir:
1717
desc: Generate Directory application manifests
1818
vars:
19-
DEST_VALUES: "{{ .ROOT_DIR }}/applications/dir/gen.values.yaml"
2019
FEDERATION_SOURCE: "{{ .ROOT_DIR }}/onboarding/federation/*.yaml"
20+
DEST_VALUES: "/tmp/dir_gen_values.yaml"
21+
DEST_VALUES_DEV: "{{ .ROOT_DIR }}/applications/dir/dev/gen.values.yaml"
22+
DEST_VALUES_PROD: "{{ .ROOT_DIR }}/applications/dir/prod/gen.values.yaml"
2123
cmds:
2224
# Add initial autogen comment to the destination file
2325
- echo "# This file is autogenerated by 'task gen:dir'." > {{ .DEST_VALUES }}
@@ -26,15 +28,30 @@ tasks:
2628
# Merge all federation configs into the destination file.
2729
# Only use bash and taskfile built-ins for compatibility.
2830
- |
29-
# One-liner to convert dot notation to YAML hierarchy
31+
# Generate initial federation structure
3032
cat <<EOF >> {{ .DEST_VALUES }}
3133
apiserver:
3234
spire:
3335
federation:
3436
EOF
37+
38+
# Generate federation entries
39+
hasFederation=false
3540
for file in {{ .FEDERATION_SOURCE }}; do
3641
if [ -f "$file" ]; then
3742
echo " -" >> {{ .DEST_VALUES }}
3843
cat "$file" | sed 's/^/ /' >> {{ .DEST_VALUES }}
44+
hasFederation=true
3945
fi
4046
done
47+
48+
# Create dev and prod values files only if federation entries were found
49+
if [ "$hasFederation" = true ]; then
50+
cp {{ .DEST_VALUES }} {{ .DEST_VALUES_DEV }}
51+
cp {{ .DEST_VALUES }} {{ .DEST_VALUES_PROD }}
52+
else
53+
rm -f {{ .DEST_VALUES_DEV }} {{ .DEST_VALUES_PROD }}
54+
fi
55+
56+
# Cleanup
57+
- rm -rf {{ .DEST_VALUES }}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"chart_repo": "ghcr.io",
3+
"chart_name": "agntcy/dir/helm-charts/dirctl",
4+
"chart_version": "v0.4.2"
5+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Ref: https://github.com/agntcy/dir/blob/main/install/charts/dirctl/values.yaml
2+
3+
# Global config
4+
global:
5+
cronjob:
6+
failedJobsHistoryLimit: 10
7+
successfulJobsHistoryLimit: 10
8+
concurrencyPolicy: "Forbid"
9+
10+
# Image config
11+
image:
12+
repository: ghcr.io/agntcy/dir-ctl
13+
tag: v0.4.0
14+
pullPolicy: IfNotPresent
15+
pullSecrets: []
16+
17+
# SPIRE configuration
18+
spire:
19+
enabled: true
20+
trustDomain: prod.directory.outshift
21+
22+
# Additional environment variables (applied to all cronjobs)
23+
env:
24+
- name: DIRECTORY_CLIENT_SERVER_ADDRESS
25+
value: prod.api.directory.outshift.test:443
26+
- name: DIRECTORY_CLIENT_AUTH_MODE
27+
value: "x509"
28+
- name: DIRECTORY_CLIENT_JWT_AUDIENCE
29+
value: "spiffe://prod.directory.outshift/spire/server"
30+
31+
# CronJobs configuration
32+
cronjobs:
33+
# Search cronjob
34+
search:
35+
enabled: true
36+
schedule: "* * * * *"
37+
args:
38+
- "search"

applications/dir/prod/config.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"chart_repo": "ghcr.io",
3+
"chart_name": "agntcy/dir/helm-charts/dir",
4+
"chart_version": "v0.4.2"
5+
}

applications/dir/prod/values.yaml

Lines changed: 296 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,296 @@
1+
# Ref: https://github.com/agntcy/dir/blob/main/install/charts/dir/values.yaml
2+
3+
apiserver:
4+
# Logging configuration
5+
log_level: INFO
6+
log_format: json
7+
grpc_logging_verbose: false
8+
9+
# Image configuration
10+
image:
11+
repository: ghcr.io/agntcy/dir-apiserver
12+
tag: v0.4.0
13+
pullPolicy: IfNotPresent
14+
pullSecrets: []
15+
16+
# Expose the P2P API via NodePort for external access
17+
routingService:
18+
type: NodePort
19+
nodePort: 30555
20+
# Preserve source IPs for P2P (recommended)
21+
externalTrafficPolicy: Local
22+
23+
# Expose the DIR API via ClusterIP for internal access
24+
service:
25+
type: ClusterIP
26+
27+
# Expose the DIR API via Ingress for external access (with TLS passthrough)
28+
ingress:
29+
enabled: true
30+
className: "nginx"
31+
annotations:
32+
# Enable SSL passthrough - ingress will NOT terminate TLS
33+
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
34+
# Backend protocol is gRPC over TLS (SPIFFE mTLS)
35+
nginx.ingress.kubernetes.io/backend-protocol: "GRPCS"
36+
hosts:
37+
- host: prod.api.directory.outshift.test
38+
http:
39+
paths:
40+
- path: /
41+
pathType: ImplementationSpecific
42+
backend:
43+
service:
44+
name: dir-dir-prod-argoapp-apiserver
45+
port:
46+
number: 8888
47+
tls:
48+
- hosts:
49+
- prod.api.directory.outshift.test
50+
51+
# SPIRE configuration
52+
spire:
53+
enabled: true
54+
trustDomain: prod.directory.outshift
55+
56+
# API server configuration
57+
config:
58+
listen_address: "0.0.0.0:8888"
59+
60+
# Authentication settings (handles identity verification)
61+
# Supports both X.509 (X.509-SVID) and JWT (JWT-SVID) authentication
62+
authn:
63+
# Enable authentication
64+
enabled: true
65+
# Authentication mode: "x509" or "jwt"
66+
# - x509: Uses X.509-SVID from mutual TLS peer certificates
67+
# - jwt: Uses JWT-SVID from Authorization header
68+
mode: "x509"
69+
# SPIFFE Workload API socket path (injected by SPIRE agent)
70+
socket_path: "unix:///run/spire/agent-sockets/api.sock"
71+
# Expected audiences for JWT validation (only used in JWT mode)
72+
audiences:
73+
- "spiffe://prod.directory.outshift/spire/server"
74+
75+
# Authorization settings (handles access control policies)
76+
# Requires authentication to be enabled first
77+
authz:
78+
# Enable authorization policies
79+
enabled: true
80+
# Trust domain for this Directory server
81+
# Used to distinguish internal (same trust domain) vs external requests
82+
trust_domain: "prod.directory.outshift"
83+
84+
# Store settings for the storage backend.
85+
store:
86+
# Storage provider to use.
87+
provider: "oci"
88+
89+
# OCI-backed store
90+
oci:
91+
# Path to a local directory that will be to hold data instead of remote.
92+
# If this is set to non-empty value, only local store will be used.
93+
# local_dir: ""
94+
95+
# Cache directory to use for metadata.
96+
# cache_dir: ""
97+
98+
# Registry address to connect to
99+
# Use the external address of the Zot registry
100+
registry_address: "prod.zot.directory.outshift.test"
101+
102+
# All data will be stored under this repo.
103+
# Objects are pushed as tags, manifests, and blobs.
104+
# repository_name: ""
105+
106+
# Auth credentials to use.
107+
auth_config:
108+
insecure: "false"
109+
username: "admin"
110+
password: "admin"
111+
112+
# Routing settings for the peer-to-peer network.
113+
routing:
114+
# Address to use for routing
115+
listen_address: "/ip4/0.0.0.0/tcp/5555"
116+
117+
# Path to private key file for peer ID.
118+
# TODO: generate and mount via secret
119+
# key_path: /etc/routing/node.privkey
120+
121+
# Path to the routing datastore
122+
datastore_dir: /etc/routing/datastore
123+
124+
# Address of the Directory API server for sync operations
125+
# Use the external address of the API server
126+
directory_api_address: prod.api.directory.outshift.test:443
127+
128+
# Nodes to use for bootstrapping of the DHT.
129+
# Since we are the bootstrap node, this can be left empty.
130+
# bootstrap_peers:
131+
# - /ip4/1.1.1.1/tcp/1
132+
# - /ip4/1.1.1.1/tcp/2
133+
134+
# GossipSub configuration for efficient label announcements
135+
# When enabled, labels are propagated via GossipSub mesh to ALL subscribed peers
136+
# When disabled, falls back to DHT+Pull mechanism (higher bandwidth, limited reach)
137+
# Default: true (recommended for production)
138+
gossipsub:
139+
enabled: true
140+
141+
# Rate Limiting Configuration
142+
ratelimit:
143+
enabled: true
144+
per_client_rps: 100
145+
per_client_burst: 200
146+
147+
# Events Configuration
148+
events:
149+
subscriber_buffer_size: 100
150+
log_slow_consumers: true
151+
log_published_events: false
152+
153+
# Sync configuration
154+
sync:
155+
# How frequently the scheduler checks for pending syncs
156+
scheduler_interval: "30s"
157+
158+
# Maximum number of sync workers running concurrently
159+
worker_count: 3
160+
161+
# Timeout for individual sync operations
162+
worker_timeout: "10m"
163+
164+
# Registry monitor configuration
165+
registry_monitor:
166+
check_interval: "1m"
167+
168+
# Authentication configuration for sync operations
169+
auth_config:
170+
username: "user"
171+
password: "user"
172+
173+
# Publication configuration
174+
publication:
175+
# How frequently the scheduler checks for pending publications
176+
scheduler_interval: "15m"
177+
178+
# Maximum number of publication workers running concurrently
179+
worker_count: 2
180+
181+
# Timeout for individual publication operations
182+
worker_timeout: "30m"
183+
184+
# Extra environment variables for the apiserver container.
185+
# Add ZOT CA certs here for OCI registry TLS verification.
186+
extraEnv:
187+
- name: SSL_CERT_DIR
188+
value: "/etc/ca-certs"
189+
190+
# Persistance storage for routing datastore
191+
pvc:
192+
create: true
193+
storageClassName: "" # Use default storage class
194+
size: 5Gi
195+
196+
# Extra volume mounts for the apiserver container
197+
extraVolumeMounts:
198+
- name: zot-config-storage
199+
mountPath: /etc/zot
200+
- name: dir-ca-certs
201+
mountPath: /etc/ca-certs
202+
203+
# Extra volumes
204+
extraVolumes:
205+
# Zot config storage volume for config hot-reloading
206+
- name: zot-config-storage
207+
hostPath:
208+
path: /opt/zot-config
209+
type: DirectoryOrCreate
210+
# CA certs for Zot registry TLS verification
211+
- name: dir-ca-certs
212+
secret:
213+
secretName: prod-zot-directory-outshift-test-tls
214+
items:
215+
- key: ca.crt
216+
path: zot-ca.crt
217+
218+
# Zot registry configuration (subchart)
219+
zot:
220+
# Add persistence for data
221+
persistence: true
222+
pvc:
223+
create: true
224+
storage: 100Gi
225+
storageClassName: "" # Use default storage class
226+
accessModes: ["ReadWriteOnce"]
227+
228+
# Expose the Zot registry via Ingress for external access (with TLS termination)
229+
ingress:
230+
enabled: true
231+
className: "nginx"
232+
annotations:
233+
cert-manager.io/cluster-issuer: letsencrypt
234+
hosts:
235+
- host: prod.zot.directory.outshift.test
236+
paths:
237+
- path: /
238+
pathType: ImplementationSpecific
239+
tls:
240+
- secretName: prod-zot-directory-outshift-test-tls # legit:ignore
241+
hosts:
242+
- prod.zot.directory.outshift.test
243+
244+
# ZOT secrets
245+
mountSecret: true
246+
authHeader: "admin:admin"
247+
secretFiles:
248+
# Example htpasswd with 'admin:admin' & 'user:user' user:pass pairs
249+
htpasswd: |-
250+
admin:$2y$05$vmiurPmJvHylk78HHFWuruFFVePlit9rZWGA/FbZfTEmNRneGJtha
251+
user:$2y$05$L86zqQDfH5y445dcMlwu6uHv.oXFgT6AiJCwpv3ehr7idc0rI3S2G
252+
253+
# Zot config
254+
mountConfig: true
255+
configFiles:
256+
config.json: |-
257+
{
258+
"distSpecVersion": "1.1.1",
259+
"storage": {
260+
"rootDirectory": "/var/lib/registry"
261+
},
262+
"http": {
263+
"address": "0.0.0.0",
264+
"port": "5000",
265+
"auth": {
266+
"htpasswd": {
267+
"path": "/secret/htpasswd"
268+
}
269+
},
270+
"accessControl": {
271+
"adminPolicy": {
272+
"users": ["admin"],
273+
"actions": ["read", "create", "update", "delete"]
274+
},
275+
"repositories": {
276+
"**": {
277+
"anonymousPolicy": [],
278+
"defaultPolicy": ["read"]
279+
}
280+
}
281+
}
282+
},
283+
"log": {
284+
"level": "info"
285+
},
286+
"extensions": {
287+
"search": {
288+
"enable": true
289+
},
290+
"trust": {
291+
"enable": true,
292+
"cosign": true,
293+
"notation": false
294+
}
295+
}
296+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"chart_repo": "https://spiffe.github.io/helm-charts-hardened",
3+
"chart_name": "spire-crds",
4+
"chart_version": "0.5.0"
5+
}

0 commit comments

Comments
 (0)