aws-ec2-setup
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAWS EC2 Setup
AWS EC2 配置指南
Overview
概述
Amazon EC2 provides resizable compute capacity in the cloud. Launch and configure virtual servers with complete control over networking, storage, and security settings. Scale automatically based on demand.
Amazon EC2 在云中提供可调整大小的计算容量。您可以启动并配置虚拟服务器,完全控制网络、存储和安全设置,并根据需求自动扩缩容。
When to Use
适用场景
- Web application servers
- Application backends and APIs
- Batch processing and compute jobs
- Development and testing environments
- Containerized applications (ECS)
- Kubernetes clusters (EKS)
- Database servers
- VPN and proxy servers
- Web应用服务器
- 应用后端与API
- 批处理与计算任务
- 开发与测试环境
- 容器化应用(ECS)
- Kubernetes集群(EKS)
- 数据库服务器
- VPN与代理服务器
Implementation Examples
实现示例
1. EC2 Instance Creation with AWS CLI
1. 使用AWS CLI创建EC2实例
bash
undefinedbash
undefinedCreate security group
Create security group
aws ec2 create-security-group
--group-name web-server-sg
--description "Web server security group"
--vpc-id vpc-12345678
--group-name web-server-sg
--description "Web server security group"
--vpc-id vpc-12345678
aws ec2 create-security-group
--group-name web-server-sg
--description "Web server security group"
--vpc-id vpc-12345678
--group-name web-server-sg
--description "Web server security group"
--vpc-id vpc-12345678
Add ingress rules
Add ingress rules
aws ec2 authorize-security-group-ingress
--group-id sg-0123456789abcdef0
--protocol tcp
--port 80
--cidr 0.0.0.0/0
--group-id sg-0123456789abcdef0
--protocol tcp
--port 80
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress
--group-id sg-0123456789abcdef0
--protocol tcp
--port 443
--cidr 0.0.0.0/0
--group-id sg-0123456789abcdef0
--protocol tcp
--port 443
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress
--group-id sg-0123456789abcdef0
--protocol tcp
--port 22
--cidr YOUR_IP/32
--group-id sg-0123456789abcdef0
--protocol tcp
--port 22
--cidr YOUR_IP/32
aws ec2 authorize-security-group-ingress
--group-id sg-0123456789abcdef0
--protocol tcp
--port 80
--cidr 0.0.0.0/0
--group-id sg-0123456789abcdef0
--protocol tcp
--port 80
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress
--group-id sg-0123456789abcdef0
--protocol tcp
--port 443
--cidr 0.0.0.0/0
--group-id sg-0123456789abcdef0
--protocol tcp
--port 443
--cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress
--group-id sg-0123456789abcdef0
--protocol tcp
--port 22
--cidr YOUR_IP/32
--group-id sg-0123456789abcdef0
--protocol tcp
--port 22
--cidr YOUR_IP/32
Create key pair
Create key pair
aws ec2 create-key-pair
--key-name my-app-key
--query 'KeyMaterial'
--output text > my-app-key.pem
--key-name my-app-key
--query 'KeyMaterial'
--output text > my-app-key.pem
chmod 400 my-app-key.pem
aws ec2 create-key-pair
--key-name my-app-key
--query 'KeyMaterial'
--output text > my-app-key.pem
--key-name my-app-key
--query 'KeyMaterial'
--output text > my-app-key.pem
chmod 400 my-app-key.pem
Create IAM role for EC2
Create IAM role for EC2
aws iam create-role
--role-name ec2-app-role
--assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" }] }'
--role-name ec2-app-role
--assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" }] }'
aws iam create-role
--role-name ec2-app-role
--assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" }] }'
--role-name ec2-app-role
--assume-role-policy-document '{ "Version": "2012-10-17", "Statement": [{ "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole" }] }'
Attach policies
Attach policies
aws iam attach-role-policy
--role-name ec2-app-role
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
--role-name ec2-app-role
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
aws iam attach-role-policy
--role-name ec2-app-role
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
--role-name ec2-app-role
--policy-arn arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy
Create instance profile
Create instance profile
aws iam create-instance-profile --instance-profile-name ec2-app-profile
aws iam add-role-to-instance-profile
--instance-profile-name ec2-app-profile
--role-name ec2-app-role
--instance-profile-name ec2-app-profile
--role-name ec2-app-role
aws iam create-instance-profile --instance-profile-name ec2-app-profile
aws iam add-role-to-instance-profile
--instance-profile-name ec2-app-profile
--role-name ec2-app-role
--instance-profile-name ec2-app-profile
--role-name ec2-app-role
Launch instance
Launch instance
aws ec2 run-instances
--image-id ami-0c55b159cbfafe1f0
--instance-type t3.micro
--key-name my-app-key
--security-group-ids sg-0123456789abcdef0
--iam-instance-profile Name=ec2-app-profile
--user-data file://user-data.sh
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server}]'
--image-id ami-0c55b159cbfafe1f0
--instance-type t3.micro
--key-name my-app-key
--security-group-ids sg-0123456789abcdef0
--iam-instance-profile Name=ec2-app-profile
--user-data file://user-data.sh
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server}]'
undefinedaws ec2 run-instances
--image-id ami-0c55b159cbfafe1f0
--instance-type t3.micro
--key-name my-app-key
--security-group-ids sg-0123456789abcdef0
--iam-instance-profile Name=ec2-app-profile
--user-data file://user-data.sh
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server}]'
--image-id ami-0c55b159cbfafe1f0
--instance-type t3.micro
--key-name my-app-key
--security-group-ids sg-0123456789abcdef0
--iam-instance-profile Name=ec2-app-profile
--user-data file://user-data.sh
--tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=web-server}]'
undefined2. User Data Script
2. 用户数据脚本
bash
#!/bin/bashbash
#!/bin/bashuser-data.sh
user-data.sh
set -e
set -x
set -e
set -x
Update system
Update system
apt-get update
apt-get upgrade -y
apt-get update
apt-get upgrade -y
Install dependencies
Install dependencies
apt-get install -y
curl
wget
git
nodejs
npm
postgresql-client
curl
wget
git
nodejs
npm
postgresql-client
apt-get install -y
curl
wget
git
nodejs
npm
postgresql-client
curl
wget
git
nodejs
npm
postgresql-client
Install Node.js application
Install Node.js application
mkdir -p /opt/app
cd /opt/app
git clone https://github.com/myorg/myapp.git .
npm install --production
mkdir -p /opt/app
cd /opt/app
git clone https://github.com/myorg/myapp.git .
npm install --production
Create systemd service
Create systemd service
cat > /etc/systemd/system/myapp.service << EOF
[Unit]
Description=My Node App
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/app
ExecStart=/usr/bin/node index.js
Restart=on-failure
RestartSec=5
Environment="NODE_ENV=production"
Environment="PORT=3000"
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable myapp
systemctl start myapp
cat > /etc/systemd/system/myapp.service << EOF
[Unit]
Description=My Node App
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/opt/app
ExecStart=/usr/bin/node index.js
Restart=on-failure
RestartSec=5
Environment="NODE_ENV=production"
Environment="PORT=3000"
[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable myapp
systemctl start myapp
Install and configure CloudWatch agent
Install and configure CloudWatch agent
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
dpkg -i -E ./amazon-cloudwatch-agent.deb
wget https://s3.amazonaws.com/amazoncloudwatch-agent/ubuntu/amd64/latest/amazon-cloudwatch-agent.deb
dpkg -i -E ./amazon-cloudwatch-agent.deb
Configure log streaming
Configure log streaming
cat > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json << EOF
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/syslog",
"log_group_name": "/aws/ec2/web-server",
"log_stream_name": "{instance_id}"
},
{
"file_path": "/opt/app/logs/*.log",
"log_group_name": "/aws/ec2/app",
"log_stream_name": "{instance_id}"
}
]
}
}
},
"metrics": {
"metrics_collected": {
"cpu": {"measurement": [{"name": "cpu_usage_idle"}]},
"mem": {"measurement": [{"name": "mem_used_percent"}]},
"disk": {"measurement": [{"name": "used_percent"}]}
}
}
}
EOF
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl
-a fetch-config
-m ec2
-s
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
-a fetch-config
-m ec2
-s
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
undefinedcat > /opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json << EOF
{
"logs": {
"logs_collected": {
"files": {
"collect_list": [
{
"file_path": "/var/log/syslog",
"log_group_name": "/aws/ec2/web-server",
"log_stream_name": "{instance_id}"
},
{
"file_path": "/opt/app/logs/*.log",
"log_group_name": "/aws/ec2/app",
"log_stream_name": "{instance_id}"
}
]
}
}
},
"metrics": {
"metrics_collected": {
"cpu": {"measurement": [{"name": "cpu_usage_idle"}]},
"mem": {"measurement": [{"name": "mem_used_percent"}]},
"disk": {"measurement": [{"name": "used_percent"}]}
}
}
}
EOF
/opt/aws/amazon-cloudwatch-agent/bin/amazon-cloudwatch-agent-ctl
-a fetch-config
-m ec2
-s
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
-a fetch-config
-m ec2
-s
-c file:/opt/aws/amazon-cloudwatch-agent/etc/amazon-cloudwatch-agent.json
undefined3. Terraform EC2 Configuration
3. Terraform EC2 配置
hcl
undefinedhcl
undefinedec2.tf
ec2.tf
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.0"
}
}
}
provider "aws" {
region = "us-east-1"
}
VPC
VPC
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "main-vpc" }
}
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
tags = { Name = "main-vpc" }
}
Public Subnet
Public Subnet
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = { Name = "public-subnet" }
}
resource "aws_subnet" "public" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-east-1a"
map_public_ip_on_launch = true
tags = { Name = "public-subnet" }
}
Internet Gateway
Internet Gateway
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = { Name = "main-igw" }
}
resource "aws_internet_gateway" "main" {
vpc_id = aws_vpc.main.id
tags = { Name = "main-igw" }
}
Route table
Route table
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = { Name = "public-rt" }
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
resource "aws_route_table" "public" {
vpc_id = aws_vpc.main.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.main.id
}
tags = { Name = "public-rt" }
}
resource "aws_route_table_association" "public" {
subnet_id = aws_subnet.public.id
route_table_id = aws_route_table.public.id
}
Security group
Security group
resource "aws_security_group" "web" {
name_prefix = "web-"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["YOUR_IP/32"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_security_group" "web" {
name_prefix = "web-"
vpc_id = aws_vpc.main.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
ingress {
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["YOUR_IP/32"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
IAM role
IAM role
resource "aws_iam_role" "ec2_role" {
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "ec2_policy" {
role = aws_iam_role.ec2_role.name
policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
}
resource "aws_iam_instance_profile" "ec2_profile" {
role = aws_iam_role.ec2_role.name
}
resource "aws_iam_role" "ec2_role" {
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [{
Action = "sts:AssumeRole"
Effect = "Allow"
Principal = {
Service = "ec2.amazonaws.com"
}
}]
})
}
resource "aws_iam_role_policy_attachment" "ec2_policy" {
role = aws_iam_role.ec2_role.name
policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
}
resource "aws_iam_instance_profile" "ec2_profile" {
role = aws_iam_role.ec2_role.name
}
Key pair
Key pair
resource "aws_key_pair" "deployer" {
key_name = "deployer-key"
public_key = file("~/.ssh/id_rsa.pub")
}
resource "aws_key_pair" "deployer" {
key_name = "deployer-key"
public_key = file("~/.ssh/id_rsa.pub")
}
AMI data source
AMI data source
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
data "aws_ami" "ubuntu" {
most_recent = true
owners = ["099720109477"] # Canonical
filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}
}
EC2 instance
EC2 instance
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web.id]
iam_instance_profile = aws_iam_instance_profile.ec2_profile.name
key_name = aws_key_pair.deployer.key_name
user_data = base64encode(file("${path.module}/user-data.sh"))
root_block_device {
volume_size = 20
volume_type = "gp3"
delete_on_termination = true
encrypted = true
}
tags = {
Name = "web-server"
}
lifecycle {
create_before_destroy = true
}
}
resource "aws_instance" "web" {
ami = data.aws_ami.ubuntu.id
instance_type = "t3.micro"
subnet_id = aws_subnet.public.id
vpc_security_group_ids = [aws_security_group.web.id]
iam_instance_profile = aws_iam_instance_profile.ec2_profile.name
key_name = aws_key_pair.deployer.key_name
user_data = base64encode(file("${path.module}/user-data.sh"))
root_block_device {
volume_size = 20
volume_type = "gp3"
delete_on_termination = true
encrypted = true
}
tags = {
Name = "web-server"
}
lifecycle {
create_before_destroy = true
}
}
Elastic IP
Elastic IP
resource "aws_eip" "web" {
instance = aws_instance.web.id
domain = "vpc"
tags = { Name = "web-eip" }
}
resource "aws_eip" "web" {
instance = aws_instance.web.id
domain = "vpc"
tags = { Name = "web-eip" }
}
Auto Scaling Group
Auto Scaling Group
resource "aws_launch_template" "app" {
image_id = data.aws_ami.ubuntu.id
instance_type = "t3.small"
vpc_security_group_ids = [aws_security_group.web.id]
iam_instance_profile {
name = aws_iam_instance_profile.ec2_profile.name
}
user_data = base64encode(file("${path.module}/user-data.sh"))
tag_specifications {
resource_type = "instance"
tags = {
Name = "app-instance"
}
}
}
resource "aws_autoscaling_group" "app" {
name = "app-asg"
vpc_zone_identifier = [aws_subnet.public.id]
min_size = 1
max_size = 3
desired_capacity = 2
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
health_check_type = "ELB"
health_check_grace_period = 300
tag {
key = "Name"
value = "app-asg-instance"
propagate_at_launch = true
}
}
undefinedresource "aws_launch_template" "app" {
image_id = data.aws_ami.ubuntu.id
instance_type = "t3.small"
vpc_security_group_ids = [aws_security_group.web.id]
iam_instance_profile {
name = aws_iam_instance_profile.ec2_profile.name
}
user_data = base64encode(file("${path.module}/user-data.sh"))
tag_specifications {
resource_type = "instance"
tags = {
Name = "app-instance"
}
}
}
resource "aws_autoscaling_group" "app" {
name = "app-asg"
vpc_zone_identifier = [aws_subnet.public.id]
min_size = 1
max_size = 3
desired_capacity = 2
launch_template {
id = aws_launch_template.app.id
version = "$Latest"
}
health_check_type = "ELB"
health_check_grace_period = 300
tag {
key = "Name"
value = "app-asg-instance"
propagate_at_launch = true
}
}
undefinedBest Practices
最佳实践
✅ DO
✅ 推荐做法
- Use security groups for network control
- Attach IAM roles for AWS access
- Enable CloudWatch monitoring
- Use AMI for consistent deployments
- Implement auto-scaling for variable load
- Use EBS for persistent storage
- Enable termination protection for production
- Keep systems patched and updated
- 使用安全组进行网络控制
- 附加IAM角色以获取AWS访问权限
- 启用CloudWatch监控
- 使用AMI实现一致部署
- 针对可变负载实现自动扩缩容
- 使用EBS进行持久化存储
- 为生产实例启用终止保护
- 保持系统补丁更新
❌ DON'T
❌ 不推荐做法
- Use overly permissive security groups
- Store credentials in user data
- Ignore CloudWatch metrics
- Use outdated AMIs
- Create hardcoded configurations
- Forget to monitor costs
- 使用过于宽松的安全组规则
- 在用户数据中存储凭证
- 忽略CloudWatch指标
- 使用过时的AMI
- 创建硬编码配置
- 忘记监控成本
Monitoring
监控
- CloudWatch metrics and dashboards
- CloudWatch Logs from applications
- CloudWatch Alarms for thresholds
- EC2 Instance Health Checks
- Auto Scaling Activities
- CloudWatch指标与仪表板
- 来自应用的CloudWatch日志
- 基于阈值的CloudWatch告警
- EC2实例健康检查
- 自动扩缩容活动