Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
133 changes: 121 additions & 12 deletions contracts/ripple/backend/backend.yml.tftpl
Original file line number Diff line number Diff line change
@@ -1,3 +1,51 @@
%{ for i, vault in tpl.vaults ~}
---
apiVersion: v1
kind: ConfigMap
metadata:
name: vault-${i}-supervisord-config
data:
supervisord.conf: |
[supervisord]
nodaemon=true
logfile=/dev/null
logfile_maxbytes=0
pidfile=/tmp/supervisord.pid

[program:vault-core]
command=/opt/vault-core/bin/vault-core-omnibus-s390x-g++ -p ${vault.platform} -u 0.0.0.0:${vault.grpc_port}
directory=/opt/vault-core
autostart=true
autorestart=true
autorestart_delay=2
startretries=5
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/dev/fd/2
stderr_logfile_maxbytes=0

[program:vault-bridge]
command=/opt/vault-bridge/bin/vault-bridge
directory=/opt/vault-bridge
priority=3
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/dev/fd/2
stderr_logfile_maxbytes=0
startsecs=0
stopasgroup=true

[program:healthcheck]
command=/opt/vault-bridge-health-check/bin/vault-bridge-health-check
directory=/opt/vault-bridge-health-check
priority=4
stdout_logfile=/dev/fd/1
stdout_logfile_maxbytes=0
stderr_logfile=/dev/fd/2
stderr_logfile_maxbytes=0
startsecs=0
stopasgroup=true
%{ endfor ~}
---
apiVersion: v1
kind: Pod
Expand All @@ -11,12 +59,14 @@ spec:
- name: cold-bridge
image: ${tpl.cold_bridge_image}
env:
# This must be same as VAULT_ID below
- name: Vault__Ids__0
value: "${tpl.vault_id}"
# Dynamic vault IDs - supports 1 to N vaults
%{ for i, vault in tpl.vaults ~}
- name: Vault__Ids__${i}
value: "${vault.vault_id}"
%{ endfor ~}
# Passphrase: "{{EMPTY}}" is needed so that the bridge data is not cyphered and can be managed by OSO
- name: Passphrase
value: "${tpl.passphrase}"
value: "{{EMPTY}}"
volumeMounts:
- name: app-data
mountPath: /App_Data
Expand All @@ -26,15 +76,32 @@ spec:
volumeMounts:
- name: ibm-cfg
mountPath: /opt/kms/cfg/ibm.cfg
- name: ibm-cfg
mountPath: /app/cfg/ibm.cfg
- name: cert
mountPath: /data/cert
readOnly: true

- name: cold-vault
# KMS vault containers - one per vault
# supervisord.conf is mounted from a ConfigMap per vault with unique -u <address>
# so all vault instances can coexist in the shared pod network namespace
%{ for i, vault in tpl.vaults ~}
- name: vault-${i}
image: ${tpl.cold_vault_image}
command:
- /bin/bash
- -c
args:
- |
until (echo > /dev/tcp/localhost/10000) 2>/dev/null; do
sleep 2
done
exec /opt/entrypoint.sh
env:
- name: VAULT_CORE_ADDRESS
value: "0.0.0.0:${vault.grpc_port}"
- name: PLATFORM
value: "kms"
value: "${vault.platform}"
- name: VAULT_BRIDGE_LOGLEVEL
value: "7"
- name: VAULT_CORE_LOGLEVEL
Expand All @@ -44,10 +111,24 @@ spec:
- name: VAULT_TRUSTED_SIG
value: "pem:${tpl.notary_messaging_public_key}"
- name: VAULT_ID
value: "${tpl.vault_id}"
# This comes from the docker container that is spun up above. If it's normal vault, then it would be API end point.
value: "${vault.vault_id}"
- name: HARMONIZE_CORE_ENDPOINT
value: "http://localhost:8080/internal/v1"
- name: HMZ_FEATURE_OPTIONAL_MAXIMUM_FEE
value: "true"
%{ if vault.log_level != "" ~}
- name: HMZ_LOG_LEVEL
value: "${vault.log_level}"
%{ endif ~}
%{ if vault.vault_log_level != "" ~}
- name: VAULT_LOG_LEVEL
value: "${vault.vault_log_level}"
%{ endif ~}
volumeMounts:
- name: vault-${i}-supervisord-config
mountPath: /opt/supervisord/supervisord.conf
subPath: supervisord.conf
%{ endfor ~}

