guidewire-multi-env-setup
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".
- License 许可
- MIT
- 最近更新
- 2026-11-15
- Stars
- ★ 2.0k
- Forks
- 233
01 前言 Front Matter
- name
- guidewire-multi-env-setup
- author
- Jeremy Longshore <jeremy@intentsolutions.io>
- license
- MIT
- version
- 1.0.0
- description
- 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".
- allowed-tools
- Read, Write, Edit, Bash(curl:*), Bash(gradle:*), Grep
03 SKILL.md 正文
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
| Aspect | DEV | QA | UAT | PROD |
|---|---|---|---|---|
| Purpose | Development | Integration Testing | Acceptance | Live |
| Data | Synthetic | Anonymized | Prod-like | Production |
| Integrations | Mocked | Sandbox | Sandbox | Production |
| Access | Developers | QA Team | Business Users | Restricted |
| Refresh Cycle | On-demand | Weekly | Monthly | N/A |
| Monitoring | Basic | Standard | Standard | Comprehensive |
Output
- Environment configuration structure
- Gradle multi-environment build
- Secrets management integration
- Promotion workflow automation
- Health monitoring dashboard
Resources
Next Steps
For monitoring and observability, see guidewire-observability.
04 同仓库更多 Skills
web-artifacts-builder
Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn/ui). Use for complex artifacts requiring state management, routing, or shadcn/ui components - not for simple single-file HTML/JSX artifacts.
webapp-testing
Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.
neuropixels-analysis
Neuropixels neural recording analysis. Load SpikeGLX/OpenEphys data, preprocess, motion correction, Kilosort4 spike sorting, quality metrics, Allen/IBL curation, AI-assisted visual analysis, for Neuropixels 1.0/2.0 extracellular electrophysiology. Use when working with neural recordings, spike sorting, extracellular electrophysiology, or when the user mentions Neuropixels, SpikeGLX, Open Ephys, Kilosort, quality metrics, or unit curation.
skill-creator
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
notebooklm
Use this skill to query your Google NotebookLM notebooks directly from Claude Code for source-grounded, citation-backed answers from Gemini. Browser automation, library management, persistent auth. Drastically reduced hallucinations through document-only responses.
slack-gif-creator
Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like "make me a GIF of X doing Y for Slack."