| name | apollo-deploy-integration |
| description | Deploy Apollo.io integrations to production. Use when deploying Apollo integrations, configuring production environments, or setting up deployment pipelines. Trigger with phrases like "deploy apollo", "apollo production deploy", "apollo deployment pipeline", "apollo to production". |
| allowed-tools | Read, Write, Edit, Bash(gh:*), Bash(curl:*) |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
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.