
Description:  SM_STUDIO Hybrid DNS Demo -  ON PREMISES
Parameters:
  LatestAmiId:
    Description: AMI for EC2 instances (default = AmaLinux Latest)
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
  LatestWinAmiId:
    Description: WIN AMI for EC2 instances (default = AmaLinux Latest)
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-windows-latest/Windows_Server-2016-English-Full-Base'
  EC2KeyPair:
    Description: EC2 Key pair
    Type: AWS::EC2::KeyPair::KeyName
    Default: 'ec2-kp'
Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 192.168.10.0/24
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: STUDIO-onprem
  SubnetPRIVATEA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      CidrBlock: 192.168.10.0/26
      Tags:
        - Key: Name
          Value: sn-onprem-A
  RouteTablePrivate: 
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref VPC
      Tags:
      - Key: Name
        Value: STUDIO-ONPREM-RT
  SubnetPRIVATEB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 1, !GetAZs '' ]
      CidrBlock: 192.168.10.64/26
      Tags:
        - Key: Name
          Value: sn-onprem-B
  RouteTableAssociationPrivateA:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref SubnetPRIVATEA
      RouteTableId: !Ref RouteTablePrivate
  RouteTableAssociationPrivateB:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref SubnetPRIVATEB
      RouteTableId: !Ref RouteTablePrivate


  SubnetPUBLICA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 0, !GetAZs '' ]
      CidrBlock: 192.168.10.128/26
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: sn-onprem-public-A
  RouteTablePublic: 
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref VPC
      Tags:
      - Key: Name
        Value: STUDIO-ONPREM-PUBLIC-RT
  SubnetPUBLICB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [ 1, !GetAZs '' ]
      CidrBlock: 192.168.10.192/26
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: sn-onprem-public-B
  RouteTableAssociationPublicA:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref SubnetPUBLICA
      RouteTableId: !Ref RouteTablePublic
  RouteTableAssociationPublicB:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref SubnetPUBLICB
      RouteTableId: !Ref RouteTablePublic
## INTERNET GATEWAY
  InternetGateway:
    Type: AWS::EC2::InternetGateway
  
  GatewayToInternet:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref VPC
      InternetGatewayId: !Ref InternetGateway
  
  ## PUBLIC ROUTING
  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: GatewayToInternet
    Properties:
      RouteTableId: !Ref RouteTablePublic
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  ONPREMSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Enable SSH and DNS
      SecurityGroupIngress: 
        - Description: 'Allow SSH IPv4 IN'
          IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: '0.0.0.0/0'
        - Description: 'Allow HTTP IPv4 IN'
          IpProtocol: tcp
          FromPort: '80'
          ToPort: '80'
          CidrIp: '0.0.0.0/0'
        - Description: 'Allow DNS IN'
          IpProtocol: -1
          FromPort: '53'
          ToPort: '53'
          CidrIp: '0.0.0.0/0'
        - IpProtocol: icmp
          FromPort: -1
          ToPort: -1
          CidrIp: '0.0.0.0/0'
  ONPREMWINSecurityGroup:
    Type: 'AWS::EC2::SecurityGroup'
    Properties:
      VpcId: !Ref VPC
      GroupDescription: Enable RDP
      SecurityGroupIngress: 
        - Description: 'Allow RDP IN'
          IpProtocol: tcp
          FromPort: '3389'
          ToPort: '3389'
          CidrIp: '0.0.0.0/0'
  DefaultInstanceSecurityGroupSelfReferenceRule:
    Type: "AWS::EC2::SecurityGroupIngress"
    Properties:
      GroupId: !Ref ONPREMSecurityGroup
      IpProtocol: 'tcp'
      FromPort: '0'
      ToPort: '65535'
      SourceSecurityGroupId: !Ref ONPREMSecurityGroup
  DNSA:
    Type: AWS::EC2::Instance
    DependsOn: 
      - ssminterfaceendpoint
      - ssmec2messagesinterfaceendpoint
      - ssmmessagesinterfaceendpoint
    Properties:
      InstanceType: "t2.micro"
      ImageId: !Ref LatestAmiId
      IamInstanceProfile: !Ref EC2InstanceProfile
      SubnetId: !Ref SubnetPRIVATEA
      SecurityGroupIds: 
        - !Ref ONPREMSecurityGroup
      Tags:
        - Key: Name
          Value: STUDIO-ONPREM-DNSA
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          yum update -y
          yum install bind bind-utils -y
          cat <<EOF > /etc/named.conf
          options {
            directory	"/var/named";
            dump-file	"/var/named/data/cache_dump.db";
            statistics-file "/var/named/data/named_stats.txt";
            memstatistics-file "/var/named/data/named_mem_stats.txt";
            allow-query { any; };
            allow-transfer     { localhost; ${DNSB.PrivateIp}; };
            recursion yes;
            forward first;
            forwarders {
              192.168.10.2;
            };
            dnssec-enable yes;
            dnssec-validation yes;
            dnssec-lookaside auto;
            /* Path to ISC DLV key */
            bindkeys-file "/etc/named.iscdlv.key";
            managed-keys-directory "/var/named/dynamic";
          };
          zone "corp.bigshoecorp.org" IN {
              type master;
              file "corp.bigshoecorp.org.zone";
              allow-update { none; };
          };
          EOF
          cat <<EOF > /var/named/corp.bigshoecorp.org.zone
          \$TTL 86400
          @   IN  SOA     ns1.mydomain.com. root.mydomain.com. (
                  2013042201  ;Serial
                  3600        ;Refresh
                  1800        ;Retry
                  604800      ;Expire
                  86400       ;Minimum TTL
          )
          ; Specify our two nameservers
              IN	NS		dnsA.corp.bigshoecorp.org.
              IN	NS		dnsB.corp.bigshoecorp.org.
          ; Resolve nameserver hostnames to IP, replace with your two droplet IP addresses.
          dnsA		IN	A		1.1.1.1
          dnsB	  IN	A		8.8.8.8

          ; Define hostname -> IP pairs which you wish to resolve
          @		  IN	A		${APP.PrivateIp}
          app		IN	A	  ${APP.PrivateIp}
          EOF
          service named restart
          chkconfig named on
  DNSB:
    Type: AWS::EC2::Instance
    DependsOn: 
      - ssminterfaceendpoint
      - ssmec2messagesinterfaceendpoint
      - ssmmessagesinterfaceendpoint
    Properties:
      InstanceType: "t2.micro"
      ImageId: !Ref LatestAmiId
      IamInstanceProfile: !Ref EC2InstanceProfile
      SubnetId: !Ref SubnetPRIVATEB
      SecurityGroupIds: 
        - !Ref ONPREMSecurityGroup
      Tags:
        - Key: Name
          Value: STUDIO-ONPREM-DNSB
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash -xe
          yum update -y
          yum install bind bind-utils -y
          cat <<EOF > /etc/named.conf
          options {
            directory	"/var/named";
            dump-file	"/var/named/data/cache_dump.db";
            statistics-file "/var/named/data/named_stats.txt";
            memstatistics-file "/var/named/data/named_mem_stats.txt";
            allow-query { any; };
            recursion yes;
            forward first;
            forwarders {
              192.168.10.2;
            };
            dnssec-enable yes;
            dnssec-validation yes;
            dnssec-lookaside auto;
            /* Path to ISC DLV key */
            bindkeys-file "/etc/named.iscdlv.key";
            managed-keys-directory "/var/named/dynamic";
          };
          zone "corp.bigshoecorp.org" IN {
              type master;
              file "corp.bigshoecorp.org.zone";
              allow-update { none; };
          };
          EOF
          cat <<EOF > /var/named/corp.bigshoecorp.org.zone
          \$TTL 86400
          @   IN  SOA     ns1.mydomain.com. root.mydomain.com. (
                  2013042201  ;Serial
                  3600        ;Refresh
                  1800        ;Retry
                  604800      ;Expire
                  86400       ;Minimum TTL
          )
          ; Specify our two nameservers
              IN	NS		dnsA.corp.bigshoecorp.org.
              IN	NS		dnsB.corp.bigshoecorp.org.
          ; Resolve nameserver hostnames to IP, replace with your two droplet IP addresses.
          dnsA		IN	A		1.1.1.1
          dnsB	  IN	A		8.8.8.8

          ; Define hostname -> IP pairs which you wish to resolve
          @		  IN	A		${APP.PrivateIp}
          app		IN	A	  ${APP.PrivateIp}
          EOF
          service named restart
          chkconfig named on
  APP:
    Type: AWS::EC2::Instance
    DependsOn: 
      - ssminterfaceendpoint
      - ssmec2messagesinterfaceendpoint
      - ssmmessagesinterfaceendpoint
    Properties:
      InstanceType: "t2.micro"
      ImageId: !Ref LatestAmiId
      IamInstanceProfile: !Ref EC2InstanceProfile
      SubnetId: !Ref SubnetPRIVATEB
      SecurityGroupIds: 
        - !Ref ONPREMSecurityGroup
      Tags:
        - Key: Name
          Value: STUDIO-ONPREM-APP
  WINAPP:
    Type: AWS::EC2::Instance
    DependsOn: 
      - ssminterfaceendpoint
      - ssmec2messagesinterfaceendpoint
      - ssmmessagesinterfaceendpoint
    Properties:
      InstanceType: "t2.small"
      ImageId: !Ref LatestWinAmiId
      IamInstanceProfile: !Ref EC2InstanceProfile
      SubnetId: !Ref SubnetPUBLICB
      KeyName: !Ref EC2KeyPair
      SecurityGroupIds: 
        - !Ref ONPREMWINSecurityGroup
      Tags:
        - Key: Name
          Value: STUDIO-ONPREM-WINAPP
  EC2Role:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
              - ec2.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: root
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action: 
                  - 'ssm:DescribeAssociation'
                  - 'ssm:GetDeployablePatchSnapshotForInstance'
                  - 'ssm:GetDocument'
                  - 'ssm:DescribeDocument'
                  - 'ssm:GetManifest'
                  - 'ssm:GetParameter'
                  - 'ssm:GetParameters'
                  - 'ssm:ListAssociations'
                  - 'ssm:ListInstanceAssociations'
                  - 'ssm:PutInventory'
                  - 'ssm:PutComplianceItems'
                  - 'ssm:PutConfigurePackageResult'
                  - 'ssm:UpdateAssociationStatus'
                  - 'ssm:UpdateInstanceAssociationStatus'
                  - 'ssm:UpdateInstanceInformation'
                Resource: '*'
              - Effect: Allow
                Action:
                  - 'ssmmessages:CreateControlChannel'
                  - 'ssmmessages:CreateDataChannel'
                  - 'ssmmessages:OpenControlChannel'
                  - 'ssmmessages:OpenDataChannel' 
                Resource: '*'
              - Effect: Allow
                Action: 
                  - 'ec2messages:AcknowledgeMessage'
                  - 'ec2messages:DeleteMessage'
                  - 'ec2messages:FailMessage'
                  - 'ec2messages:GetEndpoint'
                  - 'ec2messages:GetMessages'
                  - 'ec2messages:SendReply'
                Resource: '*'
              - Effect: Allow
                Action: 
                  - 's3:*'
                Resource: '*'
  EC2InstanceProfile:
    Type: 'AWS::IAM::InstanceProfile'
    Properties:
      Path: /
      Roles:
        - !Ref EC2Role
  ssminterfaceendpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcEndpointType: "Interface"
      PrivateDnsEnabled: "True"
      SubnetIds:
        - !Ref SubnetPRIVATEA
        - !Ref SubnetPRIVATEB
      SecurityGroupIds:
        - !Ref ONPREMSecurityGroup
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ssm
      VpcId: !Ref VPC
  ssmec2messagesinterfaceendpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcEndpointType: "Interface"
      PrivateDnsEnabled: "True"
      SubnetIds:
        - !Ref SubnetPRIVATEA
        - !Ref SubnetPRIVATEB
      SecurityGroupIds:
        - !Ref ONPREMSecurityGroup
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ec2messages
      VpcId: !Ref VPC
  ssmmessagesinterfaceendpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      VpcEndpointType: "Interface"
      PrivateDnsEnabled: "True"
      SubnetIds:
        - !Ref SubnetPRIVATEA
        - !Ref SubnetPRIVATEB
      SecurityGroupIds:
        - !Ref ONPREMSecurityGroup
      ServiceName: !Sub com.amazonaws.${AWS::Region}.ssmmessages
      VpcId: !Ref VPC
  s3endpoint:
    Type: AWS::EC2::VPCEndpoint
    Properties:
      RouteTableIds:
        - !Ref RouteTablePrivate
      ServiceName: !Sub com.amazonaws.${AWS::Region}.s3
      VpcId: !Ref VPC





