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 de API necesita un volumen de datos persistente que sobreviva a los reinicios y se comporte como un disco local. Los archivos adjuntos subidos por el usuario pertenecen a un Object Storage al que se accede mediante HTTP con credenciales S3, y no deben estar conectados a una sola 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 nodo.
Los tres se provisionan de la misma manera: recursos de Terraform declarativos contra la API de IONOS CLOUD, con el mismo modelo de creación y espera asíncrona que ha utilizado desde la Unidad 1.1. Las diferencias que le 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 del protocolo. Esta unidad analiza cada tipo de almacenamiento a nivel de código y muestra dónde estas restricciones cambian lo que escribe.
1. Volúmenes de Almacenamiento en Bloque con Terraform
El Almacenamiento en Bloque se proporciona como ionoscloud_volume y se comporta como un dispositivo de bloque iSCSI conectado a un servidor. Debe declarar el tamaño, el tipo de almacenamiento y la zona de disponibilidad, y Terraform maneja la provisión asíncrona y la conexión. Un volumen 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 del volumen es 1 GiB y el máximo es 4096 GiB (4 TiB) para cada tipo de Almacenamiento en Bloque. Se pueden solicitar volúmenes más grandes 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 tarde.
1.1 Declarar y conectar un volumen
La siguiente configuración crea un volumen de datos SSD Premium y lo conecta al servidor de la API TaskBoard. Los image_name y image_password (o ssh_key_path) son necesarios cuando el volumen es inicializable; 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 los mayores IOPS por Volume, SSD Standard intercambia rendimiento por costo, y HDD es la opción de giro más económica. Las tres 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 Compute solo admiten las zonas 1, 2 y Auto. La zona 3 existe para el almacenamiento pero no hay zona 3 para la computación.
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 del servidor, usted restringe la programación sin beneficio alguno. El valor seguro por defecto es AUTO tanto en el servidor como en el Volume, a menos que 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 Vololumes pueden combinarse entre tipos en una sola VM. Un servidor puede llevar tanto volúmenes SSD como HDD al mismo tiempo. Una VM admite hasta 24 volúmenes adjuntos de cualquier combinación de tipos de almacenamiento; el recuento es compartido entre todos los tipos, no por tipo. Planifique diseños de varios volúmenes contra ese límite de 24 volúmenes.
1.3 Contexto de cifrado y durabilidad
Block Storage proporciona almacenamiento con doble redundancia: los datos se escriben en dos servidores de almacenamiento, cada uno protegido por RAID, para redundancia a nivel de plataforma. El cifrado en reposo para volúmenes lógicos utiliza el algoritmo AES-XTS. Usted no configura ninguno de los dos en el recurso de volumen; ambos son propiedades de la capa de almacenamiento de la plataforma, por lo que su Terraform se centra en el tamaño, el tipo y la colocación.
2. Cubetas de Object Storage y Claves de Acceso
El Object Storage se provisiona con ionoscloud_s3_bucket, y sus credenciales de acceso se crean con ionoscloud_s3_key. La diferencia crítica con respecto a todos los demás recursos en este curso: el Object Storage no se autentica con su token de portador de IONOS CLOUD. Implementa la API de AWS S3 y se autentica con una Clave de Acceso y una Clave Secreta. Su aplicación, su tubería de CI y cualquier cliente de S3 utilizan esas claves, nunca el token de API de la nube.
resource "ionoscloud_s3_key" "taskboard" {
user_id = var.user_id
}
resource "ionoscloud_s3_bucket" "attachments" {
name = "taskboard-attachments-prod"
}
Los nombres de los contenedores deben ser únicos a nivel global en todos los inquilinos de Object Storage 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 según sea necesario.
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 rotar sin tiempo de inactividad: crear la nueva clave, actualizar la configuración de la aplicación y luego destruir la clave antigua. Las credenciales no están vinculadas a una región o bucket específicos; un par de claves funciona en todos los buckets 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, debe 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 su código y el backend de Terraform harán referencia.
| 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 |
Elija el punto de conexión que coincida con la región donde crea el bucket y réalo en todas partes: en boto3, en el bloque de backend S3 a continuación y en cualquier generación de URL presignada. Las conexiones utilizan TLS, con TLS 1.2 y 1.3 compatibles. El tamaño máximo del objeto es 5 TB. Object Storage ofrece una sola clase de almacenamiento, STANDARD, y un bucket admite hasta 1000 reglas de ciclo de vida para la expiración de objetos; las reglas del ciclo de vida no pueden transitar objetos a otra clase de almacenamiento (no hay un nivel frío o archivo).
3. Object Storage como backend de estado de Terraform
Dado que Object Storage es compatible con S3, también puede funcionar como un backend de estado remoto para Terraform. Esto soluciona el problema que se presentó en la Unidad 1.2: el estado local no sobrevive en un equipo o en un ejecutor de CI. Almacenar el estado en un bucket proporciona a cada ejecución de la canalización una fuente de verdad compartida y duradera.
3.1 Configuración del backend
El s3 backend necesita el punto de conexión de IONOS CLOUD y las mismas banderas de omisión que se utilizan para cualquier implementación de S3 que no sea de AWS, porque el backend de otro modo 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 manera 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, para que una canalización de desarrollo no pueda leer el estado de producción. Esto se lleva directamente al trabajo de CI/CD en el Módulo 3, donde las mismas credenciales se convierten en secretos de la canalización.
4. Almacenamiento compartido NFS
Cuando varios servidores necesitan leer y escribir los mismos archivos, ni un volumen de Block Storage de un solo punto de montaje ni un Object Storage se adapta limpiamente. NFS le proporciona un sistema de archivos POSIX montado de forma concurrente en clientes Linux. Se provisiona 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 terraform destroy de limpieza se aplica.
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 Restricciones de protocolo y capacidad
NFS en IONOS CLOUD habla solo 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 del Cluster va desde un mínimo de 2 TiB hasta un máximo de 42 TiB, con toda la capacidad provisionada completamente utilizable. Las cuotas de compartición se expresan en MiB.
El cifrado en reposo está proporcionado por la plataforma. El cifrado en tránsito no está documentado para NFS, así que para datos sensibles mantenga el compartido en una LAN privada y confíe en el aislamiento de red en lugar de esperar TLS en el montaje. El Cluster se ejecuta en un modo de alta disponibilidad Activo-Pasivo y se alcanza a través de una IP privada que usted asigna en el bloque connections.
4.2 Montar el compartido
Después de aplicar, el compartido se monta desde un cliente Linux utilizando la IP del Cluster y el UUID del compartido devuelto en la salida del recurso nfs_path. Linux es el sistema operativo cliente compatible.
sudo mount -t nfs 10.7.222.100:/<share-uuid> /mnt/uploads
El aplastamiento de raíz es compatible, así que mapee UID y GID en la compartición para que coincidan con el usuario de la aplicación que lee y escribe los archivos, como se muestra por los argumentos uid y gid anteriores. La propiedad no coincidente es la causa habitual de errores de permiso denegado justo después de una montura exitosa.
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 carga de trabajo de un solo escritor. Object Storage se accede a través de HTTP con credenciales S3 y escala de forma independiente a 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 al nivel que necesita mientras escribe Terraform.
| Necesidad | Recurso | Adjunto | Autenticación |
|---|---|---|---|
| Disco persistente de un solo servidor | ionoscloud_volume |
Un servidor, iSCSI | Token de API de IONOS CLOUD (aprovisionamiento) |
| Almacén de objetos accesible por HTTP | ionoscloud_s3_bucket + ionoscloud_s3_key |
Ninguno (API S3) | Clave de acceso + Clave secreta |
| Sistema de archivos compartido, muchos clientes | ionoscloud_nfs_cluster + ionoscloud_nfs_share |
Muchos clientes Linux, NFSv4.2 | Montaje de LAN privada |
Para TaskBoard, esto se resuelve limpiamente. El volumen de datos del servidor API es Block Storage, adjuntado 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 API nunca proxy los bytes. NFS no se utiliza en la versión base de TaskBoard; es el patrón al que llega más tarde si agrega una flota de trabajadores que deben compartir un directorio de contenido.
Tarjeta rápida de referencia de API
Puntos de conexión de API clave 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 volumen de Block Storage |
POST |
/datacenters/{dcId}/servers/{serverId}/volumes |
Adjunta un volumen a un servidor |
DELETE |
/datacenters/{dcId}/volumes/{id} |
Elimina un volumen |
GET |
/um/users/{userId}/s3keys |
Lista las claves de acceso S3 para un usuario |
POST |
/um/users/{userId}/s3keys |
Crea una clave de acceso S3 |
URL base de la API de Cloud: 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 la API de NFS: https://nfs.{region}.ionos.com
Autenticación: La API de Cloud 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 volumen de datos de Block Storage conectado al servidor de API y un cubo de Object Storage con credenciales de acceso que se muestran como valores sensibles.
Requisitos previos:
- Cuenta de IONOS CLOUD con token de API (
IONOS_TOKENexportado) - Terraform 1.5+ con el
ionos-cloud/ionoscloudproveedor - Un centro de datos y un servidor de API existentes (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 que traducir. Por favor, proporcione el texto técnico que desea que traduzca.
(no output; init resolves the provider in Step 4)
Paso 2: Declarar el volumen de datos de Block Storage
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 depósito de Object Storage y la 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 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 para traducir. Por favor, proporcione el texto técnico que desea que traduzca.
(a 92-character access key, then a 64-character secret key)
Paso 7: Verificar el bucket con un cliente S3
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 que 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:
- [ ] El volumen muestra
Creation completey está conectado al servidor de API - [ ]
terraform outputdevuelve entradas redactadas(sensitive value)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 volumen en la Zona 3 mientras el servidor está en la Zona 1 o 2
- Problema: Un volumen 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 volumen, a menos que tenga un plan de fijación de zona deliberado, y nunca establezcaZONE_3en un servidor.
- Problema: Un volumen creado en
-
Enviar el token de portador de IONOS CLOUD a Object Storage
- Problema: Las solicitudes S3 devuelven
403 SignatureDoesNotMatchoAccessDeniedincluso aunque su token de API de nube sea válido. - Por qué sucede: Object Storage implementa la API de AWS S3 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 final S3. - Solución: Genere credenciales con
ionoscloud_s3_key, establezcaAWS_ACCESS_KEY_IDyAWS_SECRET_ACCESS_KEY, y siempre pase la URL del punto final S3 de IONOS CLOUD explícita.
- Problema: Las solicitudes S3 devuelven
-
Montar una compartición 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 CLOUD 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 v3 (NFSv4.2 negocia por defecto) y alinee la compartición
uid/gidcon el usuario de la aplicación, ya que la compresión de raíz 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 CLOUD enteramente en Terraform y conectarlos a una aplicación. Los volúmenes de Block Storage se adjuntan a un solo servidor 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 buckets de Object Storage y las claves 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 buckets respaldan su estado remoto de Terraform. Los clústeres y comparticiones de NFS entregan acceso concurrente NFSv4.2 para los casos en que muchos clientes 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 S3 y la versión del protocolo 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 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 S3 específico de la región, nunca el token de portador de IONOS CLOUD
- Los buckets de Object Storage funcionan como un backend de estado remoto compatible con S3 para Terraform con las banderas skip-validation establecidas
- NFS proporciona almacenamiento compartido NFSv4.2 desde 2 TiB hasta 42 TiB; no se admite NFSv3
Terminología importante:
ionoscloud_volume: Recurso de Terraform para un volumen iSCSI de Block Storage adjunto a un servidor.ionoscloud_s3_key: Recurso de Terraform que crea un par de Access Key y Secret Key para Object Storage; salida como sensible.- Punto final 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 bucket de Object Storage configurado con el tipo de backend
s3. - Root squash: Comportamiento NFS que asigna la raíz del cliente a una identidad no privilegiada; requiere alinear la compartición
uid/gidcon el usuario de la aplicación.
Próximos pasos
Continúe aprendiendo: Unidad 2.5: Provisionamiento de base de datos y servicio de transmisión
Temas relacionados: