17 min de lectura

Objetivos de aprendizaje

Al final de este módulo, podrás:

  • Configurar y fijar la versión del proveedor de Terraform de IONOS CLOUD y autenticarse utilizando la variable de entorno `IONOS_TOKEN` o un bloque de proveedor
  • Aprovisionar un VDC base completo con recursos `ionoscloud_datacenter`, `ionoscloud_lan`, `ionoscloud_server`, `ionoscloud_volume` y `ionoscloud_nic`
  • Configurar un backend de estado remoto compatible con S3 en IONOS Cloud Object Storage, teniendo en cuenta el bloqueo del estado
  • Utilizar las fuentes de datos `ionoscloud_image` y `ionoscloud_location` para seleccionar imágenes y regiones de forma dinámica
  • Importar recursos existentes de IONOS CLOUD al estado de Terraform y ejecutar un ciclo de vida de entorno efímero con `plan`, `apply` y `destroy`

Unidad 1.2: Proveedor de Terraform y patrones fundamentales

Introducción

En la Unidad 1.1 aprovisionó un servidor de tres maneras: mediante la API sin procesar con curl, el SDK de Python y ionosctl. Las tres son imperativas. Emite una POST, realiza consultas a /requests/{id}/status hasta que DONE, y luego emite la siguiente llamada. Eso funciona, pero no le proporciona una descripción reproducible y controlada por versiones de su infraestructura. Para TaskBoard, la API de gestión de tareas y la interfaz de usuario que está construyendo a lo largo de este curso, necesita una infraestructura que resida en Git, que se revise como código y que se desmonte de forma limpia para que los entornos de prueba nunca le facturen silenciosamente.

Esta unidad lo lleva al aprovisionamiento declarativo con el proveedor de Terraform para IONOS CLOUD. Escribirá el HCL que construye el VDC base de TaskBoard, observará lo que Terraform hace internamente con la API asíncrona de IONOS CLOUD, almacenará el estado de forma remota en Object Storage y adoptará el patrón de entorno efímero que mantiene los costos bajo control. La consulta asíncrona que manejó manualmente en 1.1 ahora es responsabilidad del proveedor.

1. Configuración del proveedor y autenticación

El proveedor de IONOS CLOUD para Terraform interactúa con los recursos de cómputo, almacenamiento y red de IONOS CLOUD. Actualmente, admite las ofertas más recientes de las API V5 y V6, y se publica en el Registro de Terraform bajo ionos-cloud/ionoscloud. Antes de que cualquier cosa funcione, debe contar con una cuenta de IONOS CLOUD cuyas credenciales se autenticen contra la Cloud API, exactamente como en la Unidad 1.1.

1.1 Declaración y fijación del proveedor

Fije siempre la versión del proveedor. El bloque required_providers de Terraform lo fija a una versión estable y probada, de modo que un terraform init el próximo mes no introduzca un cambio que rompa la compatibilidad en su pipeline.

# versions.tf
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    ionoscloud = {
      source  = "ionos-cloud/ionoscloud"
      version = "~> 6.4"
    }
  }
}

La restricción ~> 6.4 permite actualizaciones de parche y menores dentro de la línea 6.x, pero bloquea el salto a la versión 7.0. Ejecute terraform init para descargar el proveedor fijado en .terraform/. Commite el archivo .terraform.lock.hcl generado para que cada compañero de equipo y cada ejecutor de CI resuelva la misma compilación del proveedor.

1.2 Autenticación: variable de entorno frente a bloque de proveedor

El patrón más limpio es autenticarse con el token de portador de Token Manager (cubierto en la Unidad 1.1) a través de la variable de entorno IONOS_TOKEN. De este modo, ningún dato confidencial toca su HCL ni su historial de Git.

export IONOS_TOKEN="eyJ0eXAiOiJKV1QiLCJraWQiO..."
terraform plan

Con la variable configurada, el bloque de proveedor puede estar vacío:

# provider.tf
provider "ionoscloud" {}

