Skip to main content

Project Management

A project in Michelangelo is a top-level organizational unit that groups related ML pipelines, models, and resources under a single namespace. Each project typically maps to a business use case -- for example, a product recommendation system, a fraud detection pipeline, or a document classification service.

Projects provide:

  • Namespace isolation -- each project runs in its own Kubernetes namespace (an isolated scope for resources)
  • Ownership and access control -- define teams and individuals who manage the project
  • Pipeline grouping -- all pipelines within a project share configuration and resources
  • Lifecycle tracking -- projects progress through phases from development to production

A project must be created before you can register or run pipelines. See Pipeline Management for creating pipelines within a project.

Prerequisites

Before creating a project, complete the initial setup:

  1. Set up the Michelangelo CLI and sandbox environment. See the CLI Reference - Prerequisites for installation and setup instructions.

  2. Verify the environment is ready:

    ma project get --namespace="default"

    If the sandbox is running correctly, this command returns successfully (an empty list is expected for a new environment).

Create a project

To create a project, define a project.yaml configuration file and apply it with the ma CLI.

Step 1: Create a project folder

Create a folder in your repository with a config/ subdirectory:

my-project/
config/
project.yaml

Step 2: Define the project configuration

Create a project.yaml file with the following structure:

apiVersion: michelangelo.api/v2
kind: Project
metadata:
name: my-ml-project # Must follow Kubernetes naming conventions
namespace: my-ml-project # Must match the name field exactly
annotations:
michelangelo/worker_queue: "default" # Optional: override the workflow execution queue
spec:
description: "Product recommendation model training and serving"
owner:
owningTeam: "a1b2c3d4-e5f6-7890-abcd-ef1234567890" # Team identifier (UUID format)
owners:
- jane.smith
- john.doe
ownerGroups:
- ml-platform-team
tier: 3 # Service criticality: 1 (highest/most critical) to 5 (inactive/soft deletion)
gitRepo: https://github.com/your-org/your-ml-repo
rootDir: path/to/ml/project

Step 3: Apply the configuration

Run the following command to create the project:

ma project apply -f "./my-project/config/project.yaml"

The apply command is an upsert operation: it creates the project if it does not exist, or updates it if it does. You can use the same command to modify project settings later.

Step 4: Verify the project was created

ma project get --namespace="my-ml-project" --name="my-ml-project"

This will display the project's metadata and spec if the project was created successfully.

Project YAML reference

Required fields

FieldTypeDescription
metadata.namestringProject name. Must follow Kubernetes naming conventions (lowercase, alphanumeric, hyphens).
metadata.namespacestringKubernetes namespace. Must match metadata.name exactly.
spec.descriptionstringHuman-readable description of the project.
spec.owner.owningTeamstringTeam identifier in UUID format (e.g., a1b2c3d4-e5f6-7890-abcd-ef1234567890).
spec.owner.ownerslistList of individual owner identifiers.
spec.tierintegerService criticality tier: 1 (most critical) to 4 (least critical), or 5 (inactive project, soft deletion before hard deletion in production).
spec.gitRepostringURL of the Git repository containing the project code.
spec.rootDirstringPath within the repository to the project root directory. Used to locate workflow code and configuration files.

Optional fields

FieldTypeDescription
metadata.annotationsmapKey-value metadata. Use michelangelo/worker_queue to override the default Cadence/Temporal (the workflow orchestration engine) worker queue for this project.
spec.owner.ownerGroupslistList of group identifiers for group-based ownership.
spec.commitobjectGit commit information associated with the project.
spec.supportingLinksmapKey-value map of related resource URLs (dashboards, documentation, etc.).
spec.retentionConfigobjectRetention policies for deployments, endpoints, and models.
spec.typeInfoobjectProject classification flags (isCoreMl, isGenerativeAi).

Manage projects

List all projects in a namespace

ma project get --namespace="my-ml-project"

Use --limit to control the number of results (default: 100):

ma project get --namespace="my-ml-project" --limit=10

Get a specific project

ma project get --namespace="my-ml-project" --name="my-ml-project"

Update a project

Modify your project.yaml file and re-run apply:

ma project apply -f "./my-project/config/project.yaml"

The CLI detects that the project already exists and performs an update.

Delete a project

ma project delete --namespace="my-ml-project" --name="my-ml-project"

See the CLI Reference for the full list of supported commands and flags.

Project-pipeline relationship

Projects are the top-level container for ML pipelines. Every pipeline must belong to a project, and the pipeline's namespace must match the project's namespace.

Project (my-ml-project)
├── Pipeline: training-pipeline
├── Pipeline: evaluation-pipeline
└── Pipeline: serving-pipeline

To create a pipeline within a project, register it with the same namespace:

apiVersion: michelangelo.api/v2
kind: Pipeline
metadata:
namespace: "my-ml-project" # Must match the project namespace
name: "training-pipeline"
spec:
type: "PIPELINE_TYPE_TRAIN"
manifest:
filePath: my_project.training_workflow
ma pipeline apply -f "./pipeline.yaml"

See Pipeline Management for details on creating and managing pipelines.

Project lifecycle

States

A project transitions through the following states after creation:

StateDescription
PROVISIONINGProject resources are being set up.
PROVISION_PENDINGProvisioning is queued and waiting to start.
READYProject is fully provisioned and available for use.
ERRORProvisioning failed. Check the project status for error details.

Phases

Projects can be tagged with a lifecycle phase. Phases are organizational labels. Only DECOMMISSION has a functional effect -- it blocks new pipeline and pipeline run creation.

PhaseDescription
DEVELOPMENTActive development and experimentation.
STAGINGPre-production validation.
PRODUCTIONServing live traffic.
DECOMMISSIONMarked for retirement. New pipelines and pipeline runs cannot be created in a decommissioned project.

Validation rules

The API enforces the following constraints when creating or updating projects:

  1. Name must match namespace. The metadata.name and metadata.namespace fields must be identical. A mismatch will cause a validation error.
  2. Reserved namespaces are forbidden. Projects cannot be created in the default or kube-* namespaces.
  3. owningTeam must be a UUID. The spec.owner.owningTeam field must be a valid UUID string (e.g., a1b2c3d4-e5f6-7890-abcd-ef1234567890). Plain text names will be rejected.
  4. Tier must be 1-5. The spec.tier field must be an integer between 1 and 5 inclusive. Tier 5 indicates an inactive project (soft deletion) before hard deletion in production.
  5. Kubernetes naming conventions apply. The project name must be lowercase, alphanumeric, and may include hyphens. No underscores or uppercase characters.

Next steps