Ya tienes la red lista (VPC, subred pública, Internet Gateway y rutas). Ahora vamos a poner el protagonista: un servidor EC2 dentro de esa subred, accesible desde internet. Recuerda todo lo del Capítulo 4 sobre instancias; ahora lo escribimos en Terraform.

Qué vamos a añadir

Sobre la red del subcapítulo anterior, añadimos una instancia EC2:

┌──────────── VPC (10.0.0.0/16) ────────────┐
│   ┌─ Subred pública (10.0.1.0/24) ─┐       │
│   │   ┌──────────────────┐          │      │
│   │   │  Instancia EC2   │ ◄── nueva │      │
│   │   │   (servidor web) │          │      │
│   │   └──────────────────┘          │      │
│   └─────────────────────────────────┘      │
└────────────────────────────────────────────┘

Paso 1: Encontrar la AMI (la imagen base)

Recuerda que toda instancia parte de una AMI (subcapítulo 4.2). En lugar de escribir a mano un ID de AMI (que cambia con el tiempo y según la región), lo mejor es buscar la más reciente automáticamente con un bloque data:

data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

  filter {
    name   = "name"
    values = ["al2023-ami-*-x86_64"]
  }
}

¿Qué es un bloque data? Es una novedad importante: mientras resource crea algo, un bloque data (data source) consulta información existente en AWS sin crear nada. Aquí preguntamos a AWS «¿cuál es la AMI más reciente de Amazon Linux 2023?» y guardamos la respuesta para usarla. Es muy útil para no escribir valores fijos que caducan.

Paso 2: Definir variables (buena práctica)

Para que el código sea flexible (subcapítulo 10.1), definimos algunas variables:

variable "tipo_instancia" {
  description = "Tipo de instancia EC2"
  type        = string
  default     = "t3.micro"     # apta para capa gratuita (Capítulo 4)
}

variable "nombre_proyecto" {
  type    = string
  default = "mi-primer-servidor"
}

Usar t3.micro (subcapítulo 4.1) es ideal para aprender, porque entra en la capa gratuita de AWS.

Paso 3: Crear la instancia EC2

Ahora el recurso principal. Lo colocamos en nuestra subred pública:

resource "aws_instance" "web" {
  ami                    = data.aws_ami.amazon_linux.id   # la AMI que buscamos
  instance_type          = var.tipo_instancia             # la variable
  subnet_id              = aws_subnet.publica.id          # ← en la subred pública
  vpc_security_group_ids = [aws_security_group.web.id]    # firewall (subcap. 12.3)

  tags = {
    Name = var.nombre_proyecto
  }
}

Analicemos las conexiones:

  • ami → referencia al data source del paso 1 (la AMI encontrada).
  • instance_type → la variable del paso 2.
  • subnet_id → referencia a la subred pública del subcapítulo 12.1. Esto coloca el servidor en nuestra red, en la zona pública.
  • vpc_security_group_ids → referencia al Security Group (el firewall), que crearemos en el siguiente subcapítulo.

Cada referencia crea una dependencia: Terraform creará primero la subred y el Security Group, y luego la instancia.

Paso 4: Instalar software al arrancar (user_data)

A menudo quieres que el servidor haga algo nada más arrancar, como instalar un servidor web. Para eso existe user_data: un script que se ejecuta automáticamente la primera vez que la instancia arranca.

resource "aws_instance" "web" {
  ami                    = data.aws_ami.amazon_linux.id
  instance_type          = var.tipo_instancia
  subnet_id              = aws_subnet.publica.id
  vpc_security_group_ids = [aws_security_group.web.id]

  user_data = <<-EOF
    #!/bin/bash
    yum update -y
    yum install -y httpd
    systemctl start httpd
    systemctl enable httpd
    echo "<h1>¡Hola desde mi primer servidor en AWS con Terraform!</h1>" > /var/www/html/index.html
  EOF

  tags = {
    Name = var.nombre_proyecto
  }
}

