Configurar la retención de exportaciones temporales

CloudflareBeginner
Practicar Ahora

Introducción

Un servicio de exportación debe eliminar las descargas temporales sin borrar los documentos retenidos. Aplicará reglas de expiración por prefijo, transición de clase de almacenamiento y limpieza de cargas incompletas en un bucket privado nuevo. Después, inspeccionará la política real y los metadatos de los objetos.

Complete primero la gestión de objetos y la limpieza de cargas multipart. Esta nueva VM utiliza Node.js 22.22.0, Wrangler 4.131.1 y AWS SDK 3.888.0. R2 debe estar activo y usted necesita permiso para configurar el bucket nuevo. Revise el comportamiento del ciclo de vida y los precios, incluidos los cargos por duración mínima y recuperación de Infrequent Access. El recurso de prueba permanece en el almacenamiento Standard y se elimina explícitamente durante esta sesión. Las comprobaciones de aceptación validan las reglas aplicadas y los metadatos actuales, no una eliminación o transición ocurrida días después. No se requiere ningún dominio.

Crear el bucket privado de documentos

En este paso, autorizará esta VM y creará un bucket desechable. La autorización del dispositivo confirma su cuenta de aprendizaje. La gestión de buckets de R2 utiliza un token de API independiente, restringido a esa cuenta.

Inicie Bash para usar la sintaxis de comandos que aparece a continuación. Después, vaya al proyecto preparado y compruebe sus herramientas. Mantenga abierto este mismo terminal para conservar disponibles las variables con los nombres de sus recursos:

bash
cd /home/labex/project/r2-lab
export PATH="$PWD/.tools/node-v22.22.0-linux-x64/bin:$PATH"
node --version
npx wrangler --version

Autorice el código de dispositivo mostrado en su propio navegador. Confirme la cuenta de aprendizaje y los ámbitos de lectura de la cuenta y del usuario solicitados antes de aceptar:

npx wrangler login --device --browser=false --scopes account:read user:read
npx wrangler whoami --json

Exija que aparezca loggedIn: true. Lea el nombre de la cuenta aunque solo aparezca una cuenta. Sustituya YOUR_ACCOUNT_ID en el siguiente bloque por el ID real de 32 caracteres de esa cuenta. openssl rand -hex 6 genera doce caracteres hexadecimales aleatorios para evitar que este laboratorio entre en conflicto con una ejecución anterior. El documento here-document escribe un archivo de configuración estándar; el shell sustituye en él los valores de sus variables.

ACCOUNT_ID=YOUR_ACCOUNT_ID
RUN_ID=$(openssl rand -hex 6)
NAME="labex-c05-r07-$RUN_ID"
BUCKET="$NAME-docs"
cat > wrangler.jsonc <<JSON
{"name":"$NAME","account_id":"$ACCOUNT_ID","compatibility_date":"2026-07-30","r2_buckets":[{"binding":"DOCUMENTS","bucket_name":"$BUCKET"}]}
JSON

Para gestionar el bucket, abra la página API Tokens de su perfil de Cloudflare y cree un token personalizado con el nombre de este laboratorio. Conceda Account → Workers R2 Storage → Edit y restrinja Account Resources a la cuenta de aprendizaje cuyo ID guardó. Configure una caducidad breve. No incluya otras cuentas ni permisos no relacionados. Este token de administración sirve para administrar buckets, incluida su creación y eliminación. Más adelante en este mismo paso, creará un token de objetos separado, limitado a este bucket, para que el SDK de S3 trabaje con los objetos.

Copie el token una sola vez en este prompt de la VM oculta. umask 077 restringe el archivo a su usuario; read -s oculta la entrada. El archivo utiliza la variable de token estándar de Wrangler y queda excluido de Git.

umask 077
read -r -s -p 'R2 management API token: ' R2_MANAGEMENT_TOKEN; printf '\n'
printf 'CLOUDFLARE_API_TOKEN=%s\n' "$R2_MANAGEMENT_TOKEN" > .env.management
unset R2_MANAGEMENT_TOKEN

Use --env-file=.env.management únicamente con los comandos de gestión de R2; whoami seguirá comprobando la autorización del dispositivo de la VM.

Coloque --env-file al final de cada comando de Wrangler para que su lista de archivos no incluya el nombre del comando. Después de crear cada bucket, si Wrangler pregunta si debe añadir un enlace a la configuración, escriba n y pulse Enter. La configuración ya contiene el enlace previsto.

npx wrangler r2 bucket create "$BUCKET" --env-file=.env.management

Enumere sus buckets y busque el nombre generado exacto. Los demás buckets pertenecen a otros trabajos; no los modifique.

npx wrangler r2 bucket list --env-file=.env.management

En el Dashboard, abra Storage & databases → R2 → Overview, seleccione este bucket exacto e inspeccione su lista de objetos vacía. En la configuración, deje desactivadas la URL pública de desarrollo y los dominios personalizados. El nombre del bucket en el Dashboard confirma su identidad; las comprobaciones de descarga posteriores demostrarán cuáles son los bytes almacenados.

La API compatible con S3 permite que los SDK de almacenamiento estándar accedan a R2. Utiliza un par de claves de acceso independiente en lugar del token de dispositivo de Wrangler. En R2 Overview, vaya a Account Details → API Tokens → Manage y cree un User API token con el nombre del recurso generado para este laboratorio. Elija Object Read & Write, restrinja el token a este bucket nuevo exacto y seleccione una caducidad breve si el formulario ofrece esa opción. No elija todos los buckets ni el acceso de administrador. Mantenga abierta esta página del token hasta haber guardado el secreto de un solo uso.

Utilice los siguientes prompts de Bash en la VM. read -s oculta la entrada; umask 077 hace que el archivo de credenciales solo pueda leerlo su usuario. Estos nombres son las variables de entorno estándar del AWS SDK. Pegue el Access Key ID y el Secret Access Key en sus respectivos prompts y pulse Enter. No pegue el valor del token de API general.

umask 077
read -r -s -p 'Access Key ID: ' AWS_ACCESS_KEY_ID; printf '\n'
read -r -s -p 'Secret Access Key: ' AWS_SECRET_ACCESS_KEY; printf '\n'
printf 'AWS_ACCESS_KEY_ID=%s\nAWS_SECRET_ACCESS_KEY=%s\n' "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY" > .env.s3
unset AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY

Escriba un cliente reutilizable para el SDK estándar. El SDK requiere una cadena de región; R2 utiliza auto. Leer la configuración existente garantiza que las operaciones de la CLI y del SDK se dirijan a la misma cuenta y al mismo bucket.

cat > storage.mjs <<'JS'
import { S3Client } from "@aws-sdk/client-s3";
import { readFileSync } from "node:fs";
const config = JSON.parse(readFileSync("wrangler.jsonc", "utf8"));
export const Bucket = config.r2_buckets[0].bucket_name;
export const s3 = new S3Client({
  region: "auto",
  endpoint: `https://${config.account_id}.r2.cloudflarestorage.com`,
  credentials: {
    accessKeyId: process.env.AWS_ACCESS_KEY_ID,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY
  }
});
JS

Aplicar reglas de ciclo de vida específicas por prefijo

En este paso, configurará una lifecycle policy, es decir, un conjunto de acciones de almacenamiento que R2 aplica a medida que los objetos envejecen. Las exportaciones temporales deben caducar, mientras que los manuales retenidos deben quedar fuera de esas reglas. Una transición de clase de almacenamiento cambia la clase de facturación y acceso; no elimina el objeto.

Este bucket desechable nuevo utilizará dos reglas: los objetos de temporary/ caducan después de dos días y las cargas sin finalizar de ese prefijo se cancelan después de un día; los objetos de archive/ pasan a Infrequent Access después de treinta días. Ninguna regla afecta a retained/.

