AWS Cloud Formation (example 5)

Based on https://docs.aws.amazon.com/vpc/latest/userguide/VPC_Scenario2.html

  • VPC
  • Internet Gateway
  • NAT Gateway
  • Public Subnet
  • Private Subnet
  • Security Group
  • EC2

Cloud Formation template

AWSTemplateFormatVersion: 2010-09-09

Parameters:
  BastionKeyName:
    Description: The EC2 Key Pair to allow SSH access to the bastion
    Type: 'AWS::EC2::KeyPair::KeyName'
  InstanceKeyName:
    Description: The EC2 Key Pair to allow SSH access to the instance
    Type: 'AWS::EC2::KeyPair::KeyName'

Resources:

# VPC -----------------------------------------------------

  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
      - Key: Name
        Value:  !Join ['', [!Ref "AWS::StackName", "-vpc" ]]

# InternetGateway -----------------------------------------------------

  InternetGateway:
    Type: AWS::EC2::InternetGateway
    DependsOn: VPC
    Properties:
      Tags:
      - Key: Name
        Value:  !Join ['', [!Ref "AWS::StackName", "-ig" ]]

  AttachGateway:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway


# NATGateway -------------------------------------------------------

  ElasticIPAddress:
    Type: AWS::EC2::EIP
    Properties:
      Domain: VPC

  NATGateway:
    Type: AWS::EC2::NatGateway
    DependsOn: PublicSubnet
    Properties:
      AllocationId: !GetAtt ElasticIPAddress.AllocationId
      SubnetId: !Ref PublicSubnet
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-nat

# Subnet --------------------------------------------------------------

  PublicSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: !Select [ 0, !GetAZs ]
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-public

  PrivateSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [ 0, !GetAZs ]
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-private

# PublicRouteTable -------------------------------------------------------

  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-public
  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway
  PublicSubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnet
      RouteTableId: !Ref PublicRouteTable

# PrivateRouteTable -------------------------------------------------------

  PrivateRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-private
  PrivateRoute:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NATGateway
  PrivateSubnetARouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateSubnet
      RouteTableId: !Ref PrivateRouteTable

# SecurityGroup --------------------------------------------------------------------

  WebServerSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Web access
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-web
      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

  DBServerSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Instance access
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-db
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '1433'
        ToPort: '1433'
        "SourceSecurityGroupId": {
          "Fn::GetAtt": [
            "WebServerSecurityGroup",
            "GroupId"
          ]
        }
      - IpProtocol: tcp
        FromPort: '3306'
        ToPort: '3306'
        "SourceSecurityGroupId": {
          "Fn::GetAtt": [
            "WebServerSecurityGroup",
            "GroupId"
          ]
        }

# EC2 --------------------------------------------------------------------

  ElasticIPAddressWeb1:
    Type: AWS::EC2::EIP
    Properties:
      Domain: VPC
      InstanceId: !Ref Web1Ec2Instance

  ElasticIPAddressWeb2:
    Type: AWS::EC2::EIP
    Properties:
      Domain: VPC
      InstanceId: !Ref Web2Ec2Instance

  ElasticIPAddressWeb3:
    Type: AWS::EC2::EIP
    Properties:
      Domain: VPC
      InstanceId: !Ref Web3Ec2Instance

  Web1Ec2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      KeyName: !Ref InstanceKeyName
      ImageId: 'ami-035b3c7efe6d061d5'
      NetworkInterfaces:
      - AssociatePublicIpAddress: False
        DeviceIndex: "0"
        GroupSet:
        - !Ref WebServerSecurityGroup
        SubnetId:
          !Ref PublicSubnet
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-web-1

  Web2Ec2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      KeyName: !Ref InstanceKeyName
      ImageId: 'ami-035b3c7efe6d061d5'
      NetworkInterfaces:
      - AssociatePublicIpAddress: False
        DeviceIndex: "0"
        GroupSet:
        - !Ref WebServerSecurityGroup
        SubnetId:
          !Ref PublicSubnet
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-web-2

  Web3Ec2Instance:
    Type: 'AWS::EC2::Instance'
    Properties:
      KeyName: !Ref InstanceKeyName
      ImageId: 'ami-035b3c7efe6d061d5'
      NetworkInterfaces:
      - AssociatePublicIpAddress: False
        DeviceIndex: "0"
        GroupSet:
        - !Ref WebServerSecurityGroup
        SubnetId:
          !Ref PublicSubnet
      Tags:
      - Key: Name
        Value: !Sub ${AWS::StackName}-web-3