Este script: actualiza el sistema, instala el servidor web Apache (httpd), lo arranca y crea una página de bienvenida. Cuando la instancia esté lista, servirá una web con ese mensaje.

Lo que acabamos de lograr: con user_data, el servidor se autoconfigura al nacer. No necesitas conectarte a instalar nada a mano. Esto es clave para automatizar y para el autoescalado (Capítulo 13): cada nuevo servidor se prepara solo. (Para configuraciones complejas, se prefiere crear una AMI ya lista, recuerda el subcapítulo 4.2, pero user_data es perfecto para empezar.)

El estado actual

Ahora mismo tenemos:

✓ Red completa (subcapítulo 12.1)
✓ Una AMI encontrada automáticamente (data source)
✓ Una instancia EC2 en la subred pública
✓ Un script que instala un servidor web al arrancar
✗ Falta: el Security Group (firewall) — subcapítulo 12.3
✗ Falta: una IP fija y los outputs — subcapítulos 12.3 y 12.4

Si ejecutaras plan ahora, Terraform se quejaría de que falta el Security Group (aws_security_group.web) que referenciamos pero aún no hemos creado. Eso lo resolvemos en el siguiente subcapítulo.

Lo que debes recordar

  • Un bloque data (data source) consulta información existente en AWS sin crear nada (lo usamos para encontrar la AMI más reciente automáticamente, evitando IDs fijos que caducan).
  • La instancia se coloca en la subred con subnet_id, referenciando la subred pública del capítulo anterior.
  • Usar variables (como tipo_instancia) hace el código flexible; t3.micro es ideal para la capa gratuita.
  • user_data es un script que el servidor ejecuta al arrancar, perfecto para autoconfigurarse (instalar software, etc.) sin intervención manual.
  • Las referencias entre recursos crean las dependencias y el orden de creación automático.

En el siguiente subcapítulo crearemos el Security Group (firewall) que falta y le daremos al servidor una Elastic IP fija.

Cloud, AWS & Terraform — De cero a experto

Capítulo 1 · Qué es el cloud computing

Capítulo 2 · El mercado cloud y los grandes proveedores

Capítulo 3 · Regiones, zonas de disponibilidad y edge

Capítulo 4 · Cómputo: EC2

Capítulo 5 · Almacenamiento: S3

Capítulo 6 · Redes: VPC

Capítulo 7 · Identidad y acceso: IAM

Capítulo 8 · Bases de datos gestionadas

Capítulo 9 · Por qué Infraestructura como Código

Capítulo 10 · HCL: el lenguaje de Terraform

Capítulo 11 · Providers y estado

Capítulo 12 · Tu primera infraestructura real en Terraform

Capítulo 13 · Balanceo de carga y autoescalado

Capítulo 14 · Serverless con Lambda

Capítulo 15 · Mensajería y eventos

Capítulo 16 · Entrega de contenido y DNS

Capítulo 17 · Contenedores en AWS

Capítulo 18 · Módulos: reutilización y composición

Capítulo 19 · Workspaces y gestión de entornos

Capítulo 20 · Backends remotos y locking

Capítulo 21 · Testing de infraestructura

Capítulo 22 · Terraform en CI/CD

Capítulo 23 · Seguridad en profundidad

Capítulo 24 · Observabilidad: logs, métricas y trazas

Capítulo 25 · Optimización de costes

Capítulo 26 · Alta disponibilidad y disaster recovery

Capítulo 27 · Well-Architected Framework de AWS

Capítulo 28 · Arquitecturas serverless a escala

Capítulo 29 · Plataformas de datos en AWS

Capítulo 30 · Multi-cuenta y landing zones

Capítulo 31 · Platform Engineering e Internal Developer Platform

Capítulo 32 · Certificaciones AWS relevantes

Capítulo 33 · Proyectos para consolidar lo aprendido

Capítulo 34 · Recursos y comunidad

© Copyright 2024. Todos los derechos reservados