- name: backend-plugin
image: ${tpl.backend_plugin_image}
Expand All @@ -58,16 +139,34 @@ spec:
env:
- name: COMPONENT
value: "backend_plugin"
- name: SEED
- name: OSOENCRYPTIONPASS
value: "${tpl.seed}"
- name: COLD_BRIDGE_ENDPOINT
value: "http://localhost:8080"
- name: PORT
value: "4000"
- name: COLD_BRIDGE_ENDPOINT
value: "${tpl.cold_bridge_endpoint}"
- name: DEBUG
value: "${tpl.debug}"
%{ if tpl.debug == "true" ~}
- name: SSH_PORT
value: "${tpl.ssh_port}"
- name: OSO_SSH_PUBKEY
value: "${tpl.ssh_pubkey}"
- name: OSO_SSH_PASSWORD
value: "${tpl.ssh_password}"
%{ endif ~}
%{ if tpl.debug == "true" ~}
volumeMounts:
- name: debug
mountPath: /debug
%{ endif ~}
ports:
- containerPort: 4000
hostPort: 4000

%{ if tpl.debug == "true" ~}
- containerPort: ${tpl.ssh_port}
hostPort: ${tpl.ssh_port}
%{ endif ~}

%{ if tpl.enable_ep11server }
- name: ep11server
Expand Down Expand Up @@ -135,3 +234,13 @@ spec:
type: CharDevice

%{~ endif ~}
%{ for i, vault in tpl.vaults ~}
- name: vault-${i}-supervisord-config
configMap:
name: vault-${i}-supervisord-config
%{ endfor ~}

%{ if tpl.debug == "true" ~}
- name: debug
emptyDir: {}
%{ endif ~}
14 changes: 14 additions & 0 deletions contracts/ripple/backend/terraform.tfvars.template
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ COLD_BRIDGE_IMAGE="registry.control23.dap.local/metaco-ripple/vault-cold-bridge@
COLD_VAULT_IMAGE="registry.control23.dap.local/metaco-ripple/vault-releases@sha256:"
KMSCONNECT_IMAGE="registry.control23.dap.local/metaco-ripple/kms-ibm@sha256:"

MOCK_VAULTS = [
{
vault_id = ""
mock_phrase = ""
}
]

# Vault Configuration
VAULT_ID=""
NOTARY_MESSAGING_PUBLIC_KEY=""
Expand All @@ -19,6 +26,13 @@ WORKLOAD_VOLUME_PREV_SEED=""
# Default value points to the cold-bridge service running on localhost
# COLD_BRIDGE_ENDPOINT="http://localhost:8080"

# Multi-Vault Configuration (use VAULTS instead of VAULT_ID for multiple vaults)
# Each vault container will be assigned KMS_URL="0.0.0.0:10001", "0.0.0.0:10002", etc.
# VAULTS = [
# { vault_id = "", log_level = "", vault_log_level = "" },
# { vault_id = "", log_level = "", vault_log_level = "" },
# ]

# Update volume name if it is different from default value vault_vol
# VOLUME_NAME = ""

Expand Down
36 changes: 32 additions & 4 deletions contracts/ripple/backend/user_data_backend.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,30 @@ resource "local_file" "grep_client_cert" {
}


# Local variable to handle both single vault (VAULT_ID) and multi-vault (VAULTS) configurations
# Normalizes all vault configurations to KMS-only platform with required runtime settings
locals {
# If VAULT_ID is provided, create a single-vault list with default KMS values
# Otherwise, use the VAULTS list (which is already KMS-only)
resolved_vaults_raw = var.VAULT_ID != "" ? [
{
vault_id = var.VAULT_ID
log_level = ""
vault_log_level = ""
}
] : var.VAULTS

# Inject grpc_port per vault (10001, 10002, 10003, ...) so the template
# can reference vault.grpc_port without inline arithmetic.
# KMS_URL is set to "0.0.0.0:<grpc_port>" on each vault container so that
# each vault instance binds its gRPC listener on a unique port within the
# shared pod network namespace. cold-bridge is told the matching endpoint
# via Vault__GrpcEndpoints__N. See: DAPCS-1965.
resolved_vaults = [
for i, v in local.resolved_vaults_raw : merge(v, { grpc_port = 10001 + i, platform = "kms" })
]
}

resource "local_file" "podman-play" {
content = templatefile(
"${path.module}/backend.yml.tftpl",
Expand All @@ -46,14 +70,18 @@ resource "local_file" "podman-play" {
cold_bridge_image = var.COLD_BRIDGE_IMAGE,
cold_vault_image = var.COLD_VAULT_IMAGE,
kmsconnect_image = var.KMSCONNECT_IMAGE,
vault_id = var.VAULT_ID,
vaults = local.resolved_vaults,
passphrase = var.PASSPHRASE,
notary_messaging_public_key = var.NOTARY_MESSAGING_PUBLIC_KEY,
seed = var.SEED,
cold_bridge_endpoint = var.COLD_BRIDGE_ENDPOINT,
seed = var.OSOENCRYPTIONPASS,
enable_ep11server = var.INTERNAL_GREP11,
crypto_pass_enable = var.CRYPTO_PASSTHROUGH_ENABLEMENT,
grep11_image = var.GREP11_IMAGE,
debug = var.DEBUG ? "true" : "false",
ssh_pubkey = var.SSH_PUBKEY,
ssh_port = var.SSH_PORT,
ssh_password = var.SSH_PASSWORD,
} },
)
filename = "podman-play/play.yml"
Expand Down Expand Up @@ -81,8 +109,8 @@ resource "null_resource" "crypto_deps" {
]
}

