---
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Amazon Local EKS Sample VPC - Private subnet with VPC Endpoints'

Parameters:

  VpcBlock:
    Type: String
    Default: 192.168.0.0/16
    Description: The CIDR range for the VPC. This should be a valid private (RFC 1918) CIDR range.

  OutpostArn:
    Type: String
    Description: Outpost Arn 
    AllowedPattern: ^arn:aws:outposts:.+:.+:outpost\/.+

  OutpostAz:
    Type: String
    Description: Outpost Availability Zone
    AllowedPattern: ^.+

  PrivateOutpostSubnetBlock:
    Type: String
    Default: 192.168.0.0/18
    Description: CidrBlock for private outpost subnet within the VPC

  PrivateInRegionSubnetBlock:
    Type: String
    Default: 192.168.64.0/18
    Description: CidrBlock for private in-region subnet within the VPC for VPC Endpoints

Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      -
        Label:
          default: "Worker Network Configuration"
        Parameters:
          - VpcBlock
          - OutpostArn
          - OutpostAz
          - PrivateOutpostSubnetBlock
          - PrivateInRegionSubnetBlock

Resources:
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock:  !Ref VpcBlock
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
      - Key: Name
        Value: !Sub '${AWS::StackName}-VPC'

  PrivateOutpostRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
      - Key: Name
        Value: private-route-table
      - Key: Network
        Value: Private

  PrivateOutpostSubnet:
    Type: AWS::EC2::Subnet
    Metadata:
      Comment: Private Outpost Subnet for EKS local cluster
    Properties:
      AvailabilityZone: !Ref OutpostAz
      CidrBlock:
        Ref: PrivateOutpostSubnetBlock
      VpcId:
        Ref: VPC
      OutpostArn: !Ref OutpostArn
      Tags:
      - Key: Name
        Value: !Sub "${AWS::StackName}-PrivateOutpostSubnet"
    
  PrivateInRegionSubnet:
    Type: AWS::EC2::Subnet
    Metadata:
      Comment: Private In-region Subnet for EKS local cluster VPC Endpoints
    Properties:
      AvailabilityZone: !Ref OutpostAz
      CidrBlock:
        Ref: PrivateInRegionSubnetBlock
      VpcId:
        Ref: VPC
      Tags:
      - Key: Name
        Value: !Sub "${AWS::StackName}-PrivateInRegionSubnet"

  PrivateOutpostSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateOutpostSubnet
      RouteTableId: !Ref PrivateOutpostRouteTable

  PrivateInRegionSubnetRouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PrivateInRegionSubnet
      RouteTableId: !Ref PrivateOutpostRouteTable


  VPCESecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      GroupDescription: "Security group assigned to VPC Endpoints used in fully private local clusters"
      GroupName: !Sub "${AWS::StackName}-VPCESecurityGroup"
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 443
          ToPort: 443
          CidrIp: !Ref PrivateOutpostSubnetBlock

  SSMInterfaceEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssm"
      VpcId: !Ref VPC
      SubnetIds: 
        - !Ref PrivateInRegionSubnet
      SecurityGroupIds:
        - !Ref VPCESecurityGroup

  EC2MessagesInterfaceEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ec2messages"
      VpcId: !Ref VPC
      SubnetIds: 
        - !Ref PrivateInRegionSubnet
      SecurityGroupIds:
        - !Ref VPCESecurityGroup
  
  SSMMessagesInterfaceEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssmmessages"
      VpcId: !Ref VPC
      SubnetIds: 
        - !Ref PrivateInRegionSubnet
      SecurityGroupIds:
        - !Ref VPCESecurityGroup

  EC2InterfaceEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ec2"
      VpcId: !Ref VPC
      SubnetIds: 
        - !Ref PrivateInRegionSubnet
      SecurityGroupIds:
        - !Ref VPCESecurityGroup

  SecretsManagerInterfaceEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.secretsmanager"
      VpcId: !Ref VPC
      SubnetIds: 
        - !Ref PrivateInRegionSubnet
      SecurityGroupIds:
        - !Ref VPCESecurityGroup

  LogsInterfaceEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.logs"
      VpcId: !Ref VPC
      SubnetIds: 
        - !Ref PrivateInRegionSubnet
      SecurityGroupIds:
        - !Ref VPCESecurityGroup

  STSInterfaceEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.sts"
      VpcId: !Ref VPC
      SubnetIds: 
        - !Ref PrivateInRegionSubnet
      SecurityGroupIds:
        - !Ref VPCESecurityGroup

  EcrApiInterfaceEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.api"
      VpcId: !Ref VPC
      SubnetIds: 
        - !Ref PrivateInRegionSubnet
      SecurityGroupIds:
        - !Ref VPCESecurityGroup
  
  EcrDkrInterfaceEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Interface
      PrivateDnsEnabled: true
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.ecr.dkr"
      VpcId: !Ref VPC
      SubnetIds: 
        - !Ref PrivateInRegionSubnet
      SecurityGroupIds:
        - !Ref VPCESecurityGroup

  S3GatewayEndpoint:
    Type: 'AWS::EC2::VPCEndpoint'
    Properties:
      VpcEndpointType: Gateway
      ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3"
      VpcId: !Ref VPC
      RouteTableIds:
        - !Ref PrivateOutpostRouteTable

Outputs:

  PrivateInRegionSubnetId:
    Description: Private Subnet ID in the VPC
    Value: !Ref PrivateInRegionSubnet

  PrivateOutpostSubnetId:
    Description: Private Subnet ID in the VPC
    Value: !Ref PrivateOutpostSubnet

  VpcId:
    Description: The VPC Id
    Value: !Ref VPC

  VPCESecurityGroupId:
    Description: VPC Endpoints SecurityGroup Id
    Value: !Ref VPCESecurityGroup
