apollo-deploy-integration
SKILL.md
Apollo Deploy Integration
Overview
Deploy Apollo.io integrations to production environments with proper configuration, health checks, and rollback procedures.
Deployment Platforms
Vercel Deployment
// vercel.json
{
"env": {
"APOLLO_API_KEY": "@apollo-api-key"
},
"build": {
"env": {
"APOLLO_API_KEY": "@apollo-api-key"
}
}
}
# Add secret to Vercel
vercel secrets add apollo-api-key "your-api-key"
# Deploy
vercel --prod
Google Cloud Run
# cloudbuild.yaml
steps:
- name: 'gcr.io/cloud-builders/docker'
args: ['build', '-t', 'gcr.io/$PROJECT_ID/apollo-service', '.']
- name: 'gcr.io/cloud-builders/docker'
args: ['push', 'gcr.io/$PROJECT_ID/apollo-service']
- name: 'gcr.io/cloud-builders/gcloud'
args:
- 'run'
- 'deploy'
- 'apollo-service'
- '--image=gcr.io/$PROJECT_ID/apollo-service'
- '--platform=managed'
- '--region=us-central1'
- '--set-secrets=APOLLO_API_KEY=apollo-api-key:latest'
- '--allow-unauthenticated'
# Create secret in Google Cloud
gcloud secrets create apollo-api-key --data-file=-
echo -n "your-api-key" | gcloud secrets versions add apollo-api-key --data-file=-
# Grant access to Cloud Run
gcloud secrets add-iam-policy-binding apollo-api-key \
--member="serviceAccount:YOUR-SA@PROJECT.iam.gserviceaccount.com" \
--role="roles/secretmanager.secretAccessor"
AWS Lambda
# serverless.yml
service: apollo-integration
provider:
name: aws
runtime: nodejs20.x
region: us-east-1
environment:
APOLLO_API_KEY: ${ssm:/apollo/api-key~true}
functions:
search:
handler: src/handlers/search.handler
events:
- http:
path: /api/apollo/search
method: post
timeout: 30
enrich:
handler: src/handlers/enrich.handler
events:
- http:
path: /api/apollo/enrich
method: get
timeout: 30
# Store secret in SSM
aws ssm put-parameter \
--name "/apollo/api-key" \
--type "SecureString" \
--value "your-api-key"
# Deploy
serverless deploy --stage production
Kubernetes
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: apollo-service
spec:
replicas: 3
selector:
matchLabels:
app: apollo-service
template:
metadata:
labels:
app: apollo-service
spec:
containers:
- name: apollo-service
image: your-registry/apollo-service:latest
ports:
- containerPort: 3000
env:
- name: APOLLO_API_KEY
valueFrom:
secretKeyRef:
name: apollo-secrets
key: api-key
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /health/apollo
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "512Mi"
cpu: "500m"
---
apiVersion: v1
kind: Secret
metadata:
name: apollo-secrets
type: Opaque
stringData:
api-key: your-api-key # Use sealed-secrets in production
Health Check Endpoints
// src/routes/health.ts
import { Router } from 'express';
import { apollo } from '../lib/apollo/client';
const router = Router();
// Basic health check
router.get('/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
// Apollo-specific health check
router.get('/health/apollo', async (req, res) => {
try {
const start = Date.now();
await apollo.healthCheck();
const latency = Date.now() - start;
res.json({
status: 'ok',
apollo: {
connected: true,
latencyMs: latency,
},
});
} catch (error: any) {
res.status(503).json({
status: 'degraded',
apollo: {
connected: false,
error: error.message,
},
});
}
});
// Readiness check (for Kubernetes)
router.get('/ready', async (req, res) => {
try {
await apollo.healthCheck();
res.json({ ready: true });
} catch {
res.status(503).json({ ready: false });
}
});
export default router;
Blue-Green Deployment
# .github/workflows/blue-green.yml
name: Blue-Green Deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Deploy to Green
run: |
kubectl apply -f k8s/deployment-green.yaml
kubectl rollout status deployment/apollo-service-green
- name: Run smoke tests on Green
run: |
GREEN_URL=$(kubectl get svc apollo-service-green -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -sf "http://$GREEN_URL/health/apollo" || exit 1
- name: Switch traffic to Green
if: success()
run: |
kubectl patch service apollo-service -p '{"spec":{"selector":{"version":"green"}}}'
- name: Rollback on failure
if: failure()
run: |
kubectl patch service apollo-service -p '{"spec":{"selector":{"version":"blue"}}}'
Deployment Checklist
// scripts/pre-deploy-check.ts
import { apollo } from '../src/lib/apollo/client';
interface Check {
name: string;
check: () => Promise<boolean>;
required: boolean;
}
const checks: Check[] = [
{
name: 'API Key Valid',
check: async () => {
try {
await apollo.healthCheck();
return true;
} catch {
return false;
}
},
required: true,
},
{
name: 'Rate Limit Available',
check: async () => {
// Check we have rate limit headroom
const response = await apollo.searchPeople({ per_page: 1 });
return true; // If we got here, we have capacity
},
required: false,
},
{
name: 'Search Working',
check: async () => {
const result = await apollo.searchPeople({
q_organization_domains: ['apollo.io'],
per_page: 1,
});
return result.people.length > 0;
},
required: true,
},
];
async function runChecks() {
console.log('Running pre-deployment checks...\n');
let allPassed = true;
for (const { name, check, required } of checks) {
try {
const passed = await check();
const status = passed ? 'PASS' : required ? 'FAIL' : 'WARN';
console.log(`[${status}] ${name}`);
if (!passed && required) {
allPassed = false;
}
} catch (error: any) {
console.log(`[FAIL] ${name}: ${error.message}`);
if (required) {
allPassed = false;
}
}
}
if (!allPassed) {
console.error('\nPre-deployment checks failed. Aborting.');
process.exit(1);
}
console.log('\nAll checks passed. Ready to deploy.');
}
runChecks();
Environment Configuration
// src/config/environments.ts
interface EnvironmentConfig {
apollo: {
apiKey: string;
rateLimit: number;
timeout: number;
};
features: {
enrichment: boolean;
sequences: boolean;
};
}
const configs: Record<string, EnvironmentConfig> = {
development: {
apollo: {
apiKey: process.env.APOLLO_API_KEY_DEV!,
rateLimit: 10,
timeout: 30000,
},
features: {
enrichment: true,
sequences: false,
},
},
staging: {
apollo: {
apiKey: process.env.APOLLO_API_KEY_STAGING!,
rateLimit: 50,
timeout: 30000,
},
features: {
enrichment: true,
sequences: true,
},
},
production: {
apollo: {
apiKey: process.env.APOLLO_API_KEY!,
rateLimit: 90,
timeout: 30000,
},
features: {
enrichment: true,
sequences: true,
},
},
};
export function getConfig(): EnvironmentConfig {
const env = process.env.NODE_ENV || 'development';
return configs[env] || configs.development;
}
Output
- Platform-specific deployment configs (Vercel, GCP, AWS, K8s)
- Health check endpoints
- Blue-green deployment workflow
- Pre-deployment validation
- Environment configuration
Error Handling
| Issue | Resolution |
|---|---|
| Secret not found | Verify secret configuration |
| Health check fails | Check Apollo connectivity |
| Deployment timeout | Increase timeout, check resources |
| Traffic not switching | Verify service selector |
Resources
Next Steps
Proceed to apollo-webhooks-events for webhook implementation.