-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # 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