También puede pasar las credenciales de forma explícita en el bloque de proveedor, lo cual es útil cuando una sola configuración administra recursos en más de una cuenta. Se admiten el nombre de usuario y la contraseña (autenticación básica) como alternativa al token.

provider "ionoscloud" {
  token = var.ionos_token   # never hardcode; pass via TF_VAR_ionos_token
}

Prefiera la variable de entorno IONOS_TOKEN sobre un token que se haya comprometido en un archivo .tfvars. Si debe utilizar una variable, márquela como sensitive = true y proporciónela a través de TF_VAR_ionos_token en su shell o en el almacén de secretos de CI.

2. Recursos principales: creación de un VDC

Un entorno base de TaskBoard requiere un centro de datos virtual, una LAN, un servidor, un volumen de arranque y una NIC que conecte el servidor a la LAN. Cada recurso de Terraform de IONOS CLOUD tiene el prefijo ionoscloud_, lo que permite mantenerlos sin ambigüedad cuando una configuración combina proveedores.

2.1 Centro de datos, LAN, servidor, volumen, NIC

Los nombres de los recursos siguientes (ionoscloud_datacenter, ionoscloud_lan, ionoscloud_server, ionoscloud_nic) y sus esquemas de atributos siguen la documentación del proveedor de Terraform de IONOS CLOUD. El valor de ubicación y la selección de imagen se basan en las secciones de fuentes de datos de esta unidad.

# main.tf
resource "ionoscloud_datacenter" "taskboard" {
  name        = "taskboard-base"
  location    = "de/fra"
  description = "TaskBoard base VDC, managed by Terraform"
}

resource "ionoscloud_lan" "app" {
  datacenter_id = ionoscloud_datacenter.taskboard.id
  name          = "taskboard-app-lan"
  public        = true
}

resource "ionoscloud_server" "api" {
  name              = "taskboard-api"
  datacenter_id     = ionoscloud_datacenter.taskboard.id
  cores             = 2
  ram               = 4096
  cpu_family        = "INTEL_SKYLAKE"
  availability_zone = "AUTO"

  volume {
    name           = "taskboard-api-boot"
    size           = 20
    disk_type      = "SSD"
    image_name     = data.ionoscloud_image.ubuntu.id
    image_password = var.server_password
  }

  nic {
    lan  = ionoscloud_lan.app.id
    dhcp = true
  }
}

Observe que los bloques en línea volume y nic le permiten expresar el disco de arranque y la conexión de red como parte del servidor. Para un Volume de datos que se conecta después del arranque, o para gestionar el ciclo de vida de un disco de forma independiente, declare un ionoscloud_volume independiente.

2.2 Volume y NIC independientes

resource "ionoscloud_volume" "data" {
  datacenter_id = ionoscloud_datacenter.taskboard.id
  server_id     = ionoscloud_server.api.id
  name          = "taskboard-data"
  size          = 50
  disk_type     = "SSD"
  licence_type  = "OTHER"
}

resource "ionoscloud_nic" "extra" {
  datacenter_id = ionoscloud_datacenter.taskboard.id
  server_id     = ionoscloud_server.api.id
  lan           = ionoscloud_lan.app.id
  dhcp          = true
}

Las referencias como ionoscloud_datacenter.taskboard.id y ionoscloud_server.api.id son las que otorgan a Terraform su orden de ejecución. Dado que el server_id del volumen lee del recurso de servidor, Terraform sabe que el servidor debe existir primero. Nunca se escribe lógica explícita de "esperar al centro de datos". Ese grafo de dependencias es el punto central de alejarse de los scripts imperativos de la Unidad 1.1.

3. Ciclo de vida plan/apply/destroy

Los tres comandos que ejecutará constantemente son terraform plan, terraform apply y terraform destroy. Comprender lo que hace cada uno frente a la API asíncrona de IONOS CLOUD le ahorrará horas de confusión.

3.1 Qué sucede internamente

