Unidad 2.4: Provisionamiento de almacenamiento como código
Introducción
Está construyendo la capa de almacenamiento de TaskBoard, y cada pieza de estado se encuentra en un lugar diferente. El servidor API necesita un almacenamiento de datos persistente Volume que sobreviva a los reinicios y se comporte como un disco local. Los archivos adjuntos subidos por el usuario pertenecen a un almacenamiento de objetos al que se accede a través de HTTP con credenciales S3, y no deben estar unidos a un solo VM. Y si más tarde ejecuta varios trabajadores que leen el mismo conjunto de archivos, desea un sistema de archivos compartido en lugar de copias en cada Node.
Los tres se provisionan de la misma manera: recursos declarativos Terraform contra el IONOS API, con el mismo modelo de creación y espera asíncrona que ha utilizado desde la Unidad 1.1. Las diferencias que lo afectan son las restricciones. Block Storage y Compute no comparten las mismas zonas de disponibilidad. Object Storage no utiliza su token de portador en absoluto. NFS solo habla una versión de protocolo. Esta unidad analiza cada tipo de almacenamiento a nivel de código y muestra dónde estas restricciones cambian lo que escribe.
1. Block Storage Volúmenes con Terraform
Block Storage se provisiona como ionoscloud_volume y se comporta como un dispositivo de bloque iSCSI conectado a un servidor. Usted declara el tamaño, el tipo de almacenamiento y la zona de disponibilidad, y Terraform maneja la provisión y el acoplamiento asíncronos. Un Volume se crea dentro de un centro de datos y se vincula a un solo servidor a través del atributo server_id.
El tamaño mínimo de Volume es 1 GiB y el máximo es 4096 GiB (4 TiB) para cada tipo de Block Storage. Volúmenes más grandes pueden solicitarse a través del soporte de IONOS Cloud. El tipo de almacenamiento no se puede cambiar después de la provisión, así que elija correctamente en el momento de la creación en lugar de planificar convertirlo más adelante.
1.1 Declarar y acoplar un Volume
La siguiente configuración crea un disco de datos SSD Premium y lo acopla al servidor TaskBoard API. Los image_name y image_password (o ssh_key_path) son obligatorios cuando el Volume es arrancable; para un disco de datos puro, usted proporciona un licence_type en su lugar y omite la imagen.
resource "ionoscloud_datacenter" "taskboard" {
name = "taskboard"
location = "de/txl"
}
resource "ionoscloud_volume" "api_data" {
datacenter_id = ionoscloud_datacenter.taskboard.id
server_id = ionoscloud_server.api.id
name = "taskboard-api-data"
size = 50
disk_type = "SSD Premium"
licence_type = "LINUX"
availability_zone = "AUTO"
}
El disk_type acepta las variantes de tecnología de almacenamiento expuestas por Block Storage: HDD, SSD Premium, y SSD Standard. SSD Premium ofrece la mayor cantidad de IOPS por Volume, SSD Standard intercambia rendimiento por costo, y HDD es la opción de giro más económica. Las tres opciones tienen un límite de 4 TiB (4096 GiB) por Volume con un piso de 1 GiB.
1.2 La trampa de la zona de disponibilidad
Las zonas de disponibilidad de Block Storage no son el mismo conjunto que las zonas de disponibilidad de Compute, y este es el error de aprovisionamiento más común en el nivel de almacenamiento. Block Storage admite Zone 1, Zone 2, Zone 3, y Auto. Los servidores de Compute solo admiten las zonas 1, 2 y Auto. La zona 3 existe para el almacenamiento, pero no hay zona 3 para el cómputo.
Esto es importante porque un Volume y el servidor al que se conecta viven en el mismo centro de datos, pero se colocan mediante ajustes de zona independientes. Si usted fija un Volume a una zona que no se alinea con su estrategia de colocación de servidores, usted restringe la programación sin beneficio. El valor predeterminado seguro es AUTO tanto para el servidor como para el Volume, a menos que usted tenga un requisito específico de fijación de zona.
// Safe default: let the platform place both
resource "ionoscloud_server" "api" {
datacenter_id = ionoscloud_datacenter.taskboard.id
name = "taskboard-api"
cores = 4
ram = 8192
availability_zone = "AUTO" // Zone 1, 2, or AUTO only - never Zone 3
}
resource "ionoscloud_volume" "api_data" {
# ...
availability_zone = "AUTO" # Zone 1, 2, 3, or AUTO permitted for storage
}
Los volúmenes pueden combinarse entre tipos en un solo VM. Un servidor puede llevar tanto volúmenes SSD como HDD al mismo tiempo. El límite por VM Volume depende del tipo: SSD Premium permite hasta 4 volúmenes adjuntos a un VM, mientras que HDD y SSD Standard permiten hasta 24. Planifique diseños de varios Volume contra el límite del tipo que elija.
1.3 Contexto de cifrado y durabilidad
Block Storage proporciona almacenamiento con redundancia doble: los datos se escriben en dos servidores de almacenamiento, cada uno protegido por RAID, para redundancia a nivel de plataforma. El cifrado en REST para volúmenes lógicos utiliza el algoritmo AES-XTS. Usted no configura ninguno de los dos en el recurso Volume; ambos son propiedades de la capa de almacenamiento de la plataforma, por lo que su Terraform se mantiene enfocado en el tamaño, el tipo y la colocación.
2. Object Storage Cubos y claves de acceso
Object Storage se provisiona con ionoscloud_s3_bucket, y sus credenciales de acceso se acuñan con ionoscloud_s3_key. La diferencia crítica con respecto a todos los demás recursos en este curso: Object Storage no se autentica con su token IONOS. Implementa el S3 API de AWS y se autentica con una clave de acceso y una clave secreta. Su aplicación, su pipeline de CI y cualquier cliente S3 utilizan esas claves, nunca el token de nube API.
resource "ionoscloud_s3_key" "taskboard" {
user_id = var.user_id
}
resource "ionoscloud_s3_bucket" "attachments" {
name = "taskboard-attachments-prod"
}
Los nombres de los buckets deben ser únicos a nivel global en todos los Object Storage inquilinos y deben tener entre 3 y 63 caracteres. Trate el nombre como una etiqueta DNS, en minúsculas con guiones, y suponga que los nombres obvios ya están ocupados. Una colisión de nombres se produce como un error de creación en el momento de aplicar, no en el momento de planificación.
2.1 Salida de credenciales como valores sensibles
El recurso ionoscloud_s3_key produce una clave de acceso y una clave secreta. La clave secreta nunca debe aparecer en los registros o la salida en texto plano. Marque las salidas sensitive = true para que Terraform las oculte de la salida de la CLI y de los registros de CI; los valores aún viven en el estado, así que proteja el backend del estado en consecuencia.
output "s3_access_key" {
value = ionoscloud_s3_key.taskboard.id
sensitive = true
}
output "s3_secret_key" {
value = ionoscloud_s3_key.taskboard.secret_key
sensitive = true
}
output "s3_bucket_name" {
value = ionoscloud_s3_bucket.attachments.name
}
Una clave de acceso tiene 92 caracteres y una clave secreta tiene 64 caracteres. Cada usuario puede tener hasta 5 claves de acceso, lo que es suficiente para rotarlas sin tiempo de inactividad: crea la nueva clave, actualiza la configuración de tu aplicación y luego destruye la clave antigua. Las credenciales no están vinculadas a una región o cubo específico; un par de claves funciona en todos los cubos a los que el usuario puede acceder.
2.2 Puntos de conexión y regiones
Object Storage expone el estándar S3 API v2, y se accede a él a través de un punto de conexión específico de la región. A diferencia de AWS, debes establecer el punto de conexión explícitamente en cada cliente, porque los puntos de conexión predeterminados de AWS no se resolverán. La siguiente tabla enumera los puntos de conexión del servicio que harán referencia tu código y el backend de Terraform.
| Ubicación | Región | Punto de conexión S3 |
|---|---|---|
| Fráncfort, Alemania | eu-central-4 | s3.eu-central-4.ionoscloud.com |
| Berlín, Alemania | eu-central-2 | s3.eu-central-2.ionoscloud.com |
| Logroño, España | eu-south-2 | s3.eu-south-2.ionoscloud.com |
Elige el punto de conexión que coincida con la región donde creas el cubo y reutilízalo en todas partes: en boto3, en el bloque de backend de S3 a continuación, y en cualquier generación de URL firmada. Las conexiones utilizan TLS, con TLS 1.2 y 1.3 compatibles. El tamaño máximo de objeto es 5 TB. Object Storage ofrece una sola clase de almacenamiento, ESTÁNDAR, y un cubo admite hasta 1000 reglas de ciclo de vida para la expiración de objetos; las reglas de ciclo de vida no pueden transitar objetos a otra clase de almacenamiento (no hay un nivel de archivo o frío). S3, S3, Object Storage.
3. Object Storage como un Terraform de estado de backend
Dado que Object Storage es compatible con S3, actúa como un backend de estado remoto para Terraform. Esto resuelve el problema que se presentó en la Unidad 1.2: el estado local no sobrevive a través de un equipo o un ejecutor de CI. Almacenar el estado en un bucket da a cada ejecución de la canalización una fuente de verdad compartida y duradera.
3.1 Configuración de backend
El backend s3 necesita el punto de conexión de IONOS y las mismas banderas de omisión que utiliza para cualquier implementación de S3 que no sea de AWS, porque de lo contrario el backend intenta validar contra las reglas de cuenta y región de AWS que no se aplican.
terraform {
backend "s3" {
bucket = "taskboard-tfstate"
key = "infrastructure/terraform.tfstate"
region = "eu-central-4"
endpoints = {
s3 = "https://s3.eu-central-4.ionoscloud.com"
}
skip_credentials_validation = true
skip_requesting_account_id = true
skip_region_validation = true
skip_s3_checksum = true
}
}
Proporcione la clave de acceso y la clave secreta al backend a través de variables de entorno (AWS_ACCESS_KEY_ID y AWS_SECRET_ACCESS_KEY) en lugar de codificarlas de forma fija. El bucket de estado debe existir ya antes de terraform init, así que provéelo una vez con una configuración de arranque pequeña o con ionosctl, luego apunte el backend de su pila principal hacia él.
3.2 Por qué esto es importante para la canalización
El bucket de estado contiene sus claves secretas S3 y cadenas de conexión de base de datos dentro del archivo de estado. Restrinja quién puede leerlo. Un patrón práctico es un bucket por entorno, con prefijos de clave separados por pila, de modo que una canalización de desarrollo no pueda leer el estado de producción. Esto se lleva directamente al trabajo CI/CD en el Módulo 3, donde las mismas credenciales se convierten en secretos de la canalización.
4. NFS Almacenamiento compartido
Cuando varios servidores necesitan leer y escribir los mismos archivos, ni un Block Storage Volume de un solo punto de montaje ni un almacenamiento de objetos encaja limpiamente. NFS le proporciona un sistema de archivos POSIX montado de forma concurrente en Linux clientes. Está aprovisionado en dos recursos: ionoscloud_nfs_cluster define el Cluster, y ionoscloud_nfs_share define una participación dentro de él. El mismo ciclo de vida asíncrono y la limpieza de terraform destroy se aplican.
resource "ionoscloud_nfs_cluster" "shared" {
name = "taskboard-shared"
location = "de/txl"
size = 2
nfs {
min_version = "4.2"
}
connections {
datacenter_id = ionoscloud_datacenter.taskboard.id
ip_address = "10.7.222.100/24"
lan = ionoscloud_lan.app.id
}
}
resource "ionoscloud_nfs_share" "uploads" {
cluster_id = ionoscloud_nfs_cluster.shared.id
location = ionoscloud_nfs_cluster.shared.location
name = "uploads"
quota = 1024
gid = 1000
uid = 1000
}
4.1 Protocolo y limitaciones de capacidad
NFS en IONOS solo habla NFSv4.2. NFSv3 no es compatible, por lo que cualquier herramienta de cliente o entrada de fstab fijada en v3 no podrá montar. El tamaño de Cluster va desde un mínimo de 2 TiB hasta un máximo de 42 TiB, con toda la capacidad aprovisionada completamente utilizable. Las cuotas de participación se expresan en MiB.
El cifrado en REST es proporcionado por la plataforma. El cifrado en tránsito no está documentado para NFS, por lo que para datos sensibles mantenga la participación en una LAN privada y confíe en el aislamiento de red en lugar de esperar TLS en el punto de montaje. El Cluster se ejecuta en un modo de alta disponibilidad Activo-Pasivo y se accede a través de una IP privada que usted asigna en el bloque connections.
4.2 Montar la participación
Después de aplicar, la participación se monta desde un cliente Linux utilizando el Cluster IP y el UUID de la participación devuelto en la salida nfs_path del recurso. Linux es el sistema operativo del cliente compatible.
sudo mount -t nfs 10.7.222.100:/<share-uuid> /mnt/uploads
El aplastamiento de raíz es compatible, por lo que asocie UID y GID en la participación para que coincidan con el usuario de la aplicación que lee y escribe los archivos, como se muestra en los argumentos uid y gid de arriba. La propiedad no coincidente es la causa habitual de errores de denegación de permisos justo después de un montaje exitoso.
5. Selección del almacenamiento adecuado en código
Cada tipo de almacenamiento se asigna a un patrón de acceso diferente, y elegir el incorrecto se refleja como una restricción con la que luchar o una factura que no se esperaba. Block Storage se adjunta a exactamente un servidor y se comporta como un disco local: úselo para bases de datos, volúmenes de sistema operativo y cualquier Workload de un solo escritor. Object Storage se accede a través de HTTP con credenciales S3 y escala de forma independiente de cualquier VM: úselo para subidas de usuarios, copias de seguridad, activos estáticos y estado de Terraform. NFS proporciona acceso POSIX concurrente en varios clientes Linux: úselo solo cuando varios servidores deben compartir genuinamente un sistema de archivos.
La siguiente tabla resume la decisión a nivel que necesita mientras escribe Terraform.
| Necesidad | Recurso | Adjunto | Autenticación |
|---|---|---|---|
| Disco persistente de un solo servidor | ionoscloud_volume |
Un servidor, iSCSI | Token de IONOS API (aprovisionamiento) |
| Almacén de objetos accesible a través de HTTP | ionoscloud_s3_bucket + ionoscloud_s3_key |
Ninguno (S3 API) | Clave de acceso + Clave secreta |
| Sistema de archivos compartido, varios clientes | ionoscloud_nfs_cluster + ionoscloud_nfs_share |
Varios clientes Linux, NFSv4.2 | Montaje privado LAN |
Para TaskBoard, esto se resuelve de manera clara. El almacenamiento de datos del servidor API es Block Storage, adjunto a un servidor, con un tamaño para el conjunto de trabajo. Los archivos adjuntos van a Object Storage porque el navegador sube directamente con URLs firmadas y el servidor API nunca proxy los bytes. NFS no se utiliza en la versión base de TaskBoard; es el patrón al que se llega más adelante si se agrega una flota de trabajadores que deben compartir un directorio de contenido.
API Tarjeta de referencia rápida
Puntos de conexión clave de API para la provisión de almacenamiento:
| Método | Punto de conexión | Descripción |
|---|---|---|
GET |
/datacenters/{dcId}/volumes |
Lista los volúmenes de Block Storage |
POST |
/datacenters/{dcId}/volumes |
Crea un Block Storage Volume |
POST |
/datacenters/{dcId}/servers/{serverId}/volumes |
Adjunta un Volume a un servidor |
DELETE |
/datacenters/{dcId}/volumes/{id} |
Elimina un Volume |
GET |
/um/users/{userId}/s3keys |
Lista las claves de acceso de S3 para un usuario |
POST |
/um/users/{userId}/s3keys |
Crea una clave de acceso de S3 |
URL base de Cloud API: https://api.ionos.com/cloudapi/v6
Punto de conexión de Object Storage S3: https://s3.eu-central-4.ionoscloud.com (específico de la región)
URL base de NFS API: https://nfs.{region}.ionos.com
Autenticación: Cloud API utiliza Authorization: Bearer <token>; Object Storage utiliza Access Key + Secret Key (Firma AWS)
Laboratorio de código
Objetivo: Implementar la capa de almacenamiento de TaskBoard con Terraform: un centro de datos Block Storage con un Volume de datos adjunto al servidor API y un cubo Object Storage con credenciales de acceso como valores sensibles.
Requisitos previos:
- Cuenta de IONOS Cloud con token API (
IONOS_TOKENexportado) - Terraform 1.5+ con el proveedor
ionos-cloud/ionoscloud - Un centro de datos y servidor API existente (del laboratorio de la Unidad 2.1) o créelos en línea
Paso 1: Fijar el proveedor
terraform {
required_providers {
ionoscloud = {
source = "ionos-cloud/ionoscloud"
version = "~> 6.4"
}
}
}
provider "ionoscloud" {}
No hay texto para traducir. Por favor, proporcione el texto técnico que desea que traduzca.
(no output; init resolves the provider in Step 4)
Paso 2: Declarar los datos de Block Storage Volume
variable "user_id" { type = string }
resource "ionoscloud_volume" "api_data" {
datacenter_id = var.datacenter_id
server_id = var.server_id
name = "taskboard-api-data"
size = 50
disk_type = "SSD Premium"
licence_type = "LINUX"
availability_zone = "AUTO"
}
Paso 3: Declarar el Object Storage bucket y clave
resource "ionoscloud_s3_key" "taskboard" {
user_id = var.user_id
}
resource "ionoscloud_s3_bucket" "attachments" {
name = "taskboard-attachments-${var.user_id}"
}
output "s3_access_key" {
value = ionoscloud_s3_key.taskboard.id
sensitive = true
}
output "s3_secret_key" {
value = ionoscloud_s3_key.taskboard.secret_key
sensitive = true
}
Paso 4: Inicializar y planificar
terraform init
terraform plan -out=storage.plan
No hay texto para traducir. Por favor, proporcione el texto técnico que desea que traduzca.
Plan: 3 to add, 0 to change, 0 to destroy.
Changes to Outputs:
+ s3_access_key = (sensitive value)
+ s3_secret_key = (sensitive value)
Paso 5: Aplicar
terraform apply storage.plan
No hay texto para traducir. Por favor, proporcione el texto técnico que desea traducir.
ionoscloud_s3_key.taskboard: Creation complete
ionoscloud_s3_bucket.attachments: Creation complete
ionoscloud_volume.api_data: Creation complete after 1m12s
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
Paso 6: Leer las credenciales sensibles
terraform output -raw s3_access_key
terraform output -raw s3_secret_key
No hay texto que traducir. Por favor, proporcione el texto técnico que necesita ser traducido al español.
(a 92-character access key, then a 64-character secret key)
Paso 7: Verificar el bucket con un S3 cliente
export AWS_ACCESS_KEY_ID=$(terraform output -raw s3_access_key)
export AWS_SECRET_ACCESS_KEY=$(terraform output -raw s3_secret_key)
aws --endpoint-url https://s3.eu-central-4.ionoscloud.com s3 ls
No hay texto para traducir. Por favor, proporcione el texto técnico que desea que traduzca.
2026-06-05 12:01:33 taskboard-attachments-<user_id>
Lista de verificación de validación:
- [ ] Volume muestra
Creation completey está conectado al servidor API - [ ]
terraform outputdevuelve entradas(sensitive value)editadas sin-raw - [ ] El cliente S3 enumera el bucket utilizando la Clave de acceso + Clave secreta, no el token de portador
Limpieza:
terraform destroy -auto-approve
Errores comunes
Errores de los desarrolladores que deben evitarse al aprovisionar almacenamiento en IONOS Cloud:
-
Fijar un Volume en la Zona 3 mientras el servidor está en la Zona 1 o 2
- Problema: Un Volume creado en
ZONE_3no puede estar ubicado junto con un servidor de computación, porque Compute no tiene Zona 3. - Por qué sucede: Las zonas de disponibilidad de Block Storage son
Zone 1,Zone 2,Zone 3,Auto, pero Compute solo admiteZone 1,Zone 2,Auto. Los desarrolladores asumen que los conjuntos de zonas coinciden. - Solución: Utilice
availability_zone = "AUTO"en ambos el servidor y el Volume, a menos que tenga un plan de fijación de zona deliberado, y nunca establezcaZONE_3en un servidor.
- Problema: Un Volume creado en
-
Enviar el token de portador de IONOS a Object Storage
- Problema: Las solicitudes de S3 devuelven
403 SignatureDoesNotMatchoAccessDenied, aunque su token de nube API de IONOS es válido. - Por qué sucede: Object Storage implementa el token de S3 API de AWS y se autentica con una clave de acceso y una clave secreta. El token de portador utilizado para
api.ionos.comno es aceptado por el punto de conexión de S3. - Solución: Genere credenciales con
ionoscloud_s3_key, establezcaAWS_ACCESS_KEY_IDyAWS_SECRET_ACCESS_KEY, y siempre pase la URL del punto de conexión de S3 de IONOS explícito.
- Problema: Las solicitudes de S3 devuelven
-
Montar una compartición de NFS con NFSv3
- Problema:
mount -t nfs -o vers=3 ...se cuelga o falla; la compartición rechaza la conexión. - Por qué sucede: IONOS NFS admite solo NFSv4.2. NFSv3 no está disponible, por lo que cualquier opción de montaje fijada en v3 o entrada de fstab heredada no negociará.
- Solución: Monte sin una opción de v3 (NFSv4.2 negocia por defecto) y alinee la compartición
uid/gidcon el usuario de la aplicación, ya que la raíz de la calabaza está en efecto:
sudo mount -t nfs 10.7.222.100:/<share-uuid> /mnt/uploads - Problema:
Resumen
Ahora puede aprovisionar los tres niveles de almacenamiento de IONOS completamente en Terraform y conectarlos a una aplicación. Los volúmenes de Block Storage se adjuntan a un servidor único con ionoscloud_volume, con un tamaño entre 1 GiB y 4 TiB, con el tipo de almacenamiento y la zona fijos en el momento de la creación. Los cubos de Object Storage y las claves de S3 se declaran con ionoscloud_s3_bucket y ionoscloud_s3_key, autenticados con Access Key y Secret Key en lugar de su token de portador, y los mismos cubos respaldan su estado remoto de Terraform. Los clústeres y acciones de NFS entregan acceso concurrente NFSv4.2 para los casos en que muchos clientes de Linux deben compartir un sistema de archivos. La lección recurrente es que las restricciones, no la sintaxis de los recursos, deciden su diseño: las incompatibilidades de zona, el modelo de autenticación de S3 y la versión del protocolo de NFS son donde se pierde el tiempo de producción.
Puntos clave:
ionoscloud_volumeaprovisiona Block Storage desde 1 GiB hasta 4 TiB; el tipo de almacenamiento y la zona son inmutables después de la creación- Block Storage admite la Zona 1, 2, 3 y Auto, pero Compute no tiene Zona 3; establezca ambos en
AUTOpor defecto - Object Storage se autentica con Access Key + Secret Key sobre un punto final de S3 específico de la región, nunca el token de portador de IONOS
- Los cubos de Object Storage funcionan como un backend de estado remoto compatible con S3 de Terraform con las banderas de omisión de validación establecidas
- NFS proporciona almacenamiento compartido NFSv4.2 desde 2 TiB hasta 42 TiB; NFSv3 no es compatible
Terminología importante:
ionoscloud_volume: Recurso de Terraform para un Block Storage iSCSI Volume adjunto a un servidor.ionoscloud_s3_key: Recurso de Terraform que acuña un par de Access Key y Secret Key para Object Storage; salida como sensible.- Punto final de S3: URL específica de la región (por ejemplo
s3.eu-central-1.ionoscloud.com) que todos los clientes de Object Storage deben establecer explícitamente. - Backend de estado remoto: Almacenamiento compartido y duradero para el estado de Terraform; un cubo de Object Storage configurado con el tipo de backend
s3. - Root squash: Comportamiento de NFS que asigna la raíz del cliente a una identidad no privilegiada; requiere alinear la acción de la acción
uid/gidcon el usuario de la aplicación.
Próximos pasos
Continúe aprendiendo: Unidad 2.5: Provisionamiento de bases de datos y servicios de transmisión
Temas relacionados: