Arm-Architecture/cfn-templates/open5gs-infra.yaml [1:753]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AWSTemplateFormatVersion: 2010-09-09
Description: >-
  A new VPC creation for EKS LandingZone. VPC, IGW, NATGW, 2 Public Subnets, 2 Private Subnets (each per AZ) and 3 route tables get created

Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: VPC Configuration
        Parameters:
          - VpcCidr
          - AvailabilityZones
          - PublicSubnetAz1Cidr
          - PublicSubnetAz2Cidr
          - PrivateSubnetAz1Cidr
          - PrivateSubnetAz2Cidr
      - Label:
          default: Control UserPlane Network
        Parameters:
          - MultusSubnet1Az1Cidr
          - MultusSubnet1Az2Cidr
          - MultusSubnet2Az1Cidr
          - MultusSubnet2Az2Cidr
      - Label:
          default: Bastion Configuration
        Parameters:
          - BastionInstanceType
          - BastionKeyPairName
          - LatestAmiId
      - Label:
          default: DocumentDB (MongoDB) Configuration
        Parameters:
          - MasterUserName
          - MasterUserPassword
          - DBInstanceClass

Parameters:
  AvailabilityZones:
    Description: List of Availability Zones to use for the subnets in the VPC. Select 2 of them.
    Type: List<AWS::EC2::AvailabilityZone::Name>
  VpcCidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.0.0/16
    Description: CIDR block for the VPC.
    Type: String
  PublicSubnetAz1Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.0.0/24
    Description: CIDR block for the Public Subnet in AZ1.
    Type: String
  PublicSubnetAz2Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.1.0/24
    Description: CIDR block for the Public Subnet in AZ2.
    Type: String
  PrivateSubnetAz1Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.2.0/24
    Description: CIDR block for the Private Subnet in AZ1. This will be used for the main K8s network.
    Type: String
  PrivateSubnetAz2Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.3.0/24
    Description: CIDR block for the Private Subnet in AZ2. This will be used for the main K8s network.
    Type: String
  MultusSubnet1Az1Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.4.0/24
    Description: CIDR block for the Private Subnet in AZ1. This will be used for Control Plane.
    Type: String
  MultusSubnet1Az2Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.5.0/24
    Description: CIDR block for the Private Subnet in AZ2. This will be used for Control Plane.
    Type: String
  MultusSubnet2Az1Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.6.0/24
    Description: CIDR block for the Private Subnet in AZ1. This will be used for User Plane.
    Type: String
  MultusSubnet2Az2Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.7.0/24
    Description: CIDR block for the Private Subnet in AZ2. This will be used for User Plane.
    Type: String
  BastionKeyPairName:
    Description: Name of an existing key pair, which allows you
      to securely connect to your instance after it launches.
    Type: AWS::EC2::KeyPair::KeyName
  BastionInstanceType:
    Type: String
    Default: t3.medium
    Description : Instance type for a bastion host.
    AllowedValues:
      - t2.small
      - t2.medium
      - t2.large
      - t3.small
      - t3.medium
      - t3.large
  DBInstanceClass:
    Default: "db.t3.medium"
    Description : "Instance class. Please refer to: https://docs.aws.amazon.com/documentdb/latest/developerguide/db-instance-classes.html#db-instance-classes-by-region"
    Type: "String"
    AllowedValues:
      - db.t3.medium
      - db.r5.large
      - db.r5.xlarge
      - db.r5.2xlarge
      - db.r5.4xlarge
      - db.r5.12xlarge
      - db.r5.24xlarge
    ConstraintDescription : "Instance type must be of the ones supported for the region. Please refer to: https://docs.aws.amazon.com/documentdb/latest/developerguide/db-instance-classes.html#db-instance-classes-by-region"
  LatestAmiId:
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
  MasterUserName:
    Type: "String"
    MinLength: "1"
    MaxLength: "16"
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
    ConstraintDescription : "Must begin with a letter and contain only alphanumeric characters."
  MasterUserPassword:
    NoEcho: "true"
    Description : "The database admin account password"
    Type: "String"
    MinLength: "1"
    MaxLength: "41"
    AllowedPattern : "^[a-zA-Z0-9]*$"
    ConstraintDescription : "must contain only alphanumeric characters."

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

  ### IGW for the VPC
  EpcVpcIgw:
    Type: 'AWS::EC2::InternetGateway'
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "igw-${AWS::StackName}"
  EpcVpcIgwAattach:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref EpcVpc
      InternetGatewayId: !Ref EpcVpcIgw


  #### Subnet-Public #####
  PublicSubnetAz1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref PublicSubnetAz1Cidr
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      Tags:
        - Key: kubernetes.io/role/elb
          Value: 1
        - Key: Name
          Value: !Sub "publicAz1-${AWS::StackName}"
  PublicSubnetAz2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref PublicSubnetAz2Cidr
      AvailabilityZone: !Select ['1', !Ref AvailabilityZones]
      Tags:
        - Key: kubernetes.io/role/elb
          Value: 1
        - Key: Name
          Value: !Sub "publicAz2-${AWS::StackName}"
  PublicSubnetRt:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref EpcVpc
      Tags:
        - Key: Name
          Value: !Sub "publicSubnetRt-${AWS::StackName}"
  PublicRtDfltRt:
    Type: 'AWS::EC2::Route'
    DependsOn: EpcVpcIgwAattach
    Properties:
      RouteTableId: !Ref PublicSubnetRt
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref EpcVpcIgw
  PublicAz1RtAssoc:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PublicSubnetAz1
      RouteTableId: !Ref PublicSubnetRt
  PublicAz2RtAssoc:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PublicSubnetAz2
      RouteTableId: !Ref PublicSubnetRt

  ### NATGWs for the VPC
  EipNatGwAz1:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: EpcVpc
  NatGatewayAz1:
    Type: 'AWS::EC2::NatGateway'
    Properties:
      AllocationId: !GetAtt 'EipNatGwAz1.AllocationId'
      SubnetId: !Ref PublicSubnetAz1
      Tags:
        - Key: Name
          Value: !Sub "natGwAz1-${AWS::StackName}"

  EipNatGwAz2:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: EpcVpc
  NatGatewayAz2:
    Type: 'AWS::EC2::NatGateway'
    Properties:
      AllocationId: !GetAtt 'EipNatGwAz2.AllocationId'
      SubnetId: !Ref PublicSubnetAz2
      Tags:
        - Key: Name
          Value: !Sub "natGwAz2-${AWS::StackName}"


  #### Subnet-Private #####
  PrivateSubnetAz1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref PrivateSubnetAz1Cidr
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      Tags:
        - Key: kubernetes.io/role/internal-elb
          Value: 1
        - Key: Name
          Value: !Sub "privateAz1-${AWS::StackName}"
  PrivateSubnetAz2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref PrivateSubnetAz2Cidr
      AvailabilityZone: !Select ['1', !Ref AvailabilityZones]
      Tags:
        - Key: kubernetes.io/role/internal-elb
          Value: 1
        - Key: Name
          Value: !Sub "privateAz2-${AWS::StackName}"

  ### Subnet Route Table for Private Subnets
  PrivateAz1SubnetRt:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref EpcVpc
      Tags:
        - Key: Name
          Value: !Sub "privateAz1SubnetRt-${AWS::StackName}"
  PrivateAz2SubnetRt:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref EpcVpc
      Tags:
        - Key: Name
          Value: !Sub "privateAz2SubnetRt-${AWS::StackName}"
  PrivateAz1DfltRt:
    Type: 'AWS::EC2::Route'
    Properties:
      RouteTableId: !Ref PrivateAz1SubnetRt
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref NatGatewayAz1
  PrivateAz2DfltRt:
    Type: 'AWS::EC2::Route'
    Properties:
      RouteTableId: !Ref PrivateAz2SubnetRt
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref NatGatewayAz2
  PrivateAz1RtAssoc:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PrivateSubnetAz1
      RouteTableId: !Ref PrivateAz1SubnetRt
  PrivateAz2RtAssoc:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PrivateSubnetAz2
      RouteTableId: !Ref PrivateAz2SubnetRt

  ### Create Multus Subnets and Multus Security Group
  MultusSubnet1Az1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref MultusSubnet1Az1Cidr
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      Tags:
        - Key: Name
          Value: !Sub "multus1Az1-${AWS::StackName}"
  MultusSubnet2Az1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref MultusSubnet2Az1Cidr
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      Tags:
        - Key: Name
          Value: !Sub "multus2Az1-${AWS::StackName}"
  MultusSubnet1Az2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref MultusSubnet1Az2Cidr
      AvailabilityZone: !Select ['1', !Ref AvailabilityZones]
      Tags:
        - Key: Name
          Value: !Sub "multus1Az2-${AWS::StackName}"
  MultusSubnet2Az2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref MultusSubnet2Az2Cidr
      AvailabilityZone: !Select ['1', !Ref AvailabilityZones]
      Tags:
        - Key: Name
          Value: !Sub "multus2Az2-${AWS::StackName}"

  MultusSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security Group for Multus Subnets (sig/up)
      VpcId: !Ref EpcVpc
      SecurityGroupIngress:
      - IpProtocol: '-1'
        FromPort: '-1'
        ToPort: '-1'
        CidrIp: !Ref VpcCidr
      - IpProtocol: 'udp'
        FromPort: '2123'
        ToPort: '2123'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: 'udp'
        FromPort: '2152'
        ToPort: '2152'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: 'udp'
        FromPort: '8805'
        ToPort: '8805'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: '132'
        FromPort: '3868'
        ToPort: '3868'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: '132'
        FromPort: '36412'
        ToPort: '36412'
        CidrIp: '0.0.0.0/0'
      Tags:
        - Key: Name
          Value: !Sub "multus-Sg-${AWS::StackName}"

  ### Bastion Host ###
  BastionSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access via port 22
      VpcId: !Ref EpcVpc
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '22'
        ToPort: '22'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: '-1'
        FromPort: '-1'
        ToPort: '-1'
        CidrIp: !Ref VpcCidr
      Tags:
        - Key: Name
          Value: !Sub "bastion-Sg-${AWS::StackName}"

  BastionInstance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref BastionInstanceType
      KeyName: !Ref BastionKeyPairName
      NetworkInterfaces:
      - AssociatePublicIpAddress: "true"
        DeviceIndex: "0"
        GroupSet:
          - !Ref BastionSecurityGroup
        SubnetId: !Ref PublicSubnetAz1
      ImageId: !Ref LatestAmiId
      Tags:
        - Key: Name
          Value: !Sub "epcBastionHost-${AWS::StackName}"

