본문으로 건너뛰기
cccskills
무료GitHub에 공개

cdn-setup

Configure CDNs for content delivery. Set up CloudFront, Cloudflare, and Fastly. Use when optimizing global content delivery.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

설치 방법 보기

포함된 파일(1)

  • SKILL.md10.7 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

CDN Setup

Configure content delivery networks for fast, reliable global asset delivery with proper caching, invalidation, and security.

When to Use

  • Serving static assets (JS, CSS, images, fonts) globally with low latency.
  • Offloading traffic from origin servers to reduce compute costs.
  • Adding TLS termination and DDoS protection at the edge.
  • Implementing geo-based routing or content restrictions.
  • Accelerating API responses with edge caching.

Prerequisites

  • Domain with DNS management access.
  • Origin server or S3/R2 bucket with content to serve.
  • AWS CLI configured (for CloudFront).
  • Cloudflare account with zone configured (for Cloudflare CDN).
  • Terraform 1.5+ (for infrastructure-as-code examples).

AWS CloudFront

Create a Distribution via CLI

# Create an S3 origin distribution with OAC (Origin Access Control)
aws cloudfront create-distribution --distribution-config '{
  "CallerReference": "my-site-'$(date +%s)'",
  "Comment": "Production site CDN",
  "Enabled": true,
  "Origins": {
    "Quantity": 1,
    "Items": [{
      "Id": "s3-origin",
      "DomainName": "my-bucket.s3.us-east-1.amazonaws.com",
      "OriginPath": "",
      "S3OriginConfig": {
        "OriginAccessIdentity": ""
      },
      "OriginAccessControlId": "E2QWRUHAPOMQZL"
    }]
  },
  "DefaultCacheBehavior": {
    "TargetOriginId": "s3-origin",
    "ViewerProtocolPolicy": "redirect-to-https",
    "AllowedMethods": {
      "Quantity": 2,
      "Items": ["GET", "HEAD"]
    },
    "CachePolicyId": "658327ea-f89d-4fab-a63d-7e88639e58f6",
    "Compress": true
  },
  "DefaultRootObject": "index.html",
  "PriceClass": "PriceClass_100",
  "ViewerCertificate": {
    "ACMCertificateArn": "arn:aws:acm:us-east-1:123456789:certificate/abc-123",
    "SSLSupportMethod": "sni-only",
    "MinimumProtocolVersion": "TLSv1.2_2021"
  },
  "Aliases": {
    "Quantity": 1,
    "Items": ["www.example.com"]
  },
  "CustomErrorResponses": {
    "Quantity": 1,
    "Items": [{
      "ErrorCode": 404,
      "ResponseCode": "200",
      "ResponsePagePath": "/index.html",
      "ErrorCachingMinTTL": 10
    }]
  }
}'

Cache Invalidation

# Invalidate specific paths
aws cloudfront create-invalidation \
  --distribution-id E1A2B3C4D5E6F7 \
  --paths "/index.html" "/css/*" "/js/*"

# Invalidate everything (costs apply per path)
aws cloudfront create-invalidation \
  --distribution-id E1A2B3C4D5E6F7 \
  --paths "/*"

# Check invalidation status
aws cloudfront get-invalidation \
  --distribution-id E1A2B3C4D5E6F7 \
  --id I1A2B3C4D5E6F7

# List recent invalidations
aws cloudfront list-invalidations --distribution-id E1A2B3C4D5E6F7

CloudFront Functions (Lightweight Edge Logic)

// URL rewrite function — add index.html to directory requests
function handler(event) {
  var request = event.request;
  var uri = request.uri;

  if (uri.endsWith('/')) {
    request.uri += 'index.html';
  } else if (!uri.includes('.')) {
    request.uri += '/index.html';
  }

  return request;
}

CloudFront with Terraform

# cloudfront.tf
resource "aws_cloudfront_distribution" "site" {
  enabled             = true
  is_ipv6_enabled     = true
  default_root_object = "index.html"
  aliases             = ["www.example.com"]
  price_class         = "PriceClass_100"

  origin {
    domain_name              = aws_s3_bucket.site.bucket_regional_domain_name
    origin_id                = "s3-origin"
    origin_access_control_id = aws_cloudfront_origin_access_control.oac.id
  }

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "s3-origin"

    cache_policy_id          = "658327ea-f89d-4fab-a63d-7e88639e58f6" # CachingOptimized
    origin_request_policy_id = "88a5eaf4-2fd4-4709-b370-b4c650ea3fcf" # CORS-S3Origin

    viewer_protocol_policy = "redirect-to-https"
    compress               = true
  }

  # SPA fallback
  custom_error_response {
    error_code         = 404
    response_code      = 200
    response_page_path = "/index.html"
  }

  # API pass-through (no caching)
  ordered_cache_behavior {
    path_pattern     = "/api/*"
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PUT", "POST", "PATCH", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = "api-origin"

    cache_policy_id          = "4135ea2d-6df8-44a3-9df3-4b5a84be39ad" # CachingDisabled
    origin_request_policy_id = "b689b0a8-53d0-40ab-baf2-68738e2966ac" # AllViewerExceptHostHeader

    viewer_protocol_policy = "https-only"
  }

  viewer_certificate {
    acm_certificate_arn      = aws_acm_certificate.cert.arn
    ssl_support_method       = "sni-only"
    minimum_protocol_version = "TLSv1.2_2021"
  }

  restrictions {
    geo_restriction {
      restriction_type = "none"
    }
  }
}

resource "aws_cloudfront_origin_access_control" "oac" {
  name                              = "s3-oac"
  origin_access_control_origin_type = "s3"
  signing_behavior                  = "always"
  signing_protocol                  = "sigv4"
}

Cloudflare CDN

Zone Setup

# Add a zone
curl -X POST "https://api.cloudflare.com/client/v4/zones" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name":"example.com","jump_start":true}'

# Get zone ID
ZONE_ID=$(curl -s "https://api.cloudflare.com/client/v4/zones?name=example.com" \
  -H "Authorization: Bearer $CF_API_TOKEN" | jq -r '.result[0].id')

Cache Rules (Replacing Page Rules)

# Create a cache rule for static assets
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/rulesets/phases/http_request_cache_settings/entrypoint" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [
      {
        "expression": "(http.request.uri.path.extension in {\"css\" \"js\" \"png\" \"jpg\" \"woff2\" \"svg\"})",
        "action": "set_cache_settings",
        "action_parameters": {
          "cache": true,
          "browser_ttl": { "mode": "override_origin", "default": 2592000 },
          "edge_ttl": { "mode": "override_origin", "default": 86400 }
        },
        "description": "Cache static assets aggressively"
      }
    ]
  }'

Purge Cache

# Purge everything
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"purge_everything":true}'

# Purge specific URLs
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"files":["https://example.com/style.css","https://example.com/app.js"]}'

# Purge by prefix
curl -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"prefixes":["https://example.com/images/"]}'

Cache Headers on Origin

nginx Cache Headers

# Immutable hashed assets (fingerprinted filenames)
location ~* \.(js|css)$ {
    if ($uri ~* "\.[a-f0-9]{8,}\.(js|css)$") {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    expires 7d;
    add_header Cache-Control "public, must-revalidate";
}

# Images and fonts
location ~* \.(jpg|jpeg|png|gif|ico|svg|webp|woff2|ttf)$ {
    expires 30d;
    add_header Cache-Control "public, immutable";
}

# HTML — always revalidate
location ~* \.html$ {
    expires -1;
    add_header Cache-Control "no-cache, must-revalidate";
}

# API responses — no caching
location /api/ {
    add_header Cache-Control "no-store, no-cache";
    add_header Vary "Authorization, Accept";
}

Cache-Control Cheat Sheet

HeaderMeaning
public, max-age=31536000, immutableCache for 1 year, never revalidate (hashed assets)
public, max-age=86400, must-revalidateCache 1 day, check freshness after
private, max-age=600Browser cache only, 10 min (user-specific content)
no-cacheAlways revalidate with origin before serving
no-storeNever cache (sensitive data)
s-maxage=3600CDN caches for 1 hour, overrides max-age for shared caches

Cache Warming

# Warm cache for critical pages after deployment
#!/bin/bash
URLS=(
  "https://www.example.com/"
  "https://www.example.com/products"
  "https://www.example.com/about"
  "https://www.example.com/css/main.abc123.css"
  "https://www.example.com/js/app.def456.js"
)

for url in "${URLS[@]}"; do
  curl -s -o /dev/null -w "%{http_code} %{time_total}s %{url_effective}\n" "$url"
done

Monitoring Cache Performance

# Check cache status from response headers
curl -sI https://www.example.com/style.css | grep -i -E "cf-cache|x-cache|age|cache-control"

# Expected headers:
# cf-cache-status: HIT (Cloudflare)
# x-cache: Hit from cloudfront (CloudFront)
# age: 3600 (seconds since cached)

# CloudFront cache hit ratio
aws cloudwatch get-metric-statistics \
  --namespace AWS/CloudFront \
  --metric-name CacheHitRate \
  --dimensions Name=DistributionId,Value=E1A2B3C4D5E6F7 \
  --start-time $(date -u -d '1 hour ago' +%Y-%m-%dT%H:%M:%S) \
  --end-time $(date -u +%Y-%m-%dT%H:%M:%S) \
  --period 300 \
  --statistics Average

Troubleshooting

SymptomCauseFix
cf-cache-status: DYNAMICNo cache rule matches or Cache-Control prevents itSet s-maxage or create a cache rule for the path
Cache hit ratio below 50%Low TTLs or high URL cardinality (query strings)Increase TTL; strip unnecessary query strings in cache key
Stale content after deployOld objects still cached at edgeInvalidate; use content-hashed filenames to avoid this entirely
CORS errors through CDNCDN strips or caches wrong Vary headerAdd Vary: Origin and configure origin request policy to forward Origin
502 errors from CDNOrigin down or timeoutCheck origin health; increase CDN origin timeout settings
Mixed content warningsCDN serves HTTPS but origin links use HTTPSet viewer-protocol-policy: redirect-to-https; fix origin URLs
High invalidation costsPurging /* on every deployUse fingerprinted filenames; only invalidate index.html

Related Skills

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

Conduct periodic access reviews and certifications. Implement access governance and recertification workflows. Use when managing access compliance.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

BagelHole/DevOps-Security-Agent-Skills1.2천2026년 5월 22일 업데이트

Build automated evaluation suites for AI agents using golden datasets, rubrics, and regression gates. Use when shipping agent features, validating prompt changes, or gating deployments on quality.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

BagelHole/DevOps-Security-Agent-Skills1.2천2026년 5월 22일 업데이트

Instrument AI agents with tracing, token metrics, latency, and cost visibility. Use for reliability and debugging.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

BagelHole/DevOps-Security-Agent-Skills1.2천2026년 5월 22일 업데이트

Secure AI agents against prompt injection, tool abuse, and data exfiltration with defense-in-depth controls. Use when building, deploying, or hardening agentic AI systems that invoke tools, access data, or interact with production infrastructure.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

BagelHole/DevOps-Security-Agent-Skills1.2천2026년 5월 22일 업데이트

Secure AI coding agents (Claude Code, Cursor, Codex, Copilot) with permission boundaries, secret protection, code review gates, and safe sandbox configurations for team environments.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

BagelHole/DevOps-Security-Agent-Skills1.2천2026년 5월 22일 업데이트

Use service mesh patterns for AI inference traffic management, mTLS, canary releases, policy enforcement, and cross-cluster resilience.

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

BagelHole/DevOps-Security-Agent-Skills1.2천2026년 5월 22일 업데이트

BagelHole의 스킬 모두 보기

이 스킬의 문제 신고