terraform plan lee su HCL, lee el estado actual, consulta la API de IONOS CLOUD para obtener el estado en vivo de cada recurso administrado e imprime la diferencia. No cambia nada. terraform apply ejecuta esa diferencia emitiendo las mismas llamadas POST, PUT y DELETE que realizó manualmente en la sección 1.1.

El punto clave es el siguiente: las operaciones de la API de IONOS CLOUD son asíncronas. Una POST devuelve un identificador de solicitud y el recurso aún no está listo. En la Unidad 1.1, consultó /requests/{id}/status hasta que DONE antes de la siguiente llamada. El proveedor de Terraform para IONOS CLOUD realiza esa consulta internamente para cada recurso. Cuando apply muestra un recurso como aún en creación, está esperando exactamente ese estado de solicitud antes de proceder con los recursos dependientes.

terraform plan -out=taskboard.tfplan
terraform apply taskboard.tfplan

Capturar el plan en un archivo con -out y aplicar exactamente ese archivo garantiza que apply realice precisamente lo que se revisó, sin desviaciones entre el plan y la aplicación. Este es el patrón seguro para CI/CD.

3.2 Destrucción y operaciones dirigidas

# Preview what will be torn down
terraform plan -destroy

# Tear it all down
terraform destroy

# Operate on a single resource (use sparingly)
terraform apply -target=ionoscloud_server.api

terraform destroy recorre el grafo de dependencias en sentido inverso: las NIC y los volúmenes antes que el servidor, el servidor antes que la LAN, y la LAN antes que el centro de datos. Este orden inverso es la razón por la que debe permitir que Terraform gestione la pila completa en lugar de eliminar recursos manualmente en el DCD, lo cual puede dejar el estado de Terraform desincronizado con la realidad.

4. Estado remoto en Object Storage

Por defecto, Terraform escribe el estado en un archivo local terraform.tfstate. Esto no es adecuado para un equipo ni para una canalización. El estado debe almacenarse en un lugar compartido, y IONOS Cloud Object Storage es compatible con S3, por lo que sirve como backend de Terraform.

4.1 Configuración del backend de S3

IONOS CLOUD Object Storage autentica mediante una Access Key y una Secret Key, no mediante tokens de portador. Estas son las mismas credenciales de S3 que genera en la gestión de claves de Object Storage. Object Storage está disponible en varias regiones, cada una con su propio endpoint, incluyendo Frankfurt (de) en s3.eu-central-1.ionoscloud.com, Berlín (eu-central-2) en s3.eu-central-2.ionoscloud.com, y Logroño (eu-south-2) en s3.eu-south-2.ionoscloud.com.

# backend.tf
terraform {
  backend "s3" {
    bucket   = "taskboard-tfstate"
    key      = "base/terraform.tfstate"
    region   = "eu-central-1"
    endpoints = {
      s3 = "https://s3.eu-central-1.ionoscloud.com"
    }
    skip_credentials_validation = true
    skip_region_validation      = true
    skip_requesting_account_id  = true
    skip_s3_checksum            = true
  }
}

Los flags skip_* son obligatorios porque se trata de un proveedor de S3 externo (no de AWS). Sin ellos, el backend intenta llamar a puntos de acceso específicos de AWS, como el Security Token Service, y falla. Proporcione las credenciales a través de las variables de entorno estándar de S3 para que nunca se incluyan en su HCL:

export AWS_ACCESS_KEY_ID="your-object-storage-access-key"
export AWS_SECRET_ACCESS_KEY="your-object-storage-secret-key"
terraform init   # migrates local state into the bucket

4.2 Consideraciones sobre el bloqueo de estado

El bloqueo de estado impide que dos ejecuciones de apply corrompan el estado de forma simultánea. Los backends de AWS S3 tradicionalmente dependen de una tabla de DynamoDB para los bloqueos, lo cual IONOS CLOUD Object Storage no proporciona. Considere el backend S3 de IONOS CLOUD como sin bloqueo: serialice las aplicaciones mediante un único pipeline de CI/CD, nunca ejecute aplicaciones concurrentes contra la misma clave de estado y utilice un key de estado separado por entorno (por ejemplo, base/, staging/, prod/) para que las pilas no relacionadas nunca compitan.

