Перейти к содержимому

10. AWS: EC2 и S3

Иллюстрация к уроку

AWS — крупнейший облачный провайдер. EC2 — виртуальные серверы, S3 — хранилище файлов. Базовые сервисы для любого бекенда.

EC2 — виртуальные серверы (VPS)
S3 — хранение файлов (объектное хранилище)
RDS — managed БД (PostgreSQL, MySQL)
Lambda — serverless функции
ECS/EKS — контейнеры
CloudFront — CDN
Route53 — DNS
IAM — управление доступом
Окно терминала
# AWS CLI
aws ec2 run-instances \
--image-id ami-0c55b159cbfafe1f0 \ # Ubuntu 22.04
--instance-type t3.micro \
--key-name my-keypair \
--security-group-ids sg-xxxxxxxx \
--subnet-id subnet-xxxxxxxx \
--count 1 \
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=myapp}]'
Окно терминала
# Скачать key pair (.pem файл) при создании
chmod 400 my-keypair.pem
# Подключение
ssh -i my-keypair.pem [email protected]
# Или через Instance Connect (в браузере)
# EC2 Console → выбрать instance → Connect → EC2 Instance Connect
Окно терминала
# Обновление системы
sudo apt update && sudo apt upgrade -y
# Установка Node.js (через nvm)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
source ~/.bashrc
nvm install 20
nvm use 20
# Установка PM2
npm install -g pm2
# Установка Nginx
sudo apt install nginx -y
sudo systemctl enable nginx
sudo systemctl start nginx
# Firewall
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
Окно терминала
# Создание группы безопасности
aws ec2 create-security-group \
--group-name myapp-sg \
--description "MyApp Security Group"
# Разрешить SSH (22)
aws ec2 authorize-security-group-ingress \
--group-id sg-xxxxxxxx \
--protocol tcp \
--port 22 \
--cidr 0.0.0.0/0 # лучше только твой IP: $(curl -s ifconfig.me)/32
# Разрешить HTTP (80) и HTTPS (443)
aws ec2 authorize-security-group-ingress \
--group-id sg-xxxxxxxx \
--protocol tcp \
--port 80 \
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress \
--group-id sg-xxxxxxxx \
--protocol tcp \
--port 443 \
--cidr 0.0.0.0/0
Окно терминала
# Выделить Elastic IP
aws ec2 allocate-address --domain vpc
# Привязать к инстансу
aws ec2 associate-address \
--instance-id i-xxxxxxxxxxxxxxxxx \
--allocation-id eipalloc-xxxxxxxxxxxxxxxxx
Окно терминала
# Создание bucket
aws s3 mb s3://my-bucket-name --region eu-west-1
# Загрузка файлов
aws s3 cp file.jpg s3://my-bucket-name/
aws s3 cp ./dist/ s3://my-bucket-name/static/ --recursive
# Скачивание
aws s3 cp s3://my-bucket-name/file.jpg ./file.jpg
aws s3 sync s3://my-bucket-name/backup/ ./backup/
# Список файлов
aws s3 ls s3://my-bucket-name/
# Удаление
aws s3 rm s3://my-bucket-name/file.jpg
aws s3 rm s3://my-bucket-name/ --recursive
Окно терминала
npm install @aws-sdk/client-s3 @aws-sdk/s3-request-presigner
import { S3Client, PutObjectCommand, GetObjectCommand, DeleteObjectCommand } from '@aws-sdk/client-s3';
import { getSignedUrl } from '@aws-sdk/s3-request-presigner';
const s3 = new S3Client({
region: process.env.AWS_REGION || 'eu-west-1',
credentials: {
accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
},
});
// Загрузка файла
async function uploadFile(key: string, body: Buffer, contentType: string) {
await s3.send(new PutObjectCommand({
Bucket: process.env.S3_BUCKET!,
Key: key,
Body: body,
ContentType: contentType,
}));
return `https://${process.env.S3_BUCKET}.s3.amazonaws.com/${key}`;
}
// Presigned URL для прямой загрузки с клиента
async function getPresignedUploadUrl(key: string, contentType: string) {
const command = new PutObjectCommand({
Bucket: process.env.S3_BUCKET!,
Key: key,
ContentType: contentType,
});
return getSignedUrl(s3, command, { expiresIn: 3600 }); // 1 час
}
// Presigned URL для чтения приватного файла
async function getPresignedDownloadUrl(key: string) {
const command = new GetObjectCommand({
Bucket: process.env.S3_BUCKET!,
Key: key,
});
return getSignedUrl(s3, command, { expiresIn: 300 }); // 5 минут
}
// Удаление
async function deleteFile(key: string) {
await s3.send(new DeleteObjectCommand({
Bucket: process.env.S3_BUCKET!,
Key: key,
}));
}
Окно терминала
# 1. Включить static website hosting
aws s3 website s3://my-static-site/ \
--index-document index.html \
--error-document 404.html
# 2. Сделать bucket публичным (bucket policy)
aws s3api put-bucket-policy \
--bucket my-static-site \
--policy '{
"Version": "2012-10-17",
"Statement": [{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::my-static-site/*"
}]
}'
# 3. Деплой сайта
npm run build
aws s3 sync ./dist s3://my-static-site/ --delete
# URL: http://my-static-site.s3-website-eu-west-1.amazonaws.com
Окно терминала
# Создать пользователя для CI/CD
aws iam create-user --user-name github-actions-deploy
# Создать ключи доступа
aws iam create-access-key --user-name github-actions-deploy
# Сохрани AccessKeyId и SecretAccessKey → в GitHub Secrets
# Минимальные права для S3 деплоя
aws iam put-user-policy \
--user-name github-actions-deploy \
--policy-name s3-deploy \
--policy-document '{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": ["s3:PutObject", "s3:DeleteObject", "s3:ListBucket"],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
]
}]
}'
.github/workflows/deploy-s3.yml
name: Deploy to S3
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm ci && npm run build
- name: Deploy to S3
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: eu-west-1
- run: aws s3 sync ./dist s3://${{ secrets.S3_BUCKET }} --delete
  • EC2 — виртуальный сервер, полный контроль
  • Security Groups — firewall для EC2, разрешай только нужные порты
  • Elastic IP — статический IP для EC2
  • S3 — объектное хранилище, идеально для файлов и статики
  • Presigned URLs — безопасная загрузка/скачивание без прямого доступа к AWS
  • IAM — минимальные права (principle of least privilege)
  • AWS SDK v3 — модульный, тряски дерева, рекомендуется

Основные сервисы AWS и их связи: