Deploy a Scalable Web Server Environment Using Terraform
学习如何使用 Terraform 部署可扩展、高度可用的 Web 服务器基础架构来提供内容。
任务详情(通过使用AWS CLI)
虚拟私有云 (VPC)
创建名为 websrv-vpc 的虚拟私有云。
子网
在您的 VPC 中配置 4 个名为 websrv-vpc 的子网,其中 2 个子网指定为公有子网,2 个指定为私有子网。每对子网(1 个公共子网和 1 个私有子网)必须放置在不同的可用区中,以确保高可用性。
互联网网关 (IGW)
将互联网网关连接到 websrv-vpc,以允许您的 VPC 中的资源访问互联网。
NAT 网关
在 websrv-vpc 中部署至少 2 个 NAT 网关,置于不同的可用区,以允许私有子网中的实例访问互联网。
路由表
创建 3 个额外的路由表来管理 websrv-vpc 内的网络流量,包括: 公共路由表,其中包含将互联网流量定向到 IGW 的路由。 每个 AZ 中私有子网的路由表,将互联网绑定流量定向到相应 AZ 的 NAT 网关。 正确的子网关联。公共子网到公共路由表。私有子网到私有路由表。默认主子网不应有关联。
安全组
使用以下规则配置名为 websrv-sg 的安全组: 允许来自任何 IP 地址 (0.0.0.0/0) 的 HTTP 流量(端口 80)的入站规则。 允许所有流量的出站规则,以确保实例可以启动互联网连接。
启动模板
创建名为 websrv-lt 的启动模板。此模板将指定 ASG 将启动的实例的配置。
自动扩展组 (ASG)
使用 websrv-lt 启动模板设置一个名为 websrv-asg 的 ASG。 ASG 必须覆盖至少两个可用区以确保高可用性。
应用程序负载均衡器 (ALB)
部署一个名为 websrv-asg-lb 的 ALB。 ALB 的目的是在由 ASG 管理的实例之间分配传入流量。
目标群体
为 ALB 建立一个名为 websrv-lb-tg 的目标群组。 应将此目标组配置为使用 HTTP 和端口 80,并且必须向其注册 ASG 的实例。
代码参考:
region = "us-west-1" # 请根据实际情况选择区域
}
resource "aws_vpc" "websrv_vpc" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "websrv-vpc"
}
}
resource "aws_subnet" "public_subnet_1" {
vpc_id = aws_vpc.websrv_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "us-west-2a"
tags = {
Name = "websrv-vpc-public-1"
}
}
resource "aws_subnet" "private_subnet_1" {
vpc_id = aws_vpc.websrv_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "us-west-2a"
tags = {
Name = "websrv-vpc-private-1"
}
}
# 重复上述资源定义,创建第二个可用区的公有和私有子网
resource "aws_internet_gateway" "websrv_igw" {
vpc_id = aws_vpc.websrv_vpc.id
tags = {
Name = "websrv-vpc-igw"
}
}
resource "aws_nat_gateway" "nat_gw_1" {
allocation_id = aws_eip.nat_eip_1.id
subnet_id = aws_subnet.public_subnet_1.id
tags = {
Name = "websrv-vpc-nat-gw-1"
}
}
resource "aws_eip" "nat_eip_1" {
vpc = true
}
resource "aws_route_table" "public_rt" {
vpc_id = aws_vpc.websrv_vpc.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.websrv_igw.id
}
tags = {
Name = "websrv-vpc-public-rt"
}
}
resource "aws_route_table" "private_rt_1" {
vpc_id = aws_vpc.websrv_vpc.id
route {
cidr_block = "0.0.0.0/0"
nat_gateway_id = aws_nat_gateway.nat_gw_1.id
}
tags = {
Name = "websrv-vpc-private-rt-1"
}
}
# 为每个子网关联相应的路由表
resource "aws_route_table_association" "public_subnet_1_assoc" {
subnet_id = aws_subnet.public_subnet_1.id
route_table_id = aws_route_table.public_rt.id
}
resource "aws_route_table_association" "private_subnet_1_assoc" {
subnet_id = aws_subnet.private_subnet_1.id
route_table_id = aws_route_table.private_rt_1.id
}
resource "aws_security_group" "websrv_sg" {
name = "websrv-sg"
description = "Allow HTTP traffic and all outbound traffic"
vpc_id = aws_vpc.websrv_vpc.id
ingress {
from_port = 80
to_port = 80
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_launch_template" "websrv_lt" {
name_prefix = "websrv-lt-"
image_id = "ami-0c55b159cbfafe1f0" # 请替换为最新的 Amazon Linux 2 AMI ID
instance_type = "t2.micro"
security_group_ids = [aws_security_group.websrv_sg.id]
user_data = <<EOF
#!/bin/bash
yum update -y
yum install -y httpd
systemctl start httpd
systemctl enable httpd
echo "<h1>Welcome to the Jam!</h1>" > /var/www/html/index.html
EOF
}
resource "aws_autoscaling_group" "websrv_asg" {
name = "websrv-asg"
launch_template {
id = aws_launch_template.websrv_lt.id
version = "$Latest"
}
min_size = 2
max_size = 4
desired_capacity = 2
vpc_zone_identifier = [aws_subnet.private_subnet_1.id, aws_subnet.private_subnet_2.id] # 假设您已经创建了第二个私有子网
target_group_arns = [aws_lb_target_group.websrv_lb_tg.arn]
}
resource "aws_lb" "websrv_asg_lb" {
name = "websrv-asg-lb"
internal = false
load_balancer_type = "application"
security_groups = [aws_security_group.websrv_sg.id]
subnets = [aws_subnet.public_subnet_1.id, aws_subnet.public_subnet_2.id] # 假设您已经创建了第二个公有子网
}
resource "aws_lb_target_group" "websrv_lb_tg" {
name = "websrv-lb-tg"
port = 80
protocol = "HTTP"
vpc_id = aws_vpc.websrv_vpc.id
health_check {
path = "/"
interval = 30
timeout = 5
healthy_threshold = 5
unhealthy_threshold = 2
}
}
resource "aws_lb_listener" "http" {
load_balancer_arn = aws_lb.websrv_asg_lb.arn
port = "80"
protocol = "HTTP"
default_action {
type = "forward"
target_group_arn = aws_lb_target_group.websrv_lb_tg.arn
}
}