К основному содержанию
скилл CX Codex

cloudflare-r2 — скилл для Claude Code: что делает и как установить

Помогает управлять хранилищем Cloudflare R2, настраивать бакеты через Wrangler, генерировать подписанные ссылки и связывать данные с Cloudflare Workers.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add BagelHole/DevOps-Security-Agent-Skills --skill cloudflare-r2 -a claude-code
Открыть на GitHub

Что делает cloudflare-r2

Скилл даёт агенту инструкции и шаблоны для работы с объектным хранилищем Cloudflare R2. Внутри собраны готовые команды для Wrangler CLI v3+, примеры вызовов через AWS CLI и Python-библиотеку boto3, а также конфигурации привязок для Cloudflare Workers.

С его помощью агент умеет создавать бакеты с выбором региона, загружать файлы с указанием Content-Type, настраивать публичный доступ и генерировать временные presigned URL. Здесь же показан код воркера на TypeScript с обработкой GET, PUT и DELETE запросов к бакету.

Для выполнения операций обязательно нужен аккаунт Cloudflare с подключённым R2, установленный Wrangler v3+ и созданный токен R2 API при обращении через S3-совместимые клиенты. Без этих ключей команды завершатся ошибкой авторизации.

Какие задачи решает

  • Создать бакет R2 в заданном регионе через Wrangler
  • Сгенерировать подписанный URL для скачивания файла через boto3
  • Привязать хранилище R2 к воркеру в файле wrangler.toml
  • Синхронизировать локальную директорию со статикой через AWS CLI

Примеры запросов агенту

  • Создай новый бакет R2 в регионе eu с помощью Wrangler
  • Напиши код воркера для загрузки файлов в бакет user-uploads через PUT-запрос
  • Сгенерируй presigned URL для отчёта в бакете app-assets на Python через boto3

Как установить cloudflare-r2

1Через Skills CLI (Vercel)

npx skills add BagelHole/DevOps-Security-Agent-Skills --skill cloudflare-r2 -a claude-code

2Вручную: положить файлы

~/.claude/skills/cloudflare-r2/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/cloudflare-r2/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Из того же набора127

access-review Скилл проводит периодические проверки доступов в AWS IAM, GitHub и Okta: находит спящие аккаунты, лишние права и ключи без MFA. Пригодится перед аудитом по SOC 2, HIPAA или ISO 27001. CX Codex +1 337установок elk-stack Разворачивает стек ELK (Elasticsearch, Logstash, Kibana) и Filebeat в Docker, настраивает конвейеры обработки логов и правила хранения данных. CX Codex +1 336установок asset-inventory Скилл помогает вести инвентаризацию IT-активов и CMDB, собирая данные об инфраструктуре в AWS, локальных серверах и SaaS. Пригодится при подготовке к аудитам ISO 27001 или SOC 2. CX Codex +1 335установок gcp-gke Скилл для работы с Google Kubernetes Engine: создание кластеров, node pools, Workload Identity и деплой нагрузок через gcloud и kubectl. CX Codex +1 336установок vendor-management Оценивает безопасность сторонних поставщиков и распределяет их по четырём уровням риска. Пригодится при подготовке к аудитам SOC 2 и ISO 27001. CX Codex +1 334установок business-continuity Скилл помогает написать план непрерывности бизнеса, провести анализ влияния на процессы и расписать порядок действий при сбое. CX Codex +1 335установок aws-secrets-manager Скилл для работы с AWS Secrets Manager: создаёт секреты, настраивает ротацию и подключает их к приложениям. CX Codex +1 335установок mcp-server-security Скилл-руководство по укреплению MCP-серверов: TLS, OAuth 2.1, mTLS, валидация ввода и аудит вызовов инструментов. CX Codex +1 334установок

Похожие

cloudflare-development Mindrally Скилл с правилами разработки на edge-платформе Cloudflare: Workers, Pages, KV, D1, R2 и Durable Objects. Пригодится, когда агент пишет код для воркеров или настраивает wrangler.toml. CX Codex +1 689установок cloudflare-email-service cloudflare Скилл для работы с Cloudflare Email Sending и Email Routing: помогает настроить отправку и приём писем в Workers. CX Codex +1 102 300установок cloudflare-manager secondsky Скилл управляет аккаунтом Cloudflare из чата: разворачивает Workers, создаёт KV и R2, публикует Pages, настраивает DNS. CX Codex +1 393установок cloudflare cloudflare Помогает агенту подбирать сервисы Cloudflare под задачи проекта, от хостинга до очередей и AI, и выбирать между CLI cf и Wrangler. CX Codex +1 137 800установок building-mcp-server-on-cloudflare официальный Cloudflare Скилл проводит агента через сборку удалённого MCP-сервера на Cloudflare Workers: инструменты, OAuth, деплой. Пригодится, когда нужно выставить свои функции наружу по MCP. CX Codex GP ChatGPT 2установок bun-cloudflare-workers secondsky Скилл для сборки и деплоя Cloudflare Workers на Bun: подсказывает структуру проекта, биндинги KV, D1, R2 и Durable Objects. CX Codex +1 402установок

Рядом в теме «Облака: AWS, Azure, GCP»

Всё по теме «Облака: AWS, Azure, GCP» →

Вопросы о cloudflare-r2

Как установить cloudflare-r2 в Claude Code?

Выполните команду npx skills add BagelHole/DevOps-Security-Agent-Skills --skill cloudflare-r2 -a claude-code. Также можно вручную поместить файл инструкции по пути ~/.claude/skills/cloudflare-r2/SKILL.md.

Что делает скилл cloudflare-r2?

Он обучает агента операциям с хранилищем Cloudflare R2: созданию бакетов, загрузке объектов через Wrangler, вызовам через S3 API и связыванию с кодом воркеров.

Что нужно подготовить перед началом работы с R2?

Потребуется аккаунт Cloudflare с активированным R2, установленный Wrangler v3+ и авторизация через wrangler login или переменную CLOUDFLARE_API_TOKEN. Для работы со сторонними S3-клиентами нужен токен R2 API.

Исходный текст

SKILL.md · MIT
---
name: cloudflare-r2
description: Manage Cloudflare R2 buckets, lifecycle, and signed URLs. Use for low-egress object storage and media delivery.
license: MIT
metadata:
  author: devops-skills
  version: "1.0"
---

# Cloudflare R2

S3-compatible object storage with zero egress fees, built on Cloudflare's global network.

## When to Use

- Storing user uploads, media files, backups, or static assets.
- Replacing AWS S3 to eliminate egress costs for read-heavy workloads.
- Serving files at the edge via Workers or public bucket access.
- Building multi-cloud storage that avoids vendor lock-in (S3 API compatible).
- Storing ML model artifacts, training data, or inference results.

## Prerequisites

- Cloudflare account with R2 enabled (dashboard > R2 > subscribe).
- Wrangler CLI v3+ installed: `npm install -g wrangler`.
- Authenticated via `wrangler login` or `CLOUDFLARE_API_TOKEN`.
- For S3 API access: R2 API token created under **R2 > Manage R2 API Tokens**.

## Bucket Management with Wrangler

### Create and List Buckets

```bash
# Create a new bucket
npx wrangler r2 bucket create app-assets

# Create a bucket in a specific region (hint for data locality)
npx wrangler r2 bucket create eu-uploads --location=eu

# List all buckets
npx wrangler r2 bucket list

# Delete an empty bucket
npx wrangler r2 bucket delete old-bucket
```

### Object Operations

```bash
# Upload a single file
npx wrangler r2 object put app-assets/images/logo.png --file=./logo.png

# Upload with content type
npx wrangler r2 object put app-assets/data/report.json \
  --file=./report.json \
  --content-type="application/json"

# Download an object
npx wrangler r2 object get app-assets/images/logo.png --file=./downloaded-logo.png

# Delete an object
npx wrangler r2 object delete app-assets/images/old-logo.png

# Get object metadata
npx wrangler r2 object head app-assets/images/logo.png
```

## S3-Compatible API Access

R2 supports the S3 API, so existing tools (AWS CLI, boto3, s3cmd) work out of the box.

