AWSTemplateFormatVersion: "2010-09-09"
Description: AWS Infrastructure Setup with EC2, ALB, Target Group, Apache HTTPD, NAT Gateway, and Dedicated Security Groups
Parameters:
VPCCIDR:
Type: String
Default: "10.0.0.0/16"
PublicSubnetACIDR:
Type: String
Default: "10.0.0.0/24"
PublicSubnetCCIDR:
Type: String
Default: "10.0.1.0/24"
PrivateSubnetACIDR:
Type: String
Default: "10.0.10.0/24"
PrivateSubnetCCIDR:
Type: String
Default: "10.0.11.0/24"
Resources:
# VPC
WSVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCIDR
EnableDnsSupport: "true"
EnableDnsHostnames: "true"
Tags:
- Key: Name
Value: ws-vpc
# Internet Gateway
WSIGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: ws-igw
WSVPCGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref WSVPC
InternetGatewayId: !Ref WSIGW
# Public Subnets
WSPublicSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref WSVPC
CidrBlock: !Ref PublicSubnetACIDR
AvailabilityZone: !Select [0, !GetAZs ""]
MapPublicIpOnLaunch: "true"
Tags:
- Key: Name
Value: ws-pub-a
WSPublicSubnetC:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref WSVPC
CidrBlock: !Ref PublicSubnetCCIDR
AvailabilityZone: !Select [2, !GetAZs ""]
MapPublicIpOnLaunch: "true"
Tags:
- Key: Name
Value: ws-pub-c
# Private Subnets
WSPrivateSubnetA:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref WSVPC
CidrBlock: !Ref PrivateSubnetACIDR
AvailabilityZone: !Select [0, !GetAZs ""]
Tags:
- Key: Name
Value: ws-priv-a
WSPrivateSubnetC:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref WSVPC
CidrBlock: !Ref PrivateSubnetCCIDR
AvailabilityZone: !Select [2, !GetAZs ""]
Tags:
- Key: Name
Value: ws-priv-c
# Elastic IP for NAT Gateway
WSEIPA:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
WSEIPC:
Type: AWS::EC2::EIP
Properties:
Domain: vpc
# NAT Gateway in Public Subnet A
WSNATGatewayA:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt WSEIPA.AllocationId
SubnetId: !Ref WSPublicSubnetA
Tags:
- Key: Name
Value: ws-natgw-a
WSNATGatewayC:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt WSEIPC.AllocationId
SubnetId: !Ref WSPublicSubnetC
Tags:
- Key: Name
Value: ws-natgw-c
# Route Table for Public Subnets
WSPublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref WSVPC
Tags:
- Key: Name
Value: ws-pub-rt
# Route for Public Subnets to Internet Gateway
WSPublicRoute:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref WSPublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref WSIGW
# Associate Public Subnets with Public Route Table
WSPublicSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref WSPublicSubnetA
RouteTableId: !Ref WSPublicRouteTable
WSPublicSubnetCRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref WSPublicSubnetC
RouteTableId: !Ref WSPublicRouteTable
# Private Route Table for Private Subnet A
WSPrivateRouteTableA:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref WSVPC
Tags:
- Key: Name
Value: ws-priv-a-rt
# Route for Private Subnet A to NAT Gateway
WSPrivateRouteA:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref WSPrivateRouteTableA
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref WSNATGatewayA
# Associate Private Subnet A with Private Route Table A
WSPrivateSubnetARouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref WSPrivateSubnetA
RouteTableId: !Ref WSPrivateRouteTableA
# Private Route Table for Private Subnet C
WSPrivateRouteTableC:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref WSVPC
Tags:
- Key: Name
Value: ws-priv-c-rt
# Route for Private Subnet C to NAT Gateway
WSPrivateRouteB:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref WSPrivateRouteTableC
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref WSNATGatewayC
# Associate Private Subnet C with Private Route Table C
WSPrivateSubnetBRouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref WSPrivateSubnetC
RouteTableId: !Ref WSPrivateRouteTableC
# Security Group for App Servers
AppServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Allow HTTP access to App Servers"
VpcId: !Ref WSVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0 # Allow SSH access for debugging (restrict this in production)
Tags:
- Key: Name
Value: app-server-sg
# EC2 Instances (App Servers)
AppServerA:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: ami-062cddb9d94dcf95d
SubnetId: !Ref WSPrivateSubnetA
SecurityGroupIds:
- !Ref AppServerSecurityGroup
Tags:
- Key: Name
Value: app-server-a
UserData: !Base64 |
#!/bin/bash
sudo yum update -y
sudo yum install -y httpd
echo "app-server-a page" > /var/www/html/index.html
sudo systemctl start httpd
sudo systemctl enable httpd
AppServerC:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
ImageId: ami-062cddb9d94dcf95d
SubnetId: !Ref WSPrivateSubnetC
SecurityGroupIds:
- !Ref AppServerSecurityGroup
Tags:
- Key: Name
Value: app-server-b
UserData: !Base64 |
#!/bin/bash
sudo yum update -y
sudo yum install -y httpd
echo "app-server-b page" > /var/www/html/index.html
sudo systemctl start httpd
sudo systemctl enable httpd
# Target Group for ALB
WSTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
Name: ws-target-group
Protocol: HTTP
Port: "80"
VpcId: !Ref WSVPC
TargetType: instance
HealthCheckProtocol: HTTP
HealthCheckPort: "80"
HealthCheckPath: /
Matcher:
HttpCode: "200"
Targets: # Attach EC2 instances here
- Id: !Ref AppServerA
Port: 80
- Id: !Ref AppServerC
Port: 80
# ALB
WSALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: ws-alb
Subnets:
- Ref: WSPublicSubnetA
- Ref: WSPublicSubnetC
SecurityGroups:
- !GetAtt ALBSecurityGroup.GroupId
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: "60"
Scheme: internet-facing
Type: application
WSALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref WSTargetGroup
LoadBalancerArn: !Ref WSALB
Port: "80"
Protocol: HTTP
# ALB Security Group
ALBSecurityGroup:
Type: "AWS::EC2::SecurityGroup"
Properties:
GroupDescription: "Allow HTTP traffic"
VpcId: !Ref WSVPC
GroupName: "ws-alb-sg"
#inbound
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
#outbound
SecurityGroupEgress:
- IpProtocol: -1
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: "ws-alb-sg"
Outputs:
VPCId:
Value: !Ref WSVPC
PublicSubnetAId:
Value: !Ref WSPublicSubnetA
PublicSubnetBId:
Value: !Ref WSPublicSubnetC
PrivateSubnetAId:
Value: !Ref WSPrivateSubnetA
PrivateSubnetBId:
Value: !Ref WSPrivateSubnetC
LoadBalancerDNSName:
Value: !GetAtt WSALB.DNSName