EC2 & Compute Services: Hướng dẫn chi tiết

Tìm hiểu về EC2 instances, Lambda, ECS và cách chọn đúng compute service cho project của bạn.

Amazon EC2 là gì?

EC2 (Elastic Compute Cloud) cung cấp virtual servers (instances) trên AWS cloud. Bạn có thể khởi tạo, cấu hình và scale servers theo nhu cầu.

Các thành phần chính

ComponentMô tả
AMIOS template (Amazon Linux, Ubuntu…)
Instance TypeHardware specs (t3.micro, m5.large…)
EBS VolumeỔ cứng ảo
Security GroupFirewall rules
Key PairSSH key để truy cập

Triển khai EC2 với Terraform

Cấu trúc project

ec2-demo/
├── main.tf
├── variables.tf
├── outputs.tf
└── userdata.sh

Main Configuration

# main.tf

# Lấy AMI mới nhất của Amazon Linux 2023
data "aws_ami" "amazon_linux" {
  most_recent = true
  owners      = ["amazon"]

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

  filter {
    name   = "virtualization-type"
    values = ["hvm"]
  }
}

# Security Group
resource "aws_security_group" "web" {
  name        = "${var.project_name}-web-sg"
  description = "Security group for web server"
  vpc_id      = var.vpc_id

  # SSH access
  ingress {
    from_port   = 22
    to_port     = 22
    protocol    = "tcp"
    cidr_blocks = [var.my_ip]
    description = "SSH from my IP"
  }

  # HTTP
  ingress {
    from_port   = 80
    to_port     = 80
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "HTTP from anywhere"
  }

  # HTTPS
  ingress {
    from_port   = 443
    to_port     = 443
    protocol    = "tcp"
    cidr_blocks = ["0.0.0.0/0"]
    description = "HTTPS from anywhere"
  }

  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

  tags = {
    Name = "${var.project_name}-web-sg"
  }
}

# EC2 Instance
resource "aws_instance" "web" {
  ami                    = data.aws_ami.amazon_linux.id
  instance_type          = var.instance_type
  key_name               = var.key_name
  vpc_security_group_ids = [aws_security_group.web.id]
  subnet_id              = var.subnet_id
  
  # IMDSv2 (bắt buộc cho security)
  metadata_options {
    http_endpoint               = "enabled"
    http_tokens                 = "required"
    http_put_response_hop_limit = 1
  }

  # EBS root volume
  root_block_device {
    volume_type           = "gp3"
    volume_size           = 20
    encrypted             = true
    delete_on_termination = true
  }

  # User data script
  user_data = file("${path.module}/userdata.sh")

  tags = {
    Name = "${var.project_name}-web"
  }
}

Variables

# variables.tf
variable "project_name" {
  type    = string
  default = "demo"
}

variable "vpc_id" {
  description = "VPC ID to deploy instance"
  type        = string
}

variable "subnet_id" {
  description = "Subnet ID for the instance"
  type        = string
}

variable "instance_type" {
  description = "EC2 instance type"
  type        = string
  default     = "t3.micro"
}

variable "key_name" {
  description = "SSH key pair name"
  type        = string
}

variable "my_ip" {
  description = "Your IP for SSH access (CIDR format)"
  type        = string
  default     = "0.0.0.0/0"  # Thay bằng IP thật!
}

User Data Script

#!/bin/bash
# userdata.sh - Cài đặt Nginx web server

yum update -y
yum install -y nginx

systemctl start nginx
systemctl enable nginx

echo "<h1>Hello from $(hostname)</h1>" > /usr/share/nginx/html/index.html

Outputs

# outputs.tf
output "instance_id" {
  value = aws_instance.web.id
}

output "public_ip" {
  value = aws_instance.web.public_ip
}

output "public_dns" {
  value = aws_instance.web.public_dns
}

Triển khai với AWS CLI

# Tạo Security Group
aws ec2 create-security-group \
  --group-name web-sg \
  --description "Web server SG" \
  --vpc-id vpc-xxx

# Thêm rule SSH
aws ec2 authorize-security-group-ingress \
  --group-id sg-xxx \
  --protocol tcp \
  --port 22 \
  --cidr YOUR_IP/32

# Launch EC2 instance
aws ec2 run-instances \
  --image-id ami-xxx \
  --instance-type t3.micro \
  --key-name my-key \
  --security-group-ids sg-xxx \
  --subnet-id subnet-xxx \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server}]'

Instance Types chọn theo Use Case

FamilyUse CaseVí dụ
T3General purpose, burstableWeb servers, dev
M5Balanced compute/memoryEnterprise apps
C5Compute intensiveBatch, ML inference
R5Memory intensiveDatabases, caching
P3GPU workloadsML training

AWS Lambda - Serverless

Lambda chạy code mà không cần quản lý servers.

Terraform Lambda

# Lambda function
resource "aws_lambda_function" "hello" {
  filename         = "lambda.zip"
  function_name    = "${var.project_name}-hello"
  role             = aws_iam_role.lambda_exec.arn
  handler          = "index.handler"
  runtime          = "nodejs20.x"
  memory_size      = 128
  timeout          = 10

  environment {
    variables = {
      ENVIRONMENT = var.environment
    }
  }
}

# IAM Role for Lambda
resource "aws_iam_role" "lambda_exec" {
  name = "${var.project_name}-lambda-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = {
        Service = "lambda.amazonaws.com"
      }
    }]
  })
}

# Attach basic execution role
resource "aws_iam_role_policy_attachment" "lambda_basic" {
  role       = aws_iam_role.lambda_exec.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}

So sánh Compute Services

ServiceKhi nào dùngQuản lý
EC2Cần full control, persistent serversCao
LambdaEvent-driven, short tasksKhông
ECS/FargateContainers, microservicesTrung bình

Best Practices

  1. Luôn dùng IMDSv2 - Bảo mật metadata service
  2. Encrypt EBS volumes - Mặc định nên bật
  3. Principle of least privilege - Security Group chặt
  4. Use Spot Instances - Tiết kiệm 90% cho non-critical
  5. Auto Scaling - Tự động scale theo demand

Bài tiếp theo: S3 & Storage - Lưu trữ dữ liệu với Infrastructure as Code.