AWSTemplateFormatVersion: "2010-09-09"
Description: AWS Infrastructure Setup with ASG, 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"
InstanceType:
Type: String
Default: "t3.micro"
AllowedValues: [t2.micro, t3.micro, t3.small]
ImageId:
Type: String
Description: The AMI ID for the EC2 instances
Default: ami-062cddb9d94dcf95d # 기본값은 Amazon Linux 2 (us-east-1)
DesiredCapacity:
Type: Number
Default: 2
Description: The number of EC2 instances to launch
MaxSize:
Type: Number
Default: 4
Description: The maximum number of EC2 instances that can be launched
MinSize:
Type: Number
Default: 2
Description: The minimum number of EC2 instances that must be running
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-c
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
WSPrivateSubnetCRouteTableAssociation:
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
# Launch Template for Auto Scaling Group
AppServerLaunchTemplate:
Type: AWS::EC2::LaunchTemplate
Properties:
LaunchTemplateName: app-server-launch-template
LaunchTemplateData:
ImageId: !Ref ImageId
InstanceType: !Ref InstanceType
SecurityGroupIds:
- !Ref AppServerSecurityGroup
UserData: !Base64 |
#!/bin/bash
sudo yum update -y
sudo yum install -y httpd
echo "Hello from Auto Scaling Group instance $(hostname)" > /var/www/html/index.html
sudo systemctl start httpd
sudo systemctl enable httpd
# Auto Scaling Group
AppServerASG:
Type: AWS::AutoScaling::AutoScalingGroup
Properties:
AutoScalingGroupName: app-server-asg
LaunchTemplate:
LaunchTemplateId: !Ref AppServerLaunchTemplate
Version: !GetAtt AppServerLaunchTemplate.LatestVersionNumber
MinSize: !Ref MinSize
MaxSize: !Ref MaxSize
DesiredCapacity: !Ref DesiredCapacity
HealthCheckType: ELB
HealthCheckGracePeriod: 300
VPCZoneIdentifier:
- !Ref WSPrivateSubnetA
- !Ref WSPrivateSubnetC
TargetGroupARNs:
- !Ref WSTargetGroup
Tags:
- Key: Name
Value: app-server-instance
PropagateAtLaunch: true
# 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"
# ALB
WSALB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Name: ws-alb
Subnets:
- Ref: WSPublicSubnetA
- Ref: WSPublicSubnetC
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: "60"
Scheme: internet-facing
Type: application
SecurityGroups:
- !Ref AppServerSecurityGroup
WSALBListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: forward
TargetGroupArn: !Ref WSTargetGroup
LoadBalancerArn: !Ref WSALB
Port: "80"
Protocol: HTTP
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
AutoScalingGroupName:
Value: !Ref AppServerASG