CtrlK
CommunityDocumentationLog inGet started
Tessl Logo

guidewire-multi-env-setup

tessl install github:jeremylongshore/claude-code-plugins-plus-skills --skill guidewire-multi-env-setup
github.com/jeremylongshore/claude-code-plugins-plus-skills

Configure multi-environment setup for Guidewire InsuranceSuite including development, staging, and production environments with proper isolation and promotion workflows. Trigger with phrases like "guidewire environments", "multi-environment", "dev staging production", "environment configuration", "environment promotion".

Review Score

77%

Validation Score

11/16

Implementation Score

65%

Activation Score

90%

Guidewire Multi-Environment Setup

Overview

Configure and manage multiple Guidewire InsuranceSuite environments with proper isolation, configuration management, and promotion workflows.

Prerequisites

  • Guidewire Cloud Console access for all environments
  • Understanding of environment promotion workflows
  • Git-based configuration management
  • CI/CD pipeline infrastructure

Environment Topology

┌─────────────────────────────────────────────────────────────────────────────────┐
│                           Environment Landscape                                  │
├─────────────────────────────────────────────────────────────────────────────────┤
│                                                                                  │
│  ┌───────────┐    ┌───────────┐    ┌───────────┐    ┌───────────┐              │
│  │    DEV    │───▶│    QA     │───▶│    UAT    │───▶│   PROD    │              │
│  │           │    │           │    │           │    │           │              │
│  │ Feature   │    │ Integration│   │ Acceptance│    │ Production│              │
│  │ Development│   │ Testing   │    │ Testing   │    │           │              │
│  └───────────┘    └───────────┘    └───────────┘    └───────────┘              │
│       │                │                │                │                      │
│       ▼                ▼                ▼                ▼                      │
│  ┌─────────────────────────────────────────────────────────────────────────┐   │
│  │                    Shared Infrastructure                                 │   │
│  │  • Identity Provider (Guidewire Hub)                                    │   │
│  │  • Document Storage                                                      │   │
│  │  • Monitoring/Logging                                                    │   │
│  └─────────────────────────────────────────────────────────────────────────┘   │
│                                                                                  │
└─────────────────────────────────────────────────────────────────────────────────┘

Instructions

Step 1: Environment Configuration Files

# Project structure for multi-environment config
config/
├── environments/
│   ├── base/                    # Shared configuration
│   │   ├── database.properties
│   │   ├── logging.properties
│   │   └── integration.properties
│   ├── dev/
│   │   ├── env.properties
│   │   └── secrets.encrypted
│   ├── qa/
│   │   ├── env.properties
│   │   └── secrets.encrypted
│   ├── uat/
│   │   ├── env.properties
│   │   └── secrets.encrypted
│   └── prod/
│       ├── env.properties
│       └── secrets.encrypted
└── gradle.properties           # Build properties

Step 2: Environment-Specific Properties

# config/environments/dev/env.properties
environment=development
environment.code=DEV

# Guidewire Cloud endpoints
gw.tenant.id=your-tenant-dev
gw.hub.url=https://hub-dev.guidewire.com
gw.api.base.url=https://your-tenant-dev.cloud.guidewire.com

# Application URLs
policycenter.url=${gw.api.base.url}/pc/rest
claimcenter.url=${gw.api.base.url}/cc/rest
billingcenter.url=${gw.api.base.url}/bc/rest

# Database (Guidewire managed)
database.readonly.enabled=false

# Logging
logging.level.root=DEBUG
logging.level.gw.api=DEBUG
logging.level.gw.custom=DEBUG

# Features
feature.debug.enabled=true
feature.sample.data.enabled=true
feature.mock.integrations=true

# Integration endpoints (mocked in dev)
integration.rating.url=http://localhost:8081/mock/rating
integration.mvr.url=http://localhost:8081/mock/mvr
integration.credit.url=http://localhost:8081/mock/credit
# config/environments/prod/env.properties
environment=production
environment.code=PROD

# Guidewire Cloud endpoints
gw.tenant.id=your-tenant-prod
gw.hub.url=https://hub.guidewire.com
gw.api.base.url=https://your-tenant.cloud.guidewire.com