# archive of the folder containing docker-compose file. This folder could create additional resources such as files
# to be mounted into containers, environment files etc. This is why all of these files get bundled in a tgz file (base64 encoded)
# archive of the folder containing the podman-play pod YAML and supporting files (ibm.cfg, certs, etc.)
# All of these files get bundled into a tgz (base64 encoded) for the HPCR workload contract.
resource "hpcr_tgz" "workload" {
depends_on = [local_file.podman-play]
folder = "podman-play"
Expand Down
51 changes: 44 additions & 7 deletions contracts/ripple/backend/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ variable "PREFIX" {
variable "DEBUG" {
type = bool
description = "Create debug contracts, plaintext"
default = false
default = true
}

variable "SEED" {
variable "OSOENCRYPTIONPASS" {
type = string
description = "Encrypt data through the iteration pipeline (should be the same value as frontend plugin)"
default = ""
Expand All @@ -34,6 +34,12 @@ variable "BACKEND_PLUGIN_IMAGE" {
description = "Backend plugin image containing registry"
}

variable "BACKEND_ENDPOINT" {
type = string
description = "Backend plugin endpoint URL (required by backend_plugin_manager.py)"
default = "http://localhost:4000"
}

variable "COLD_BRIDGE_ENDPOINT" {
type = string
description = "Cold bridge endpoint URL for the cold bridge service"
Expand All @@ -56,16 +62,28 @@ variable "KMSCONNECT_IMAGE" {
}

variable "VAULT_ID" {
type = string
description = "Vault ID"
type = string
description = "Vault ID (single vault, use VAULTS for multi-vault)"
default = ""
}

variable "VAULTS" {
type = list(object({
vault_id = string
log_level = optional(string, "")
vault_log_level = optional(string, "")
}))
description = "List of KMS vault configurations (supports 1 to N vaults). Use instead of VAULT_ID for multi-vault setups."
default = []
}

variable "PASSPHRASE" {
type = string
default = "{{EMPTY}}"
description = "Required to enable plugin to view content within a JSON format"
type = string
description = "Passphrase for cold-bridge. Use '{{EMPTY}}' so that the bridge data is not cyphered and can be managed by OSO"
default = "{{EMPTY}}"
}


variable "NOTARY_MESSAGING_PUBLIC_KEY" {
type = string
description = "Notary messaging public key after performing genesis"
Expand Down Expand Up @@ -199,3 +217,22 @@ variable "CRYPTO_PASSTHROUGH_ENABLEMENT" {
default = true
description = "Crypto passthrough enablement configuration"
}

variable "SSH_PUBKEY" {
type = string
description = "SSH public key for debug access"
default = ""
}

variable "SSH_PORT" {
type = string
description = "SSH port for debug access"
default = "5000"
}

variable "SSH_PASSWORD" {
type = string
description = "SSH password for debug access (fallback when publickey auth fails). Only active when DEBUG=true."
default = ""
sensitive = true
}
10 changes: 6 additions & 4 deletions contracts/ripple/frontend_plugin/frontend_plugin.yml.tftpl
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
apiVersion: v1
kind: Pod
metadata:
name: frontend_plugin
name: frontend-plugin-pod
spec:
containers:
- name: frontend_plugin
- name: frontend-plugin
image: ${tpl.image}
envFrom:
- configMapRef:
Expand All @@ -25,10 +25,12 @@ spec:
value: "${tpl.HMZ_API_HOSTNAME}"
- name: ROOTCERT
value: "${tpl.ROOTCERT}"
- name: SEED
- name: SEED
value: "${tpl.SEED}"
- name: TOKEN_EXP
value: "${tpl.TOKEN_EXP}"
ports:
- containerPort: 4000
- containerPort: 4000
hostPort: 4000


1 change: 1 addition & 0 deletions contracts/ripple/frontend_plugin/terraform.tfvars.template
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ HMZ_AUTH_HOSTNAME=""
HMZ_API_HOSTNAME=""
VAULT_ID=""
SK=""
HMZ_USER_SK=""
Loading