| name | apollo-multi-env-setup |
| description | Configure Apollo.io multi-environment setup.
Use when setting up development, staging, and production environments,
or managing multiple Apollo configurations.
Trigger with phrases like "apollo environments", "apollo staging",
"apollo dev prod", "apollo multi-tenant", "apollo env config".
|
| allowed-tools | Read, Write, Edit, Bash(kubectl:*), Bash(curl:*) |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
Apollo Multi-Environment Setup
Overview
Configure Apollo.io for multiple environments (development, staging, production) with proper isolation, configuration management, and deployment strategies.
Environment Strategy
| Environment | Purpose | API Key | Rate Limit | Data Access |
|---|
| Development | Local dev | Dev/Sandbox | Low (10/min) | Test data only |
| Staging | Pre-prod testing | Staging key | Medium (50/min) | Limited prod |
| Production | Live system | Production key | Full (100/min) | Full access |
Configuration Structure
import { z } from 'zod';
const EnvironmentConfigSchema = z.object({
apiKey: z.string().min(1),
baseUrl: z.string().url().default('https://api.apollo.io/v1'),
rateLimit: z.number().positive(),
timeout: z.number().positive().default(30000),
cacheEnabled: z.boolean().default(true),
cacheTtl: z.number().positive().default(300),
features: z.object({
search: z.boolean().default(true),
enrichment: z.boolean().default(true),
sequences: z.boolean().default(false),
webhooks: z.boolean().default(false),
}),
: z.({
: z.([, , , ]),
: z.().(),
}),
});
= z.< >;
: <, > = {
: {
: process.. || ,
: ,
: ,
: ,
: ,
: ,
: {
: ,
: ,
: ,
: ,
},
: {
: ,
: ,
},
},
: {
: process.. || ,
: ,
: ,
: ,
: ,
: ,
: {
: ,
: ,
: ,
: ,
},
: {
: ,
: ,
},
},
: {
: process.. || ,
: ,
: ,
: ,
: ,
: ,
: {
: ,
: ,
: ,
: ,
},
: {
: ,
: ,
},
},
};
(): {
env = process.. || ;
config = configs[env];
(!config) {
();
}
result = .(config);
(!result.) {
();
}
result.;
}
(): {
config = ();
(!config.) {
();
}
.();
.();
.();
}
Environment Files
NODE_ENV=development
APOLLO_API_KEY_DEV=your-dev-api-key
APOLLO_RATE_LIMIT=10
APOLLO_CACHE_TTL=60
APOLLO_LOG_LEVEL=debug
NODE_ENV=staging
APOLLO_API_KEY_STAGING=your-staging-api-key
APOLLO_RATE_LIMIT=50
APOLLO_CACHE_TTL=300
APOLLO_LOG_LEVEL=info
NODE_ENV=production
APOLLO_API_KEY=your-prod-api-key
APOLLO_RATE_LIMIT=90
APOLLO_CACHE_TTL=900
APOLLO_LOG_LEVEL=warn
Kubernetes ConfigMaps
apiVersion: v1
kind: ConfigMap
metadata:
name: apollo-config
namespace: development
data:
NODE_ENV: "development"
APOLLO_RATE_LIMIT: "10"
APOLLO_CACHE_TTL: "60"
APOLLO_LOG_LEVEL: "debug"
APOLLO_FEATURES_SEARCH: "true"
APOLLO_FEATURES_ENRICHMENT: "true"
APOLLO_FEATURES_SEQUENCES: "false"
APOLLO_FEATURES_WEBHOOKS: "false"
---
apiVersion: v1
kind: ConfigMap
metadata:
name: apollo-config
namespace: staging
data:
NODE_ENV: "staging"
APOLLO_RATE_LIMIT: "50"
APOLLO_CACHE_TTL: "300"
APOLLO_LOG_LEVEL: "info"
APOLLO_FEATURES_SEARCH: "true"
APOLLO_FEATURES_ENRICHMENT: "true"
APOLLO_FEATURES_SEQUENCES: "true"
Secrets Management
apiVersion: v1
kind: Secret
metadata:
name: apollo-secrets
namespace: ${NAMESPACE}
type: Opaque
stringData:
api-key: ${APOLLO_API_KEY}
webhook-secret: ${APOLLO_WEBHOOK_SECRET}
apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
name: apollo-secrets
spec:
refreshInterval: 1h
secretStoreRef:
name: gcp-secret-manager
kind: ClusterSecretStore
target:
name: apollo-secrets
data:
- secretKey: api-key
remoteRef:
key: apollo-api-key-${ENV}
- secretKey: webhook-secret
remoteRef:
key: apollo-webhook-secret-${ENV}
Environment-Aware Client
import { getConfig } from '../../config/apollo/environments';
class EnvironmentAwareApolloClient {
private config = getConfig();
async request<T>(options: RequestOptions): Promise<T> {
if (!this.isFeatureEnabled(options.feature)) {
throw new Error(`Feature ${options.feature} is disabled in ${process.env.NODE_ENV}`);
}
await this.rateLimiter.acquire();
const response = await axios({
...options,
baseURL: this.config.baseUrl,
timeout: this.config.timeout,
params: {
...options.params,
api_key: this.config.apiKey,
},
});
this.(, , {
: response.,
: response.[],
});
response.;
}
(: ): {
..[feature keyof ..] ?? ;
}
(: , : , ?: ): {
(.(level)) {
sanitized = ...
? .(meta)
: meta;
[level ](, sanitized);
}
}
(: ): {
levels = [, , , ];
levels.(level) >= levels.(...);
}
}
Testing Across Environments
describe('Environment Configuration', () => {
const originalEnv = process.env.NODE_ENV;
afterEach(() => {
process.env.NODE_ENV = originalEnv;
});
it('loads development config correctly', () => {
process.env.NODE_ENV = 'development';
const config = getConfig();
expect(config.rateLimit).toBe(10);
expect(config.features.sequences).toBe(false);
});
it('loads staging config correctly', () => {
process.env.NODE_ENV = 'staging';
const config = getConfig();
expect(config.rateLimit).toBe(50);
expect(config.features.sequences).toBe(true);
});
it('loads production config correctly', () => {
process.env. = ;
config = ();
(config.).();
(config..).();
});
(, {
process.. = ;
process..;
( ()).();
});
});
Environment Promotion
#!/bin/bash
echo "Promoting to staging environment..."
if [ -z "$APOLLO_API_KEY_STAGING" ]; then
echo "Error: APOLLO_API_KEY_STAGING not set"
exit 1
fi
NODE_ENV=staging npm run test:integration
kubectl apply -f k8s/configmaps/apollo-config-staging.yaml
kubectl apply -f k8s/secrets/apollo-secrets-staging.yaml
kubectl rollout restart deployment/apollo-service -n staging
kubectl rollout status deployment/apollo-service -n staging
curl -sf https://staging.example.com/health/apollo || exit 1
echo "Successfully promoted to staging"
Output
- Environment-specific configurations
- Kubernetes ConfigMaps and Secrets
- Environment-aware client
- Feature flags per environment
- Environment promotion scripts
Error Handling
| Issue | Resolution |
|---|
| Wrong environment | Check NODE_ENV variable |
| Missing API key | Verify secrets configuration |
| Feature disabled | Check environment config |
| Rate limit mismatch | Verify config values |
Resources
Next Steps
Proceed to apollo-observability for monitoring setup.