Task 2: Firewall
Task goals:
- Public Subnet firewall: allow 22, 80, 443 from the Internet
- Private Subnet firewall: allow 22, 80, 443 from Public Subnet
Upload the CloudFormation template “vpc-santeri-vauramo.yaml” to AWS Sandbox CloudShell.
Run the following CLI commands:
aws cloudformation validate-template --template-body file://vpc-santeri-vauramo.yaml
aws cloudformation create-stack --stack-name SanteriVPC --template-body file://vpc-santeri-vauramo.yaml --capabilities CAPABILITY_NAMED_IAM CAPABILITY_AUTO_EXPAND --parameters ParameterKey=KeyName,ParameterValue=learner-vm-key ParameterKey=EnvironmentName,ParameterValue=Production
This is a continuation for Task 1: Networking
- Public and Private Network Access Control Lists (NACL) and rules for different ports (columns 344-493 in the .yaml file)
- Public Subnets: Allow ports 22, 80, 443 from the Internet
- Private Subnets: Allow ports 22, 80, 443 from Public Subnet
### The template file:
AWSTemplateFormatVersion: '2010-09-09'
Description: This template deploys a VPC, with a pair of public and private subnets spread across two Availability Zones with configured Network Firewall.
Parameters:
EnvironmentName:
Description: VPC Networking
Type: String
VpcCIDR:
Description: VPC CIDR
Type: String
Default: 10.25.36.0/22
PublicSubnet1CIDR:
Description: AZ1 Public Subnet
Type: String
Default: 10.25.36.0/24
PublicSubnet2CIDR:
Description: AZ2 Public Subnet
Type: String
Default: 10.25.37.0/24
PrivateSubnet1CIDR:
Description: AZ1 Private Subnet
Type: String
Default: 10.25.38.0/24
PrivateSubnet2CIDR:
Description: AZ2 Private Subnet
Type: String
Default: 10.25.39.0/24
Course:
Type: String
Default: 'Cloud Architectures - AWS'
Description: Name of the course
ImplementationID:
Type: String
Default: 'ICI010AS3AE-3003'
Description: Course implementation
Task:
Type: String
Default: 'Task 2: Firewall'
Description: Project prep task
Learner:
Type: String
Default: 'Santeri Vauramo'
Description: Author of this template
KeyName:
Description: Name of an existing EC2 KeyPair to enable SSH access
Type: AWS::EC2::KeyPair::KeyName
DeploymentType:
Type: String
Default: 'Console'
Description: Deployment type
AllowedValues:
- Console
- CLI
- IaC
- IaC with Configuration Management
- CI/CD
- CI/CD with Configuration Management
ConstraintDescription: Type of deployment of the resources
InstanceType:
Description: EC2 instance type
Type: String
Default: t3.nano
AllowedValues:
- t2.nano
- t2.micro
- t2.small
- t3.nano
- t3.micro
- t3.small
ConstraintDescription: EC2 instance types supported by AWS Sandbox
Resources:
SanteriVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCIDR
EnableDnsSupport: true
EnableDnsHostnames: true
Tags:
- Key: Name
Value: !Ref EnvironmentName
- Key: AccountId
Value: !Ref "AWS::AccountId"
- Key: Region
Value: !Ref "AWS::Region"
- Key: StackName
Value: !Ref AWS::StackName
- Key: Course
Value: !Ref Course
- Key: ImplementationID
Value: !Ref ImplementationID
- Key: Learner
Value: !Ref Learner
- Key: Task
Value: !Ref Task
- Key: DeploymentType
Value: !Ref DeploymentType
InternetGateway:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: InternetGateway
- Key: Name
Value: !Ref EnvironmentName
- Key: AccountId
Value: !Ref "AWS::AccountId"
- Key: Region
Value: !Ref "AWS::Region"
- Key: StackName
Value: !Ref AWS::StackName
- Key: Course
Value: !Ref Course
- Key: ImplementationID
Value: !Ref ImplementationID
- Key: Learner
Value: !Ref Learner
- Key: Task
Value: !Ref Task
- Key: DeploymentType
Value: !Ref DeploymentType
InternetGatewayAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref SanteriVPC
InternetGatewayId: !Ref InternetGateway
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SanteriVPC
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PublicSubnet1CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Public Subnet (AZ1)
- Key: AccountId
Value: !Ref "AWS::AccountId"
- Key: Region
Value: !Ref "AWS::Region"
- Key: StackName
Value: !Ref AWS::StackName
- Key: Course
Value: !Ref Course
- Key: ImplementationID
Value: !Ref ImplementationID
- Key: Learner
Value: !Ref Learner
- Key: Task
Value: !Ref Task
- Key: DeploymentType
Value: !Ref DeploymentType
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SanteriVPC
AvailabilityZone: !Select [ 1, !GetAZs '' ]
CidrBlock: !Ref PublicSubnet2CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Public Subnet (AZ2)
- Key: AccountId
Value: !Ref "AWS::AccountId"
- Key: Region
Value: !Ref "AWS::Region"
- Key: StackName
Value: !Ref AWS::StackName
- Key: Course
Value: !Ref Course
- Key: ImplementationID
Value: !Ref ImplementationID
- Key: Learner
Value: !Ref Learner
- Key: Task
Value: !Ref Task
- Key: DeploymentType
Value: !Ref DeploymentType
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SanteriVPC
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PrivateSubnet1CIDR
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Private Subnet (AZ1)
- Key: AccountId
Value: !Ref "AWS::AccountId"
- Key: Region
Value: !Ref "AWS::Region"
- Key: StackName
Value: !Ref AWS::StackName
- Key: Course
Value: !Ref Course
- Key: ImplementationID
Value: !Ref ImplementationID
- Key: Learner
Value: !Ref Learner
- Key: Task
Value: !Ref Task
- Key: DeploymentType
Value: !Ref DeploymentType
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref SanteriVPC
AvailabilityZone: !Select [ 1, !GetAZs '' ]
CidrBlock: !Ref PrivateSubnet2CIDR
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Private Subnet (AZ2)
- Key: AccountId
Value: !Ref "AWS::AccountId"
- Key: Region
Value: !Ref "AWS::Region"
- Key: StackName
Value: !Ref AWS::StackName
- Key: Course
Value: !Ref Course
- Key: ImplementationID
Value: !Ref ImplementationID
- Key: Learner
Value: !Ref Learner
- Key: Task
Value: !Ref Task
- Key: DeploymentType
Value: !Ref DeploymentType
NatGateway1EIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
Domain: vpc
NatGateway2EIP:
Type: AWS::EC2::EIP
DependsOn: InternetGatewayAttachment
Properties:
Domain: vpc
NatGateway1:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGateway1EIP.AllocationId
SubnetId: !Ref PublicSubnet1
NatGateway2:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGateway2EIP.AllocationId
SubnetId: !Ref PublicSubnet2
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref SanteriVPC
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Public Routes
DefaultPublicRoute:
Type: AWS::EC2::Route
DependsOn: InternetGatewayAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet1
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet2
PrivateRouteTable1:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref SanteriVPC
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Private Routes (AZ1)
DefaultPrivateRoute1:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable1
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway1
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable1
SubnetId: !Ref PrivateSubnet1
PrivateRouteTable2:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref SanteriVPC
Tags:
- Key: Name
Value: !Sub ${EnvironmentName} Private Routes (AZ2)
DefaultPrivateRoute2:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable2
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NatGateway2
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable2
SubnetId: !Ref PrivateSubnet2
PublicNACL:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref SanteriVPC
Tags:
- Key: AccountId
Value: !Ref "AWS::AccountId"
- Key: Region
Value: !Ref "AWS::Region"
- Key: StackName
Value: !Ref AWS::StackName
- Key: Course
Value: !Ref Course
- Key: ImplementationID
Value: !Ref ImplementationID
- Key: Learner
Value: !Ref Learner
- Key: Task
Value: !Ref Task
- Key: DeploymentType
Value: !Ref DeploymentType
SSHRule:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PublicNACL
RuleNumber: 100
Protocol: 6
RuleAction: allow
CidrBlock: 0.0.0.0/0
PortRange:
From: 22
To: 22
HTTPSRule:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PublicNACL
RuleNumber: 110
Protocol: 6
RuleAction: allow
CidrBlock: 0.0.0.0/0
PortRange:
From: 443
To: 443
HTTPRule:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PublicNACL
RuleNumber: 120
Protocol: 6
RuleAction: allow
CidrBlock: 0.0.0.0/0
PortRange:
From: 80
To: 80
PublicSubnet1NACLAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PublicSubnet1
NetworkAclId: !Ref PublicNACL
PublicSubnet2NACLAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PublicSubnet2
NetworkAclId: !Ref PublicNACL
PrivateNACL:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref SanteriVPC
Tags:
- Key: AccountId
Value: !Ref "AWS::AccountId"
- Key: Region
Value: !Ref "AWS::Region"
- Key: StackName
Value: !Ref AWS::StackName
- Key: Course
Value: !Ref Course
- Key: ImplementationID
Value: !Ref ImplementationID
- Key: Learner
Value: !Ref Learner
- Key: Task
Value: !Ref Task
- Key: DeploymentType
Value: !Ref DeploymentType
PrivateSubnet1NACLAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PrivateSubnet1
NetworkAclId: !Ref PrivateNACL
PrivateSubnet2NACLAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PrivateSubnet2
NetworkAclId: !Ref PrivateNACL
PrivateSSHInbound:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PrivateNACL
RuleNumber: 100
Protocol: 6 # TCP
RuleAction: allow
CidrBlock: 10.25.36.0/22
PortRange:
From: 22
To: 22
Egress: false
PrivateHTTPSInbound:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PrivateNACL
RuleNumber: 110
Protocol: 6
RuleAction: allow
CidrBlock: 10.25.36.0/22
PortRange:
From: 443
To: 443
Egress: false
PrivateHTTPInbound:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PrivateNACL
RuleNumber: 120
Protocol: 6
RuleAction: allow
CidrBlock: 10.25.36.0/22
PortRange:
From: 80
To: 80
Egress: false
PrivateDenyAllInbound:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PrivateNACL
RuleNumber: 200
Protocol: -1
RuleAction: deny
CidrBlock: 0.0.0.0/0
Egress: false
PrivateAllowAllOutbound:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PrivateNACL
RuleNumber: 100
Protocol: -1
RuleAction: allow
CidrBlock: 0.0.0.0/0
Egress: true
NoIngressSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: "no-ingress-sg"
GroupDescription: "Security group with no ingress rule"
VpcId: !Ref SanteriVPC
Outputs:
VPC:
Description: A reference to the created VPC
Value: !Ref SanteriVPC
PublicSubnets:
Description: A list of the public subnets
Value: !Join [ ",", [ !Ref PublicSubnet1, !Ref PublicSubnet2 ]]
PrivateSubnets:
Description: A list of the private subnets
Value: !Join [ ",", [ !Ref PrivateSubnet1, !Ref PrivateSubnet2 ]]
PublicSubnet1:
Description: A reference to the public subnet in the 1st Availability Zone
Value: !Ref PublicSubnet1
PublicSubnet2:
Description: A reference to the public subnet in the 2nd Availability Zone
Value: !Ref PublicSubnet2
PrivateSubnet1:
Description: A reference to the private subnet in the 1st Availability Zone
Value: !Ref PrivateSubnet1
PrivateSubnet2:
Description: A reference to the private subnet in the 2nd Availability Zone
Value: !Ref PrivateSubnet2
NoIngressSecurityGroup:
Description: Security group with no ingress rule
Value: !Ref NoIngressSecurityGroup
This document may be copied and modified in accordance with the GNU General Public License (version 2 or later). http://www.gnu.org/licenses/gpl.html
- Based on Public Cloud Solution Architect course by Pekka Korpi-Tassi 2025.
- Project Prep Tasks.
Written by Santeri Vauramo 2025.