AWSTemplateFormatVersion: '2010-09-09'
Description: 'VPC 10.0.0.0/20 with Dual NAT Gateways for High Availability'

Resources:
  # 1. VPC 생성 (4,096개 IP)
  MainVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/20
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: ha-compact-vpc

  # 2. Internet Gateway 및 연결
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: ha-igw

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

  # 3. 서브넷 설계 (10.0.0.0/20 내 배치)
  # Public Subnets (ALB, NAT GW 위치)
  PublicSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MainVPC
      CidrBlock: 10.0.0.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: sbn-pub-a

  PublicSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MainVPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: sbn-pub-b

  # App Private Subnets (EC2, EKS Node) - /22로 넉넉히 할당
  AppPrivateSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MainVPC
      CidrBlock: 10.0.4.0/22
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Name
          Value: sbn-app-a

  AppPrivateSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MainVPC
      CidrBlock: 10.0.8.0/22
      AvailabilityZone: !Select [1, !GetAZs '']
      Tags:
        - Key: Name
          Value: sbn-app-b

  # DB Private Subnets (Isolated)
  DBPrivateSubnetA:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MainVPC
      CidrBlock: 10.0.12.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      Tags:
        - Key: Name
          Value: sbn-db-a

  DBPrivateSubnetB:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref MainVPC
      CidrBlock: 10.0.13.0/24
      AvailabilityZone: !Select [1, !GetAZs '']
      Tags:
        - Key: Name
          Value: sbn-db-b

  # 4. NAT Gateway 2개 및 탄력적 IP(EIP) 2개 생성
  # NAT GW A (AZ 1용)
  NatEipA:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGatewayA:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatEipA.AllocationId
      SubnetId: !Ref PublicSubnetA
      Tags:
        - Key: Name
          Value: nat-gw-a

  # NAT GW B (AZ 2용)
  NatEipB:
    Type: AWS::EC2::EIP
    Properties:
      Domain: vpc

  NatGatewayB:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatEipB.AllocationId
      SubnetId: !Ref PublicSubnetB
      Tags:
        - Key: Name
          Value: nat-gw-b

  # 5. 라우팅 테이블 설정
  # Public: IGW로 향함
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MainVPC
      Tags:
        - Key: Name
          Value: rtb-public

  PublicRoute:
    Type: AWS::EC2::Route
    DependsOn: AttachGateway
    Properties:
      RouteTableId: !Ref PublicRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  # App A: NAT GW A로 향함
  AppRouteTableA:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MainVPC
      Tags:
        - Key: Name
          Value: rtb-app-a

  AppRouteA:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref AppRouteTableA
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGatewayA

  # App B: NAT GW B로 향함
  AppRouteTableB:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MainVPC
      Tags:
        - Key: Name
          Value: rtb-app-b

  AppRouteB:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref AppRouteTableB
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGatewayB

  # DB: 외부 라우트 없음 (격리)
  DBRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref MainVPC
      Tags:
        - Key: Name
          Value: rtb-db-isolated

  # 6. 서브넷과 라우팅 테이블 연결
  PublicSubnetAAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetA
      RouteTableId: !Ref PublicRouteTable

  PublicSubnetBAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref PublicSubnetB
      RouteTableId: !Ref PublicRouteTable

  AppSubnetAAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref AppPrivateSubnetA
      RouteTableId: !Ref AppRouteTableA

  AppSubnetBAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref AppPrivateSubnetB
      RouteTableId: !Ref AppRouteTableB

  DBSubnetAAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref DBPrivateSubnetA
      RouteTableId: !Ref DBRouteTable

  DBSubnetBAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref DBPrivateSubnetB
      RouteTableId: !Ref DBRouteTable