AWS 快速上手

通过实践快速掌握 AWS 基础操作。

环境准备

创建 IAM 用户

1. 登录 AWS Console

访问 https://console.aws.amazon.com

2. 创建 IAM 用户

# 使用 Root 账号创建第一个 IAM 用户
IAM → Users → Add user

用户名:admin-user
访问类型:
  ✓ Programmatic access(编程访问)
  ✓ AWS Management Console access(控制台访问)

权限:
  ✓ Attach existing policies directly
  ✓ AdministratorAccess(仅用于学习,生产环境需细化权限)

生成访问密钥:
  Access Key ID: AKIA...
  Secret Access Key: wJalr...
  
⚠️ 务必保存密钥,只会显示一次!

3. 启用 MFA

IAM → Users → Security credentials → Assign MFA device

选择 MFA 类型:
  • Virtual MFA device(推荐):Google Authenticator、Authy
  • Hardware MFA device:物理密钥
  • U2F security key:YubiKey

配置 AWS CLI

# 安装后配置
aws configure --profile admin

# 输入凭证
AWS Access Key ID: AKIA...
AWS Secret Access Key: wJalr...
Default region name: us-east-1
Default output format: json

# 验证配置
aws sts get-caller-identity --profile admin

# 输出:
{
  "UserId": "AIDAI...",
  "Account": "123456789012",
  "Arn": "arn:aws:iam::123456789012:user/admin-user"
}

# 设置默认 Profile
export AWS_PROFILE=admin
# 或在 ~/.bashrc 中添加
echo 'export AWS_PROFILE=admin' >> ~/.bashrc

实战:搭建第一个 Web 应用

架构图

Internet
    │
    ▼
┌─────────────────┐
│  CloudFront CDN │
└────────┬────────┘
         │
    ┌────▼─────┐
    │  ALB     │
    └────┬─────┘
         │
    ┌────▼─────────────┐
    │  Auto Scaling    │
    │  ┌───┐  ┌───┐   │
    │  │EC2│  │EC2│   │
    │  └───┘  └───┘   │
    └──────────────────┘
         │
    ┌────▼─────┐
    │   RDS    │
    │  MySQL   │
    └──────────┘

步骤 1:创建 VPC

# 创建 VPC
VPC_ID=$(aws ec2 create-vpc \
  --cidr-block 10.0.0.0/16 \
  --tag-specifications 'ResourceType=vpc,Tags=[{Key=Name,Value=my-vpc}]' \
  --query 'Vpc.VpcId' \
  --output text)

echo "VPC ID: $VPC_ID"

# 启用 DNS 主机名
aws ec2 modify-vpc-attribute \
  --vpc-id $VPC_ID \
  --enable-dns-hostnames

# 创建公有子网(2 个可用区)
SUBNET_PUBLIC_1=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.1.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1a}]' \
  --query 'Subnet.SubnetId' \
  --output text)

SUBNET_PUBLIC_2=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.2.0/24 \
  --availability-zone us-east-1b \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=public-subnet-1b}]' \
  --query 'Subnet.SubnetId' \
  --output text)

# 创建私有子网(用于数据库)
SUBNET_PRIVATE_1=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.11.0/24 \
  --availability-zone us-east-1a \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1a}]' \
  --query 'Subnet.SubnetId' \
  --output text)

SUBNET_PRIVATE_2=$(aws ec2 create-subnet \
  --vpc-id $VPC_ID \
  --cidr-block 10.0.12.0/24 \
  --availability-zone us-east-1b \
  --tag-specifications 'ResourceType=subnet,Tags=[{Key=Name,Value=private-subnet-1b}]' \
  --query 'Subnet.SubnetId' \
  --output text)

# 创建 Internet Gateway
IGW_ID=$(aws ec2 create-internet-gateway \
  --tag-specifications 'ResourceType=internet-gateway,Tags=[{Key=Name,Value=my-igw}]' \
  --query 'InternetGateway.InternetGatewayId' \
  --output text)

# 附加到 VPC
aws ec2 attach-internet-gateway \
  --vpc-id $VPC_ID \
  --internet-gateway-id $IGW_ID

# 创建路由表(公有)
RTB_PUBLIC=$(aws ec2 create-route-table \
  --vpc-id $VPC_ID \
  --tag-specifications 'ResourceType=route-table,Tags=[{Key=Name,Value=public-rtb}]' \
  --query 'RouteTable.RouteTableId' \
  --output text)

