registry/deploy/main.go
adam jones fe52766676
deploy: Deploy the registry to GCP (#255)
Adds the Pulumi code to:
- Deploy the registry (and associated services e.g. mongodb) to Google
Cloud Platform (GCP), on top of Google Kubernetes Engine (GKE)
- Sets up proper environments and secrets management
- Uses the real container image, now that it's published in #225. At the
moment attached to latest, we might want to pin the version later (or
perhaps always use `latest` in staging, and pin prod)
- Uses real domains (`staging.registry.modelcontextprotocol.io`) rather
than examples (``)

## Motivation and Context

Setting up infrastructure to deploy it. I set something up in Azure in
#227, although not super robust (e.g. no service accounts etc.). Think
we will use GCP as:
- the maintainers have experience with GCP, but none with Azure
- costs are quite low, and Anthropic is happy to cover them in the short
term
- means we only have to maintain one login system (just Google Cloud
Identity), not two (Google Workspace + Azure)

## How Has This Been Tested?

Deployed this to a staging and production cluster. Try it yourself at:

```bash
curl -H "Host: staging.registry.modelcontextprotocol.io" -k https://35.222.36.75/v0/ping
```

(will be sorting out domains very soon)

## Breaking Changes

NA - just adds support for GCP deployment

## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [x] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update

## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [x] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [x] My code follows the repository's style guidelines
- [ ] New and existing tests pass locally
- [x] I have added appropriate error handling
- [x] I have added or updated documentation as needed

## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->

Expected follow-ups:
- GitHub Action setup to deploy things to the cluster from GitHub, to
avoid gatekeeping to just the people with the secrets.
2025-08-12 17:44:50 +01:00

65 lines
1.6 KiB
Go

package main
import (
"fmt"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
"github.com/pulumi/pulumi/sdk/v3/go/pulumi/config"
"github.com/modelcontextprotocol/registry/deploy/infra/pkg/k8s"
"github.com/modelcontextprotocol/registry/deploy/infra/pkg/providers"
"github.com/modelcontextprotocol/registry/deploy/infra/pkg/providers/aks"
"github.com/modelcontextprotocol/registry/deploy/infra/pkg/providers/gcp"
"github.com/modelcontextprotocol/registry/deploy/infra/pkg/providers/local"
)
// createProvider creates the appropriate cluster provider based on configuration
func createProvider(ctx *pulumi.Context) (providers.ClusterProvider, error) {
conf := config.New(ctx, "mcp-registry")
providerName := conf.Get("provider")
if providerName == "" {
providerName = "local" // Default to local provider
}
switch providerName {
case "aks":
return &aks.Provider{}, nil
case "gcp":
return &gcp.Provider{}, nil
case "local":
return &local.Provider{}, nil
default:
return nil, fmt.Errorf("unsupported provider: %s", providerName)
}
}
func main() {
pulumi.Run(func(ctx *pulumi.Context) error {
// Get configuration
conf := config.New(ctx, "mcp-registry")
environment := conf.Require("environment")
// Create provider
provider, err := createProvider(ctx)
if err != nil {
return err
}
// Create cluster
cluster, err := provider.CreateCluster(ctx, environment)
if err != nil {
return err
}
// Deploy to Kubernetes
_, err = k8s.DeployAll(ctx, cluster, environment)
if err != nil {
return err
}
// Export outputs
ctx.Export("clusterName", cluster.Name)
return nil
})
}