Install
This project deploys the Anonymization service on Amazon EKS as part of the AI Team Edition.
Install order: prerequisites → OpenTofu infrastructure configuration → Helm deployment.
OCI registry authentication
OpenTofu OCI modules and Helm charts may require authentication. If the registry requires a login, authenticate before running tofu init or helm upgrade --install:
echo "<password>" | helm registry login <Container_Registry_Path> --username "<username>" --password-stdin
Note:
- Set
registry_auth_enabled = truefor Protegrity container registry. Set it tofalseonly for a public or pre-authenticated registry.- If deploying from the Protegrity Container Registry, use
registry.protegrity.com:9443. Specify the local registry endpoint if a local registry is used.- Verify that you are logged in to the registry before proceeding.
Deployment Steps
Step 1 - Provision cloud resources with OpenTofu
The anonymization OpenTofu module provisions all cloud prerequisites and writes an anonymization-values.yaml file with cloud-specific Helm overrides.
AWS (EKS)
The module creates:
- S3 bucket (name provided via
bucket_namevariable — must be globally unique) - IAM role + Pod Identity association →
anon-service-accountServiceAccount EC2NodeClassandNodePool(Bottlerocket FIPS, isolated nodes)anonymization-values.yaml— Helm overrides file
Azure (AKS)
The module creates:
- Storage Account + blob container for model storage
- Managed Identity + Workload Identity federated credential →
anon-service-accountServiceAccount anonymization-values.yaml— Helm overrides file
You do not have a root module
Create a new directory with a single main.tf:
Note: If deploying from the Protegrity Container Registry, use
registry.protegrity.com:9443. Specify the local registry endpoint if a local registry is used.
mkdir anon-install && cd anon-install
cat > main.tf <<'EOF'
terraform {
required_version = "~> 1.10"
required_providers {
aws = { source = "registry.opentofu.org/hashicorp/aws", version = "~> 5.0" }
kubernetes = { source = "registry.opentofu.org/hashicorp/kubernetes", version = "~> 2.35" }
}
}
variable "cluster_name" {
type = string
}
variable "bucket_name" {
type = string
}
variable "chart_version" {
type = string
default = ""
}
data "aws_eks_cluster" "this" { name = var.cluster_name }
data "aws_eks_cluster_auth" "this" { name = var.cluster_name }
provider "kubernetes" {
host = data.aws_eks_cluster.this.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.this.certificate_authority[0].data)
token = data.aws_eks_cluster_auth.this.token
}
module "anonymization" {
source = "oci://<Container_Registry_Path>/anonymization/anonymization-server/opentofu/anonymization?tag=aws-2.1.0"
cluster_name = var.cluster_name
oci_host = "<Container_Registry_Path>"
bucket_name = var.bucket_name
chart_version = var.chart_version
registry_auth_enabled = true # required for registry.protegrity.com; set false only for public/pre-authenticated registries
}
output "helm_install" { value = module.anonymization.helm_install }
output "helm_values" { value = module.anonymization.helm_values }
EOF
tofu init
tofu apply \
-var="cluster_name=<your-cluster-name>" \
-var="bucket_name=<globally-unique-bucket>" \
-var="chart_version=2.1.0"
This writes anonymization-values.yaml (S3, IAM/Pod Identity, Karpenter node isolation, affinity/tolerations already filled in).
Display both generated outputs:
tofu output
Create a new directory with a single main.tf:
Note: If deploying from the Protegrity Container Registry, use
registry.protegrity.com:9443. Specify the local registry endpoint if a local registry is used.
mkdir anon-install && cd anon-install
cat > main.tf <<'EOF'
terraform {
required_version = "~> 1.10"
required_providers {
azurerm = {
source = "registry.opentofu.org/hashicorp/azurerm"
version = "~> 5.7"
}
kubernetes = {
source = "registry.opentofu.org/hashicorp/kubernetes"
version = "~> 2.35"
}
}
}
variable "cluster_name" {
type = string
}
variable "resource_group_name" {
type = string
}
variable "storage_account_name" {
type = string
}
variable "chart_version" {
type = string
default = ""
}
variable "environment" {
type = string
default = "production"
}
provider "azurerm" {
features {}
resource_provider_registrations = "none"
}
data "azurerm_kubernetes_cluster" "this" {
name = var.cluster_name
resource_group_name = var.resource_group_name
}
provider "kubernetes" {
host = data.azurerm_kubernetes_cluster.this.kube_config[0].host
client_certificate = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_certificate)
client_key = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].client_key)
cluster_ca_certificate = base64decode(data.azurerm_kubernetes_cluster.this.kube_config[0].cluster_ca_certificate)
}
module "anonymization" {
source = "oci://<Container_Registry_Path>/anonymization/anonymization-server/opentofu/anonymization?tag=azure-2.1.0"
cluster_name = var.cluster_name
oci_host = "<Container_Registry_Path>"
resource_group_name = var.resource_group_name
storage_account_name = var.storage_account_name
chart_version = var.chart_version
registry_auth_enabled = true # required for registry.protegrity.com; set false only for public/pre-authenticated registries
}
output "helm_install" { value = module.anonymization.helm_install }
output "helm_values" { value = module.anonymization.helm_values }
EOF
tofu init
tofu apply \
-var="cluster_name=<cluster>" \
-var="resource_group_name=<rg>" \
-var="storage_account_name=<globally-unique-name>" \
-var="chart_version=2.1.0"
This writes anonymization-values.yaml (Storage Account, Managed/Workload Identity, affinity/tolerations already filled in).
Display both generated outputs:
tofu output
Module variables
| Variable | Required | Default | Description |
|---|---|---|---|
cluster_name | yes | — | EKS cluster name |
bucket_name | yes | — | S3 bucket name for model storage (must be globally unique across all AWS accounts) |
oci_host | no | <Container_Registry_Path> | OCI registry hostname Note: If deploying from the Protegrity Container Registry, use registry.protegrity.com:9443. Specify the local registry endpoint if a local registry is used. |
environment | no | production | Environment tag and S3 bucket prefix (staging or production) |
namespace | no | anon-ns | Kubernetes namespace |
registry_type | no | artifactory | Protegrity container registry or Local registry |
chart_version | no | "" | Helm chart version. When set, tofu output -raw helm_install prints a ready-to-run command. |
karpenter.enabled | no | true | Create Karpenter NodePool + EC2NodeClass |
karpenter.node_class.ami_family | no | Bottlerocket | AMI family. Bottlerocket selects FIPS AMI automatically. |
karpenter.node_class.ami_id | no | "" | Explicit AMI ID override. When set, overrides ami_family-based selection. |
karpenter.node_pool.instance_types | no | ["c5.large", ...] | EC2 instance types for Karpenter NodePool |
arch | no | amd64 | CPU architecture: amd64 |
fips | no | true | Use FIPS-validated Bottlerocket AMI. Set false to use the standard (non-FIPS) AMI. |
ami_id | no | "" | Explicit AMI ID override (highest priority). When set, bypasses both ami_family and fips selection. |
AMI selection priority:
| Priority | Condition | AMI Selected |
|---|---|---|
| 1 | ami_id is set | Exact AMI by ID (e.g. ami-0123456789abcdef0) |
| 2 | fips = true (default) | Latest bottlerocket-aws-k8s-<K8S_VER>-fips-<ARCH>-* |
| 3 | fips = false | Latest bottlerocket-aws-k8s-<K8S_VER>-<ARCH>-* |
Note: If you use
ami_id, theami_familyvalue must match the image that the AMI ID points to. The default value ofami_familyisBottlerocket.
Examples:
# Use a specific AMI (bypasses all auto-selection)
module "anonymization" {
source = "oci://..."
# ...
ami_id = "ami-0123456789abcdef0"
}
# Disable FIPS (use standard Bottlerocket AMI)
module "anonymization" {
source = "oci://..."
# ...
fips = false
}
| Variable | Required | Default | Description |
|---|---|---|---|
cluster_name | yes | — | AKS cluster name |
resource_group_name | yes | — | Azure resource group for the Managed Identity and Storage Account |
storage_account_name | yes | — | Azure Storage Account name (must be globally unique, 3-24 lowercase alphanumeric chars) |
environment | no | production | Environment tag and storage account name prefix |
namespace | no | anon-ns | Kubernetes namespace |
oci_host | no | <Container_Registry_Path> | OCI registry hostname Note: If deploying from the Protegrity Container Registry, use registry.protegrity.com:9443. Specify the local registry endpoint if a local registry is used. |
registry_type | no | artifactory | Protegrity container registry or Local registry |
chart_version | no | "" | Helm chart version. When set, tofu output -raw helm_install prints a ready-to-run command. |
instance_types | no | ["Standard_D4as_v5", ...] | VM instance types for NodePool |
Note:
- Running
tofu planis optional. It lets you review the planned changes before they are applied.tofu output -raw helm_installprints a ready-to-run Helm command with the correct version and namespace.bucket_nameis a new S3 bucket name and it is created as part of this deployment.
Step2 - Deploy with Helm
The OpenTofu module writes an anonymization-values.yaml file in your working directory.
Pass it to Helm with --values. Passwords are required on first install only — they are
preserved automatically on subsequent upgrades.
Tip:
tofu output -raw helm_installprints a ready-to-run Helm command with the correct version and namespace pre-filled.
Note: If deploying from the Protegrity Container Registry, use
registry.protegrity.com:9443. Specify the local registry endpoint if a local registry is used. Ensureharbor-secretexists in thedefaultnamespace.
export MLOPS_PASSWORD=<your-mlops-password>
export JOBSTATE_PASSWORD=<your-jobstate-password>
helm upgrade --install anonymization \
oci://<Container_Registry_Path>/anonymization/anonymization-server/helm/anonymization \
--version 2.1.0 \
--namespace anon-ns --create-namespace \
--values anonymization-values.yaml \
--set-string database.auth.mlopsPassword=$MLOPS_PASSWORD \
--set-string database.auth.jobstatePassword=$JOBSTATE_PASSWORD
On upgrade (passwords already stored in the cluster secret — omit --set):
helm upgrade anonymization \
oci://<Container_Registry_Path>/anonymization/anonymization-server/helm/anonymization \
--version <new-version> \
--namespace anon-ns \
--values anonymization-values.yaml
To rotate a password during upgrade:
helm upgrade anonymization ... \
--set-string database.auth.mlopsPassword=$NEW_MLOPS_PASSWORD
For more information about the Python SDK, refer to Python SDK Reference.
Validate installation
Note: Before proceeding, ensure your
kubectlcontext is set to the target clusterkubectl config current-context.
kubectl get pods -n anon-ns # All pods should be Running
kubectl get statefulset -n anon-ns # PostgreSQL, 1/1 ready
kubectl get deployment -n anon-ns # app, dask-scheduler, dask-worker
kubectl get hpa -n anon-ns
kubectl get nodes -l anonymization.protegrity.com/deployment=true # AWS: Karpenter nodes (if enabled) should be Ready.
kubectl get pods -n anon-ns # All pods should be Running
kubectl get statefulset -n anon-ns # PostgreSQL, 1/1 ready
kubectl get deployment -n anon-ns # app, dask-scheduler, dask-worker
kubectl get hpa -n anon-ns
Standalone Helm Install (No OpenTofu)
Use this when cloud infrastructure already exists or is managed separately.
Step 1 - Verify prerequisites
# StorageClass
kubectl get storageclass ebs-sc # AWS
# Pod Identity Agent (AWS)
kubectl get daemonset -n kube-system eks-pod-identity-agent
# Karpenter NodePool (if using node isolation)
kubectl get nodepool anonymization-cpu
kubectl get ec2nodeclass anonymization-cpu
# StorageClass
kubectl get storageclass managed-csi-premium # Azure
kubectl get nodepool anonymization-cpu
kubectl get aksnodeclass anonymization-cpu
Step 2 - Create a values override file
AWS example (my-values.yaml):
cloudProvider: aws
serviceaccount:
name: anon-service-account
annotations:
eks.amazonaws.com/role-arn: "arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>"
storage:
enabled: true
bucketName: <your-globally-unique-bucket-name>
region: us-east-1
database:
persistence:
storageClass: ebs-sc
size: 20Gi
karpenter:
enabled: true # set false if NOT using Karpenter isolation
Azure example (my-values.yaml):
cloudProvider: azure
serviceaccount:
name: anon-service-account
annotations:
azure.workload.identity/client-id: "<MANAGED_IDENTITY_CLIENT_ID>"
storage:
enabled: true
dsn: "abfss://models@<storage_account>.dfs.core.windows.net/"
database:
persistence:
storageClass: managed-csi-premium
size: 20Gi
karpenter:
enabled: false
Step 3 - Install
Note: If deploying from the Protegrity Container Registry, use
registry.protegrity.com:9443. Specify the local registry endpoint if a local registry is used. Ensureharbor-secretexists in thedefaultnamespace.
export MLOPS_PASSWORD=<your-mlops-password>
export JOBSTATE_PASSWORD=<your-jobstate-password>
helm upgrade --install anonymization \
oci://<Container_Registry_Path>/anonymization/anonymization-server/helm/anonymization \
--version 2.1.0 \
--namespace anon-ns --create-namespace \
--values my-values.yaml \
--set-string database.auth.mlopsPassword=$MLOPS_PASSWORD \
--set-string database.auth.jobstatePassword=$JOBSTATE_PASSWORD
Next Steps
For more information about the Python SDK, refer to Python SDK Reference.
If you encounter any error during or after installation, refer to Troubleshooting.
Feedback
Was this page helpful?