# 添加路由
aws ec2 create-route \
  --route-table-id $RTB_PUBLIC \
  --destination-cidr-block 0.0.0.0/0 \
  --gateway-id $IGW_ID

# 关联子网
aws ec2 associate-route-table \
  --subnet-id $SUBNET_PUBLIC_1 \
  --route-table-id $RTB_PUBLIC

aws ec2 associate-route-table \
  --subnet-id $SUBNET_PUBLIC_2 \
  --route-table-id $RTB_PUBLIC

步骤 2:创建安全组

# Web 服务器安全组
SG_WEB=$(aws ec2 create-security-group \
  --group-name web-sg \
  --description "Security group for web servers" \
  --vpc-id $VPC_ID \
  --query 'GroupId' \
  --output text)

# 允许 HTTP/HTTPS
aws ec2 authorize-security-group-ingress \
  --group-id $SG_WEB \
  --protocol tcp \
  --port 80 \
  --cidr 0.0.0.0/0

aws ec2 authorize-security-group-ingress \
  --group-id $SG_WEB \
  --protocol tcp \
  --port 443 \
  --cidr 0.0.0.0/0

# 允许 SSH(仅你的 IP)
MY_IP=$(curl -s https://checkip.amazonaws.com)
aws ec2 authorize-security-group-ingress \
  --group-id $SG_WEB \
  --protocol tcp \
  --port 22 \
  --cidr $MY_IP/32

# 数据库安全组
SG_DB=$(aws ec2 create-security-group \
  --group-name db-sg \
  --description "Security group for database" \
  --vpc-id $VPC_ID \
  --query 'GroupId' \
  --output text)

# 允许来自 Web 服务器的 MySQL 连接
aws ec2 authorize-security-group-ingress \
  --group-id $SG_DB \
  --protocol tcp \
  --port 3306 \
  --source-group $SG_WEB

步骤 3:启动 EC2 实例

# 创建密钥对
aws ec2 create-key-pair \
  --key-name my-key \
  --query 'KeyMaterial' \
  --output text > ~/.ssh/my-key.pem

chmod 400 ~/.ssh/my-key.pem

# 查找最新的 Amazon Linux 2 AMI
AMI_ID=$(aws ec2 describe-images \
  --owners amazon \
  --filters "Name=name,Values=amzn2-ami-hvm-*-x86_64-gp2" \
  --query 'sort_by(Images, &CreationDate)[-1].ImageId' \
  --output text)

# 启动实例
INSTANCE_ID=$(aws ec2 run-instances \
  --image-id $AMI_ID \
  --instance-type t2.micro \
  --key-name my-key \
  --security-group-ids $SG_WEB \
  --subnet-id $SUBNET_PUBLIC_1 \
  --associate-public-ip-address \
  --user-data file://user-data.sh \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server-1}]' \
  --query 'Instances[0].InstanceId' \
  --output text)

echo "Instance ID: $INSTANCE_ID"

# 等待实例运行
aws ec2 wait instance-running --instance-ids $INSTANCE_ID

# 获取公网 IP
PUBLIC_IP=$(aws ec2 describe-instances \
  --instance-ids $INSTANCE_ID \
  --query 'Reservations[0].Instances[0].PublicIpAddress' \
  --output text)

echo "Public IP: $PUBLIC_IP"

user-data.sh(启动脚本):

#!/bin/bash
# 更新系统
yum update -y

# 安装 Nginx
amazon-linux-extras install nginx1 -y

# 启动 Nginx
systemctl start nginx
systemctl enable nginx

# 创建简单的网页
cat > /usr/share/nginx/html/index.html <<EOF
<!DOCTYPE html>
<html>
<head>
    <title>My First AWS Web App</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            text-align: center;
            padding: 50px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        .container {
            background: rgba(255,255,255,0.1);
            padding: 40px;
            border-radius: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>🎉 Welcome to AWS!</h1>
        <p>This page is served from EC2 instance</p>
        <p>Instance ID: $(ec2-metadata --instance-id | cut -d ' ' -f 2)</p>
        <p>Availability Zone: $(ec2-metadata --availability-zone | cut -d ' ' -f 2)</p>
    </div>
</body>
</html>
EOF

步骤 4:访问应用

# SSH 连接实例
ssh -i ~/.ssh/my-key.pem ec2-user@$PUBLIC_IP

# 浏览器访问
echo "Visit: http://$PUBLIC_IP"

步骤 5:创建 RDS 数据库

# 创建 DB 子网组
aws rds create-db-subnet-group \
  --db-subnet-group-name my-db-subnet-group \
  --db-subnet-group-description "Subnet group for RDS" \
  --subnet-ids $SUBNET_PRIVATE_1 $SUBNET_PRIVATE_2

# 创建 MySQL 实例
aws rds create-db-instance \
  --db-instance-identifier my-database \
  --db-instance-class db.t3.micro \
  --engine mysql \
  --engine-version 8.0.35 \
  --master-username admin \
  --master-user-password MySecurePassword123! \
  --allocated-storage 20 \
  --vpc-security-group-ids $SG_DB \
  --db-subnet-group-name my-db-subnet-group \
  --backup-retention-period 7 \
  --no-publicly-accessible

# 等待可用(约 5-10 分钟)
aws rds wait db-instance-available \
  --db-instance-identifier my-database

# 获取数据库端点
DB_ENDPOINT=$(aws rds describe-db-instances \
  --db-instance-identifier my-database \
  --query 'DBInstances[0].Endpoint.Address' \
  --output text)

echo "Database Endpoint: $DB_ENDPOINT"

步骤 6:配置 S3 存储

# 创建 S3 存储桶
BUCKET_NAME="my-web-assets-$(date +%s)"
aws s3 mb s3://$BUCKET_NAME --region us-east-1

# 上传静态文件
echo "Hello from S3!" > test.html
aws s3 cp test.html s3://$BUCKET_NAME/

# 配置静态网站托管
aws s3 website s3://$BUCKET_NAME/ \
  --index-document index.html

# 设置公开读权限(注意安全)
aws s3api put-bucket-policy \
  --bucket $BUCKET_NAME \
  --policy '{
    "Version": "2012-10-17",
    "Statement": [{
      "Sid": "PublicReadGetObject",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::'$BUCKET_NAME'/*"
    }]
  }'

# 访问 URL
echo "S3 Website: http://$BUCKET_NAME.s3-website-us-east-1.amazonaws.com"

清理资源

# 删除 EC2 实例
aws ec2 terminate-instances --instance-ids $INSTANCE_ID
aws ec2 wait instance-terminated --instance-ids $INSTANCE_ID

# 删除 RDS 实例
aws rds delete-db-instance \
  --db-instance-identifier my-database \
  --skip-final-snapshot

# 删除 S3 存储桶
aws s3 rm s3://$BUCKET_NAME --recursive
aws s3 rb s3://$BUCKET_NAME

# 删除安全组
aws ec2 delete-security-group --group-id $SG_WEB
aws ec2 delete-security-group --group-id $SG_DB

# 删除子网
aws ec2 delete-subnet --subnet-id $SUBNET_PUBLIC_1
aws ec2 delete-subnet --subnet-id $SUBNET_PUBLIC_2
aws ec2 delete-subnet --subnet-id $SUBNET_PRIVATE_1
aws ec2 delete-subnet --subnet-id $SUBNET_PRIVATE_2

# 分离并删除 IGW
aws ec2 detach-internet-gateway \
  --internet-gateway-id $IGW_ID \
  --vpc-id $VPC_ID

aws ec2 delete-internet-gateway --internet-gateway-id $IGW_ID

# 删除路由表
aws ec2 delete-route-table --route-table-id $RTB_PUBLIC

# 删除 VPC
aws ec2 delete-vpc --vpc-id $VPC_ID

成本估算

使用免费套餐,这个实践项目几乎免费:

服务 免费套餐 成本
EC2 t2.micro 750 小时/月 $0
RDS db.t3.micro 750 小时/月 $0
S3 5GB 存储 $0
ELB 750 小时/月 $0

⚠️ 记得及时清理资源,避免产生费用!

常见问题

1. 无法 SSH 连接?

检查:

  • 安全组是否允许你的 IP
  • 密钥文件权限是否正确(chmod 400)
  • 实例是否在运行状态

2. 网页无法访问?

检查:

  • 安全组是否允许 80/443 端口
  • Nginx 是否正常运行(systemctl status nginx)
  • 公网 IP 是否正确

3. 如何降低成本?

  • 使用预留实例或 Savings Plans
  • 关闭不用的资源
  • 使用 Spot 实例
  • 启用 S3 生命周期策略

下一步

掌握了基础操作后,接下来学习:

  1. EC2 深入:实例类型、Auto Scaling
  2. S3 高级:生命周期、版本控制
  3. VPC 网络:子网设计、VPN 连接
  4. RDS 管理:备份恢复、读副本
  5. 监控运维:CloudWatch、Systems Manager

继续探索 AWS 的强大功能!