### Generate R2 API Tokens

1. Go to **R2 > Manage R2 API Tokens > Create API token**.
2. Select permissions: Object Read & Write, or Object Read only.
3. Scope to specific buckets if possible.
4. Save the Access Key ID and Secret Access Key.

### AWS CLI Configuration

```bash
# Configure a named profile for R2
aws configure --profile r2
# Access Key ID: <your-r2-access-key>
# Secret Access Key: <your-r2-secret-key>
# Region: auto
# Output: json

# Use the R2 endpoint
export R2_ENDPOINT="https://<ACCOUNT_ID>.r2.cloudflarestorage.com"

# List buckets
aws s3 ls --endpoint-url=$R2_ENDPOINT --profile=r2

# Sync a directory
aws s3 sync ./dist s3://app-assets/static/ \
  --endpoint-url=$R2_ENDPOINT \
  --profile=r2

# Copy a file
aws s3 cp ./backup.tar.gz s3://app-assets/backups/backup-$(date +%Y%m%d).tar.gz \
  --endpoint-url=$R2_ENDPOINT \
  --profile=r2

# List objects with prefix
aws s3 ls s3://app-assets/images/ \
  --endpoint-url=$R2_ENDPOINT \
  --profile=r2

# Remove objects by prefix
aws s3 rm s3://app-assets/tmp/ --recursive \
  --endpoint-url=$R2_ENDPOINT \
  --profile=r2
```

### Python boto3 Client

```python
import boto3

s3 = boto3.client(
    "s3",
    endpoint_url="https://<ACCOUNT_ID>.r2.cloudflarestorage.com",
    aws_access_key_id="<R2_ACCESS_KEY>",
    aws_secret_access_key="<R2_SECRET_KEY>",
    region_name="auto",
)

# Upload file
s3.upload_file("./report.pdf", "app-assets", "reports/report.pdf")

# Generate presigned URL (valid for 1 hour)
url = s3.generate_presigned_url(
    "get_object",
    Params={"Bucket": "app-assets", "Key": "reports/report.pdf"},
    ExpiresIn=3600,
)
print(url)

# List objects
response = s3.list_objects_v2(Bucket="app-assets", Prefix="images/", MaxKeys=100)
for obj in response.get("Contents", []):
    print(f"{obj['Key']} - {obj['Size']} bytes")
```

## Worker Bindings

Bind R2 buckets to Workers or Pages Functions for server-side access without API tokens.

### Wrangler Configuration

```toml
# wrangler.toml
name = "asset-worker"
main = "src/index.ts"
compatibility_date = "2024-09-01"

[[r2_buckets]]
binding = "ASSETS"
bucket_name = "app-assets"

[[r2_buckets]]
binding = "UPLOADS"
bucket_name = "user-uploads"
```

### Worker with R2 Operations

```typescript
// src/index.ts
interface Env {
  ASSETS: R2Bucket;
  UPLOADS: R2Bucket;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const url = new URL(request.url);

    // GET — serve file from R2
    if (request.method === "GET") {
      const key = url.pathname.slice(1); // strip leading /
      const object = await env.ASSETS.get(key);

      if (!object) {
        return new Response("Not Found", { status: 404 });
      }

      const headers = new Headers();
      object.writeHttpMetadata(headers);
      headers.set("etag", object.httpEtag);
      headers.set("cache-control", "public, max-age=86400");

      return new Response(object.body, { headers });
    }

    // PUT — upload file to R2
    if (request.method === "PUT") {
      const key = url.pathname.slice(1);
      const contentType = request.headers.get("content-type") || "application/octet-stream";

      await env.UPLOADS.put(key, request.body, {
        httpMetadata: { contentType },
        customMetadata: { uploadedAt: new Date().toISOString() },
      });

      return new Response(JSON.stringify({ key, status: "uploaded" }), {
        headers: { "Content-Type": "application/json" },
      });
    }

    // DELETE — remove file
    if (request.method === "DELETE") {
      const key = url.pathname.slice(1);
      await env.UPLOADS.delete(key);
      return new Response(null, { status: 204 });
    }

    return new Response("Method Not Allowed", { status: 405 });
  },
};
```