## DocumentDB ##
  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "DocumentDB instances security group"
      GroupName: !Sub "docDbSecGroup-${AWS::StackName}"
      VpcId: !Ref EpcVpc
      SecurityGroupIngress:
        -
          CidrIp: !Ref VpcCidr
          FromPort: 27017
          IpProtocol: "tcp"
          ToPort: 27017
      SecurityGroupEgress:
        -
          CidrIp: "0.0.0.0/0"
          IpProtocol: "-1"

  DBSubnetGroup:
    Type: AWS::DocDB::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: "DocumentDB subnet group"
      DBSubnetGroupName: !Sub "docDbSubnetGroup-${AWS::StackName}"
      SubnetIds:
        - !Ref PrivateSubnetAz1
        - !Ref PrivateSubnetAz2
      Tags:
        - Key: Name
          Value: !Sub "docDbSubnetGroup-${AWS::StackName}"

  DBParameterGroup:
    Type: AWS::DocDB::DBClusterParameterGroup
    Properties:
      Description: "DocumentDB Parameter Group"
      Family: docdb3.6
      Name: !Sub "docDbParameterGroup-${AWS::StackName}"
      Parameters:
        audit_logs: "disabled"
        tls: "enabled"
        ttl_monitor: "enabled"
      Tags:
        - Key: Name
          Value: !Sub "docDbParamGroup-${AWS::StackName}"

  DBCluster:
    Type: AWS::DocDB::DBCluster
    Properties:
      BackupRetentionPeriod : 5
      DBClusterIdentifier : Open5gsDocDbCluster
      DBClusterParameterGroupName : !Ref DBParameterGroup
      DBSubnetGroupName : !Ref DBSubnetGroup
      EngineVersion : 3.6.0
      MasterUsername : !Ref MasterUserName
      MasterUserPassword : !Ref MasterUserPassword
      Port : "27017"
      PreferredBackupWindow : "23:00-23:59"
      PreferredMaintenanceWindow : "sun:00:00-sun:05:00"
      VpcSecurityGroupIds:
        - !Ref DBSecurityGroup
      StorageEncrypted : true
      Tags:
        - Key: Name
          Value: !Sub "docDbCluster-${AWS::StackName}"

  DBInstance:
    Type: AWS::DocDB::DBInstance
    Properties:
      AutoMinorVersionUpgrade: true
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      DBClusterIdentifier: !Ref DBCluster
      DBInstanceClass: !Ref DBInstanceClass
      DBInstanceIdentifier: "Open5gsDocDbInstance"
      PreferredMaintenanceWindow: "sun:00:00-sun:05:00"
      Tags:
        - Key: Name
          Value: !Sub "docDbInstance-${AWS::StackName}"

  ## EKS cluster ##
  EksIamRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - eks.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      RoleName: !Sub "eksIamRole-${AWS::StackName}"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
        - arn:aws:iam::aws:policy/AmazonEKSServicePolicy
  EksControlSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Cluster communication with worker nodes
      VpcId: !Ref EpcVpc
  EksCluster:
    Type: AWS::EKS::Cluster
    Properties:
      Name: !Sub "eks-${AWS::StackName}"
      RoleArn: !GetAtt EksIamRole.Arn
      ResourcesVpcConfig:
        SecurityGroupIds:
          - !Ref EksControlSecurityGroup
        SubnetIds:
          - !Ref PublicSubnetAz1
          - !Ref PublicSubnetAz2
          - !Ref PrivateSubnetAz1
          - !Ref PrivateSubnetAz2
    DependsOn: [EksIamRole, PublicSubnetAz1, PublicSubnetAz2, PrivateSubnetAz1, PrivateSubnetAz2, EksControlSecurityGroup]

  EksAdminRoleForLambda:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
                - lambda.amazonaws.com
                - cloudformation.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      RoleName: !Sub "eksAdminRoleForLambda-${AWS::StackName}"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEC2FullAccess
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  EksAdminPolicyForLambda:
    Type: "AWS::IAM::Policy"
    DependsOn: EksAdminRoleForLambda
    Properties:
      PolicyName: !Sub "eksAdminPolicyForLambda-${AWS::StackName}"
      Roles: [
          !Ref EksAdminRoleForLambda
        ]
      PolicyDocument:
          Version: 2012-10-17
          Statement:
            - Effect: Allow
              Action: [
                "cloudformation:*"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "eks:*"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "iam:CreateInstanceProfile",
                "iam:DeleteInstanceProfile",
                "iam:GetRole",
                "iam:GetInstanceProfile",
                "iam:RemoveRoleFromInstanceProfile",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:AttachRolePolicy",
                "iam:PutRolePolicy",
                "iam:AddRoleToInstanceProfile",
                "iam:PassRole",
                "iam:DetachRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:GetRolePolicy"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "lambda:*"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                s3:GetObject
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "events:PutRule",
                "events:DescribeRule",
                "events:RemoveTargets",
                "events:PutTargets",
                "events:DeleteRule"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "serverlessrepo:GetCloudFormationTemplate",
                "serverlessrepo:CreateCloudFormationTemplate"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "ssm:GetParameters",
                "ssm:GetParameter"
              ]
              Resource: "arn:aws:ssm:*:*:parameter/aws/service/eks/optimized-ami/*"

  S11SgwcHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-S11Sgwc"
      Name: "s11.sgwc.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  S5SmfHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-S5Smf"
      Name: "s5.smf.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  SxSgwuHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-SxSgwu"
      Name: "sx.sgwu.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  SxUpfHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-SxUpf"
      Name: "sx.upf.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  GxPcrfHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-GxPcrf"
      Name: "gx.pcrf.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  S6aHssHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-S6aHss"
      Name: "s6a.hss.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  S6aMmeHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-S6aMme"
      Name: "s6a.mme.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'

Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref EpcVpc
    Export:
      Name: !Sub "${AWS::StackName}-VpcId"
  VpcCidr:
    Description: VPC CIDR
    Value: !GetAtt EpcVpc.CidrBlock
    Export:
      Name: !Sub "${AWS::StackName}-VpcCidr"
  BastionPublicIp:
    Description: BastionHost Public IP
    Value: !GetAtt BastionInstance.PublicIp
    Export:
      Name: !Sub "${AWS::StackName}-BastionPublicIp"
  DBCluster:
    Description: The DB Cluster Name
    Value: !Ref DBCluster
  DBSubnetGroup:
    Description: The db subnet group name
    Value: !Ref DBSubnetGroup
  DBParameterGroup:
    Description: The db subnet group name
    Value: !Ref DBParameterGroup
  EksCluster:
    Description: EKS Cluster Name
    Value: !Ref EksCluster
    Export:
      Name: !Sub "${AWS::StackName}-EksCluster"
  EksAdminRoleForLambdaArn:
    Description: EKS Admin Role For Lambda (ARN)
    Value: !GetAtt EksAdminRoleForLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-EksAdminRoleForLambdaArn"
  EksControlSecurityGroup:
    Description: EKS Control plane security group
    Value: !Ref EksControlSecurityGroup
    Export:
      Name: !Sub "${AWS::StackName}-EksControlSecurityGroup"
  PrivateSubnetAz1:
    Description: EKS WorkerNode PrivateSubnet at AZ1. This will be used for K8s default networking.
    Value: !Ref PrivateSubnetAz1
    Export:
      Name: !Sub "${AWS::StackName}-PrivateSubnetAz1"
  PrivateSubnetAz2:
    Description: EKS WorkerNode PrivateSubnet at AZ2. This will be used for K8s default networking.
    Value: !Ref PrivateSubnetAz2
    Export:
      Name: !Sub "${AWS::StackName}-PrivateSubnetAz2"
  MultusSubnet1Az1:
    Description: EKS WorkerNode MultusSubnet1Az1 at AZ1. This will be used for Multus interface (control-plane).
    Value: !Ref MultusSubnet1Az1
    Export:
      Name: !Sub "${AWS::StackName}-MultusSubnet1Az1"
  MultusSubnet2Az1:
    Description: EKS WorkerNode MultusSubnet2Az1 at AZ1. This will be used for Multus interface (user-plane).
    Value: !Ref MultusSubnet2Az1
    Export:
      Name: !Sub "${AWS::StackName}-MultusSubnet2Az1"
  MultusSubnet1Az2:
    Description: EKS WorkerNode MultusSubnet1Az2 at AZ2. This will be used for Multus interface (control-plane).
    Value: !Ref MultusSubnet1Az2
    Export:
      Name: !Sub "${AWS::StackName}-MultusSubnet1Az2"
  MultusSubnet2Az2:
    Description: EKS WorkerNode MultusSubnet2Az2 at AZ2. This will be used for Multus interface (user-plane).
    Value: !Ref MultusSubnet2Az2
    Export:
      Name: !Sub "${AWS::StackName}-MultusSubnet2Az2"
  MultusSecurityGroup:
    Description: EKS WorkerNode SecurityGroup for Multus Subnets.
    Value: !Ref MultusSecurityGroup
    Export:
      Name: !Sub "${AWS::StackName}-MultusSecurityGroup"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



x86-Architecture/cfn-templates/open5gs-infra.yaml [1:753]:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AWSTemplateFormatVersion: 2010-09-09
Description: >-
  A new VPC creation for EKS LandingZone. VPC, IGW, NATGW, 2 Public Subnets, 2 Private Subnets (each per AZ) and 3 route tables get created

Metadata:
  "AWS::CloudFormation::Interface":
    ParameterGroups:
      - Label:
          default: VPC Configuration
        Parameters:
          - VpcCidr
          - AvailabilityZones
          - PublicSubnetAz1Cidr
          - PublicSubnetAz2Cidr
          - PrivateSubnetAz1Cidr
          - PrivateSubnetAz2Cidr
      - Label:
          default: Control UserPlane Network
        Parameters:
          - MultusSubnet1Az1Cidr
          - MultusSubnet1Az2Cidr
          - MultusSubnet2Az1Cidr
          - MultusSubnet2Az2Cidr
      - Label:
          default: Bastion Configuration
        Parameters:
          - BastionInstanceType
          - BastionKeyPairName
          - LatestAmiId
      - Label:
          default: DocumentDB (MongoDB) Configuration
        Parameters:
          - MasterUserName
          - MasterUserPassword
          - DBInstanceClass

Parameters:
  AvailabilityZones:
    Description: List of Availability Zones to use for the subnets in the VPC. Select 2 of them.
    Type: List<AWS::EC2::AvailabilityZone::Name>
  VpcCidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.0.0/16
    Description: CIDR block for the VPC.
    Type: String
  PublicSubnetAz1Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.0.0/24
    Description: CIDR block for the Public Subnet in AZ1.
    Type: String
  PublicSubnetAz2Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.1.0/24
    Description: CIDR block for the Public Subnet in AZ2.
    Type: String
  PrivateSubnetAz1Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.2.0/24
    Description: CIDR block for the Private Subnet in AZ1. This will be used for the main K8s network.
    Type: String
  PrivateSubnetAz2Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.3.0/24
    Description: CIDR block for the Private Subnet in AZ2. This will be used for the main K8s network.
    Type: String
  MultusSubnet1Az1Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.4.0/24
    Description: CIDR block for the Private Subnet in AZ1. This will be used for Control Plane.
    Type: String
  MultusSubnet1Az2Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.5.0/24
    Description: CIDR block for the Private Subnet in AZ2. This will be used for Control Plane.
    Type: String
  MultusSubnet2Az1Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.6.0/24
    Description: CIDR block for the Private Subnet in AZ1. This will be used for User Plane.
    Type: String
  MultusSubnet2Az2Cidr:
    AllowedPattern: ^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(\/(1[6-9]|2[0-8]))$
    ConstraintDescription: CIDR block parameter must be in the form x.x.x.x/16–28
    Default: 10.0.7.0/24
    Description: CIDR block for the Private Subnet in AZ2. This will be used for User Plane.
    Type: String
  BastionKeyPairName:
    Description: Name of an existing key pair, which allows you
      to securely connect to your instance after it launches.
    Type: AWS::EC2::KeyPair::KeyName
  BastionInstanceType:
    Type: String
    Default: t3.medium
    Description : Instance type for a bastion host.
    AllowedValues:
      - t2.small
      - t2.medium
      - t2.large
      - t3.small
      - t3.medium
      - t3.large
  DBInstanceClass:
    Default: "db.t3.medium"
    Description : "Instance class. Please refer to: https://docs.aws.amazon.com/documentdb/latest/developerguide/db-instance-classes.html#db-instance-classes-by-region"
    Type: "String"
    AllowedValues:
      - db.t3.medium
      - db.r5.large
      - db.r5.xlarge
      - db.r5.2xlarge
      - db.r5.4xlarge
      - db.r5.12xlarge
      - db.r5.24xlarge
    ConstraintDescription : "Instance type must be of the ones supported for the region. Please refer to: https://docs.aws.amazon.com/documentdb/latest/developerguide/db-instance-classes.html#db-instance-classes-by-region"
  LatestAmiId:
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
  MasterUserName:
    Type: "String"
    MinLength: "1"
    MaxLength: "16"
    AllowedPattern: "[a-zA-Z][a-zA-Z0-9]*"
    ConstraintDescription : "Must begin with a letter and contain only alphanumeric characters."
  MasterUserPassword:
    NoEcho: "true"
    Description : "The database admin account password"
    Type: "String"
    MinLength: "1"
    MaxLength: "41"
    AllowedPattern : "^[a-zA-Z0-9]*$"
    ConstraintDescription : "must contain only alphanumeric characters."

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

  ### IGW for the VPC
  EpcVpcIgw:
    Type: 'AWS::EC2::InternetGateway'
    Properties:
      Tags:
        - Key: Name
          Value: !Sub "igw-${AWS::StackName}"
  EpcVpcIgwAattach:
    Type: 'AWS::EC2::VPCGatewayAttachment'
    Properties:
      VpcId: !Ref EpcVpc
      InternetGatewayId: !Ref EpcVpcIgw


  #### Subnet-Public #####
  PublicSubnetAz1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref PublicSubnetAz1Cidr
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      Tags:
        - Key: kubernetes.io/role/elb
          Value: 1
        - Key: Name
          Value: !Sub "publicAz1-${AWS::StackName}"
  PublicSubnetAz2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref PublicSubnetAz2Cidr
      AvailabilityZone: !Select ['1', !Ref AvailabilityZones]
      Tags:
        - Key: kubernetes.io/role/elb
          Value: 1
        - Key: Name
          Value: !Sub "publicAz2-${AWS::StackName}"
  PublicSubnetRt:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref EpcVpc
      Tags:
        - Key: Name
          Value: !Sub "publicSubnetRt-${AWS::StackName}"
  PublicRtDfltRt:
    Type: 'AWS::EC2::Route'
    DependsOn: EpcVpcIgwAattach
    Properties:
      RouteTableId: !Ref PublicSubnetRt
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref EpcVpcIgw
  PublicAz1RtAssoc:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PublicSubnetAz1
      RouteTableId: !Ref PublicSubnetRt
  PublicAz2RtAssoc:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PublicSubnetAz2
      RouteTableId: !Ref PublicSubnetRt

  ### NATGWs for the VPC
  EipNatGwAz1:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: EpcVpc
  NatGatewayAz1:
    Type: 'AWS::EC2::NatGateway'
    Properties:
      AllocationId: !GetAtt 'EipNatGwAz1.AllocationId'
      SubnetId: !Ref PublicSubnetAz1
      Tags:
        - Key: Name
          Value: !Sub "natGwAz1-${AWS::StackName}"

  EipNatGwAz2:
    Type: 'AWS::EC2::EIP'
    Properties:
      Domain: EpcVpc
  NatGatewayAz2:
    Type: 'AWS::EC2::NatGateway'
    Properties:
      AllocationId: !GetAtt 'EipNatGwAz2.AllocationId'
      SubnetId: !Ref PublicSubnetAz2
      Tags:
        - Key: Name
          Value: !Sub "natGwAz2-${AWS::StackName}"


  #### Subnet-Private #####
  PrivateSubnetAz1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref PrivateSubnetAz1Cidr
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      Tags:
        - Key: kubernetes.io/role/internal-elb
          Value: 1
        - Key: Name
          Value: !Sub "privateAz1-${AWS::StackName}"
  PrivateSubnetAz2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref PrivateSubnetAz2Cidr
      AvailabilityZone: !Select ['1', !Ref AvailabilityZones]
      Tags:
        - Key: kubernetes.io/role/internal-elb
          Value: 1
        - Key: Name
          Value: !Sub "privateAz2-${AWS::StackName}"

  ### Subnet Route Table for Private Subnets
  PrivateAz1SubnetRt:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref EpcVpc
      Tags:
        - Key: Name
          Value: !Sub "privateAz1SubnetRt-${AWS::StackName}"
  PrivateAz2SubnetRt:
    Type: 'AWS::EC2::RouteTable'
    Properties:
      VpcId: !Ref EpcVpc
      Tags:
        - Key: Name
          Value: !Sub "privateAz2SubnetRt-${AWS::StackName}"
  PrivateAz1DfltRt:
    Type: 'AWS::EC2::Route'
    Properties:
      RouteTableId: !Ref PrivateAz1SubnetRt
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref NatGatewayAz1
  PrivateAz2DfltRt:
    Type: 'AWS::EC2::Route'
    Properties:
      RouteTableId: !Ref PrivateAz2SubnetRt
      DestinationCidrBlock: '0.0.0.0/0'
      NatGatewayId: !Ref NatGatewayAz2
  PrivateAz1RtAssoc:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PrivateSubnetAz1
      RouteTableId: !Ref PrivateAz1SubnetRt
  PrivateAz2RtAssoc:
    Type: 'AWS::EC2::SubnetRouteTableAssociation'
    Properties:
      SubnetId: !Ref PrivateSubnetAz2
      RouteTableId: !Ref PrivateAz2SubnetRt

  ### Create Multus Subnets and Multus Security Group
  MultusSubnet1Az1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref MultusSubnet1Az1Cidr
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      Tags:
        - Key: Name
          Value: !Sub "multus1Az1-${AWS::StackName}"
  MultusSubnet2Az1:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref MultusSubnet2Az1Cidr
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      Tags:
        - Key: Name
          Value: !Sub "multus2Az1-${AWS::StackName}"
  MultusSubnet1Az2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref MultusSubnet1Az2Cidr
      AvailabilityZone: !Select ['1', !Ref AvailabilityZones]
      Tags:
        - Key: Name
          Value: !Sub "multus1Az2-${AWS::StackName}"
  MultusSubnet2Az2:
    Type: 'AWS::EC2::Subnet'
    Properties:
      VpcId: !Ref EpcVpc
      CidrBlock: !Ref MultusSubnet2Az2Cidr
      AvailabilityZone: !Select ['1', !Ref AvailabilityZones]
      Tags:
        - Key: Name
          Value: !Sub "multus2Az2-${AWS::StackName}"

  MultusSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Security Group for Multus Subnets (sig/up)
      VpcId: !Ref EpcVpc
      SecurityGroupIngress:
      - IpProtocol: '-1'
        FromPort: '-1'
        ToPort: '-1'
        CidrIp: !Ref VpcCidr
      - IpProtocol: 'udp'
        FromPort: '2123'
        ToPort: '2123'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: 'udp'
        FromPort: '2152'
        ToPort: '2152'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: 'udp'
        FromPort: '8805'
        ToPort: '8805'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: '132'
        FromPort: '3868'
        ToPort: '3868'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: '132'
        FromPort: '36412'
        ToPort: '36412'
        CidrIp: '0.0.0.0/0'
      Tags:
        - Key: Name
          Value: !Sub "multus-Sg-${AWS::StackName}"

  ### Bastion Host ###
  BastionSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH access via port 22
      VpcId: !Ref EpcVpc
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '22'
        ToPort: '22'
        CidrIp: '0.0.0.0/0'
      - IpProtocol: '-1'
        FromPort: '-1'
        ToPort: '-1'
        CidrIp: !Ref VpcCidr
      Tags:
        - Key: Name
          Value: !Sub "bastion-Sg-${AWS::StackName}"

  BastionInstance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref BastionInstanceType
      KeyName: !Ref BastionKeyPairName
      NetworkInterfaces:
      - AssociatePublicIpAddress: "true"
        DeviceIndex: "0"
        GroupSet:
          - !Ref BastionSecurityGroup
        SubnetId: !Ref PublicSubnetAz1
      ImageId: !Ref LatestAmiId
      Tags:
        - Key: Name
          Value: !Sub "epcBastionHost-${AWS::StackName}"

## DocumentDB ##
  DBSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: "DocumentDB instances security group"
      GroupName: !Sub "docDbSecGroup-${AWS::StackName}"
      VpcId: !Ref EpcVpc
      SecurityGroupIngress:
        -
          CidrIp: !Ref VpcCidr
          FromPort: 27017
          IpProtocol: "tcp"
          ToPort: 27017
      SecurityGroupEgress:
        -
          CidrIp: "0.0.0.0/0"
          IpProtocol: "-1"

  DBSubnetGroup:
    Type: AWS::DocDB::DBSubnetGroup
    Properties:
      DBSubnetGroupDescription: "DocumentDB subnet group"
      DBSubnetGroupName: !Sub "docDbSubnetGroup-${AWS::StackName}"
      SubnetIds:
        - !Ref PrivateSubnetAz1
        - !Ref PrivateSubnetAz2
      Tags:
        - Key: Name
          Value: !Sub "docDbSubnetGroup-${AWS::StackName}"

  DBParameterGroup:
    Type: AWS::DocDB::DBClusterParameterGroup
    Properties:
      Description: "DocumentDB Parameter Group"
      Family: docdb3.6
      Name: !Sub "docDbParameterGroup-${AWS::StackName}"
      Parameters:
        audit_logs: "disabled"
        tls: "enabled"
        ttl_monitor: "enabled"
      Tags:
        - Key: Name
          Value: !Sub "docDbParamGroup-${AWS::StackName}"

  DBCluster:
    Type: AWS::DocDB::DBCluster
    Properties:
      BackupRetentionPeriod : 5
      DBClusterIdentifier : Open5gsDocDbCluster
      DBClusterParameterGroupName : !Ref DBParameterGroup
      DBSubnetGroupName : !Ref DBSubnetGroup
      EngineVersion : 3.6.0
      MasterUsername : !Ref MasterUserName
      MasterUserPassword : !Ref MasterUserPassword
      Port : "27017"
      PreferredBackupWindow : "23:00-23:59"
      PreferredMaintenanceWindow : "sun:00:00-sun:05:00"
      VpcSecurityGroupIds:
        - !Ref DBSecurityGroup
      StorageEncrypted : true
      Tags:
        - Key: Name
          Value: !Sub "docDbCluster-${AWS::StackName}"

  DBInstance:
    Type: AWS::DocDB::DBInstance
    Properties:
      AutoMinorVersionUpgrade: true
      AvailabilityZone: !Select ['0', !Ref AvailabilityZones]
      DBClusterIdentifier: !Ref DBCluster
      DBInstanceClass: !Ref DBInstanceClass
      DBInstanceIdentifier: "Open5gsDocDbInstance"
      PreferredMaintenanceWindow: "sun:00:00-sun:05:00"
      Tags:
        - Key: Name
          Value: !Sub "docDbInstance-${AWS::StackName}"

  ## EKS cluster ##
  EksIamRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - eks.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      RoleName: !Sub "eksIamRole-${AWS::StackName}"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
        - arn:aws:iam::aws:policy/AmazonEKSServicePolicy
  EksControlSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Cluster communication with worker nodes
      VpcId: !Ref EpcVpc
  EksCluster:
    Type: AWS::EKS::Cluster
    Properties:
      Name: !Sub "eks-${AWS::StackName}"
      RoleArn: !GetAtt EksIamRole.Arn
      ResourcesVpcConfig:
        SecurityGroupIds:
          - !Ref EksControlSecurityGroup
        SubnetIds:
          - !Ref PublicSubnetAz1
          - !Ref PublicSubnetAz2
          - !Ref PrivateSubnetAz1
          - !Ref PrivateSubnetAz2
    DependsOn: [EksIamRole, PublicSubnetAz1, PublicSubnetAz2, PrivateSubnetAz1, PrivateSubnetAz2, EksControlSecurityGroup]

  EksAdminRoleForLambda:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - ec2.amazonaws.com
                - lambda.amazonaws.com
                - cloudformation.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      RoleName: !Sub "eksAdminRoleForLambda-${AWS::StackName}"
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEC2FullAccess
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole

  EksAdminPolicyForLambda:
    Type: "AWS::IAM::Policy"
    DependsOn: EksAdminRoleForLambda
    Properties:
      PolicyName: !Sub "eksAdminPolicyForLambda-${AWS::StackName}"
      Roles: [
          !Ref EksAdminRoleForLambda
        ]
      PolicyDocument:
          Version: 2012-10-17
          Statement:
            - Effect: Allow
              Action: [
                "cloudformation:*"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "eks:*"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "iam:CreateInstanceProfile",
                "iam:DeleteInstanceProfile",
                "iam:GetRole",
                "iam:GetInstanceProfile",
                "iam:RemoveRoleFromInstanceProfile",
                "iam:CreateRole",
                "iam:DeleteRole",
                "iam:AttachRolePolicy",
                "iam:PutRolePolicy",
                "iam:AddRoleToInstanceProfile",
                "iam:PassRole",
                "iam:DetachRolePolicy",
                "iam:DeleteRolePolicy",
                "iam:GetRolePolicy"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "lambda:*"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                s3:GetObject
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "events:PutRule",
                "events:DescribeRule",
                "events:RemoveTargets",
                "events:PutTargets",
                "events:DeleteRule"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "serverlessrepo:GetCloudFormationTemplate",
                "serverlessrepo:CreateCloudFormationTemplate"
              ]
              Resource: "*"
            - Effect: Allow
              Action: [
                "ssm:GetParameters",
                "ssm:GetParameter"
              ]
              Resource: "arn:aws:ssm:*:*:parameter/aws/service/eks/optimized-ami/*"

  S11SgwcHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-S11Sgwc"
      Name: "s11.sgwc.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  S5SmfHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-S5Smf"
      Name: "s5.smf.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  SxSgwuHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-SxSgwu"
      Name: "sx.sgwu.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  SxUpfHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-SxUpf"
      Name: "sx.upf.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  GxPcrfHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-GxPcrf"
      Name: "gx.pcrf.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  S6aHssHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-S6aHss"
      Name: "s6a.hss.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'
  S6aMmeHostedZone:
    Type: 'AWS::Route53::HostedZone'
    Properties:
      HostedZoneConfig:
        Comment: !Sub "${AWS::StackName}-PrivateHostedZone-S6aMme"
      Name: "s6a.mme.open5gs.service"
      VPCs:
      - VPCId: !Ref EpcVpc
        VPCRegion: !Ref 'AWS::Region'

