# Tema 1 · 1 · Crear tu primera máquina virtual y conectarte Presentación del Tema 1: «Ejemplo creación VM (IaaS)». Duración: unos 25 minutos. Coste: céntimos si borras la máquina el mismo día (la limpieza está en el [paso 3 de esta serie](01.03-PararRedimensionarBorrar.md)). > **Etiquetas de lo que creas.** Todo recurso que crees a mano (máquina, volumen, bucket, base de datos, tabla, función...) ponle estas etiquetas, al crearlo (apartado *Tags* / *Etiquetas*) o después desde su pestaña de etiquetas: `curso` = `G214`, `universidad` = `CUNEF` y `actividad` = `01.01-CrearYConectarVM`. Si algún día hay que borrar recursos a mano, se localizan todos de golpe con `aws resourcegroupstaggingapi get-resources --region eu-north-1 --tag-filters Key=actividad,Values=01.01-CrearYConectarVM`. Más detalle (cómo etiquetar con la CLI, cómo buscar y qué hacer en una emergencia): [README principal](../README.md), sección «Etiquetas». ## Qué vas a hacer Crear una máquina virtual Linux (EC2) en tu propia cuenta de AWS y entrar en ella de dos maneras: desde el navegador (botón *Connect*) y desde tu equipo con `ssh` y una llave. Es la base de todo el curso: todas las demás prácticas arrancan de una máquina como esta. Esta carpeta **no tiene ficheros que descargar**: todo se hace desde la consola de AWS y desde tu terminal. Solo contiene esta guía. ## Las tres carpetas del Tema 1 | Carpeta | Qué haces | |---|---| | **`01.01-CrearYConectarVM.md`** (esta) | Crear la máquina y entrar en ella | | [`01.02-ServidorWeb.md`](01.02-ServidorWeb.md) | Publicar una página web desde la máquina | | [`01.03-PararRedimensionarBorrar.md`](01.03-PararRedimensionarBorrar.md) | Parar, cambiar de tamaño y **borrarlo todo** | Hazlas por ese orden: las tres usan la misma máquina. ## Antes de empezar - [ ] Cuenta de AWS propia con sesión iniciada en la consola (Anexo Tema 0: *Creación de la cuenta*). - [ ] La región de la consola es **Europe (Stockholm) `eu-north-1`** (selector de arriba a la derecha). Un recurso creado en otra región no aparece en el listado y sigue facturando sin que lo veas. - [ ] Una terminal con el comando `ssh`: PowerShell o CMD en Windows 10/11 (OpenSSH viene incluido), Terminal en macOS y Linux, o Git Bash. - [ ] Sabes qué son una IP, un puerto y un CIDR (resumen al final de esta guía) y los comandos básicos de Linux (Anexo Tema 0: *Comandos Linux*). - [ ] **No uses claves de acceso de la cuenta principal.** Esta guía no las necesita. - [ ] Recomendado: un presupuesto con alerta por correo en AWS Budgets (*Billing and Cost Management > Budgets*). ## Cuánto cuesta Precios de lista de `eu-north-1` (API de precios de AWS, 3 de octubre de 2026; pueden cambiar, compruébalos en la calculadora): | Concepto | Precio | |---|---| | `t3.micro` | 0,0108 USD/h (unos 7,88 USD al mes encendida) | | `t3.small` | 0,0216 USD/h | | Disco gp3 | 0,0836 USD por GB y mes (8 GiB = 0,67 USD al mes) | | **Cada dirección IPv4 pública** | 0,005 USD/h (unos 3,65 USD al mes), **también cuando está asociada a una máquina en marcha** | Una máquina olvidada una noche son céntimos; un mes entero, varios dólares. Parada, una máquina no cuesta CPU, pero **sigue cobrando el disco**. Solo *Terminate* lo borra todo. ## Paso a paso ### Paso 1 · Crear la máquina EC2 > Instances > **Launch instance** y estos valores: | Campo | Valor | |---|---| | Nombre | `maquina` | | AMI (imagen) | Amazon Linux 2023, arquitectura **64-bit (x86)**: hay también una versión Arm, que es para los tipos `t4g` y no vale con `t3.micro` | | Tipo de instancia | `t3.micro` (incluido en el plan gratuito) | | Key pair | **Create new key pair**: nombre `llave-ssh`, tipo ED25519, formato `.pem`. Se descarga **una sola vez**: guárdala en un sitio que recuerdes (por ejemplo `Descargas`) | | Network settings | Security Group nuevo (*Create security group*) con *Allow SSH traffic from*: **My IP**. Para usar el botón *Connect* de la consola hace falta además el rango de Instance Connect (paso 2.1) | | Storage | 8 GiB gp3 (por defecto) | Pulsa **Launch instance**. **Qué debes ver:** en EC2 > Instances, la máquina pasa a **Running** y, en 1 o 2 minutos, el *Status check* muestra **2/2 checks passed**. Apunta su **Public IPv4 address** (al seleccionarla, en *Details*). El usuario para entrar es `ec2-user` (Amazon Linux). Con otras imágenes: `ubuntu` (Ubuntu) o `admin` (Debian), según la documentación de EC2 de AWS. **Si prefieres Ubuntu** (opcional): en *Application and OS Images* elige la pestaña **Ubuntu** y **Ubuntu Server 24.04 LTS** (64-bit x86); el resto de valores es igual. El usuario es `ubuntu`: con `ec2-user` da `Permission denied (publickey)`. No necesitas el identificador (ID) de la AMI: la consola lo rellena sola. Solo lo necesitarías al lanzar la máquina con la CLI; para Amazon Linux 2023 sale del parámetro público de SSM `/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64`. ### Paso 2 · Entrar en la máquina Hay tres maneras. Con una basta, pero las dos primeras forman parte del ejercicio. #### 2.1 Desde la consola (EC2 Instance Connect) Instances > selecciona `maquina` > **Connect** > pestaña **EC2 Instance Connect** > **Connect**. **Qué debes ver:** un terminal en el navegador con el prompt `[ec2-user@ip-... ~]$`. Necesita el **puerto 22 abierto** en el Security Group **y que admita el origen de Instance Connect**: este botón conecta desde las IP de AWS, no desde la tuya. Hay dos opciones para el puerto 22 (Security Groups > el de tu máquina > *Edit inbound rules*): 1. **Solo *My IP***: el botón *Connect* **no funciona** y da *timeout*. Entras desde tu equipo con la llave (apartado 2.2). 2. ***My IP* y, además, el rango de Instance Connect:** añade una **segunda regla SSH (22)** cuyo origen sea `13.48.4.200/30`, el rango de `EC2_INSTANCE_CONNECT` en `eu-north-1`. Así el botón funciona y el 22 no queda abierto a todo Internet. Solo durante la práctica, si no quieres añadir el rango, puedes poner el origen de la regla SSH en `0.0.0.0/0`; vuelve a *My IP* al terminar (es lo más expuesto de todo el laboratorio). **Cómo comprobar el rango.** AWS lo publica en , en la entrada con `"service": "EC2_INSTANCE_CONNECT"` y `"region": "eu-north-1"` (campo `ip_prefix`). Puede cambiar con el tiempo, así que consúltalo si el botón falla. Desde una terminal: ```bash # Linux, macOS, Git Bash o CloudShell (con jq) curl -s https://ip-ranges.amazonaws.com/ip-ranges.json | jq -r '.prefixes[] | select(.service=="EC2_INSTANCE_CONNECT" and .region=="eu-north-1") | .ip_prefix' ``` ```powershell # PowerShell (Invoke-RestMethod https://ip-ranges.amazonaws.com/ip-ranges.json).prefixes | Where-Object { $_.service -eq 'EC2_INSTANCE_CONNECT' -and $_.region -eq 'eu-north-1' } | Select-Object -ExpandProperty ip_prefix ``` **Qué debes ver:** `13.48.4.200/30`. No hace falta nada de esto si entras desde tu equipo con la llave (2.2): ahí el origen es tu IP. #### 2.2 Desde tu equipo, con la llave Ajusta antes los permisos de la llave; si no, `ssh` la rechaza (`UNPROTECTED PRIVATE KEY FILE`): - **macOS / Linux:** `chmod 400 ~/Descargas/llave-ssh.pem` - **Windows (PowerShell):** `icacls .\llave-ssh.pem /inheritance:r /grant:r "${env:USERNAME}:R"` Después: ```bash ssh -i ruta/a/llave-ssh.pem ec2-user@ ``` La primera vez pregunta por la huella (*Are you sure you want to continue connecting*): responde `yes`. **Qué debes ver:** el banner de *Amazon Linux 2023* y el prompt `[ec2-user@ip-... ~]$`. Para salir: `exit`. #### 2.3 Sin llave (Session Manager) También puedes entrar sin llave con **Session Manager (SSM)**: no usa el puerto 22, pero la máquina necesita un rol de IAM con la política `AmazonSSMManagedInstanceCore`. No forma parte de este ejercicio. > **Resumen de la llave.** Para entrar por SSH desde tu equipo necesitas la llave. Sin llave puedes entrar desde la consola: con *EC2 Instance Connect* (requiere el puerto 22 abierto) o con *Session Manager* (requiere un rol IAM; no usa el puerto 22). ## Errores frecuentes | Síntoma | Causa | Solución | |---|---|---| | `Permission denied (publickey)` | Usuario o llave equivocados | Usa `ec2-user` en Amazon Linux (`ubuntu` en Ubuntu, `admin` en Debian, según la documentación de AWS) y la llave de *esta* máquina | | `UNPROTECTED PRIVATE KEY FILE` | La llave la pueden leer otros usuarios | `chmod 400` (macOS/Linux) o `icacls` (Windows), ver el apartado 2.2 | | `error in libcrypto` o `invalid format` al usar la llave | La llave se guardó con saltos de línea `\r` (Git Bash) o en UTF-16 (PowerShell antiguo con `>`) | Descarga la llave de la consola (no da este problema). Si la creaste con la CLI: en Git Bash, `tr -d '\r' < llave.pem > llave2.pem`; en PowerShell, guarda con `\| Out-File -Encoding ascii llave.pem` en vez de `>` | | `ssh: connect ... timed out` | El puerto 22 no está abierto a tu IP, o tu IP ha cambiado | Edita la regla SSH del Security Group (*My IP* de nuevo) | | El botón *Connect* de la consola da *timeout* | El 22 solo admite tu IP y la consola conecta desde las IP de AWS | Añade una regla SSH (22) con origen `13.48.4.200/30` (ver 2.1) o, solo durante la práctica, `0.0.0.0/0`; o entra con `ssh` y la llave | | La máquina no aparece en el listado | Región equivocada | Cambia a `eu-north-1` | ## Conceptos mínimos - **IP pública / privada.** La pública es la que ve Internet y cambia al parar la máquina; la privada (`172.31...`) solo vale dentro de AWS. - **Puerto.** La «puerta» de un servicio dentro de la máquina: 22 SSH, 80 HTTP, 443 HTTPS, 3306 MySQL. - **CIDR.** Un rango de IPs: `/32` es una sola IP (*My IP*), `/24` son 256 y `/0` es todo Internet (`0.0.0.0/0`). - **Security Group.** Cortafuegos de la máquina. Solo tiene reglas de permiso (*ALLOW*); con varias reglas se suman: entra el tráfico si alguna lo permite, es decir, prevalece la más permisiva. Es con estado: la respuesta vuelve sola. Quitar una regla cierra solo ese acceso. - **SSH.** Conexión cifrada para manejar la máquina desde tu terminal. ## Cómo sabes que has terminado - [ ] La máquina `maquina` está en **Running** con *2/2 checks passed*. - [ ] Has entrado con el botón *Connect* (o sabes por qué no funciona con solo *My IP*). - [ ] Has entrado desde tu terminal con `ssh -i llave-ssh.pem ec2-user@` y ves el prompt `[ec2-user@ip-... ~]$`. - [ ] **No cierres la máquina todavía:** la usas en la siguiente carpeta. Siguiente: [`01.02-ServidorWeb.md`](01.02-ServidorWeb.md)