5. Fuentes de datos, importaciones y control de costos

Codificar de forma fija los identificadores de imágenes y las cadenas de región hace que las configuraciones sean frágiles. Las fuentes de datos consultan la API de IONOS CLOUD en el momento de la planificación, de modo que su HCL se mantenga portable. Las importaciones permiten gestionar recursos creados fuera de Terraform. Y un proceso de destrucción disciplinado mantiene su factura honesta.

5.1 Fuentes de datos de imágenes y ubicaciones

data "ionoscloud_location" "frankfurt" {
  name    = "fra"
  feature = "SSD"
}

data "ionoscloud_image" "ubuntu" {
  type     = "HDD"
  location = "de/fra"
  cloud_init = "V1"
  image_alias = "ubuntu:latest"
}

La fuente de datos ionoscloud_image resuelve una imagen actual para que no fije un UUID de imagen obsoleto que podría haberse dado de baja. La fuente de datos ionoscloud_location confirma una región y la disponibilidad de sus funciones antes de aprovisionar en ella. Referencie el resultado con data.ionoscloud_image.ubuntu.id en el bloque volume del servidor, como se muestra en la Sección 2.

La siguiente tabla resume las cuatro formas de gestionar el aprovisionamiento de IONOS CLOUD que ha visto a lo largo de las Unidades 1.1 y 1.2.

Enfoque Ideal para Interfaz Estado rastreado
API Direct Control total, llamadas puntuales curl / HTTP Ninguno (manual)
SDK Código de aplicaciones Python / Go / JS Ninguno (manual)
Terraform Infraestructura reproducible HCL Sí (archivo de estado)
ionosctl Tareas rápidas, scripts CLI Ninguno (manual)

Utilice Terraform cuando la infraestructura deba ser reproducible y revisable. Recurra al SDK o a ionosctl para operaciones en tiempo de ejecución y comprobaciones rápidas que no correspondan a su pila declarativa.

5.2 Importación de recursos existentes

Si un centro de datos o un servidor ya existe, posiblemente creado en el DCD o mediante un script anterior de curl, impórtelo en lugar de volver a crearlo. Escriba primero un bloque de recurso correspondiente y luego realice la importación. Las importaciones de IONOS CLOUD utilizan un ID compuesto que une el ID del centro de datos y el ID del recurso.

# Import an existing server: format is datacenter_id/server_id
terraform import ionoscloud_server.api \
  3fa85f64-5717-4562-b3fc-2c963f66afa6/9bc92f81-1234-4cde-8901-abcdef012345

# Import a datacenter (single ID)
terraform import ionoscloud_datacenter.taskboard 3fa85f64-5717-4562-b3fc-2c963f66afa6

Después de la importación, ejecute terraform plan. Si el plan muestra cambios, su HCL aún no coincide con la realidad. Ajuste los atributos del bloque de recursos a la configuración activa hasta que plan no reporte cambios. Solo entonces el recurso estará de forma segura bajo gestión.

5.3 Conciencia de costos y entornos efímeros

Cada recurso que Terraform aprovisiona en apply genera cargos desde el momento en que existe. El flujo de trabajo disciplinado es: siempre plan antes de apply, y siempre destroy lo que inicie para pruebas. El patrón de entorno efímero crea una pila completa para una ejecución de prueba y luego la desmonta.

# Spin up a throwaway environment for a feature branch
terraform workspace new pr-142
terraform apply -auto-approve

# ... run integration tests against the live infrastructure ...

# Tear it all down so it stops billing
terraform destroy -auto-approve
terraform workspace delete pr-142

Integrar terraform destroy en la etapa de desmontaje de un trabajo de CI garantiza que un entorno de rama olvidado no acumule costos de forma silenciosa durante semanas.

Tarjeta rápida de referencia de la API

El proveedor Terraform de IONOS CLOUD invoca estos puntos finales de la Cloud API internamente. Conocerlos le ayuda a depurar un apply que se ha quedado atascado.