Outputs:
  VpcId:
    Description: VPC ID
    Value: !Ref EpcVpc
    Export:
      Name: !Sub "${AWS::StackName}-VpcId"
  VpcCidr:
    Description: VPC CIDR
    Value: !GetAtt EpcVpc.CidrBlock
    Export:
      Name: !Sub "${AWS::StackName}-VpcCidr"
  BastionPublicIp:
    Description: BastionHost Public IP
    Value: !GetAtt BastionInstance.PublicIp
    Export:
      Name: !Sub "${AWS::StackName}-BastionPublicIp"
  DBCluster:
    Description: The DB Cluster Name
    Value: !Ref DBCluster
  DBSubnetGroup:
    Description: The db subnet group name
    Value: !Ref DBSubnetGroup
  DBParameterGroup:
    Description: The db subnet group name
    Value: !Ref DBParameterGroup
  EksCluster:
    Description: EKS Cluster Name
    Value: !Ref EksCluster
    Export:
      Name: !Sub "${AWS::StackName}-EksCluster"
  EksAdminRoleForLambdaArn:
    Description: EKS Admin Role For Lambda (ARN)
    Value: !GetAtt EksAdminRoleForLambda.Arn
    Export:
      Name: !Sub "${AWS::StackName}-EksAdminRoleForLambdaArn"
  EksControlSecurityGroup:
    Description: EKS Control plane security group
    Value: !Ref EksControlSecurityGroup
    Export:
      Name: !Sub "${AWS::StackName}-EksControlSecurityGroup"
  PrivateSubnetAz1:
    Description: EKS WorkerNode PrivateSubnet at AZ1. This will be used for K8s default networking.
    Value: !Ref PrivateSubnetAz1
    Export:
      Name: !Sub "${AWS::StackName}-PrivateSubnetAz1"
  PrivateSubnetAz2:
    Description: EKS WorkerNode PrivateSubnet at AZ2. This will be used for K8s default networking.
    Value: !Ref PrivateSubnetAz2
    Export:
      Name: !Sub "${AWS::StackName}-PrivateSubnetAz2"
  MultusSubnet1Az1:
    Description: EKS WorkerNode MultusSubnet1Az1 at AZ1. This will be used for Multus interface (control-plane).
    Value: !Ref MultusSubnet1Az1
    Export:
      Name: !Sub "${AWS::StackName}-MultusSubnet1Az1"
  MultusSubnet2Az1:
    Description: EKS WorkerNode MultusSubnet2Az1 at AZ1. This will be used for Multus interface (user-plane).
    Value: !Ref MultusSubnet2Az1
    Export:
      Name: !Sub "${AWS::StackName}-MultusSubnet2Az1"
  MultusSubnet1Az2:
    Description: EKS WorkerNode MultusSubnet1Az2 at AZ2. This will be used for Multus interface (control-plane).
    Value: !Ref MultusSubnet1Az2
    Export:
      Name: !Sub "${AWS::StackName}-MultusSubnet1Az2"
  MultusSubnet2Az2:
    Description: EKS WorkerNode MultusSubnet2Az2 at AZ2. This will be used for Multus interface (user-plane).
    Value: !Ref MultusSubnet2Az2
    Export:
      Name: !Sub "${AWS::StackName}-MultusSubnet2Az2"
  MultusSecurityGroup:
    Description: EKS WorkerNode SecurityGroup for Multus Subnets.
    Value: !Ref MultusSecurityGroup
    Export:
      Name: !Sub "${AWS::StackName}-MultusSecurityGroup"
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -



