" Default: "/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64" Resources: #VPC VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${EnvironmentName}-vpc #InternetGateway InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub ${EnvironmentName}-igw InternetGatewayAttac"> " Default: "/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64" Resources: #VPC VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${EnvironmentName}-vpc #InternetGateway InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub ${EnvironmentName}-igw InternetGatewayAttac"> " Default: "/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64" Resources: #VPC VPC: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCIDR EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Sub ${EnvironmentName}-vpc #InternetGateway InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub ${EnvironmentName}-igw InternetGatewayAttac">
Description: 2Subnet-1AZ

Parameters:
  EnvironmentName:
    Description: prefixed to resource names
    Type: String
    Default: "wsi"

  VpcCIDR:
    Description: VPC-CIDR
    Type: String
    Default: 10.0.0.0/16

  PublicSubnet1CIDR:
    Description: Public1-CIDR
    Type: String
    Default: 10.0.0.0/24

  PrivateSubnet1CIDR:
    Description: Private1-CIDR
    Type: String
    Default: 10.0.1.0/24

  LatestAmiId:
    Type: "AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>"
    Default: "/aws/service/ami-amazon-linux-latest/al2023-ami-minimal-kernel-default-x86_64"

Resources:
  #VPC
  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock: !Ref VpcCIDR
      EnableDnsSupport: true
      EnableDnsHostnames: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-vpc

  #InternetGateway
  InternetGateway:
    Type: AWS::EC2::InternetGateway
    Properties:
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-igw

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

  #Subnet
  #Public Subnet
  PublicSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs ""]
      CidrBlock: !Ref PublicSubnet1CIDR
      MapPublicIpOnLaunch: true
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-a

  #Private Subnet
  PrivateSubnet1:
    Type: AWS::EC2::Subnet
    Properties:
      VpcId: !Ref VPC
      AvailabilityZone: !Select [0, !GetAZs ""]
      CidrBlock: !Ref PrivateSubnet1CIDR
      MapPublicIpOnLaunch: false
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-private-a

  #NatGateway
  NatGateway1EIP:
    Type: AWS::EC2::EIP
    DependsOn: InternetGatewayAttachment
    Properties:
      Domain: vpc

  NatGateway1:
    Type: AWS::EC2::NatGateway
    Properties:
      AllocationId: !GetAtt NatGateway1EIP.AllocationId
      SubnetId: !Ref PublicSubnet1
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-nat-a

  #RouteTable
  #Public Route Table
  PublicRouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-public-rt

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

  PublicSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PublicRouteTable
      SubnetId: !Ref PublicSubnet1

  PrivateRouteTable1:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-private-a-rt

  #Private Route Table
  DefaultPrivateRoute1:
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      DestinationCidrBlock: 0.0.0.0/0
      NatGatewayId: !Ref NatGateway1

  PrivateSubnet1RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      RouteTableId: !Ref PrivateRouteTable1
      SubnetId: !Ref PrivateSubnet1

  #KeyPair
  KeyPair:
    Type: AWS::EC2::KeyPair
    Properties:
      KeyName: !Sub ${EnvironmentName}
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}

  #Public EC2
  BastionInstance:
    Type: "AWS::EC2::Instance"
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t3.small
      SecurityGroupIds:
        - !Ref BastionSecurityGroup
      SubnetId: !Ref PublicSubnet1
      KeyName: !Ref KeyPair
      IamInstanceProfile: !Ref AdminInstanceProfile
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum update -y
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-bastion-ec2

  #private EC2
  PirvateEC2Instance:
    Type: "AWS::EC2::Instance"
    Properties:
      ImageId: !Ref LatestAmiId
      InstanceType: t3.small
      SecurityGroupIds:
        - !Ref PrivateEC2SecurityGroup
      SubnetId: !Ref PrivateSubnet1
      KeyName: !Ref KeyPair
      IamInstanceProfile: !Ref AdminInstanceProfile
      UserData:
        Fn::Base64: !Sub |
          #!/bin/bash
          yum update -y
          yum install -y httpd
          service httpd start
          echo $(hostname -I) > /var/www/html/ip.html
          echo "Index Page" > /var/www/html/index.html
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-server

  #Public Security Group
  BastionSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: ${EnvironmentName}-bastion-sg
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 22
          ToPort: 22
          CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-bastion-sg

  #private Security Group
  PrivateEC2SecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: !Sub ${EnvironmentName}-server-sg
      VpcId: !Ref VPC
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: 80
          ToPort: 80
          CidrIp: 0.0.0.0/0
      SecurityGroupEgress:
        - IpProtocol: -1
          CidrIp: 0.0.0.0/0
      Tags:
        - Key: Name
          Value: !Sub ${EnvironmentName}-server-sg

  #IAM
  AdminIAMRole:
    Type: AWS::IAM::Role
    DeletionPolicy: Retain
    Properties:
      RoleName: !Sub ${EnvironmentName}-admin-role
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: "Allow"
            Principal:
              Service:
                - "ec2.amazonaws.com"
            Action:
              - "sts:AssumeRole"
      Path: "/"
      ManagedPolicyArns:
        - "arn:aws:iam::aws:policy/AdministratorAccess"

  AdminInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles:
        - !Ref "AdminIAMRole"

Outputs:
  VPC:
    Description: "VPC"
    Value: !Ref VPC
    Export:
      Name:
        "Fn::Sub": "${AWS::StackName}-VPC"

  PublicSubnets:
    Description: A list of the public subnets
    Value: !Join [",", [!Ref PublicSubnet1]]

  PrivateSubnets:
    Description: A list of the private subnets
    Value: !Join [",", [!Ref PrivateSubnet1]]

  PublicSubnet1:
    Description: "Public Subnet AZ a"
    Value: !Ref PublicSubnet1
    Export:
      Name:
        "Fn::Sub": "${AWS::StackName}-public-a"

  PrivateSubnet1:
    Description: "Private Subnet AZ a"
    Value: !Ref PrivateSubnet1
    Export:
      Name:
        "Fn::Sub": "${AWS::StackName}-private-a"

  BastionInstance:
    Description: "bastion Instance"
    Value: !Ref BastionInstance
    Export:
      Name:
        "Fn::Sub": "${AWS::StackName}-bastion-Instance"

  PirvateEC2Instance:
    Description: "private Instance"
    Value: !Ref PirvateEC2Instance
    Export:
      Name:
        "Fn::Sub": "${AWS::StackName}-private-Instance"

  BastionSecurityGroup:
    Description: "bastion Group"
    Value: !Ref BastionSecurityGroup
    Export:
      Name:
        "Fn::Sub": "${AWS::StackName}-bastion-sg"

  PrivateEC2SecurityGroup:
    Description: "private Group"
    Value: !Ref PrivateEC2SecurityGroup
    Export:
      Name:
        "Fn::Sub": "${AWS::StackName}-server-sg"

  AdminIAMRole:
    Description: "Private Instance"
    Value: !GetAtt AdminIAMRole.Arn
    Export:
      Name:
        "Fn::Sub": "${AWS::StackName}-admin-role"