mirror of
https://github.com/ksyasuda/dotfiles.git
synced 2026-03-21 06:11:27 -07:00
update skills
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
# Cloudflare Network Interconnect (CNI)
|
||||
|
||||
Private, high-performance connectivity to Cloudflare's network. **Enterprise-only**.
|
||||
|
||||
## Connection Types
|
||||
|
||||
**Direct**: Physical fiber in shared datacenter. 10/100 Gbps. You order cross-connect.
|
||||
|
||||
**Partner**: Virtual via Console Connect, Equinix, Megaport, etc. Managed via partner SDN.
|
||||
|
||||
**Cloud**: AWS Direct Connect or GCP Cloud Interconnect. Magic WAN only.
|
||||
|
||||
## Dataplane Versions
|
||||
|
||||
**v1 (Classic)**: GRE tunnel support, VLAN/BFD/LACP, asymmetric MTU (1500↓/1476↑), peering support.
|
||||
|
||||
**v2 (Beta)**: No GRE, 1500 MTU both ways, no VLAN/BFD/LACP yet, ECMP instead.
|
||||
|
||||
## Use Cases
|
||||
|
||||
- **Magic Transit DSR**: DDoS protection, egress via ISP (v1/v2)
|
||||
- **Magic Transit + Egress**: DDoS + egress via CF (v1/v2)
|
||||
- **Magic WAN + Zero Trust**: Private backbone (v1 needs GRE, v2 native)
|
||||
- **Peering**: Public routes at PoP (v1 only)
|
||||
- **App Security**: WAF/Cache/LB (v1/v2 over Magic Transit)
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Enterprise plan
|
||||
- IPv4 /24+ or IPv6 /48+ prefixes
|
||||
- BGP ASN for v1
|
||||
- See [locations PDF](https://developers.cloudflare.com/network-interconnect/static/cni-locations-2026-01.pdf)
|
||||
|
||||
## Specs
|
||||
|
||||
- /31 point-to-point subnets
|
||||
- 10km max optical distance
|
||||
- 10G: 10GBASE-LR single-mode
|
||||
- 100G: 100GBASE-LR4 single-mode
|
||||
- **No SLA** (free service)
|
||||
- Backup Internet required
|
||||
|
||||
## Throughput
|
||||
|
||||
| Direction | 10G | 100G |
|
||||
|-----------|-----|------|
|
||||
| CF → Customer | 10 Gbps | 100 Gbps |
|
||||
| Customer → CF (peering) | 10 Gbps | 100 Gbps |
|
||||
| Customer → CF (Magic) | 1 Gbps/tunnel or CNI | 1 Gbps/tunnel or CNI |
|
||||
|
||||
## Timeline
|
||||
|
||||
2-4 weeks typical. Steps: request → config review → order connection → configure → test → enable health checks → activate → monitor.
|
||||
|
||||
## In This Reference
|
||||
- [configuration.md](./configuration.md) - BGP, routing, setup
|
||||
- [api.md](./api.md) - API endpoints, SDKs
|
||||
- [patterns.md](./patterns.md) - HA, hybrid cloud, failover
|
||||
- [gotchas.md](./gotchas.md) - Troubleshooting, limits
|
||||
|
||||
## Reading Order by Task
|
||||
|
||||
| Task | Files to Load |
|
||||
|------|---------------|
|
||||
| Initial setup | README → configuration.md → api.md |
|
||||
| Create interconnect via API | api.md → gotchas.md |
|
||||
| Design HA architecture | patterns.md → README |
|
||||
| Troubleshoot connection | gotchas.md → configuration.md |
|
||||
| Cloud integration (AWS/GCP) | configuration.md → patterns.md |
|
||||
| Monitor + alerts | configuration.md |
|
||||
|
||||
## Automation Boundary
|
||||
|
||||
**API-Automatable:**
|
||||
- List/create/delete interconnects (Direct, Partner)
|
||||
- List available slots
|
||||
- Get interconnect status
|
||||
- Download LOA PDF
|
||||
- Create/update CNI objects (BGP config)
|
||||
- Query settings
|
||||
|
||||
**Requires Account Team:**
|
||||
- Initial request approval
|
||||
- AWS Direct Connect setup (send LOA+VLAN to CF)
|
||||
- GCP Cloud Interconnect final activation
|
||||
- Partner interconnect acceptance (Equinix, Megaport)
|
||||
- VLAN assignment (v1)
|
||||
- Configuration document generation (v1)
|
||||
- Escalations + troubleshooting support
|
||||
|
||||
**Cannot Be Automated:**
|
||||
- Physical cross-connect installation (Direct)
|
||||
- Partner portal operations (virtual circuit ordering)
|
||||
- AWS/GCP portal operations
|
||||
- Maintenance window coordination
|
||||
|
||||
## See Also
|
||||
- [tunnel](../tunnel/) - Alternative for private network connectivity
|
||||
- [spectrum](../spectrum/) - Layer 4 proxy for TCP/UDP traffic
|
||||
@@ -0,0 +1,199 @@
|
||||
# CNI API Reference
|
||||
|
||||
See [README.md](README.md) for overview.
|
||||
|
||||
## Base
|
||||
|
||||
```
|
||||
https://api.cloudflare.com/client/v4
|
||||
Auth: Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
## SDK Namespaces
|
||||
|
||||
**Primary (recommended):**
|
||||
```typescript
|
||||
client.networkInterconnects.interconnects.*
|
||||
client.networkInterconnects.cnis.*
|
||||
client.networkInterconnects.slots.*
|
||||
```
|
||||
|
||||
**Alternate (deprecated):**
|
||||
```typescript
|
||||
client.magicTransit.cfInterconnects.*
|
||||
```
|
||||
|
||||
Use `networkInterconnects` namespace for all new code.
|
||||
|
||||
## Interconnects
|
||||
|
||||
```http
|
||||
GET /accounts/{account_id}/cni/interconnects # Query: page, per_page
|
||||
POST /accounts/{account_id}/cni/interconnects # Query: validate_only=true (optional)
|
||||
GET /accounts/{account_id}/cni/interconnects/{icon}
|
||||
GET /accounts/{account_id}/cni/interconnects/{icon}/status
|
||||
GET /accounts/{account_id}/cni/interconnects/{icon}/loa # Returns PDF
|
||||
DELETE /accounts/{account_id}/cni/interconnects/{icon}
|
||||
```
|
||||
|
||||
**Create Body:** `account`, `slot_id`, `type`, `facility`, `speed`, `name`, `description`
|
||||
**Status Values:** `active` | `healthy` | `unhealthy` | `pending` | `down`
|
||||
|
||||
**Response Example:**
|
||||
```json
|
||||
{"result": [{"id": "icon_abc", "name": "prod", "type": "direct", "facility": "EWR1", "speed": "10G", "status": "active"}]}
|
||||
```
|
||||
|
||||
## CNI Objects (BGP config)
|
||||
|
||||
```http
|
||||
GET /accounts/{account_id}/cni/cnis
|
||||
POST /accounts/{account_id}/cni/cnis
|
||||
GET /accounts/{account_id}/cni/cnis/{cni}
|
||||
PUT /accounts/{account_id}/cni/cnis/{cni}
|
||||
DELETE /accounts/{account_id}/cni/cnis/{cni}
|
||||
```
|
||||
|
||||
Body: `account`, `cust_ip`, `cf_ip`, `bgp_asn`, `bgp_password`, `vlan`
|
||||
|
||||
## Slots
|
||||
|
||||
```http
|
||||
GET /accounts/{account_id}/cni/slots
|
||||
GET /accounts/{account_id}/cni/slots/{slot}
|
||||
```
|
||||
|
||||
Query: `facility`, `occupied`, `speed`
|
||||
|
||||
## Health Checks
|
||||
|
||||
Configure via Magic Transit/WAN tunnel endpoints (CNI v2).
|
||||
|
||||
```typescript
|
||||
await client.magicTransit.tunnels.update(accountId, tunnelId, {
|
||||
health_check: { enabled: true, target: '192.0.2.1', rate: 'high', type: 'request' },
|
||||
});
|
||||
```
|
||||
|
||||
Rates: `high` | `medium` | `low`. Types: `request` | `reply`. See [Magic Transit docs](https://developers.cloudflare.com/magic-transit/how-to/configure-tunnel-endpoints/#add-tunnels).
|
||||
|
||||
## Settings
|
||||
|
||||
```http
|
||||
GET /accounts/{account_id}/cni/settings
|
||||
PUT /accounts/{account_id}/cni/settings
|
||||
```
|
||||
|
||||
Body: `default_asn`
|
||||
|
||||
## TypeScript SDK
|
||||
|
||||
```typescript
|
||||
import Cloudflare from 'cloudflare';
|
||||
|
||||
const client = new Cloudflare({ apiToken: process.env.CF_TOKEN });
|
||||
|
||||
// List
|
||||
await client.networkInterconnects.interconnects.list({ account_id: id });
|
||||
|
||||
// Create with validation
|
||||
await client.networkInterconnects.interconnects.create({
|
||||
account_id: id,
|
||||
account: id,
|
||||
slot_id: 'slot_abc',
|
||||
type: 'direct',
|
||||
facility: 'EWR1',
|
||||
speed: '10G',
|
||||
name: 'prod-interconnect',
|
||||
}, {
|
||||
query: { validate_only: true }, // Dry-run validation
|
||||
});
|
||||
|
||||
// Create without validation
|
||||
await client.networkInterconnects.interconnects.create({
|
||||
account_id: id,
|
||||
account: id,
|
||||
slot_id: 'slot_abc',
|
||||
type: 'direct',
|
||||
facility: 'EWR1',
|
||||
speed: '10G',
|
||||
name: 'prod-interconnect',
|
||||
});
|
||||
|
||||
// Status
|
||||
await client.networkInterconnects.interconnects.get(accountId, iconId);
|
||||
|
||||
// LOA (use fetch)
|
||||
const res = await fetch(`https://api.cloudflare.com/client/v4/accounts/${id}/cni/interconnects/${iconId}/loa`, {
|
||||
headers: { Authorization: `Bearer ${token}` },
|
||||
});
|
||||
await fs.writeFile('loa.pdf', Buffer.from(await res.arrayBuffer()));
|
||||
|
||||
// CNI object
|
||||
await client.networkInterconnects.cnis.create({
|
||||
account_id: id,
|
||||
account: id,
|
||||
cust_ip: '192.0.2.1/31',
|
||||
cf_ip: '192.0.2.0/31',
|
||||
bgp_asn: 65000,
|
||||
vlan: 100,
|
||||
});
|
||||
|
||||
// Slots (filter by facility and speed)
|
||||
await client.networkInterconnects.slots.list({
|
||||
account_id: id,
|
||||
occupied: false,
|
||||
facility: 'EWR1',
|
||||
speed: '10G',
|
||||
});
|
||||
```
|
||||
|
||||
## Python SDK
|
||||
|
||||
```python
|
||||
from cloudflare import Cloudflare
|
||||
|
||||
client = Cloudflare(api_token=os.environ["CF_TOKEN"])
|
||||
|
||||
# List, create, status (same pattern as TypeScript)
|
||||
client.network_interconnects.interconnects.list(account_id=id)
|
||||
client.network_interconnects.interconnects.create(account_id=id, account=id, slot_id="slot_abc", type="direct", facility="EWR1", speed="10G")
|
||||
client.network_interconnects.interconnects.get(account_id=id, icon=icon_id)
|
||||
|
||||
# CNI objects and slots
|
||||
client.network_interconnects.cnis.create(account_id=id, cust_ip="192.0.2.1/31", cf_ip="192.0.2.0/31", bgp_asn=65000)
|
||||
client.network_interconnects.slots.list(account_id=id, occupied=False)
|
||||
```
|
||||
|
||||
## cURL
|
||||
|
||||
```bash
|
||||
# List interconnects
|
||||
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/cni/interconnects" \
|
||||
-H "Authorization: Bearer ${CF_TOKEN}"
|
||||
|
||||
# Create interconnect
|
||||
curl -X POST "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/cni/interconnects?validate_only=true" \
|
||||
-H "Authorization: Bearer ${CF_TOKEN}" -H "Content-Type: application/json" \
|
||||
-d '{"account": "id", "slot_id": "slot_abc", "type": "direct", "facility": "EWR1", "speed": "10G"}'
|
||||
|
||||
# LOA PDF
|
||||
curl "https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/cni/interconnects/${ICON_ID}/loa" \
|
||||
-H "Authorization: Bearer ${CF_TOKEN}" --output loa.pdf
|
||||
```
|
||||
|
||||
## Not Available via API
|
||||
|
||||
**Missing Capabilities:**
|
||||
- BGP session state query (use Dashboard or BGP logs)
|
||||
- Bandwidth utilization metrics (use external monitoring)
|
||||
- Traffic statistics per interconnect
|
||||
- Historical uptime/downtime data
|
||||
- Light level readings (contact account team)
|
||||
- Maintenance window scheduling (notifications only)
|
||||
|
||||
## Resources
|
||||
|
||||
- [API Docs](https://developers.cloudflare.com/api/resources/network_interconnects/)
|
||||
- [TypeScript SDK](https://github.com/cloudflare/cloudflare-typescript)
|
||||
- [Python SDK](https://github.com/cloudflare/cloudflare-python)
|
||||
@@ -0,0 +1,114 @@
|
||||
# CNI Configuration
|
||||
|
||||
See [README.md](README.md) for overview.
|
||||
|
||||
## Workflow (2-4 weeks)
|
||||
|
||||
1. **Submit request** (Week 1): Contact account team, provide type/location/use case
|
||||
2. **Review config** (Week 1-2, v1 only): Approve IP/VLAN/spec doc
|
||||
3. **Order connection** (Week 2-3):
|
||||
- **Direct**: Get LOA, order cross-connect from facility
|
||||
- **Partner**: Order virtual circuit in partner portal
|
||||
- **Cloud**: Order Direct Connect/Cloud Interconnect, send LOA+VLAN to CF
|
||||
4. **Configure** (Week 3): Both sides configure per doc
|
||||
5. **Test** (Week 3-4): Ping, verify BGP, check routes
|
||||
6. **Health checks** (Week 4): Configure [Magic Transit](https://developers.cloudflare.com/magic-transit/how-to/configure-tunnel-endpoints/#add-tunnels) or [Magic WAN](https://developers.cloudflare.com/magic-wan/configuration/manually/how-to/configure-tunnel-endpoints/#add-tunnels) health checks
|
||||
7. **Activate** (Week 4): Route traffic, verify flow
|
||||
8. **Monitor**: Enable [maintenance notifications](https://developers.cloudflare.com/network-interconnect/monitoring-and-alerts/#enable-cloudflare-status-maintenance-notification)
|
||||
|
||||
## BGP Configuration
|
||||
|
||||
**v1 Requirements:**
|
||||
- BGP ASN (provide during setup)
|
||||
- /31 subnet for peering
|
||||
- Optional: BGP password
|
||||
|
||||
**v2:** Simplified, less BGP config needed.
|
||||
|
||||
**BGP over CNI (Dec 2024):** Magic WAN/Transit can now peer BGP directly over CNI v2 (no GRE tunnel required).
|
||||
|
||||
**Example v1 BGP:**
|
||||
```
|
||||
Router ID: 192.0.2.1
|
||||
Peer IP: 192.0.2.0
|
||||
Remote ASN: 13335
|
||||
Local ASN: 65000
|
||||
Password: [optional]
|
||||
VLAN: 100
|
||||
```
|
||||
|
||||
## Cloud Interconnect Setup
|
||||
|
||||
### AWS Direct Connect (Beta)
|
||||
|
||||
**Requirements:** Magic WAN, AWS Dedicated Direct Connect 1/10 Gbps.
|
||||
|
||||
**Process:**
|
||||
1. Contact CF account team
|
||||
2. Choose location
|
||||
3. Order in AWS portal
|
||||
4. AWS provides LOA + VLAN ID
|
||||
5. Send to CF account team
|
||||
6. Wait ~4 weeks
|
||||
|
||||
**Post-setup:** Add [static routes](https://developers.cloudflare.com/magic-wan/configuration/manually/how-to/configure-routes/#configure-static-routes) to Magic WAN. Enable [bidirectional health checks](https://developers.cloudflare.com/magic-wan/configuration/manually/how-to/configure-tunnel-endpoints/#legacy-bidirectional-health-checks).
|
||||
|
||||
### GCP Cloud Interconnect (Beta)
|
||||
|
||||
**Setup via Dashboard:**
|
||||
1. Interconnects → Create → Cloud Interconnect → Google
|
||||
2. Provide name, MTU (match GCP VLAN attachment), speed (50M-50G granular options available for partner interconnects)
|
||||
3. Enter VLAN attachment pairing key
|
||||
4. Confirm order
|
||||
|
||||
**Routing to GCP:** Add [static routes](https://developers.cloudflare.com/magic-wan/configuration/manually/how-to/configure-routes/#configure-static-routes). BGP routes from GCP Cloud Router **ignored**.
|
||||
|
||||
**Routing to CF:** Configure [custom learned routes](https://cloud.google.com/network-connectivity/docs/router/how-to/configure-custom-learned-routes) in Cloud Router. Request prefixes from CF account team.
|
||||
|
||||
## Monitoring
|
||||
|
||||
**Dashboard Status:**
|
||||
|
||||
| Status | Meaning |
|
||||
|--------|---------|
|
||||
| **Healthy** | Link operational, traffic flowing, health checks passing |
|
||||
| **Active** | Link up, sufficient light, Ethernet negotiated |
|
||||
| **Unhealthy** | Link down, no/low light (<-20 dBm), can't negotiate |
|
||||
| **Pending** | Cross-connect incomplete, device unresponsive, RX/TX swapped |
|
||||
| **Down** | Physical link down, no connectivity |
|
||||
|
||||
**Alerts:**
|
||||
|
||||
**CNI Connection Maintenance** (Magic Networking only):
|
||||
```
|
||||
Dashboard → Notifications → Add
|
||||
Product: Cloudflare Network Interconnect
|
||||
Type: Connection Maintenance Alert
|
||||
```
|
||||
Warnings up to 2 weeks advance. 6hr delay for new additions.
|
||||
|
||||
**Cloudflare Status Maintenance** (entire PoP):
|
||||
```
|
||||
Dashboard → Notifications → Add
|
||||
Product: Cloudflare Status
|
||||
Filter PoPs: gru,fra,lhr
|
||||
```
|
||||
|
||||
**Find PoP code:**
|
||||
```
|
||||
Dashboard → Magic Transit/WAN → Configuration → Interconnects
|
||||
Select CNI → Note Data Center (e.g., "gru-b")
|
||||
Use first 3 letters: "gru"
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
**Critical config-specific practices:**
|
||||
- /31 subnets required for BGP
|
||||
- BGP passwords recommended
|
||||
- BFD for fast failover (v1 only)
|
||||
- Test ping connectivity before BGP
|
||||
- Enable maintenance notifications immediately after activation
|
||||
- Monitor status programmatically via API
|
||||
|
||||
For design patterns, HA architecture, and security best practices, see [patterns.md](./patterns.md).
|
||||
@@ -0,0 +1,165 @@
|
||||
# CNI Gotchas & Troubleshooting
|
||||
|
||||
## Common Errors
|
||||
|
||||
### "Status: Pending"
|
||||
|
||||
**Cause:** Cross-connect not installed, RX/TX fibers reversed, wrong fiber type, or low light levels
|
||||
**Solution:**
|
||||
1. Verify cross-connect installed
|
||||
2. Check fiber at patch panel
|
||||
3. Swap RX/TX fibers
|
||||
4. Check light with optical power meter (target > -20 dBm)
|
||||
5. Contact account team
|
||||
|
||||
### "Status: Unhealthy"
|
||||
|
||||
**Cause:** Physical issue, low light (<-20 dBm), optic mismatch, or dirty connectors
|
||||
**Solution:**
|
||||
1. Check physical connections
|
||||
2. Clean fiber connectors
|
||||
3. Verify optic types (10GBASE-LR/100GBASE-LR4)
|
||||
4. Test with known-good optics
|
||||
5. Check patch panel
|
||||
6. Contact account team
|
||||
|
||||
### "BGP Session Down"
|
||||
|
||||
**Cause:** Wrong IP addressing, wrong ASN, password mismatch, or firewall blocking TCP/179
|
||||
**Solution:**
|
||||
1. Verify IPs match CNI object
|
||||
2. Confirm ASN correct
|
||||
3. Check BGP password
|
||||
4. Verify no firewall on TCP/179
|
||||
5. Check BGP logs
|
||||
6. Review BGP timers
|
||||
|
||||
### "Low Throughput"
|
||||
|
||||
**Cause:** MTU mismatch, fragmentation, single GRE tunnel (v1), or routing inefficiency
|
||||
**Solution:**
|
||||
1. Check MTU (1500↓/1476↑ for v1, 1500 both for v2)
|
||||
2. Test various packet sizes
|
||||
3. Add more GRE tunnels (v1)
|
||||
4. Consider upgrading to v2
|
||||
5. Review routing tables
|
||||
6. Use LACP for bundling (v1)
|
||||
|
||||
## API Errors
|
||||
|
||||
### 400 Bad Request: "slot_id already occupied"
|
||||
|
||||
**Cause:** Another interconnect already uses this slot
|
||||
**Solution:** Use `occupied=false` filter when listing slots:
|
||||
```typescript
|
||||
await client.networkInterconnects.slots.list({
|
||||
account_id: id,
|
||||
occupied: false,
|
||||
facility: 'EWR1',
|
||||
});
|
||||
```
|
||||
|
||||
### 400 Bad Request: "invalid facility code"
|
||||
|
||||
**Cause:** Typo or unsupported facility
|
||||
**Solution:** Check [locations PDF](https://developers.cloudflare.com/network-interconnect/static/cni-locations-2026-01.pdf) for valid codes
|
||||
|
||||
### 403 Forbidden: "Enterprise plan required"
|
||||
|
||||
**Cause:** Account not enterprise-level
|
||||
**Solution:** Contact account team to upgrade
|
||||
|
||||
### 422 Unprocessable: "validate_only request failed"
|
||||
|
||||
**Cause:** Dry-run validation found issues (wrong slot, invalid config)
|
||||
**Solution:** Review error message details, fix config before real creation
|
||||
|
||||
### Rate Limiting
|
||||
|
||||
**Limit:** 1200 requests/5min per token
|
||||
**Solution:** Implement exponential backoff, cache slot listings
|
||||
|
||||
## Cloud-Specific Issues
|
||||
|
||||
### AWS Direct Connect: "VLAN not matching"
|
||||
|
||||
**Cause:** VLAN ID from AWS LOA doesn't match CNI config
|
||||
**Solution:**
|
||||
1. Get VLAN from AWS Console after ordering
|
||||
2. Send exact VLAN to CF account team
|
||||
3. Verify match in CNI object config
|
||||
|
||||
### AWS: "Connection stuck in Pending"
|
||||
|
||||
**Cause:** LOA not provided to CF or AWS connection not accepted
|
||||
**Solution:**
|
||||
1. Verify AWS connection status is "Available"
|
||||
2. Confirm LOA sent to CF account team
|
||||
3. Wait for CF team acceptance (can take days)
|
||||
|
||||
### GCP: "BGP routes not propagating"
|
||||
|
||||
**Cause:** BGP routes from GCP Cloud Router **ignored by design**
|
||||
**Solution:** Use [static routes](https://developers.cloudflare.com/magic-wan/configuration/manually/how-to/configure-routes/#configure-static-routes) in Magic WAN instead
|
||||
|
||||
### GCP: "Cannot query VLAN attachment status via API"
|
||||
|
||||
**Cause:** GCP Cloud Interconnect Dashboard-only (no API yet)
|
||||
**Solution:** Check status in CF Dashboard or GCP Console
|
||||
|
||||
## Partner Interconnect Issues
|
||||
|
||||
### Equinix: "Virtual circuit not appearing"
|
||||
|
||||
**Cause:** CF hasn't accepted Equinix connection request
|
||||
**Solution:**
|
||||
1. Verify VC created in Equinix Fabric Portal
|
||||
2. Contact CF account team to accept
|
||||
3. Allow 2-3 business days
|
||||
|
||||
### Console Connect/Megaport: "API creation fails"
|
||||
|
||||
**Cause:** Partner interconnects require partner portal + CF approval
|
||||
**Solution:** Cannot fully automate. Order in partner portal, notify CF account team.
|
||||
|
||||
## Anti-Patterns
|
||||
|
||||
| Anti-Pattern | Why Bad | Solution |
|
||||
|--------------|---------|----------|
|
||||
| Single interconnect for production | No SLA, single point of failure | Use ≥2 with device diversity |
|
||||
| No backup Internet | CNI fails = total outage | Always maintain alternate path |
|
||||
| Polling status every second | Rate limits, wastes API calls | Poll every 30-60s max |
|
||||
| Using v1 for Magic WAN v2 workloads | GRE overhead, complexity | Use v2 for simplified routing |
|
||||
| Assuming BGP session = traffic flowing | BGP up ≠ routes installed | Verify routing tables + test traffic |
|
||||
| Not enabling maintenance alerts | Surprise downtime during maintenance | Enable notifications immediately |
|
||||
| Hardcoding VLAN in automation | VLAN assigned by CF (v1) | Get VLAN from CNI object response |
|
||||
| Using Direct without colocation | Can't access cross-connect | Use Partner or Cloud interconnect |
|
||||
|
||||
## What's Not Queryable via API
|
||||
|
||||
**Cannot retrieve:**
|
||||
- BGP session state (use Dashboard or BGP logs)
|
||||
- Light levels (contact account team)
|
||||
- Historical metrics (uptime, traffic)
|
||||
- Bandwidth utilization per interconnect
|
||||
- Maintenance window schedules (notifications only)
|
||||
- Fiber path details
|
||||
- Cross-connect installation status
|
||||
|
||||
**Workarounds:**
|
||||
- External monitoring for BGP state
|
||||
- Log aggregation for historical data
|
||||
- Notifications for maintenance windows
|
||||
|
||||
## Limits
|
||||
|
||||
| Resource/Limit | Value | Notes |
|
||||
|----------------|-------|-------|
|
||||
| Max optical distance | 10km | Physical limit |
|
||||
| MTU (v1) | 1500↓ / 1476↑ | Asymmetric |
|
||||
| MTU (v2) | 1500 both | Symmetric |
|
||||
| GRE tunnel throughput | 1 Gbps | Per tunnel (v1) |
|
||||
| Recovery time | Days | No formal SLA |
|
||||
| Light level minimum | -20 dBm | Target threshold |
|
||||
| API rate limit | 1200 req/5min | Per token |
|
||||
| Health check delay | 6 hours | New maintenance alert subscriptions |
|
||||
@@ -0,0 +1,166 @@
|
||||
# CNI Patterns
|
||||
|
||||
See [README.md](README.md) for overview.
|
||||
|
||||
## High Availability
|
||||
|
||||
**Critical:** Design for resilience from day one.
|
||||
|
||||
**Requirements:**
|
||||
- Device-level diversity (separate hardware)
|
||||
- Backup Internet connectivity (no SLA on CNI)
|
||||
- Network-resilient locations preferred
|
||||
- Regular failover testing
|
||||
|
||||
**Architecture:**
|
||||
```
|
||||
Your Network A ──10G CNI v2──> CF CCR Device 1
|
||||
│
|
||||
Your Network B ──10G CNI v2──> CF CCR Device 2
|
||||
│
|
||||
CF Global Network (AS13335)
|
||||
```
|
||||
|
||||
**Capacity Planning:**
|
||||
- Plan across all links
|
||||
- Account for failover scenarios
|
||||
- Your responsibility
|
||||
|
||||
## Pattern: Magic Transit + CNI v2
|
||||
|
||||
**Use Case:** DDoS protection, private connectivity, no GRE overhead.
|
||||
|
||||
```typescript
|
||||
// 1. Create interconnect
|
||||
const ic = await client.networkInterconnects.interconnects.create({
|
||||
account_id: id,
|
||||
type: 'direct',
|
||||
facility: 'EWR1',
|
||||
speed: '10G',
|
||||
name: 'magic-transit-primary',
|
||||
});
|
||||
|
||||
// 2. Poll until active
|
||||
const status = await pollUntilActive(id, ic.id);
|
||||
|
||||
// 3. Configure Magic Transit tunnel via Dashboard/API
|
||||
```
|
||||
|
||||
**Benefits:** 1500 MTU both ways, simplified routing.
|
||||
|
||||
## Pattern: Multi-Cloud Hybrid
|
||||
|
||||
**Use Case:** AWS/GCP workloads with Cloudflare.
|
||||
|
||||
**AWS Direct Connect:**
|
||||
```typescript
|
||||
// 1. Order Direct Connect in AWS Console
|
||||
// 2. Get LOA + VLAN from AWS
|
||||
// 3. Send to CF account team (no API)
|
||||
// 4. Configure static routes in Magic WAN
|
||||
|
||||
await configureStaticRoutes(id, {
|
||||
prefix: '10.0.0.0/8',
|
||||
nexthop: 'aws-direct-connect',
|
||||
});
|
||||
```
|
||||
|
||||
**GCP Cloud Interconnect:**
|
||||
```
|
||||
1. Get VLAN attachment pairing key from GCP Console
|
||||
2. Create via Dashboard: Interconnects → Create → Cloud Interconnect → Google
|
||||
- Enter pairing key, name, MTU, speed
|
||||
3. Configure static routes in Magic WAN (BGP routes from GCP ignored)
|
||||
4. Configure custom learned routes in GCP Cloud Router
|
||||
```
|
||||
|
||||
**Note:** Dashboard-only. No API/SDK support yet.
|
||||
|
||||
## Pattern: Multi-Location HA
|
||||
|
||||
**Use Case:** 99.99%+ uptime.
|
||||
|
||||
```typescript
|
||||
// Primary (NY)
|
||||
const primary = await client.networkInterconnects.interconnects.create({
|
||||
account_id: id,
|
||||
type: 'direct',
|
||||
facility: 'EWR1',
|
||||
speed: '10G',
|
||||
name: 'primary-ewr1',
|
||||
});
|
||||
|
||||
// Secondary (NY, different hardware)
|
||||
const secondary = await client.networkInterconnects.interconnects.create({
|
||||
account_id: id,
|
||||
type: 'direct',
|
||||
facility: 'EWR2',
|
||||
speed: '10G',
|
||||
name: 'secondary-ewr2',
|
||||
});
|
||||
|
||||
// Tertiary (LA, different geography)
|
||||
const tertiary = await client.networkInterconnects.interconnects.create({
|
||||
account_id: id,
|
||||
type: 'partner',
|
||||
facility: 'LAX1',
|
||||
speed: '10G',
|
||||
name: 'tertiary-lax1',
|
||||
});
|
||||
|
||||
// BGP local preferences:
|
||||
// Primary: 200
|
||||
// Secondary: 150
|
||||
// Tertiary: 100
|
||||
// Internet: Last resort
|
||||
```
|
||||
|
||||
## Pattern: Partner Interconnect (Equinix)
|
||||
|
||||
**Use Case:** Quick deployment, no colocation.
|
||||
|
||||
**Setup:**
|
||||
1. Order virtual circuit in Equinix Fabric Portal
|
||||
2. Select Cloudflare as destination
|
||||
3. Choose facility
|
||||
4. Send details to CF account team
|
||||
5. CF accepts in portal
|
||||
6. Configure BGP
|
||||
|
||||
**No API automation** – partner portals managed separately.
|
||||
|
||||
## Failover & Security
|
||||
|
||||
**Failover Best Practices:**
|
||||
- Use BGP local preferences for priority
|
||||
- Configure BFD for fast detection (v1)
|
||||
- Test regularly with traffic shift
|
||||
- Document runbooks
|
||||
|
||||
**Security:**
|
||||
- BGP password authentication
|
||||
- BGP route filtering
|
||||
- Monitor unexpected routes
|
||||
- Magic Firewall for DDoS/threats
|
||||
- Minimum API token permissions
|
||||
- Rotate credentials periodically
|
||||
|
||||
## Decision Matrix
|
||||
|
||||
| Requirement | Recommended |
|
||||
|-------------|-------------|
|
||||
| Collocated with CF | Direct |
|
||||
| Not collocated | Partner |
|
||||
| AWS/GCP workloads | Cloud |
|
||||
| 1500 MTU both ways | v2 |
|
||||
| VLAN tagging | v1 |
|
||||
| Public peering | v1 |
|
||||
| Simplest config | v2 |
|
||||
| BFD fast failover | v1 |
|
||||
| LACP bundling | v1 |
|
||||
|
||||
## Resources
|
||||
|
||||
- [Magic Transit Docs](https://developers.cloudflare.com/magic-transit/)
|
||||
- [Magic WAN Docs](https://developers.cloudflare.com/magic-wan/)
|
||||
- [Argo Smart Routing](https://developers.cloudflare.com/argo/)
|
||||
Reference in New Issue
Block a user