AWSTemplateFormatVersion: "2010-09-09"
Description: >
  Broken Labs - VPC Lab 10.
  A web server is deployed with working IGW, route table, and security group, but the
  page won't load. The NACL outbound rule only permits port 80, blocking ephemeral port
  return traffic.
  Licensed under CC BY-NC-SA 4.0: https://creativecommons.org/licenses/by-nc-sa/4.0/
  Developed by: Mark Schoonover <mark.schoonover@gmail.com>

Resources:

  LabVPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: 10.0.0.0/16
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: brokenlabs-vpc-lab-10-vpc

  LabSubnet:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref LabVPC
      CidrBlock: 10.0.1.0/24
      AvailabilityZone: !Select [0, !GetAZs '']
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: brokenlabs-vpc-lab-10-subnet

  LabIGW:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: brokenlabs-vpc-lab-10-igw

  LabIGWAttach:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      VpcId: !Ref LabVPC
      InternetGatewayId: !Ref LabIGW

  LabRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref LabVPC
      Tags:
        - Key: Name
          Value: brokenlabs-vpc-lab-10-rt

  LabRoute:
    Type: AWS::EC2::Route
    DependsOn: LabIGWAttach
    Properties:
      RouteTableId: !Ref LabRouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref LabIGW

  LabSNAssoc:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref LabSubnet
      RouteTableId: !Ref LabRouteTable

  LabNACL:
    Type: AWS::EC2::NetworkAcl
    Properties:
      VpcId: !Ref LabVPC
      Tags:
        - Key: Name
          Value: brokenlabs-vpc-lab-10-nacl

  LabNACLSubnetAssoc:
    Type: AWS::EC2::SubnetNetworkAclAssociation
    Properties:
      SubnetId: !Ref LabSubnet
      NetworkAclId: !Ref LabNACL

  LabNACLInbound:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref LabNACL
      RuleNumber: 100
      Protocol: 6
      RuleAction: allow
      Egress: false
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 80
        To: 80

  LabNACLOutbound:
    Type: AWS::EC2::NetworkAclEntry
    Properties:
      NetworkAclId: !Ref LabNACL
      RuleNumber: 100
      Protocol: 6
      RuleAction: allow
      Egress: true
      CidrBlock: 0.0.0.0/0
      PortRange:
        From: 80
        To: 80  # THE BREAK: should include 1024-65535 for ephemeral port return traffic

  LabSG:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Broken Labs VPC Lab 10 security group
      VpcId: !Ref LabVPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: brokenlabs-vpc-lab-10-sg

  LabInstance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: t2.micro
      ImageId: "{{resolve:ssm:/aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64}}"
      SubnetId: !Ref LabSubnet
      SecurityGroupIds:
        - !Ref LabSG
      Tags:
        - Key: Name
          Value: brokenlabs-vpc-lab-10
      UserData:
        Fn::Base64: |
          #!/bin/bash
          mkdir -p /var/www/html
          cat > /var/www/html/index.html << 'HTMLEOF'
          <!DOCTYPE html>
          <html lang="en">
          <head>
            <meta charset="UTF-8" />
            <meta name="viewport" content="width=device-width, initial-scale=1.0" />
            <title>AWS Broken Labs</title>
            <style>
              * { box-sizing: border-box; margin: 0; padding: 0; }
              body {
                font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
                background: linear-gradient(to bottom, #1976D2, #1565C0);
                color: #e8eaed;
                display: flex;
                align-items: center;
                justify-content: center;
                min-height: 100vh;
              }
              .container { text-align: center; padding: 2rem; }
              .logo {
                font-size: 0.85rem;
                font-weight: 600;
                letter-spacing: 0.2em;
                text-transform: uppercase;
                color: #ff9900;
                margin-bottom: 1rem;
              }
              h1 { font-size: 2.5rem; font-weight: 700; color: #ffffff; margin-bottom: 0.5rem; }
              h2 { font-size: 1.2rem; font-weight: 400; color: #9aa0a6; }
              .badge {
                display: inline-block;
                margin-top: 2rem;
                padding: 0.4rem 1rem;
                border: 1px solid #ff9900;
                border-radius: 4px;
                font-size: 0.8rem;
                color: #ff9900;
                letter-spacing: 0.1em;
              }
              .site-link {
                display: block;
                margin-top: 1rem;
                font-size: 0.8rem;
                color: #ff9900;
                text-decoration: none;
                letter-spacing: 0.05em;
              }
              .site-link:hover { text-decoration: underline; }
            </style>
          </head>
          <body>
            <div class="container">
              <h2 class="logo">AWS Cloud Path Academy</h2>
              <h1>AWS Broken Labs</h1>
              <h2>If you can read this, the lab is fixed.</h2>
              <div class="badge">VPC Lab 10 &mdash; Network ACL</div>
              <a class="site-link" href="https://www.cloudpathacademy.com">www.cloudpathacademy.com</a>
            </div>
          </body>
          </html>
          HTMLEOF
          cat > /etc/systemd/system/lab-web.service << 'EOF'
          [Unit]
          Description=Lab Web Server

          [Service]
          ExecStart=/usr/bin/python3 -m http.server 80 --directory /var/www/html
          Restart=always

          [Install]
          WantedBy=multi-user.target
          EOF
          systemctl enable lab-web
          systemctl start lab-web

Outputs:

  InstancePublicIP:
    Description: Public IP address of the instance
    Value: !GetAtt LabInstance.PublicIp

  WebPageURL:
    Description: URL of the web page (will load once the lab is fixed)
    Value: !Sub "http://${LabInstance.PublicIp}/"