# Application URLs
policycenter.url=${gw.api.base.url}/pc/rest
claimcenter.url=${gw.api.base.url}/cc/rest
billingcenter.url=${gw.api.base.url}/bc/rest

# Database
database.readonly.enabled=false

# Logging
logging.level.root=WARN
logging.level.gw.api=INFO
logging.level.gw.custom=INFO

# Features
feature.debug.enabled=false
feature.sample.data.enabled=false
feature.mock.integrations=false

# Integration endpoints (production)
integration.rating.url=https://rating.production.com/api
integration.mvr.url=https://mvr.production.com/api
integration.credit.url=https://credit.production.com/api

Step 3: Gradle Environment Configuration

// build.gradle
plugins {
    id 'com.guidewire.gradle' version '10.12.0'
}

// Environment-specific configuration
ext {
    environment = project.findProperty('env') ?: 'dev'
    envConfigDir = file("config/environments/${environment}")
}

// Load environment properties
def loadEnvProperties() {
    def props = new Properties()

    // Load base properties
    file('config/environments/base').eachFile { f ->
        if (f.name.endsWith('.properties')) {
            props.load(f.newReader())
        }
    }

    // Load environment-specific properties (override base)
    envConfigDir.eachFile { f ->
        if (f.name.endsWith('.properties')) {
            props.load(f.newReader())
        }
    }

    return props
}

ext.envProps = loadEnvProperties()

// Configure Guidewire plugin with environment
guidewire {
    server {
        environment = project.ext.environment
        properties = project.ext.envProps
    }
}

// Tasks for each environment
['dev', 'qa', 'uat', 'prod'].each { env ->
    tasks.register("deploy${env.capitalize()}") {
        description = "Deploy to ${env} environment"
        group = 'deployment'

        doLast {
            println "Deploying to ${env}..."
            // Deployment logic here
        }
    }
}

// Validate environment configuration
tasks.register('validateEnvConfig') {
    description = 'Validate environment configuration'
    doLast {
        def requiredProps = [
            'gw.tenant.id',
            'gw.hub.url',
            'gw.api.base.url'
        ]

        requiredProps.each { prop ->
            if (!project.ext.envProps.containsKey(prop)) {
                throw new GradleException("Missing required property: ${prop}")
            }
        }

        println "Environment configuration valid for: ${project.ext.environment}"
    }
}

Step 4: Environment Manager

// Multi-environment configuration manager
interface EnvironmentConfig {
  name: string;
  code: string;
  tenantId: string;
  hubUrl: string;
  apiBaseUrl: string;
  features: Record<string, boolean>;
  integrations: Record<string, string>;
}

class EnvironmentManager {
  private configs: Map<string, EnvironmentConfig> = new Map();

  constructor() {
    this.loadConfigurations();
  }

  private loadConfigurations(): void {
    this.configs.set('dev', {
      name: 'Development',
      code: 'DEV',
      tenantId: process.env.GW_TENANT_DEV!,
      hubUrl: 'https://hub-dev.guidewire.com',
      apiBaseUrl: `https://${process.env.GW_TENANT_DEV}.cloud.guidewire.com`,
      features: {
        debug: true,
        sampleData: true,
        mockIntegrations: true
      },
      integrations: {
        rating: 'http://localhost:8081/mock/rating',
        mvr: 'http://localhost:8081/mock/mvr'
      }
    });

    this.configs.set('prod', {
      name: 'Production',
      code: 'PROD',
      tenantId: process.env.GW_TENANT_PROD!,
      hubUrl: 'https://hub.guidewire.com',
      apiBaseUrl: `https://${process.env.GW_TENANT_PROD}.cloud.guidewire.com`,
      features: {
        debug: false,
        sampleData: false,
        mockIntegrations: false
      },
      integrations: {
        rating: 'https://rating.production.com/api',
        mvr: 'https://mvr.production.com/api'
      }
    });
  }

  getConfig(env: string): EnvironmentConfig {
    const config = this.configs.get(env);
    if (!config) {
      throw new Error(`Unknown environment: ${env}`);
    }
    return config;
  }

  getCurrentEnvironment(): string {
    return process.env.GW_ENVIRONMENT || 'dev';
  }

  isFeatureEnabled(feature: string): boolean {
    const config = this.getConfig(this.getCurrentEnvironment());
    return config.features[feature] ?? false;
  }
}

// Environment-aware API client
class EnvironmentAwareClient {
  private envManager: EnvironmentManager;
  private tokenManager: TokenManager;

  constructor() {
    this.envManager = new EnvironmentManager();
    const config = this.envManager.getConfig(this.envManager.getCurrentEnvironment());

    this.tokenManager = new TokenManager({
      clientId: this.getClientId(),
      clientSecret: this.getClientSecret(),
      hubUrl: config.hubUrl
    });
  }

  private getClientId(): string {
    const env = this.envManager.getCurrentEnvironment();
    return process.env[`GW_CLIENT_ID_${env.toUpperCase()}`]!;
  }

  private getClientSecret(): string {
    const env = this.envManager.getCurrentEnvironment();
    return process.env[`GW_CLIENT_SECRET_${env.toUpperCase()}`]!;
  }

  async request<T>(path: string, options?: RequestOptions): Promise<T> {
    const config = this.envManager.getConfig(this.envManager.getCurrentEnvironment());
    const token = await this.tokenManager.getToken();

    const response = await fetch(`${config.apiBaseUrl}${path}`, {
      ...options,
      headers: {
        ...options?.headers,
        'Authorization': `Bearer ${token}`,
        'X-GW-Environment': config.code
      }
    });

    return response.json();
  }
}

Step 5: Secrets Management

// Secure secrets management for multiple environments
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';

interface EnvironmentSecrets {
  clientId: string;
  clientSecret: string;
  webhookSecret: string;
  encryptionKey: string;
}

class SecretsManager {
  private client: SecretManagerServiceClient;
  private projectId: string;

  constructor(projectId: string) {
    this.client = new SecretManagerServiceClient();
    this.projectId = projectId;
  }

  async getSecrets(environment: string): Promise<EnvironmentSecrets> {
    const prefix = `gw-${environment}`;

    const [clientId, clientSecret, webhookSecret, encryptionKey] = await Promise.all([
      this.getSecret(`${prefix}-client-id`),
      this.getSecret(`${prefix}-client-secret`),
      this.getSecret(`${prefix}-webhook-secret`),
      this.getSecret(`${prefix}-encryption-key`)
    ]);

    return {
      clientId,
      clientSecret,
      webhookSecret,
      encryptionKey
    };
  }

  private async getSecret(secretName: string): Promise<string> {
    const name = `projects/${this.projectId}/secrets/${secretName}/versions/latest`;

    const [response] = await this.client.accessSecretVersion({ name });
    return response.payload?.data?.toString() || '';
  }

  async rotateSecret(environment: string, secretName: string, newValue: string): Promise<void> {
    const fullName = `gw-${environment}-${secretName}`;
    const parent = `projects/${this.projectId}/secrets/${fullName}`;

    // Add new version
    await this.client.addSecretVersion({
      parent,
      payload: {
        data: Buffer.from(newValue)
      }
    });

    console.log(`Rotated secret: ${fullName}`);
  }
}

Step 6: Environment Promotion Workflow

// Environment promotion automation
interface PromotionRequest {
  sourceEnv: string;
  targetEnv: string;
  packageVersion: string;
  approver: string;
  changeTicket: string;
}

class EnvironmentPromotion {
  private allowedPromotionPaths = [
    ['dev', 'qa'],
    ['qa', 'uat'],
    ['uat', 'prod']
  ];

  async promote(request: PromotionRequest): Promise<PromotionResult> {
    // Validate promotion path
    this.validatePromotionPath(request.sourceEnv, request.targetEnv);

    // Pre-promotion checks
    await this.runPrePromotionChecks(request);

    // Get package from source
    const package = await this.getPackageFromEnvironment(
      request.sourceEnv,
      request.packageVersion
    );

    // Deploy to target
    const deploymentId = await this.deployToEnvironment(
      request.targetEnv,
      package
    );

    // Wait for deployment
    await this.waitForDeployment(deploymentId);

    // Run post-promotion validation
    await this.runPostPromotionValidation(request.targetEnv);

    // Record promotion
    return await this.recordPromotion(request, deploymentId);
  }

  private validatePromotionPath(source: string, target: string): void {
    const isValid = this.allowedPromotionPaths.some(
      ([from, to]) => from === source && to === target
    );

    if (!isValid) {
      throw new Error(`Invalid promotion path: ${source} -> ${target}`);
    }
  }

  private async runPrePromotionChecks(request: PromotionRequest): Promise<void> {
    // Check change ticket is approved
    if (request.targetEnv === 'prod') {
      const ticketApproved = await this.checkChangeTicketApproved(request.changeTicket);
      if (!ticketApproved) {
        throw new Error('Change ticket not approved for production promotion');
      }
    }

    // Check source environment is stable
    const sourceHealth = await this.checkEnvironmentHealth(request.sourceEnv);
    if (!sourceHealth.healthy) {
      throw new Error(`Source environment unhealthy: ${sourceHealth.issues.join(', ')}`);
    }

    // Check target environment is available
    const targetAvailable = await this.checkEnvironmentAvailable(request.targetEnv);
    if (!targetAvailable) {
      throw new Error('Target environment not available for deployment');
    }
  }

  private async runPostPromotionValidation(environment: string): Promise<void> {
    // Run smoke tests
    const smokeResults = await this.runSmokeTests(environment);
    if (!smokeResults.passed) {
      throw new Error(`Smoke tests failed: ${smokeResults.failures.join(', ')}`);
    }

    // Verify critical integrations
    const integrationResults = await this.verifyIntegrations(environment);
    if (!integrationResults.allHealthy) {
      console.warn('Some integrations unhealthy:', integrationResults.unhealthy);
    }
  }
}

Step 7: Environment Health Dashboard

// Environment health monitoring
interface EnvironmentHealth {
  environment: string;
  status: 'healthy' | 'degraded' | 'unhealthy';
  components: ComponentHealth[];
  lastUpdated: Date;
}

interface ComponentHealth {
  name: string;
  status: 'up' | 'down' | 'degraded';
  latency?: number;
  errorRate?: number;
}

class EnvironmentHealthMonitor {
  private environments = ['dev', 'qa', 'uat', 'prod'];

  async checkAllEnvironments(): Promise<Map<string, EnvironmentHealth>> {
    const results = new Map<string, EnvironmentHealth>();

    await Promise.all(
      this.environments.map(async (env) => {
        const health = await this.checkEnvironment(env);
        results.set(env, health);
      })
    );

    return results;
  }

  async checkEnvironment(env: string): Promise<EnvironmentHealth> {
    const envManager = new EnvironmentManager();
    const config = envManager.getConfig(env);

    const components = await Promise.all([
      this.checkPolicyCenter(config),
      this.checkClaimCenter(config),
      this.checkBillingCenter(config),
      this.checkIntegrations(config)
    ]);

    const unhealthyCount = components.filter(c => c.status === 'down').length;
    const degradedCount = components.filter(c => c.status === 'degraded').length;

    let status: EnvironmentHealth['status'] = 'healthy';
    if (unhealthyCount > 0) {
      status = 'unhealthy';
    } else if (degradedCount > 0) {
      status = 'degraded';
    }

    return {
      environment: env,
      status,
      components,
      lastUpdated: new Date()
    };
  }

  private async checkPolicyCenter(config: EnvironmentConfig): Promise<ComponentHealth> {
    const startTime = Date.now();
    try {
      const response = await fetch(`${config.apiBaseUrl}/pc/rest/common/v1/system-info`);
      return {
        name: 'PolicyCenter',
        status: response.ok ? 'up' : 'degraded',
        latency: Date.now() - startTime
      };
    } catch {
      return { name: 'PolicyCenter', status: 'down' };
    }
  }
}

Environment Matrix

AspectDEVQAUATPROD
PurposeDevelopmentIntegration TestingAcceptanceLive
DataSyntheticAnonymizedProd-likeProduction
IntegrationsMockedSandboxSandboxProduction
AccessDevelopersQA TeamBusiness UsersRestricted
Refresh CycleOn-demandWeeklyMonthlyN/A
MonitoringBasicStandardStandardComprehensive

Output

  • Environment configuration structure
  • Gradle multi-environment build
  • Secrets management integration
  • Promotion workflow automation
  • Health monitoring dashboard

Resources

  • Guidewire Cloud Console
  • Environment Management

Next Steps

For monitoring and observability, see guidewire-observability.