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
| Component | Mô tả |
|---|---|
| AMI | OS template (Amazon Linux, Ubuntu…) |
| Instance Type | Hardware specs (t3.micro, m5.large…) |
| EBS Volume | Ổ cứng ảo |
| Security Group | Firewall rules |
| Key Pair | SSH 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
| Family | Use Case | Ví dụ |
|---|---|---|
| T3 | General purpose, burstable | Web servers, dev |
| M5 | Balanced compute/memory | Enterprise apps |
| C5 | Compute intensive | Batch, ML inference |
| R5 | Memory intensive | Databases, caching |
| P3 | GPU workloads | ML 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
| Service | Khi nào dùng | Quản lý |
|---|---|---|
| EC2 | Cần full control, persistent servers | Cao |
| Lambda | Event-driven, short tasks | Không |
| ECS/Fargate | Containers, microservices | Trung bình |
Best Practices
- Luôn dùng IMDSv2 - Bảo mật metadata service
- Encrypt EBS volumes - Mặc định nên bật
- Principle of least privilege - Security Group chặt
- Use Spot Instances - Tiết kiệm 90% cho non-critical
- 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.