AWS por línea de comandos
La AWS CLI es la forma de crear y administrar recursos de AWS escribiendo comandos, en lugar de hacer clic en la consola web. Todo lo que hace la consola, lo hace la CLI, y además se puede guardar, repetir y automatizar.
En la práctica vas a levantar tres servicios clásicos y luego destruirlos, todo desde la terminal. Estos son los tres:
S3 almacenamiento
Guarda archivos, o cualquier dato, en contenedores llamados buckets. No es un disco ni un servidor: es almacenamiento al que se llega por su nombre.
Es de los servicios más usados de AWS: sirve para respaldos, para servir archivos de un sitio web, para guardar datos que luego procesa otro servicio. Un detalle que importa hoy: el nombre de cada bucket es único en todo el mundo, no solo en tu cuenta.
Vas a crear un bucket, bloquearle el acceso público, subir un archivo y generar un enlace temporal para compartirlo.
EC2 cómputo
Un servidor virtual en la nube: una computadora que enciendes cuando la necesitas y apagas cuando terminas. Tú eliges el tamaño y el sistema operativo.
Es la base de gran parte de AWS. Antes de conectarte, hay que decidir quién puede alcanzarla, y eso lo controla un Security Group, que es el firewall de la instancia: define qué puertos están abiertos y desde qué direcciones.
Vas a lanzar una instancia pequeña, abrir el puerto SSH solo para tu IP, conectarte por SSH y, opcionalmente, levantar un servidor web dentro de ella.
RDS base de datos
Bases de datos administradas: AWS se encarga de instalarlas, respaldarlas y parcharlas. Tú solo la usas. Soporta MySQL, PostgreSQL y otros motores.
En el laboratorio la base no tiene acceso público, a propósito. Solo se puede alcanzar desde dentro de tu red, y su Security Group lo hace explícito: acepta conexiones únicamente desde la EC2. Por eso te conectas a la base desde la instancia, no desde tu computadora.
Vas a crear una base MySQL sin acceso público, conectarte a ella desde la EC2, y crear una tabla con un registro.
Lo que cuesta dinero importante
S3 casi no cuesta con lo que vamos a guardar. Pero EC2 y RDS cobran por hora mientras existan, aunque no los estés usando.
Por eso el laboratorio termina destruyendo todo, y ese paso es tan importante como los de creación. Detener una instancia no basta: un servidor detenido sigue cobrando su disco. Hay que terminarla.
Lo que no destruyes, lo pagas. No cierres el día sin completar el paso de limpieza.
Y la CLI
Cada comando de la práctica empieza con aws, sigue con el servicio
(s3, ec2, rds) y luego la acción. Por ejemplo
aws ec2 run-instances lanza una instancia, y
aws ec2 terminate-instances la destruye.
La documentación oficial está aquí, y cualquier comando acepta help al
final para ver todas sus opciones:
| Recurso | Dónde |
|---|---|
| Referencia de comandos de la CLI | docs.aws.amazon.com/cli/latest/reference/ |
| Guía de usuario de la AWS CLI | docs.aws.amazon.com/cli/latest/userguide/ |
| Ayuda desde la terminal | aws ec2 run-instances help |
Pasa a la pestaña de Práctica para empezar.
Laboratorio AWS por línea de comandos
Vas a crear un bucket S3, una instancia EC2 y una base de datos RDS, y luego a destruirlo todo. Elige tu sistema operativo: los comandos cambian entre macOS y Windows.
Con macOS y Windows. Para dárselo a un asistente de IA.
EC2 y RDS cobran por hora mientras existan. Crea el budget del paso 3 y no cierres el día sin completar el paso 9, la limpieza. En Windows usa PowerShell, no CMD ni Git Bash.
-
Instala la AWS CLI
Necesitas la versión 2.32.0 o superior, que es la que trae
aws login.macOS
curl "https://awscli.amazonaws.com/AWSCLIV2.pkg" -o "AWSCLIV2.pkg" sudo installer -pkg AWSCLIV2.pkg -target /O con Homebrew, si lo tienes:
brew install awscliWindows · PowerShell
msiexec.exe /i https://awscli.amazonaws.com/AWSCLIV2.msiO con winget:
winget install Amazon.AWSCLICierra y vuelve a abrir PowerShell después de instalar.
aws --version✓Listo si
imprimeaws-cli/2.32.0o mayor. -
Inicia sesión
Se abre el navegador, inicias sesión en tu cuenta y autorizas. Las credenciales quedan en la terminal.
aws loginFija la región por defecto:
aws configure set region us-east-1Y confirma quién eres:
aws sts get-caller-identity✓Listo si
responde con tu número de cuenta y elArnde tu usuario. -
Evita el paginador
La CLI abre un visor que bloquea los comandos. Desactívalo y fija la región para esta terminal.
macOS
export AWS_PAGER="" export AWS_REGION="us-east-1"Windows · PowerShell
$env:AWS_PAGER = "" $env:AWS_REGION = "us-east-1"!Ojo
Las variables como$BUCKETo$EC2_SGsolo existen en la terminal donde las creas. Si la cierras, tendrás que volver a leerlas (está en el archivo descargable, anexo A). -
Crea el bucket S3
El nombre es único en todo el mundo, así que le agregamos un número al azar.
macOS
BUCKET="xela-demo-$RANDOM$RANDOM" echo $BUCKETWindows · PowerShell
$BUCKET = "xela-demo-$(Get-Random -Minimum 100000 -Maximum 999999)" $BUCKETCréalo, y bloquéale el acceso público:
aws s3 mb "s3://$BUCKET"aws s3api put-public-access-block --bucket $BUCKET \ --public-access-block-configuration \ "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"Sube un archivo y genera un enlace temporal de 5 minutos:
echo "Hola desde Xela AI Builders" > hola.txt"Hola desde Xela AI Builders" | Out-File -Encoding ascii hola.txtaws s3 cp hola.txt "s3://$BUCKET/"aws s3 presign "s3://$BUCKET/hola.txt" --expires-in 300✓Listo si
la URL firmada abre el archivo en el navegador, y deja de funcionar después de 5 minutos. -
Prepara la red y la seguridad
Un Security Group es el firewall de un recurso. Vas a crear dos: uno para la EC2 que abre SSH solo a tu IP, y uno para RDS que abre MySQL solo a la EC2.
Primero busca la VPC por defecto y tu IP pública:
macOS
VPC_ID=$(aws ec2 describe-vpcs --filters "Name=is-default,Values=true" \ --query "Vpcs[0].VpcId" --output text) MY_IP=$(curl -s https://checkip.amazonaws.com) echo "$VPC_ID $MY_IP"Windows · PowerShell
$VPC_ID = aws ec2 describe-vpcs --filters "Name=is-default,Values=true" ` --query "Vpcs[0].VpcId" --output text $MY_IP = (Invoke-RestMethod https://checkip.amazonaws.com).Trim() "$VPC_ID $MY_IP"Crea el Security Group de la EC2 y ábrele SSH solo a tu IP:
EC2_SG=$(aws ec2 create-security-group --group-name xela-ec2-sg \ --description "SG para EC2 Xela" --vpc-id $VPC_ID \ --query GroupId --output text) aws ec2 authorize-security-group-ingress --group-id $EC2_SG \ --protocol tcp --port 22 --cidr "$MY_IP/32"$EC2_SG = aws ec2 create-security-group --group-name xela-ec2-sg ` --description "SG para EC2 Xela" --vpc-id $VPC_ID ` --query GroupId --output text aws ec2 authorize-security-group-ingress --group-id $EC2_SG ` --protocol tcp --port 22 --cidr "$MY_IP/32"Y el de RDS, que solo acepta MySQL desde el SG de la EC2:
RDS_SG=$(aws ec2 create-security-group --group-name xela-rds-sg \ --description "SG para RDS Xela" --vpc-id $VPC_ID \ --query GroupId --output text) aws ec2 authorize-security-group-ingress --group-id $RDS_SG \ --protocol tcp --port 3306 --source-group $EC2_SG$RDS_SG = aws ec2 create-security-group --group-name xela-rds-sg ` --description "SG para RDS Xela" --vpc-id $VPC_ID ` --query GroupId --output text aws ec2 authorize-security-group-ingress --group-id $RDS_SG ` --protocol tcp --port 3306 --source-group $EC2_SG!Nunca abras el puerto 22 a0.0.0.0/0: eso expone tu servidor a todo internet. -
Lanza la instancia EC2
Crea la llave SSH. AWS no la vuelve a mostrar, así que guárdala y nunca la subas a GitHub.
macOS
aws ec2 create-key-pair --key-name xela-key \ --query "KeyMaterial" --output text > xela-key.pem chmod 400 xela-key.pemWindows · PowerShell
aws ec2 create-key-pair --key-name xela-key ` --query "KeyMaterial" --output text | Out-File -Encoding ascii xela-key.pem icacls.exe xela-key.pem /reset icacls.exe xela-key.pem /grant:r "$($env:USERNAME):(R)" icacls.exe xela-key.pem /inheritance:rBusca la imagen de Amazon Linux 2023 más reciente y lanza la instancia:
AMI_ID=$(aws ssm get-parameters \ --names /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 \ --query "Parameters[0].Value" --output text) INSTANCE_ID=$(aws ec2 run-instances \ --image-id $AMI_ID --instance-type t3.micro --key-name xela-key \ --security-group-ids $EC2_SG \ --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=xela-ec2}]" \ --query "Instances[0].InstanceId" --output text) echo $INSTANCE_ID$AMI_ID = aws ssm get-parameters ` --names /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 ` --query "Parameters[0].Value" --output text $INSTANCE_ID = aws ec2 run-instances ` --image-id $AMI_ID --instance-type t3.micro --key-name xela-key ` --security-group-ids $EC2_SG ` --tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=xela-ec2}]" ` --query "Instances[0].InstanceId" --output text $INSTANCE_IDEspera a que arranque y toma su IP pública:
aws ec2 wait instance-running --instance-ids $INSTANCE_ID PUBLIC_IP=$(aws ec2 describe-instances --instance-ids $INSTANCE_ID \ --query "Reservations[0].Instances[0].PublicIpAddress" --output text) echo $PUBLIC_IPaws ec2 wait instance-running --instance-ids $INSTANCE_ID $PUBLIC_IP = aws ec2 describe-instances --instance-ids $INSTANCE_ID ` --query "Reservations[0].Instances[0].PublicIpAddress" --output text $PUBLIC_IPConéctate por SSH. Escribe
yesa la huella; sales conexit:ssh -i xela-key.pem ec2-user@$PUBLIC_IP✓Listo si
el prompt cambia a[ec2-user@ip-...]$. Ya estás dentro del servidor. -
Crea la base de datos RDS
Elige una contraseña de mínimo 8 caracteres, sin
/ @ "ni espacios.macOS
DB_PASS='Xela2026Pass' aws rds create-db-instance \ --db-instance-identifier xela-db --db-instance-class db.t3.micro \ --engine mysql --master-username admin --master-user-password "$DB_PASS" \ --allocated-storage 20 --db-name xela \ --vpc-security-group-ids $RDS_SG \ --no-publicly-accessible --no-multi-az --backup-retention-period 0Windows · PowerShell
$DB_PASS = 'Xela2026Pass' aws rds create-db-instance ` --db-instance-identifier xela-db --db-instance-class db.t3.micro ` --engine mysql --master-username admin --master-user-password "$DB_PASS" ` --allocated-storage 20 --db-name xela ` --vpc-security-group-ids $RDS_SG ` --no-publicly-accessible --no-multi-az --backup-retention-period 0Tarda de 5 a 10 minutos. Espera a que esté disponible y toma su dirección:
aws rds wait db-instance-available --db-instance-identifier xela-db DB_HOST=$(aws rds describe-db-instances --db-instance-identifier xela-db \ --query "DBInstances[0].Endpoint.Address" --output text) echo $DB_HOSTaws rds wait db-instance-available --db-instance-identifier xela-db $DB_HOST = aws rds describe-db-instances --db-instance-identifier xela-db ` --query "DBInstances[0].Endpoint.Address" --output text $DB_HOSTLa base no tiene acceso público, así que te conectas desde la EC2. Entra por SSH y ahí dentro:
dentro de la EC2sudo dnf install -y mariadb105 mysql -h <PEGA-AQUI-EL-DB_HOST> -u admin -pCon la contraseña, ya en MySQL:
en MySQLUSE xela; CREATE TABLE asistentes (id INT PRIMARY KEY AUTO_INCREMENT, nombre VARCHAR(50)); INSERT INTO asistentes (nombre) VALUES ('Tu nombre'); SELECT * FROM asistentes; EXIT;✓Listo siSELECTmuestra la fila que insertaste. Sal de MySQL conEXITy de la EC2 conexit. -
Limpieza: destruye todo
El paso más importante. Sigue este orden: los Security Groups no se borran mientras algo los use.
Termina la EC2 (terminar, no detener):
aws ec2 terminate-instances --instance-ids $INSTANCE_ID aws ec2 wait instance-terminated --instance-ids $INSTANCE_IDBorra la base de datos:
aws rds delete-db-instance --db-instance-identifier xela-db \ --skip-final-snapshot --delete-automated-backups aws rds wait db-instance-deleted --db-instance-identifier xela-dbBorra los Security Groups, primero el de RDS:
aws ec2 delete-security-group --group-id $RDS_SG aws ec2 delete-security-group --group-id $EC2_SGBorra la llave y vacía el bucket:
aws ec2 delete-key-pair --key-name xela-key aws s3 rb "s3://$BUCKET" --force!Si algo falla
UnDependencyViolational borrar un Security Group significa que un recurso todavía lo usa: espera un minuto y reintenta. -
Verifica que no quedó nada
Cada comando debe devolver una lista vacía. Iguales en macOS y Windows.
aws ec2 describe-instances \ --filters "Name=instance-state-name,Values=pending,running,stopping,stopped" \ --query "Reservations[*].Instances[*].InstanceId" --output text aws rds describe-db-instances --query "DBInstances[*].DBInstanceIdentifier" --output text aws s3 ls✓Listo si
los tres comandos no devuelven nada tuyo. Revisa Billing → Bills al día siguiente: los cargos tardan hasta 24 horas en aparecer.
Comandos de la AWS CLI
Los comandos que usa el laboratorio, agrupados por servicio. Todos empiezan con
aws, siguen con el servicio y luego la acción.
aws <servicio> <acción> [opciones]. Por ejemplo
aws ec2 run-instances es el servicio ec2 con la acción
run-instances. Cualquier comando acepta help al final para
ver todas sus opciones: aws ec2 run-instances help.
Sesión e identidad
| Comando | Qué hace |
|---|---|
aws --version | Versión instalada de la CLI |
aws login | Inicia sesión por el navegador y guarda credenciales temporales |
aws configure set region | Fija la región por defecto |
aws sts get-caller-identity | Muestra con qué cuenta y usuario estás autenticado |
S3 · almacenamiento
| Comando | Qué hace |
|---|---|
aws s3 mb | Crea un bucket (make bucket) |
aws s3 cp | Copia archivos hacia o desde un bucket |
aws s3 ls | Lista buckets, o el contenido de uno |
aws s3 presign | Genera un enlace temporal a un objeto |
aws s3 rb | Borra un bucket (remove bucket). Con --force lo vacía primero |
aws s3api put-public-access-block | Bloquea el acceso público del bucket |
aws s3api get-bucket-encryption | Muestra el cifrado por defecto del bucket |
EC2 · cómputo y red
| Comando | Qué hace |
|---|---|
aws ec2 run-instances | Lanza una instancia nueva |
aws ec2 describe-instances | Consulta instancias y sus datos, como la IP pública |
aws ec2 wait | Espera hasta que una instancia llegue a un estado, como instance-running |
aws ec2 terminate-instances | Destruye una instancia. No es lo mismo que detenerla |
aws ec2 create-key-pair | Crea la llave SSH para conectarte |
aws ec2 create-security-group | Crea un firewall para un recurso |
aws ec2 authorize-security-group-ingress | Abre un puerto en un Security Group |
aws ec2 describe-vpcs | Consulta las redes virtuales de la cuenta |
aws ec2 delete-security-group | Borra un Security Group |
aws ec2 delete-key-pair | Borra la llave SSH |
RDS · base de datos
| Comando | Qué hace |
|---|---|
aws rds create-db-instance | Crea una base de datos administrada |
aws rds describe-db-instances | Consulta las bases y sus datos, como el endpoint |
aws rds wait | Espera un estado, como db-instance-available |
aws rds delete-db-instance | Borra una base de datos |
Otros
| Comando | Qué hace |
|---|---|
aws ssm get-parameters | Lee parámetros del sistema. En el lab, la imagen más reciente de Amazon Linux |
aws budgets create-budget | Crea un presupuesto con alerta de gasto |
Dos trucos de la CLI
Filtra la salida para quedarte solo con el dato que quieres, en lugar de todo el JSON. Por eso el lab guarda un id en una variable con
--query "Instances[0].InstanceId" --output text.
Cambia el formato:
json por defecto, text para guardar en
variables, table para leer en pantalla.
Documentación oficial
| Recurso | Dónde |
|---|---|
| Referencia completa de comandos | docs.aws.amazon.com/cli/latest/reference/ |
| Guía de usuario de la AWS CLI | docs.aws.amazon.com/cli/latest/userguide/ |
| Ayuda desde la terminal | aws <servicio> <acción> help |