Método Punto final Descripción
POST /datacenters Crear un VDC (respalda ionoscloud_datacenter)
POST /datacenters/{id}/servers Crear un servidor (respalda ionoscloud_server)
POST /datacenters/{id}/volumes Crear un volumen (respalda ionoscloud_volume)
POST /datacenters/{id}/lans Crear una LAN (respalda ionoscloud_lan)
GET /requests/{id}/status Estado de la solicitud asíncrona que el proveedor consulta

URL base: https://api.ionos.com/cloudapi/v6 Autenticación: Authorization: Bearer <token> (el proveedor lee IONOS_TOKEN)

Laboratorio de código

Objetivo: Construir el VDC base de TaskBoard con Terraform: un centro de datos, una LAN y un servidor con un volumen adjunto. Planificar, aplicar, verificar y destruir.

Requisitos previos:

  • Cuenta de IONOS CLOUD con un token de API exportado como IONOS_TOKEN
  • Terraform 1.5 o posterior instalado localmente
  • ionosctl configurado (desde la Unidad 1.1) para la verificación

Paso 1: Crear la estructura de la configuración

mkdir taskboard-base && cd taskboard-base
touch versions.tf provider.tf main.tf

Salida esperada:

(no output; three empty files created)

Paso 2: Agregar el proveedor y fijar la versión

Coloque el contenido de versions.tf de la sección 1.1 y provider "ionoscloud" {} de la sección 1.2 en sus archivos, y luego inicie.

terraform init

Salida esperada:

Initializing provider plugins...
- Installing ionos-cloud/ionoscloud v6.4.x...
Terraform has been successfully initialized!

Paso 3: Escribir los recursos de VDC

Agregue los bloques ionoscloud_datacenter, ionoscloud_lan y ionoscloud_server de la sección 2.1, junto con la fuente de datos ionoscloud_image de la sección 5.1, a main.tf.

Paso 4: Planificar y revisar

export TF_VAR_server_password="ChangeMe-Strong-Pw-1"
terraform plan -out=taskboard.tfplan

Salida esperada:

Plan: 3 to add, 0 to change, 0 to destroy.

Paso 5: Aplicar

terraform apply taskboard.tfplan

Salida esperada:

ionoscloud_datacenter.taskboard: Creation complete after 25s [id=3fa85f64-...]
ionoscloud_server.api: Still creating... [1m20s elapsed]
ionoscloud_server.api: Creation complete after 2m10s [id=9bc92f81-...]
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Paso 6: Verificar con ionosctl

terraform output -raw datacenter_id 2>/dev/null || true
ionosctl server list --datacenter-id $(terraform state show ionoscloud_datacenter.taskboard | grep -m1 'id ' | awk '{print $3}' | tr -d '"')

Salida esperada:

ServerId   Name            State       Cores   Ram
9bc92f81   taskboard-api   AVAILABLE   2       4096

Paso 7: Inspeccionar el estado

terraform state list

Salida esperada:

data.ionoscloud_image.ubuntu
ionoscloud_datacenter.taskboard
ionoscloud_lan.app
ionoscloud_server.api

Lista de verificación de validación:

  • [ ] terraform apply completado con 3 recursos agregados
  • [ ] ionosctl server list muestra el servidor como AVAILABLE
  • [ ] terraform state list muestra todos los recursos administrados

Limpieza:

terraform destroy -auto-approve