### Presigned URL Generation in a Worker

```typescript
// Generate time-limited signed URLs using Workers
import { AwsClient } from "aws4fetch";

interface Env {
  R2_ACCESS_KEY: string;
  R2_SECRET_KEY: string;
  R2_ACCOUNT_ID: string;
}

export default {
  async fetch(request: Request, env: Env): Promise<Response> {
    const aws = new AwsClient({
      accessKeyId: env.R2_ACCESS_KEY,
      secretAccessKey: env.R2_SECRET_KEY,
    });

    const url = new URL(request.url);
    const key = url.searchParams.get("key");
    if (!key) return new Response("Missing key", { status: 400 });

    const r2Url = `https://${env.R2_ACCOUNT_ID}.r2.cloudflarestorage.com/app-assets/${key}`;

    const signed = await aws.sign(new Request(r2Url), {
      aws: { signQuery: true },
    });

    return Response.json({ url: signed.url });
  },
};
```

## Public Bucket Access

Enable public access to serve files directly without a Worker.

1. Go to **R2 > bucket > Settings > Public access**.
2. Enable and set a custom domain (e.g., `assets.example.com`).
3. Objects are accessible at `https://assets.example.com/<key>`.

```bash
# Or enable via the r2.dev subdomain (for testing)
# Bucket Settings > R2.dev subdomain > Allow Access
# URL: https://pub-<hash>.r2.dev/<key>
```

## Lifecycle Rules

Configure automatic object expiration or transition.

```bash
# Set lifecycle rules via the Cloudflare dashboard:
# R2 > bucket > Settings > Object lifecycle rules

# Or via API
curl -X PUT "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/r2/buckets/app-assets/lifecycle" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [
      {
        "id": "expire-tmp-files",
        "enabled": true,
        "conditions": { "prefix": "tmp/" },
        "actions": { "deleteObject": { "daysAfterCreationDate": 7 } }
      },
      {
        "id": "expire-old-logs",
        "enabled": true,
        "conditions": { "prefix": "logs/" },
        "actions": { "deleteObject": { "daysAfterCreationDate": 90 } }
      }
    ]
  }'
```

## CORS Configuration

```bash
# Set CORS policy for browser-based uploads
curl -X PUT "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ID/r2/buckets/app-assets/cors" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "corsRules": [
      {
        "allowedOrigins": ["https://example.com"],
        "allowedMethods": ["GET", "PUT", "HEAD"],
        "allowedHeaders": ["Content-Type", "Authorization"],
        "maxAgeSeconds": 3600
      }
    ]
  }'
```

## Troubleshooting

| Symptom | Cause | Fix |
|---------|-------|-----|
| `NoSuchBucket` error via S3 API | Wrong endpoint or bucket name | Verify endpoint is `https://<ACCOUNT_ID>.r2.cloudflarestorage.com` |
| `SignatureDoesNotMatch` | Incorrect secret key or endpoint mismatch | Regenerate R2 API token; ensure region is `auto` |
| Uploads succeed but GET returns 404 | Key path mismatch (leading slash) | R2 keys should not start with `/` |
| Slow uploads for large files | Single-stream upload | Use multipart upload; set `--expected-size` with wrangler |
| CORS errors in browser | Missing CORS config on bucket | Add CORS rules for your origin domain |
| Worker binding returns `undefined` | `wrangler.toml` binding name mismatch | Verify `binding` name matches `Env` interface property |
| Public access returns 403 | Public access not enabled | Enable in bucket Settings > Public access |

## Related Skills

- [cloudflare-workers](../cloudflare-workers/) - Signed URL generation and edge file serving
- [cloudflare-pages](../cloudflare-pages/) - Pages Functions with R2 bindings
- [cdn-setup](../../networking/cdn-setup/) - CDN configuration for asset delivery

© devops-skills · MIT · BagelHole/DevOps-Security-Agent-Skills

Смотрите также

Спонсоры проекта

Компании, которые помогают держать аналитику открытой