La API expresa las edades en segundos: un día equivale a 86.400 segundos. Escriba la política con un here-document entre comillas para conservar su JSON:

cat > lifecycle.json <<'JSON'
{
  "rules": [
    {
      "id": "temporary-exports",
      "enabled": true,
      "conditions": {
        "prefix": "temporary/"
      },
      "deleteObjectsTransition": {
        "condition": {
          "type": "Age",
          "maxAge": 172800
        }
      },
      "abortMultipartUploadsTransition": {
        "condition": {
          "type": "Age",
          "maxAge": 86400
        }
      }
    },
    {
      "id": "archive-transition",
      "enabled": true,
      "conditions": {
        "prefix": "archive/"
      },
      "storageClassTransitions": [
        {
          "condition": {
            "type": "Age",
            "maxAge": 2592000
          },
          "storageClass": "InfrequentAccess"
        }
      ]
    }
  ]
}
JSON
npx wrangler r2 bucket lifecycle set "$BUCKET" --file lifecycle.json --env-file=.env.management
npx wrangler r2 bucket lifecycle list "$BUCKET" --env-file=.env.management

El comando set reemplaza la política, así que confirme que solo está afectado este bucket nuevo del laboratorio. Exija exactamente los dos prefijos, el estado habilitado y las edades indicadas. No aplique este reemplazo a un bucket de una aplicación existente. En el Dashboard, abra Settings → Object Lifecycle Rules del mismo bucket e inspeccione las acciones sin modificarlas.

Límite de costes: Infrequent Access tiene cargos de recuperación y una duración mínima de almacenamiento. Este laboratorio configura una transición futura y elimina durante la limpieza sus nuevos objetos Standard. No esperará treinta días, no forzará una transición ni afirmará que la transición se produjo realmente.

Esta vista real del Dashboard muestra acciones futuras configuradas: eliminar objetos temporary/ tras 2 días, abortar cargas incompletas de ese prefijo tras 1 día y pasar objetos archive/ a Infrequent Access tras 30 días. No demuestra que hayan transcurrido esos plazos ni que las acciones se hayan ejecutado. El siguiente paso comprueba los metadatos actuales; retained/ queda fuera de ambos prefijos.

Reglas de ciclo de vida por prefijo activadas

Inspeccionar los metadatos de expiración recién aplicados

En este paso, cargará objetos nuevos después de aplicar la política. R2 documenta que los objetos nuevos reflejan una expiración aplicable en x-amz-expiration; los objetos existentes pueden tardar más en reflejar una regla modificada. El SDK expone esta cabecera como Expiration.

cat > seed.mjs <<'JS'
import { PutObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3";
import { readFileSync } from "node:fs";
import { s3, Bucket } from "./storage.mjs";
for (const Key of ["temporary/export.txt", "archive/export.txt"]) {
  await s3.send(new PutObjectCommand({ Bucket, Key, Body: readFileSync("document.txt"), ContentType: "text/plain" }));
}
await s3.send(new PutObjectCommand({ Bucket, Key: "retained/handbook.txt", Body: readFileSync("retained.txt"), ContentType: "text/plain" }));
for (const Key of ["temporary/export.txt", "archive/export.txt", "retained/handbook.txt"]) {
  const head = await s3.send(new HeadObjectCommand({ Bucket, Key }));
  console.log({ key: Key, expiration: head.Expiration || "none", storageClass: head.StorageClass || "STANDARD" });
}
JS
node --env-file=.env.s3 seed.mjs

Exija una fecha de expiración para temporary/export.txt, ninguna fecha de expiración por eliminación para el manual retenido y almacenamiento Standard para el objeto de archivo nuevo. La transición futura queda demostrada por la regla remota, no por una clase de almacenamiento IA actual. Si faltan los metadatos de expiración esperados del objeto nuevo, inspeccione el prefijo y la política aplicados; no considere que la comprobación de expiración fue correcta.

Descargue el objeto retenido y compare sus bytes originales:

npx wrangler r2 object get "$BUCKET/retained/handbook.txt" --remote --file retained-download.txt --env-file=.env.management
cmp retained.txt retained-download.txt

Una lectura correcta de la política y un objeto retenido que se pueda leer establecen el resultado acotado de este laboratorio. La eliminación real del ciclo de vida es asíncrona y puede producirse después de la expiración nominal; este laboratorio no evalúa un evento ocurrido varias horas más tarde.

Vaciar explícitamente el almacenamiento del laboratorio

En este paso, eliminará ahora los tres recursos de prueba en lugar de depender de sus futuras acciones del ciclo de vida. En este laboratorio no se creó ninguna carga incompleta, pero también debe enumerar ese inventario: las listas de objetos por sí solas no pueden demostrar que un bucket no tenga partes sin finalizar.

cat > empty.mjs <<'JS'
import { DeleteObjectCommand, ListObjectsV2Command, ListMultipartUploadsCommand } from "@aws-sdk/client-s3";
import { s3, Bucket } from "./storage.mjs";
for (const Key of ["temporary/export.txt", "archive/export.txt", "retained/handbook.txt"]) await s3.send(new DeleteObjectCommand({ Bucket, Key }));
const objects = await s3.send(new ListObjectsV2Command({ Bucket }));
const uploads = await s3.send(new ListMultipartUploadsCommand({ Bucket }));
console.log("Objects:", objects.Contents || []);
console.log("Incomplete uploads:", uploads.Uploads || []);
JS
node --env-file=.env.s3 empty.mjs

Exija que las matrices de objetos y de cargas incompletas estén vacías. Si creó una sesión multipart mientras experimentaba, utilice la operación de cancelación del laboratorio anterior con esa clave y ese ID de carga exactos que le pertenecen y repita estas listas de solo lectura. Nunca ignore silenciosamente las solicitudes de listado fallidas.

Eliminar el bucket vacío y su política

En este paso, eliminará el bucket que posee después de que la comprobación de objetos y cargas sea correcta. La política forma parte de la configuración del bucket y desaparece junto con él.

npx wrangler r2 bucket delete "$BUCKET" --env-file=.env.management
npx wrangler r2 bucket list --env-file=.env.management

Confirme el nombre generado exacto. Exija que ese nombre no aparezca en una lista autenticada correcta. Ejecute la comprobación de eliminación de la plataforma antes de revocar la credencial de gestión.

Revocar la credencial del laboratorio y cerrar sesión

En este paso, cerrará el acceso que dejó este ejercicio. En la página R2 API Tokens, revoque únicamente el token de objetos que tiene el nombre de este laboratorio. En la página API Tokens de su perfil, revoque el token de gestión de R2 independiente que creó para este laboratorio. Eliminar un bucket no revoca un token, y cerrar sesión en Wrangler no revoca las credenciales de S3.

Después de revocar los tokens, elimine el archivo local de credenciales y cierre la sesión de esta VM:

rm .env.s3 .env.management
npx wrangler logout

Inspeccione la identidad estructurada. Su estado distinto de cero es esperado cuando la sesión está cerrada:

npx wrangler whoami --json || true

Exija que aparezca loggedIn: false; mantenga iniciada su sesión habitual en el Dashboard. La plataforma comprueba la eliminación local de las credenciales y el cierre de sesión de Wrangler. La revocación de ambos tokens son comprobaciones manuales en el Dashboard en este laboratorio; no se deduce de la eliminación de los archivos.

Resumen

Aplique reglas de expiración por ámbito, futuras transiciones de almacenamiento y limpieza de cargas multipart, inspeccione los metadatos actuales, conserve los datos retenidos y realice la limpieza de forma explícita.