Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save jv199768/334fadd2a0d0c9414a01d5b14fa65bda to your computer and use it in GitHub Desktop.

Select an option

Save jv199768/334fadd2a0d0c9414a01d5b14fa65bda to your computer and use it in GitHub Desktop.
AWS Clod Formation Template for - Creating VPC, NAT Gateway, EIP, Public & Private Subnets, Route Tables, Internet Gateway, NACLs, Security Groups, EC2 Servers, Bastion, IAM Role, and IAM Policy.
# Author : Anvesh Muppeda
# Source Code: https://github.com/anveshmuppeda/aws
AWSTemplateFormatVersion: 2010-09-09
Description: AWS CFT for - Creating VPC, NAT Gateway, EIP, Public & Private Subnetes, Route Tables, Internet Gateway, NACLs, Security Groups, EC2 Servers, Bastion, IAM Role, and IAM Policy.
# Parameters for VPC configuration, instance settings, and resource tagging
Parameters:
myTag:
Description: Tag for the all resources
Type: String
Default: from-cft
VpcCIDR:
Description: Please enter the IP range (CIDR notation) for this VPC
Type: String
Default: 10.0.0.0/16
PublicSubnet1CIDR:
Description: Please enter the IP range (CIDR notation) for the public subnet in the first Availability Zone
Type: String
Default: 10.0.1.0/24
PublicSubnet2CIDR:
Description: Please enter the IP range (CIDR notation) for the public subnet in the second Availability Zone
Type: String
Default: 10.0.2.0/24
PrivateSubnet1CIDR:
Description: Please enter the IP range (CIDR notation) for the private subnet in the first Availability Zone
Type: String
Default: 10.0.3.0/24
PrivateSubnet2CIDR:
Description: Please enter the IP range (CIDR notation) for the private subnet in the second Availability Zone
Type: String
Default: 10.0.4.0/24
TypeOfInstance:
Description: "Specify the Instance Type."
Type: String
Default: t2.micro
AllowedValues:
- t2.nano
- t2.micro
- t2.small
AmiID:
Type: AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>
Description: "The ID of the AMI."
Default: /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2
KeyPairName:
Type: String
Description: The name of an existing Amazon EC2 key pair in this region to use to SSH into the Amazon EC2 instances.
Default: us-east-1
SecurityGroupSuffix:
Type: String
Description: Please enter the Security Group Suffix Name
Default: sg
Resources:
# VPC resource
MyVPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VpcCIDR
Tags:
- Key: Name
Value: MyCFT-Demo-VPC
- Key: myTag
Value: !Ref myTag
# IAM Role for EC2 instances to list S3 buckets
ListS3BucketsRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: '2012-10-17'
Statement:
- Effect: Allow
Principal:
Service:
- ec2.amazonaws.com
Action:
- sts:AssumeRole
Path: "/"
# IAM Policy to allow listing S3 buckets
ListS3BucketsPolicy:
Type: AWS::IAM::Policy
Properties:
PolicyName: ListS3BucketsPolicy
PolicyDocument:
Statement:
- Effect: Allow
Action:
- s3:List*
Resource: "*"
Roles:
- Ref: ListS3BucketsRole
ListS3BucketsInstanceProfile:
Type: AWS::IAM::InstanceProfile
Properties:
Path: "/"
Roles:
- Ref: ListS3BucketsRole
# Public subnet in the first availability zone
PublicSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PublicSubnet1CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: Public-1A
- Key: myTag
Value: !Ref myTag
# Public subnet in the second availability zone
PublicSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: !Select [ 1, !GetAZs '' ]
CidrBlock: !Ref PublicSubnet2CIDR
MapPublicIpOnLaunch: true
Tags:
- Key: Name
Value: Public-2A
- Key: myTag
Value: !Ref myTag
# Private subnet in the first availability zone
PrivateSubnet1:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: !Select [ 0, !GetAZs '' ]
CidrBlock: !Ref PrivateSubnet1CIDR
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: Private-1A
- Key: myTag
Value: !Ref myTag
# Private subnet in the second availability zone
PrivateSubnet2:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref MyVPC
AvailabilityZone: !Select [ 1, !GetAZs '' ]
CidrBlock: !Ref PrivateSubnet2CIDR
MapPublicIpOnLaunch: false
Tags:
- Key: Name
Value: Private-2A
- Key: myTag
Value: !Ref myTag
# Internet Gateway resource
MyIGW:
Type: AWS::EC2::InternetGateway
Properties:
Tags:
- Key: Name
Value: MyIGW
- Key: myTag
Value: !Ref myTag
# Attach Internet Gateway to the VPC
MyIGWAttachment:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
InternetGatewayId: !Ref MyIGW
VpcId: !Ref MyVPC
# Public Route Table
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: Public_RT
- Key: myTag
Value: !Ref myTag
# Route in Public Route Table to allow internet traffic
MainRouteTableIGWAttachement:
Type: AWS::EC2::Route
DependsOn: MyIGWAttachment
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref MyIGW
# Private Route Table
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: Private_RT
- Key: myTag
Value: !Ref myTag
# Associate Private Subnet 1 with Private Route Table
PrivateSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable
SubnetId: !Ref PrivateSubnet1
# Associate Private Subnet 2 with Private Route Table
PrivateSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PrivateRouteTable
SubnetId: !Ref PrivateSubnet2
# Elastic IP for NAT Gateway
NatGatewayEIP:
Type: AWS::EC2::EIP
DependsOn: MyIGWAttachment
Properties:
Domain: vpc
Tags:
- Key: Name
Value: MyEIP
- Key: myTag
Value: !Ref myTag
# NAT Gateway in Public Subnet 1
MyNatGateway:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt NatGatewayEIP.AllocationId
SubnetId: !Ref PublicSubnet1
# Route in Private Route Table to route traffic through NAT Gateway
PrivateRouteAssociateNAT:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref MyNatGateway
# Public Network ACL
MyPublicNACL:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: Public-Nacl
publicInboundRule:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: MyPublicNACL
RuleNumber: 100
Protocol: 6
RuleAction: allow
CidrBlock: 0.0.0.0/0
PortRange:
From: 22
To: 22
publicInboundRule2:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: MyPublicNACL
RuleNumber: 99
Protocol: -1
RuleAction: allow
CidrBlock: 0.0.0.0/0
OutboundRule:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: MyPublicNACL
RuleNumber: 100
Protocol: -1
Egress: true
RuleAction: allow
CidrBlock: 0.0.0.0/0
publicSubnet1NetworkAclAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId:
Ref: PublicSubnet1
NetworkAclId:
Ref: MyPublicNACL
publicSubnet2NetworkAclAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId:
Ref: PublicSubnet2
NetworkAclId:
Ref: MyPublicNACL
# Private Network ACL
MyPrivateNACL:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref MyVPC
Tags:
- Key: Name
Value: Private-Nacl
privateInboundRule:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: MyPrivateNACL
RuleNumber: 100
Protocol: 6
RuleAction: allow
CidrBlock: 10.0.1.0/24
PortRange:
From: 22
To: 22
privateInboundHTTPNACL:
Type: "AWS::EC2::NetworkAclEntry"
Properties:
NetworkAclId:
Ref: MyPrivateNACL
RuleNumber: 99
Protocol: "6"
RuleAction: "allow"
Egress: "false"
CidrBlock: "0.0.0.0/0"
PortRange:
From: '80'
To: '80'
privateInboundHTTPSNACL:
Type: "AWS::EC2::NetworkAclEntry"
Properties:
NetworkAclId:
Ref: MyPrivateNACL
RuleNumber: 98
Protocol: "6"
RuleAction: "allow"
Egress: "false"
CidrBlock: "0.0.0.0/0"
PortRange:
From: '443'
To: '443'
privateOutboundRule:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId:
Ref: MyPrivateNACL
RuleNumber: 100
Protocol: -1
Egress: true
RuleAction: allow
CidrBlock: 0.0.0.0/0
privateSubnet1NetworkAclAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId:
Ref: PrivateSubnet1
NetworkAclId:
Ref: MyPrivateNACL
privateSubnet2NetworkAclAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId:
Ref: PrivateSubnet2
NetworkAclId:
Ref: MyPrivateNACL
# Security Group for public instances
PublicSercuritGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Join ["-", [public, !Ref SecurityGroupSuffix]]
GroupDescription: "Allow HTTP/HTTPS and SSH inbound and outbound traffic"
VpcId: !Ref MyVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: public-security-group
- Key: myTag
Value: !Ref myTag
# Security Group for private instances
PrivateSercuritGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupName: !Join ["-", [private, !Ref SecurityGroupSuffix]]
GroupDescription: "Allow HTTP/HTTPS and SSH inbound and outbound traffic"
VpcId: !Ref MyVPC
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 80
ToPort: 80
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
- IpProtocol: tcp
FromPort: 22
ToPort: 22
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: private-security-group
- Key: myTag
Value: !Ref myTag
PublicSubnet1RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet1
PublicSubnet2RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref PublicRouteTable
SubnetId: !Ref PublicSubnet2
# Bastion Server in public subnet 1
MyBastionServer:
Type: AWS::EC2::Instance
DependsOn: PublicSercuritGroup
Properties:
SubnetId: !Ref PublicSubnet1
ImageId: !Ref AmiID
InstanceType: !Ref TypeOfInstance
KeyName: !Ref KeyPairName
SecurityGroupIds:
- !Ref PublicSercuritGroup
IamInstanceProfile:
Ref: ListS3BucketsInstanceProfile
Tags:
- Key: Name
Value: bastion
- Key: myTag
Value: !Ref myTag
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
yum update -y
yum install -y httpd.x86_64
systemctl start httpd.service
systemctl enable httpd.service
echo "Hello this is from Bastion Server, i.e., Public Subnet 1" > /var/www/html/index.html
# EC2 instance in private subnet 1
MyPrivateServer1:
Type: AWS::EC2::Instance
DependsOn: PrivateSercuritGroup
Properties:
SubnetId: !Ref PrivateSubnet1
ImageId: !Ref AmiID
InstanceType: !Ref TypeOfInstance
KeyName: !Ref KeyPairName
IamInstanceProfile:
Ref: ListS3BucketsInstanceProfile
SecurityGroupIds:
- !Ref PrivateSercuritGroup
Tags:
- Key: Name
Value: private1
- Key: myTag
Value: !Ref myTag
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
yum update -y
yum install -y httpd.x86_64
systemctl start httpd.service
systemctl enable httpd.service
echo "Hello this is from Private Server, i.e., Private Subnete 1" > /var/www/html/index.html
yum update -y
yum install python3
# EC2 instance in public subnet 2
MyPublicServer:
Type: AWS::EC2::Instance
DependsOn: PublicSercuritGroup
Properties:
SubnetId: !Ref PublicSubnet2
ImageId: !Ref AmiID
InstanceType: !Ref TypeOfInstance
KeyName: !Ref KeyPairName
SecurityGroupIds:
- !Ref PublicSercuritGroup
Tags:
- Key: Name
Value: public2
- Key: myTag
Value: !Ref myTag
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
yum update -y
yum install -y httpd.x86_64
systemctl start httpd.service
systemctl enable httpd.service
echo "Hello this is from Public Server, i.e., Public Subnet 2" > /var/www/html/index.html
# EC2 instance in private subnet 1
MyPrivateServer2:
Type: AWS::EC2::Instance
DependsOn: PrivateSercuritGroup
Properties:
SubnetId: !Ref PrivateSubnet2
ImageId: !Ref AmiID
InstanceType: !Ref TypeOfInstance
KeyName: !Ref KeyPairName
SecurityGroupIds:
- !Ref PrivateSercuritGroup
Tags:
- Key: Name
Value: private2
- Key: myTag
Value: !Ref myTag
UserData:
Fn::Base64:
!Sub |
#!/bin/bash
yum update -y
yum install -y httpd.x86_64
systemctl start httpd.service
systemctl enable httpd.service
echo "Hello this is from Private Server, i.e., Private Subnete 2" > /var/www/html/index.html
yum install mysql-community-server
yum install mysql-community-libs
systemctl start mysqld
# Outputs for VPC, subnets, and EC2 instances
Outputs:
VpcId:
Description: VPC ID of the newly created VPC
Value: !Ref MyVPC
PrivateServer1InstanceId:
Description: InstanceId of the Bastion Server
Value: !Ref 'MyPrivateServer1'
PrivateServer2InstanceId:
Description: InstanceId of the Bastion Server
Value: !Ref 'MyPrivateServer2'
BastionInstanceId:
Description: InstanceId of the Bastion Server
Value: !Ref 'MyBastionServer'
BastionPublicIP:
Description: Public IP address of the Bastion Server
Value: !Join
- ''
- - 'http://'
- !GetAtt
- MyBastionServer
- PublicIp
PublicInstanceId:
Description: InstanceId of the Public Server
Value: !Ref 'MyPublicServer'
PublicServerPublicIP:
Description: Public IP address of the Public Server
Value: !Join
- ''
- - 'http://'
- !GetAtt
- MyPublicServer
- PublicIp
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment