Fase 2
OpenTofu 1.7+

OpenTofu Overview · Infrastructure as Code

La Fase 2 introduce IaC declarativa con OpenTofu. Define el estado deseado de la infraestructura en archivos .tf y OpenTofu reconcilia el estado real contra ellos. Dos providers coexisten: Kubernetes para el cluster local y OCI para Oracle Cloud. Mismo código, dos destinos.

01

IaC vs Configuration Management

OpenTofu y Ansible resuelven problemas distintos. Ansible configura sistemas operativos. OpenTofu crea infraestructura. Saber cuándo usar cada uno es tan importante como saber usarlos.

Enfoque
OpenTofu Declarativo: define el estado deseado. OpenTofu reconcilia el estado real contra el archivo .tf.
Ansible Procedural: define pasos para llegar al estado. Ansible ejecuta tasks en orden.
Idempotencia
OpenTofu Nativa. `tofu plan` muestra diff. Si el recurso ya existe como se declaró, no hace nada.
Ansible Depende del módulo. Ansible tiene módulos idempotentes (lineinfile, systemd) pero también comandos shell sin idempotencia.
Estado
OpenTofu State file (terraform.tfstate). OpenTofu sabe exactamente qué recursos creó y su estado actual.
Ansible Sin estado persistente. Ansible consulta el estado real del sistema en cada ejecución.
Orquestación
OpenTofu Grafo de dependencias automático. OpenTofu resuelve el orden de creación de recursos.
Ansible Orden explícito. Los plays y roles de Ansible se ejecutan en el orden definido.
Drift Detection
OpenTofu `tofu plan` detecta cambios manuales y los revierte en el próximo apply.
Ansible Los plays se ejecutan de nuevo. Si alguien cambió un archivo, lineinfile lo corrige.
Uso en este proyecto
OpenTofu Crear infraestructura (VMs, redes, NSG, buckets, vault) y recursos de Kubernetes (namespace, ConfigMaps).
Ansible Configurar SO (paquetes, SELinux, firewalld, SSH). No crea infraestructura, la configura.
02

Dos Providers, Dos Destinos

El proyecto usa dos configuraciones de OpenTofu independientes. La local gestiona recursos dentro del cluster k3s. La de Oracle Cloud crea toda la infraestructura de red, computo y servicios gestionados. No comparten state — son stacks separados.

tofu/
hashicorp/kubernetes ~> 2.30

Provider que apunta al kubeconfig de k3s. Crea el namespace aiops y dos ConfigMaps: la configuración de Prometheus (scrape + alert rules) y los datasources de Grafana.

tofu/oracle/
oracle/oci ~> 6.0

Provider que autentica contra OCI via API key. Crea VCN, subnets, NSGs, VMs Ampere A1, OCI Vault y Object Storage. Todo dentro del Free Tier — costo $0.

03

Recursos Locales (tofu/)

Tres recursos en el stack local. Son la base que el resto de los manifiestos de Kubernetes asumen como preexistente.

namespace
kubernetes_namespace.aiops

Crea el namespace `aiops` donde vive todo el stack. Etiquetado con `managed-by: opentofu` para trazabilidad.

config
kubernetes_config_map.prometheus

ConfigMap con `prometheus.yml` y `alert_rules.yml`. Define scrape configs para Prometheus, node-exporter y k3s-metrics, más tres alertas base: HighCPU, DiskSpaceLow, ServiceDown.

config
kubernetes_config_map.grafana

ConfigMap con `datasources.yml`. Provisiona automáticamente los datasources de Prometheus y Loki en Grafana sin configuración manual post-deploy.

¿Por qué OpenTofu para ConfigMaps y no kubectl apply? Porque OpenTofu garantiza que el ConfigMap existe antes de que los Deployments intenten montarlo. El grafo de dependencias de Tofu asegura el orden: namespace → ConfigMap. Con kubectl apply -f, el orden depende de cómo se listaron los archivos.
04

Recursos Oracle Cloud (tofu/oracle/)

Seis archivos .tf que juntos definen la infraestructura completa de Oracle Cloud. Cada archivo tiene una responsabilidad única.

network.tf

VCN (10.0.0.0/16), subnet pública (10.0.1.0/24), Internet Gateway y route table. Free Tier no incluye NAT Gateway — ambas VMs van en subnet pública protegidas por NSG.

main.tf

Dos Network Security Groups (bastion + k3s) con reglas least-privilege. SSH al bastion solo desde la IP admin. k3s solo acepta SSH y API desde el bastion. HTTPS público para Grafana demo.

compute.tf

Dos VMs Ampere A1 ARM64: bastion (1 OCPU, 6 GB) y k3s (3 OCPUs, 18 GB). Imagen Rocky Linux 9 con fallback a Oracle Linux 9. Cloud-init via template.

object_storage.tf

Bucket OCI Object Storage para Loki como backend de logs. Retention de 31 días dentro del límite de 10 GB/mes del Free Tier.

vault.tf

OCI Vault + master encryption key (AES-256). Secrets placeholder ('CHANGE_ME') que se pueblan manualmente post-apply desde la consola OCI.

data.tf

Data sources: availability domains, object storage namespace. Referencian recursos existentes sin crearlos.

La arquitectura de red sigue un principio simple: VCN con una subnet pública, ambas VMs con IP pública, pero protegidas por NSG. El bastion solo acepta SSH desde la IP administrativa. La VM de k3s solo acepta SSH y k3s API desde la IP privada del bastion. HTTPS está abierto al mundo para la demo pública de Grafana.

05

Workflow: init → plan → apply

El ciclo de trabajo con OpenTofu tiene tres comandos. El proceso es el mismo para el provider de Kubernetes y para el de OCI.

1
tofu/ tofu init

Descarga providers y módulos. Crea el directorio `.terraform/`. Solo se ejecuta una vez o al cambiar providers.

2
tofu/ tofu plan

Compara el estado deseado (.tf) con el real (state). Muestra qué recursos se van a crear, modificar o destruir. No aplica cambios.

3
tofu/ tofu apply

Aplica el plan. Crea, modifica o destruye recursos para que el estado real coincida con el deseado. Pide confirmación.

tofu workflow
# Inicializar — descarga el provider de Kubernetes
$cd tofu && tofu init
Initializing the backend...
Initializing provider plugins...
Provider hashicorp/kubernetes v2.30.0
OpenTofu has been successfully initialized!
# Planificar — ver qué se va a crear sin aplicar
$tofu plan
OpenTofu will perform the following actions:
+ kubernetes_namespace.aiops
+ kubernetes_config_map.prometheus
+ kubernetes_config_map.grafana
Plan: 3 to add, 0 to change, 0 to destroy.
# Aplicar — crear los recursos
$tofu apply
Do you want to perform these actions? Only 'yes' will be accepted.
Enter a value: yes
kubernetes_namespace.aiops: Creating...
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.
06

Variables & Outputs

OpenTofu separa la definición de recursos de los valores concretos. Las variables permiten reutilizar el mismo código para el lab local y Oracle Cloud. Los outputs exponen información generada (IPs, OCIDs) para otros tools.

Variables (input)
Definen qué se puede parametrizar sin tocar el código. El archivo terraform.tfvars asigna valores concretos. Las variables marcadas sensitive no se muestran en logs ni en el output de plan.
kubeconfig_path namespace grafana_admin_password region compartment_id ssh_public_key admin_cidr
Outputs (output)
Exponen valores generados durante el apply — IPs, OCIDs, nombres. Útiles para scripts que necesitan saber la IP del bastion o el ID del Vault después del deploy. Se consultan con tofu output.
bastion_public_ip k3s_private_ip vault_id loki_bucket_name namespace_name
outputs
# Después del apply, consultar los outputs
$tofu output
bastion_public_ip = "129.153.x.x"
k3s_private_ip = "10.0.1.12"
vault_id = "ocid1.vault.oc1.sa-saopaulo-1.xxx"
# Exportar IPs como variables de entorno para Ansible
$export BASTION_PUBLIC_IP=$(tofu output -raw bastion_public_ip)
$export K3S_PRIVATE_IP=$(tofu output -raw k3s_private_ip)
07

El State File

terraform.tfstate es el archivo más importante de OpenTofu. Contiene el mapeo entre los recursos declarados en .tf y los recursos reales en el provider. Sin este archivo, OpenTofu no sabe qué recursos gestiona.

Local por defecto. En el lab local, el state se guarda en terraform.tfstate en el mismo directorio. Es suficiente para un solo desarrollador.
Remoto para equipos. En producción se usaría un backend remoto (S3, OCI Object Storage) para compartir el state entre múltiples personas y evitar conflictos.
Nunca se edita manualmente. El state es JSON generado por OpenTofu. Editarlo a mano rompe la consistencia entre el estado deseado y el real. Solo se modifica via tofu apply o tofu state.
08

OpenTofu en el Resto del Proyecto

La Fase 2 sienta las bases de IaC. Las fases siguientes agregan más recursos y profundizan en cada provider.

Fase 3
HashiCorp Vault
Se agregan recursos de Kubernetes para desplegar Vault en el cluster y ConfigMaps para el Vault Agent Injector.
Fase 9
Oracle Cloud Migration
Se ejecuta tofu apply en tofu/oracle/. El provider OCI crea toda la infraestructura cloud. Ansible provisiona las VMs resultantes.

Siguiente: Kubernetes Provider

La siguiente página profundiza en el provider de Kubernetes: cómo apunta al kubeconfig de k3s, los recursos que crea y el workflow completo de init → plan → apply.

Kubernetes Provider