Errores comunes

  1. Eliminación de recursos en el DCD que Terraform administra

    • Problema: Elimina el servidor manualmente en la interfaz web y luego terraform apply genera un error o intenta recrear recursos no relacionados.
    • Por qué ocurre: El estado de Terraform aún registra el servidor eliminado. La API en vivo ya no lo tiene, por lo que el estado y la realidad divergen.
    • Solución: Elimine la entrada obsoleta del estado y luego deje que Terraform lo reconcilie:
    terraform state rm ionoscloud_server.api
    terraform plan   # now matches reality
    
  2. Olvidar las banderas de omisión del backend S3

    • Problema: terraform init contra el backend de Object Storage se queda colgado o falla con un error de STS o de identificador de cuenta.
    • Por qué ocurre: El backend S3 asume que se trata de AWS e intenta realizar llamadas exclusivas de AWS que IONOS CLOUD Object Storage no implementa.
    • Solución: Agregue las banderas de omisión y el punto de acceso explícito al bloque del backend:
    skip_credentials_validation = true
    skip_region_validation      = true
    skip_requesting_account_id  = true
    endpoints = { s3 = "https://s3.eu-central-1.ionoscloud.com" }
    
  3. Fijar un UUID de imagen obsoleto en lugar de usar una fuente de datos

    • Problema: terraform apply falla con un error de imagen no encontrada meses después de que la configuración funcionara por última vez.
    • Por qué ocurre: Un UUID de imagen codificado de forma fija fue retirado en el origen. La creación asíncrona del servidor se interrumpe porque su volumen de arranque hace referencia a una imagen que no existe.
    • Solución: Resuelva la imagen en el momento de la planificación con la fuente de datos y haga referencia a ella:
    data "ionoscloud_image" "ubuntu" {
      type        = "HDD"
      location    = "de/fra"
      image_alias = "ubuntu:latest"
    }
    # volume { image_name = data.ionoscloud_image.ubuntu.id }
    

Resumen

Ahora puede describir la infraestructura de IONOS CLOUD de forma declarativa y gestionar su ciclo de vida completo desde el código. Configuró y fijó la versión del proveedor Terraform de IONOS CLOUD, se autenticó con IONOS_TOKEN y construyó el VDC base de TaskBoard a partir de los recursos ionoscloud_datacenter, ionoscloud_lan, ionoscloud_server, ionoscloud_volume y ionoscloud_nic. Movió el estado a un backend de Object Storage compatible con S3, utilizó fuentes de datos para resolver imágenes y ubicaciones de forma dinámica, importó recursos existentes y adoptó el patrón de entorno efímero para que la infraestructura de pruebas se desmonte de forma limpia.

El modelo de aprovisionamiento asíncrono que manejó manualmente en la Unidad 1.1 ahora es una preocupación interna del proveedor: Terraform consulta el estado de las solicitudes por usted y ordena las operaciones a través de su grafo de dependencias. A partir de aquí, cada unidad de infraestructura de este curso se construye sobre esta misma base de Terraform.

Puntos clave:

  • El proveedor de IONOS CLOUD admite las ofertas de API V5 y V6; fije siempre la versión con required_providers y commitee el archivo de bloqueo
  • Autentíquese con IONOS_TOKEN para que ningún secreto entre en su HCL; todos los recursos tienen el prefijo ionoscloud_
  • Terraform consulta internamente el endpoint asíncrono /requests/{id}/status y ordena las operaciones mediante el grafo de dependencias de recursos
  • El backend S3 de Object Storage requiere las banderas skip_* y un endpoint explícito de IONOS CLOUD, y se autentica con Access Key más Secret Key, no con un token de portador
  • Siempre ejecute plan antes de apply y destroy entornos efímeros para controlar el costo

Terminología importante:

  • Proveedor: El complemento que traduce los recursos HCL en llamadas a la API de IONOS CLOUD, publicado como ionos-cloud/ionoscloud
  • Estado: El registro de Terraform de qué recursos reales de IONOS CLOUD gestiona, almacenado localmente o en un backend de Object Storage
  • Fuente de datos: Una consulta de solo lectura a la API de IONOS CLOUD en el momento de la planificación, como ionoscloud_image, utilizada para evitar codificar IDs de forma dura
  • Importación: Incorporar un recurso existente de IONOS CLOUD bajo la gestión de Terraform utilizando un datacenter_id/resource_id compuesto
  • Entorno efímero: Una pila completa creada para una ejecución de pruebas y desmontada con terraform destroy para evitar cargos pendientes

Próximos pasos

Siga aprendiendo: Unidad 1.3: Verificación de conocimientos - Fundamentos programáticos

Temas relacionados: