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.
65 lines
1.6 KiB
Go
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
|
|
})
|
|
}
|