> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gp.scale.com/llms.txt
> Use this file to discover all available pages before exploring further.

# AWS SGP Deployment

> End-to-end guide to deploying SGP in an AWS account.

## Overview

This guide will walk you through the process of deploying SGP in an AWS account. SGP AWS infrastructure is defined by terraform modules managed by Scale.

## Prerequisites

* Access to an AWS account with sufficient permissions to create resources
* The following tools installed:
  * [AWS CLI](https://aws.amazon.com/cli/)
  * [Terraform](https://www.terraform.io/)
  * [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)
* The following from Scale:
  * The SGP AWS Infrastructure Terraform modules
  * A `workspace_id` and `registration_secret` unique to your deployment
  * `install.sh` script to bootstrap the SGP cluster
* A new application configured in your identity provider to authenticate to the SGP platform (SAML or OIDC) (optional)
* A custom domain for your deployment (optional)

## Installation

### Step 1: Prepare Terraform Root Module

In a new directory, create a `.tf` file to invoke the SGP AWS infrastructure Terraform modules. Reference the `egp-hybrid-cloud-customer-deployment` module as the entrypoint for the SGP infrastructure.

```terraform theme={null}
module "egp_hybrid_deployment" {
  source                = "<path to egp-hybrid-cloud-customer-deployment module>"
  scale_account_id      = "<workspace_id>"
  registration_secret   = "<registration_secret>"  # sensitive — use TF_VAR_registration_secret env var

  domain = "<workspace_id>.workspace.egp.scale.com"  # or your custom domain

  # Core services — enable the components you need
  deploy_egp_api    = true   # EGP API backend — required for the SGP platform
  deploy_spellbook  = false  # Spellbook prompt management service (optional)
  deploy_sgp_models = false  # SGP model serving infrastructure (optional)
  deploy_llm_engine = false  # Model Engine service (optional)
  deploy_agentex    = false  # Agentex agentic workflow service (optional)
  create_agentex_tool_cache = false  # Persistent tool cache for Agentex (optional)
  enable_cloud_build = false # Cloud-based container build service for Agentex (optional)
  add_agents_service = false # Agent Service for building and running agents (optional)
  add_document_understanding_capability = false  # Document Understanding (Dex) service (optional)
  enable_reducto    = false  # Reducto OCR and document parsing service (optional)
  enable_train      = false  # SGP model training infrastructure (optional)
  enable_compass    = false  # Workflows workflow orchestration service (optional)
  enable_ukbp       = false  # Universal Knowledge Base Pipeline (optional)
  enable_system_manager = true  # System Manager deployment orchestrator — required
  enable_monitoring = false  # Observability stack (optional)

  create_temporal_postgresql = true  # Recommended; set false to use an in-cluster Cassandra instead

  omit_egp_control_plane = false  # Set true to disable communication with Scale's hosted control plane

  base_repository = "<base container registry URL>"  # Only needed if not pulling from Scale's registry

  openai_api_key    = "<openai_api_key>"     # sensitive — use TF_VAR_openai_api_key env var
  openai_org_id     = "<openai_org_id>"
  anthropic_api_key = "<anthropic_api_key>"  # sensitive — use TF_VAR_anthropic_api_key env var
  launch_api_key    = "<launch_api_key>"     # sensitive — use TF_VAR_launch_api_key env var

  authentication_type = "SAML"  # "SAML" or "OIDC"

  use_cmk = true  # Recommended for production: encrypts data at rest using AWS KMS

  # If deploying into an existing VPC rather than creating a new one, provide the IDs here
  # vpc_id             = "<existing VPC ID>"
  # private_subnet_ids = ["<subnet-id-1>", "<subnet-id-2>"]
  # public_subnet_ids  = ["<subnet-id-1>", "<subnet-id-2>"]

  access_cidrs = []  # List of CIDR blocks to allow access; defaults to open to internet

  # Load balancer configuration
  load_balancer_type = "application"  # "application" or "network"
  # waf_name          = "<WAFv2 Web ACL name>"  # Optional; only applies to application load balancers
  internal_lb        = false  # Set true to prevent internet access to the load balancer
  # additional_certs  = ["<certificate ARN>"]  # Additional TLS certificates for the load balancer

  # permissions_boundary_arn = "<ARN>"  # Optional: IAM permissions boundary for provisioned roles

  # See the module documentation for the full list of available variables
}

# Example Terraform provider and backend configuration
provider "aws" {
  region = "<your-aws-region>"
}

terraform {
  required_version = ">= 1.1.7"

  backend "s3" {
    bucket       = "sgp-<workspace_id>-terraform-state"
    key          = "sgp-<workspace_id>-sgp.tfstate"
    region       = "<your-aws-region>"
  }
}
```

### Step 2: Provision Infrastructure via Terraform

Run the following commands in the same directory as the previous step's .tf file.

```bash theme={null}
terraform init

terraform plan -out=tfplan

# Inspect this plan to review the planned resources to be provisioned before proceeding
terraform show tfplan 

terraform apply tfplan
```

*This step may take significant time due to resource creation dependencies*

<Note>
  If a pre-created certificate and domain entry are not provided, you will likely encounter the following error:

  ```bash theme={null}
  Error: creating ELBv2 Listener (arn:aws:elasticloadbalancing:us-east-1:12345678910:loadbalancer/net/scale-egp-<workspace_id>/12345678910): operation error Elastic Load Balancing v2: CreateListener, https response error StatusCode: 400, RequestID: 12345678910, api error UnsupportedCertificate: The certificate 'arn:aws:acm:us-east-1:12345678910:certificate/12345678910' must have a fully-qualified domain name, a supported signature, and a supported key size.
  ```

  Resolve this by properly configuring DNS and TLS for your domain before re-running `terraform apply`.
</Note>

### Step 3: Bootstrap the Cluster

Note the following values from the previous step's apply output:

```bash theme={null}
export SYSTEM_MANAGER_IRSA_ROLE_ARN=$(terraform output -raw system_manager_irsa_role_arn)
export SPICEDB_DATASTORE_URI=$(terraform output -raw spicedb_connection_string)
export AWS_REGION="<your-aws-region>"
```

#### Configure EKS access

Configure access for yourself to the provisioned EKS cluster:

1. Navigate to "Elastic Kubernetes Service" on the AWS console
2. Go to the required cluster
3. Go to *Access*
4. Under *IAM access entries* click *Create Access Entry*
5. Select your current AWS IAM role from the dropdown, leave the *Type* as *Standard*
6. Add the `AmazonEKSAdminPolicy` and `AmazonEKSClusterAdminPolicy` to the *Cluster* scope
7. Click create

#### Allowlist your IP (if needed)

1. Navigate to "Elastic Kubernetes Service" on the AWS console
2. Go to the required cluster
3. Go to *Networking*
4. On the right, click *Manage* and click *Endpoint Access*
5. Under *Advanced settings* add your IP address

#### Execute install.sh

Run the `install.sh` script to create the following Kubernetes resources:

* AWS Secret Manager CSI Driver
* Spicedb
* [SGP System Manager](/docs/infrastructure/system-manager)

```bash theme={null}
cd <path to install.sh>

# Set the correct kubectl context
aws eks update-kubeconfig --name scale-egp-<workspace_id> --region <aws_region>

# Execute the install.sh script
./install.sh
```

System Manager is the deployment orchestrator for the SGP platform. It will automatically begin deploying the other services required for the SGP platform within the cluster.

### Step 4: Verify the Deployment

Wait for all services to be ready:

```bash theme={null}
kubectl get helmreleases -A  # All should be Ready=True
kubectl get pods -A          # All should be Running
```

### Step 5: Configure Identity Provider

#### SAML Configuration

In your Identity Provider, configure a new SAML application with the following settings:

* Service Entity ID: `https://auth.<domain>`
* Redirect URI: `https://auth.<domain>/dashboard/org/saml/callback`

Modify the configuration `scale-egp-<workspace_id>/identity-service-saml-secrets` (either via System Manager or directly in AWS Secrets Manager):

```json theme={null}
{
  "id": "<workspace_id>",
  "samlConfiguration": {
        "entityId": "<entity id from your identity provider>",
        "x509Cert": "<x509 certificate from your identity provider>",
        "ssoUrl": "<sso URL from your identity provider>",
        "attributeMappings": {
            "email": "<email attribute name from your identity provider>",
            "firstName": "<first name attribute name from your identity provider>",
            "lastName": "<last name attribute name from your identity provider>"
        }
    }
}   
```

#### OIDC Configuration

In your Identity Provider, configure a new OIDC application with the following settings:

* Redirect URI: `https://auth.<domain>/dashboard/org/oidc/callback`

Modify the configuration `scale-egp-<workspace_id>/identity-service-oidc-secrets` (either via System Manager or directly in AWS Secrets Manager) with the following JSON:

```json theme={null}
{
  "id": "<workspace_id>",
  "oidcConfiguration": {
    "clientId": "<client ID from your identity provider>",
    "clientSecret": "<client secret from your identity provider>",
    "issuer": "<issuer from your identity provider>",
    "authorizationUrl": "<authorization URL from your identity provider>",
    "tokenUrl": "<token URL from your identity provider>",
    "userInfoUrl": "<user info URL from your identity provider>"
  }
}
```

After modifying the secret, restart the `sgp-system-manager` deployment to apply the changes.

```bash theme={null}
kubectl rollout restart deployment sgp-system-manager -n sgp-system-manager
```

## Accessing the Platform

If all goes smoothly, you should be able to navigate to the SGP platform at `https://<workspace_id>.workspace.egp.scale.com` (or your custom domain) and authenticate via the configured identity provider.
