Files
ansible-role-kraken-bot/tasks/main.yml
T
2026-10-21 21:09:45 -04:00

227 lines
7.9 KiB
YAML

---
- name: Validate deployment settings
ansible.builtin.assert:
that:
- kraken_bot_image | length > 0
- kraken_bot_dashboard_password | length >= 16
- kraken_bot_replicas | int == 1
- kraken_bot_config is mapping
- kraken_bot_config.strategies is defined
- >-
(not (kraken_bot_live_trading_enabled | bool)) or
((kraken_bot_api_key | length > 0) and (kraken_bot_api_secret | length > 0))
- >-
(kraken_bot_live_trading_enabled | bool) or
(kraken_bot_config.strategies | selectattr('mode', 'defined')
| selectattr('mode', 'equalto', 'live') | list | length == 0)
fail_msg: >-
Set kraken_bot_image and a dashboard password of at least 16 characters.
Live mode additionally requires kraken_bot_live_trading_enabled=true and
Kraken API credentials. This role only supports one replica because all
strategies share the same account and persistent state.
- name: Create application namespace
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: "{{ kraken_bot_namespace }}"
labels:
app.kubernetes.io/name: "{{ kraken_bot_name }}"
app.kubernetes.io/managed-by: ansible
kubeconfig: "{{ kraken_bot_kubeconfig | default(omit, true) }}"
context: "{{ kraken_bot_kube_context | default(omit, true) }}"
- name: Create persistent application data volume
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: "{{ kraken_bot_name }}-data"
namespace: "{{ kraken_bot_namespace }}"
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: "{{ kraken_bot_storage_size }}"
storageClassName: "{{ kraken_bot_storage_class | default(omit, true) }}"
kubeconfig: "{{ kraken_bot_kubeconfig | default(omit, true) }}"
context: "{{ kraken_bot_kube_context | default(omit, true) }}"
- name: Create strategy configuration
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: ConfigMap
metadata:
name: "{{ kraken_bot_name }}-config"
namespace: "{{ kraken_bot_namespace }}"
data:
strategies.yaml: "{{ kraken_bot_config | to_nice_yaml(indent=2, sort_keys=false) }}"
kubeconfig: "{{ kraken_bot_kubeconfig | default(omit, true) }}"
context: "{{ kraken_bot_kube_context | default(omit, true) }}"
- name: Create credentials secret
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Secret
metadata:
name: "{{ kraken_bot_name }}-secrets"
namespace: "{{ kraken_bot_namespace }}"
type: Opaque
stringData:
KRAKEN_API_KEY: "{{ kraken_bot_api_key }}"
KRAKEN_API_SECRET: "{{ kraken_bot_api_secret }}"
DASHBOARD_USERNAME: "{{ kraken_bot_dashboard_username }}"
DASHBOARD_PASSWORD: "{{ kraken_bot_dashboard_password }}"
kubeconfig: "{{ kraken_bot_kubeconfig | default(omit, true) }}"
context: "{{ kraken_bot_kube_context | default(omit, true) }}"
no_log: true
- name: Deploy continuous trading service
kubernetes.core.k8s:
state: present
definition:
apiVersion: apps/v1
kind: Deployment
metadata:
name: "{{ kraken_bot_name }}"
namespace: "{{ kraken_bot_namespace }}"
labels:
app.kubernetes.io/name: "{{ kraken_bot_name }}"
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app.kubernetes.io/name: "{{ kraken_bot_name }}"
template:
metadata:
labels:
app.kubernetes.io/name: "{{ kraken_bot_name }}"
annotations:
kraken-bot/config-sha256: "{{ kraken_bot_config | to_nice_yaml(indent=2, sort_keys=false) | hash('sha256') }}"
spec:
automountServiceAccountToken: false
securityContext:
runAsNonRoot: true
runAsUser: 10001
runAsGroup: 10001
fsGroup: 10001
seccompProfile:
type: RuntimeDefault
containers:
- name: kraken-trader
image: "{{ kraken_bot_image }}"
imagePullPolicy: "{{ kraken_bot_image_pull_policy }}"
ports:
- name: http
containerPort: 8080
protocol: TCP
env:
- name: CONFIG_PATH
value: /config/strategies.yaml
- name: DATA_DIR
value: /data
- name: HOST
value: 0.0.0.0
- name: PORT
value: "8080"
- name: LIVE_TRADING_ENABLED
value: "{{ kraken_bot_live_trading_enabled | bool | string | lower }}"
- name: LOG_LEVEL
value: "{{ kraken_bot_log_level }}"
- name: KRAKEN_API_KEY
valueFrom:
secretKeyRef:
name: "{{ kraken_bot_name }}-secrets"
key: KRAKEN_API_KEY
- name: KRAKEN_API_SECRET
valueFrom:
secretKeyRef:
name: "{{ kraken_bot_name }}-secrets"
key: KRAKEN_API_SECRET
- name: DASHBOARD_USERNAME
valueFrom:
secretKeyRef:
name: "{{ kraken_bot_name }}-secrets"
key: DASHBOARD_USERNAME
- name: DASHBOARD_PASSWORD
valueFrom:
secretKeyRef:
name: "{{ kraken_bot_name }}-secrets"
key: DASHBOARD_PASSWORD
volumeMounts:
- name: data
mountPath: /data
- name: config
mountPath: /config
readOnly: true
- name: tmp
mountPath: /tmp
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 30
periodSeconds: 30
failureThreshold: 3
readinessProbe:
httpGet:
path: /healthz
port: http
periodSeconds: 15
resources:
requests:
cpu: 50m
memory: 256Mi
limits:
memory: 512Mi
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumes:
- name: data
persistentVolumeClaim:
claimName: "{{ kraken_bot_name }}-data"
- name: config
configMap:
name: "{{ kraken_bot_name }}-config"
- name: tmp
emptyDir: {}
kubeconfig: "{{ kraken_bot_kubeconfig | default(omit, true) }}"
context: "{{ kraken_bot_kube_context | default(omit, true) }}"
- name: Expose dashboard inside the cluster
kubernetes.core.k8s:
state: present
definition:
apiVersion: v1
kind: Service
metadata:
name: "{{ kraken_bot_name }}"
namespace: "{{ kraken_bot_namespace }}"
spec:
type: "{{ kraken_bot_service_type }}"
selector:
app.kubernetes.io/name: "{{ kraken_bot_name }}"
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
kubeconfig: "{{ kraken_bot_kubeconfig | default(omit, true) }}"
context: "{{ kraken_bot_kube_context | default(omit, true) }}"