AWSTemplateFormatVersion: '2010-09-09' Transform: AWS::Serverless-2016-10-31 Description: > This CloudFormation deploys public REST API along with private network load balancer which will route the request to an EC2 website via vpc link Parameters: InstanceType: Type: String Description: Select an instance type Default: t2.micro AllowedValues: [c4.2xlarge, c4.4xlarge, c4.8xlarge, c4.large, c4.xlarge, c5.12xlarge, c5.18xlarge, c5.24xlarge, c5.2xlarge, c5.4xlarge, c5.9xlarge, c5.large, c5.metal, c5.xlarge, c5a.12xlarge, c5a.16xlarge, c5a.24xlarge, c5a.2xlarge, c5a.4xlarge, c5a.8xlarge, c5a.large, c5a.xlarge, c5d.12xlarge, c5d.18xlarge, c5d.24xlarge, c5d.2xlarge, c5d.4xlarge, c5d.9xlarge, c5d.large, c5d.metal, c5d.xlarge, c5n.18xlarge, c5n.2xlarge, c5n.4xlarge, c5n.9xlarge, c5n.large, c5n.metal, c5n.xlarge, c6g.12xlarge, c6g.16xlarge, c6g.2xlarge, c6g.4xlarge, c6g.8xlarge, c6g.large, c6g.medium, c6g.metal, c6g.xlarge, c6gd.12xlarge, c6gd.16xlarge, c6gd.2xlarge, c6gd.4xlarge, c6gd.8xlarge, c6gd.large, c6gd.medium, c6gd.metal, c6gd.xlarge, c6gn.12xlarge, c6gn.16xlarge, c6gn.2xlarge, c6gn.4xlarge, c6gn.8xlarge, c6gn.large, c6gn.medium, c6gn.xlarge, c6i.12xlarge, c6i.16xlarge, c6i.24xlarge, c6i.2xlarge, c6i.32xlarge, c6i.4xlarge, c6i.8xlarge, c6i.large, c6i.metal, c6i.xlarge, d2.2xlarge, d2.4xlarge, d2.8xlarge, d2.xlarge, d3.2xlarge, d3.4xlarge, d3.8xlarge, d3.xlarge, g3.16xlarge, g3.4xlarge, g3.8xlarge, g4ad.16xlarge, g4ad.2xlarge, g4ad.4xlarge, g4ad.8xlarge, g4ad.xlarge, g4dn.12xlarge, g4dn.16xlarge, g4dn.2xlarge, g4dn.4xlarge, g4dn.8xlarge, g4dn.metal, g4dn.xlarge, g5.12xlarge, g5.16xlarge, g5.24xlarge, g5.2xlarge, g5.48xlarge, g5.4xlarge, g5.8xlarge, g5.xlarge, i3.16xlarge, i3.2xlarge, i3.4xlarge, i3.8xlarge, i3.large, i3.metal, i3.xlarge, i3en.12xlarge, i3en.24xlarge, i3en.2xlarge, i3en.3xlarge, i3en.6xlarge, i3en.large, i3en.metal, i3en.xlarge, i4i.16xlarge, i4i.2xlarge, i4i.32xlarge, i4i.4xlarge, i4i.8xlarge, i4i.large, i4i.metal, i4i.xlarge, im4gn.16xlarge, im4gn.2xlarge, im4gn.4xlarge, im4gn.8xlarge, im4gn.large, im4gn.xlarge, inf1.24xlarge, inf1.2xlarge, inf1.6xlarge, inf1.xlarge, is4gen.2xlarge, is4gen.4xlarge, is4gen.8xlarge, is4gen.large, is4gen.medium, is4gen.xlarge, m4.10xlarge, m4.16xlarge, m4.2xlarge, m4.4xlarge, m4.large, m4.xlarge, m5.12xlarge, m5.16xlarge, m5.24xlarge, m5.2xlarge, m5.4xlarge, m5.8xlarge, m5.large, m5.metal, m5.xlarge, m5a.12xlarge, m5a.16xlarge, m5a.24xlarge, m5a.2xlarge, m5a.4xlarge, m5a.8xlarge, m5a.large, m5a.xlarge, m5ad.12xlarge, m5ad.16xlarge, m5ad.24xlarge, m5ad.2xlarge, m5ad.4xlarge, m5ad.8xlarge, m5ad.large, m5ad.xlarge, m5d.12xlarge, m5d.16xlarge, m5d.24xlarge, m5d.2xlarge, m5d.4xlarge, m5d.8xlarge, m5d.large, m5d.metal, m5d.xlarge, m6g.12xlarge, m6g.16xlarge, m6g.2xlarge, m6g.4xlarge, m6g.8xlarge, m6g.large, m6g.medium, m6g.metal, m6g.xlarge, m6i.12xlarge, m6i.16xlarge, m6i.24xlarge, m6i.2xlarge, m6i.32xlarge, m6i.4xlarge, m6i.8xlarge, m6i.large, m6i.metal, m6i.xlarge, p3.16xlarge, p3.2xlarge, p3.8xlarge, r4.16xlarge, r4.2xlarge, r4.4xlarge, r4.8xlarge, r4.large, r4.xlarge, r5.12xlarge, r5.16xlarge, r5.24xlarge, r5.2xlarge, r5.4xlarge, r5.8xlarge, r5.large, r5.metal, r5.xlarge, r5a.12xlarge, r5a.16xlarge, r5a.24xlarge, r5a.2xlarge, r5a.4xlarge, r5a.8xlarge, r5a.large, r5a.xlarge, r5ad.12xlarge, r5ad.16xlarge, r5ad.24xlarge, r5ad.2xlarge, r5ad.4xlarge, r5ad.8xlarge, r5ad.large, r5ad.xlarge, r5b.12xlarge, r5b.16xlarge, r5b.24xlarge, r5b.2xlarge, r5b.4xlarge, r5b.8xlarge, r5b.large, r5b.metal, r5b.xlarge, r5d.12xlarge, r5d.16xlarge, r5d.24xlarge, r5d.2xlarge, r5d.4xlarge, r5d.8xlarge, r5d.large, r5d.metal, r5d.xlarge, r5n.12xlarge, r5n.16xlarge, r5n.24xlarge, r5n.2xlarge, r5n.4xlarge, r5n.8xlarge, r5n.large, r5n.metal, r5n.xlarge, r6g.12xlarge, r6g.16xlarge, r6g.2xlarge, r6g.4xlarge, r6g.8xlarge, r6g.large, r6g.medium, r6g.metal, r6g.xlarge, r6gd.12xlarge, r6gd.16xlarge, r6gd.2xlarge, r6gd.4xlarge, r6gd.8xlarge, r6gd.large, r6gd.medium, r6gd.metal, r6gd.xlarge, r6i.12xlarge, r6i.16xlarge, r6i.24xlarge, r6i.2xlarge, r6i.32xlarge, r6i.4xlarge, r6i.8xlarge, r6i.large, r6i.metal, r6i.xlarge, t2.2xlarge, t2.large, t2.medium, t2.micro, t2.nano, t2.small, t2.xlarge, t3.2xlarge, t3.large, t3.medium, t3.micro, t3.nano, t3.small, t3.xlarge, t3a.2xlarge, t3a.large, t3a.medium, t3a.micro, t3a.nano, t3a.small, t3a.xlarge, t4g.2xlarge, t4g.large, t4g.medium, t4g.micro, t4g.nano, t4g.small, t4g.xlarge, u-3tb1.56xlarge, u-6tb1.112xlarge, u-6tb1.56xlarge, x1.16xlarge, x1.32xlarge, x1e.16xlarge, x1e.2xlarge, x1e.32xlarge, x1e.4xlarge, x1e.8xlarge, x1e.xlarge, x2idn.16xlarge, x2idn.24xlarge, x2idn.32xlarge, x2idn.metal, x2iedn.16xlarge, x2iedn.24xlarge, x2iedn.2xlarge, x2iedn.32xlarge, x2iedn.4xlarge, x2iedn.8xlarge, x2iedn.metal, x2iedn.xlarge, c5ad.12xlarge, c5ad.16xlarge, c5ad.24xlarge, c5ad.2xlarge, c5ad.4xlarge, c5ad.8xlarge, c5ad.large, c5ad.xlarge, c6a.12xlarge, c6a.16xlarge, c6a.24xlarge, c6a.2xlarge, c6a.32xlarge, c6a.48xlarge, c6a.4xlarge, c6a.8xlarge, c6a.large, c6a.metal, c6a.xlarge, c6id.12xlarge, c6id.16xlarge, c6id.24xlarge, c6id.2xlarge, c6id.32xlarge, c6id.4xlarge, c6id.8xlarge, c6id.large, c6id.metal, c6id.xlarge, c6in.12xlarge, c6in.16xlarge, c6in.24xlarge, c6in.2xlarge, c6in.32xlarge, c6in.4xlarge, c6in.8xlarge, c6in.large, c6in.xlarge, c7g.12xlarge, c7g.16xlarge, c7g.2xlarge, c7g.4xlarge, c7g.8xlarge, c7g.large, c7g.medium, c7g.metal, c7g.xlarge, d3en.12xlarge, d3en.2xlarge, d3en.4xlarge, d3en.6xlarge, d3en.8xlarge, d3en.xlarge, dl1.24xlarge, f1.16xlarge, f1.2xlarge, f1.4xlarge, g3s.xlarge, g5g.16xlarge, g5g.2xlarge, g5g.4xlarge, g5g.8xlarge, g5g.metal, g5g.xlarge, h1.16xlarge, h1.2xlarge, h1.4xlarge, h1.8xlarge, m5dn.12xlarge, m5dn.16xlarge, m5dn.24xlarge, m5dn.2xlarge, m5dn.4xlarge, m5dn.8xlarge, m5dn.large, m5dn.metal, m5dn.xlarge, m5n.12xlarge, m5n.16xlarge, m5n.24xlarge, m5n.2xlarge, m5n.4xlarge, m5n.8xlarge, m5n.large, m5n.metal, m5n.xlarge, m5zn.12xlarge, m5zn.2xlarge, m5zn.3xlarge, m5zn.6xlarge, m5zn.large, m5zn.metal, m5zn.xlarge, m6a.12xlarge, m6a.16xlarge, m6a.24xlarge, m6a.2xlarge, m6a.32xlarge, m6a.48xlarge, m6a.4xlarge, m6a.8xlarge, m6a.large, m6a.metal, m6a.xlarge, m6gd.12xlarge, m6gd.16xlarge, m6gd.2xlarge, m6gd.4xlarge, m6gd.8xlarge, m6gd.large, m6gd.medium, m6gd.metal, m6gd.xlarge, m6id.12xlarge, m6id.16xlarge, m6id.24xlarge, m6id.2xlarge, m6id.32xlarge, m6id.4xlarge, m6id.8xlarge, m6id.large, m6id.metal, m6id.xlarge, m6idn.12xlarge, m6idn.16xlarge, m6idn.24xlarge, m6idn.2xlarge, m6idn.32xlarge, m6idn.4xlarge, m6idn.8xlarge, m6idn.large, m6idn.xlarge, m6in.12xlarge, m6in.16xlarge, m6in.24xlarge, m6in.2xlarge, m6in.32xlarge, m6in.4xlarge, m6in.8xlarge, m6in.large, m6in.xlarge, m7g.12xlarge, m7g.16xlarge, m7g.2xlarge, m7g.4xlarge, m7g.8xlarge, m7g.large, m7g.medium, m7g.metal, m7g.xlarge, mac1.metal, mac2.metal, p2.16xlarge, p2.8xlarge, p2.xlarge, p3dn.24xlarge, p4d.24xlarge, r5dn.12xlarge, r5dn.16xlarge, r5dn.24xlarge, r5dn.2xlarge, r5dn.4xlarge, r5dn.8xlarge, r5dn.large, r5dn.metal, r5dn.xlarge, r6a.12xlarge, r6a.16xlarge, r6a.24xlarge, r6a.2xlarge, r6a.32xlarge, r6a.48xlarge, r6a.4xlarge, r6a.8xlarge, r6a.large, r6a.metal, r6a.xlarge, r6id.12xlarge, r6id.16xlarge, r6id.24xlarge, r6id.2xlarge, r6id.32xlarge, r6id.4xlarge, r6id.8xlarge, r6id.large, r6id.metal, r6id.xlarge, r6idn.12xlarge, r6idn.16xlarge, r6idn.24xlarge, r6idn.2xlarge, r6idn.32xlarge, r6idn.4xlarge, r6idn.8xlarge, r6idn.large, r6idn.xlarge, r6in.12xlarge, r6in.16xlarge, r6in.24xlarge, r6in.2xlarge, r6in.32xlarge, r6in.4xlarge, r6in.8xlarge, r6in.large, r6in.xlarge, r7g.12xlarge, r7g.16xlarge, r7g.2xlarge, r7g.4xlarge, r7g.8xlarge, r7g.large, r7g.medium, r7g.metal, r7g.xlarge, trn1.2xlarge, trn1.32xlarge, u-12tb1.112xlarge, u-18tb1.112xlarge, u-24tb1.112xlarge, u-9tb1.112xlarge, vt1.24xlarge, vt1.3xlarge, vt1.6xlarge, x2gd.12xlarge, x2gd.16xlarge, x2gd.2xlarge, x2gd.4xlarge, x2gd.8xlarge, x2gd.large, x2gd.medium, x2gd.metal, x2gd.xlarge, x2iezn.12xlarge, x2iezn.2xlarge, x2iezn.4xlarge, x2iezn.6xlarge, x2iezn.8xlarge, x2iezn.metal, z1d.12xlarge, z1d.2xlarge, z1d.3xlarge, z1d.6xlarge, z1d.large, z1d.metal, z1d.xlarge, hpc6a.48xlarge, hpc6id.32xlarge] KeyPair: Description: Select the key pair Type: AWS::EC2::KeyPair::KeyName VPC: Description: Please select if you want to use existing VPC Type: AWS::EC2::VPC::Id PrivateSubnetIDs: Description: Private Subnet IDs for VPCE Type: "List<AWS::EC2::Subnet::Id>" SecurityGroupIDsForNLBAndEC2: Description: Security group IDs for NLB and EC2. Note - please make sure that the security group allows traffic on port 80 from VPC Cidr or 0.0.0.0 Type: "List<AWS::EC2::SecurityGroup::Id>" RouteTableId: Description: PrivateSubnets route table Id Type: String Mappings: RegionMap: us-east-1: AMI: ami-0dfcb1ef8550277af us-east-2: AMI: ami-0cc87e5027adcdca8 us-west-1: AMI: ami-00569e54da628d17c us-west-2: AMI: ami-0f1a5f5ada0e7da53 ap-southeast-4: AMI: ami-0272ee0cbe63bb8e8 ap-east-1: AMI: ami-0e679816c1d0be6df ap-south-2: AMI: ami-0155ae3341da656ae ap-south-1: AMI: ami-0e742cca61fb65051 ap-northeast-3: AMI: ami-090ae0a4750988734 ap-northeast-2: AMI: ami-0f6e451b865011317 ca-central-1: AMI: ami-099effcf516c942b7 eu-north-1: AMI: ami-0bb935e4614c12d86 eu-west-1: AMI: ami-06e0ce9d3339cb039 eu-west-2: AMI: ami-09ee0944866c73f62 eu-west-3: AMI: ami-00575c0cbc20caf50 eu-central-1: AMI: ami-0c0d3776ef525d5dd ap-southeast-1: AMI: ami-0f2eac25772cd4e36 ap-southeast-2: AMI: ami-0692dea0a2f8a1b35 ap-northeast-1: AMI: ami-0ffac3e16de16665e sa-east-1: AMI: ami-01fc9174dd9330556 af-south-1: AMI: ami-0d4fd6ba7ffe8260e ap-southeast-3: AMI: ami-0ebaeda1c62cceddb eu-west-3: AMI: ami-00575c0cbc20caf50 eu-south-2: AMI: ami-089ea1de61e0c9c18 me-south-1: AMI: ami-06131a860e2930b5c me-central-1: AMI: ami-0c30c5d64bef7fade Resources: VPCE: Type: AWS::EC2::VPCEndpoint Properties: RouteTableIds: - !Ref RouteTableId ServiceName: !Sub com.amazonaws.${AWS::Region}.s3 VpcEndpointType: Gateway VpcId: !Ref VPC EC2: Type: AWS::EC2::Instance DependsOn: ApiGatewayModel Properties: InstanceType: !Ref InstanceType KeyName: !Ref KeyPair ImageId: !FindInMap [RegionMap, !Ref 'AWS::Region', AMI] SecurityGroupIds: !Ref SecurityGroupIDsForNLBAndEC2 SubnetId: !Select [0, !Ref PrivateSubnetIDs] UserData: Fn::Base64: !Sub | #!/bin/bash yum update -y sudo amazon-linux-extras install nginx1 -y sudo systemctl enable --now nginx Tags: - Key: Name Value: priv NetworkLoadBalancer: DependsOn: EC2 Type: AWS::ElasticLoadBalancingV2::LoadBalancer Properties: Name: NLB Scheme: internal Subnets: - !Select [0, !Ref PrivateSubnetIDs] - !Select [1, !Ref PrivateSubnetIDs] Type: network NetworkLoadBalancerTargetGroup: DependsOn: EC2 Type: AWS::ElasticLoadBalancingV2::TargetGroup Properties: Port: 80 Name: NLBTargetGroup HealthCheckEnabled: true Protocol: TCP VpcId: !Ref VPC Targets: - Id: !GetAtt EC2.PrivateIp Port: 80 TargetType: ip NetworkLoadBalancerListener: DependsOn: NetworkLoadBalancerTargetGroup Type: AWS::ElasticLoadBalancingV2::Listener Properties: DefaultActions: - Type: forward TargetGroupArn: !Ref NetworkLoadBalancerTargetGroup LoadBalancerArn: !Ref NetworkLoadBalancer Port: '80' Protocol: TCP ApiGatewayRestApi: Type: 'AWS::ApiGateway::RestApi' DependsOn: VPCE Properties: ApiKeySourceType: HEADER Description: An API Gateway to connect to ec2 server Name: PublicApiViaCFN EndpointConfiguration: Types: - REGIONAL ApiGatewayGetMethod: DependsOn: VPCLink Type: AWS::ApiGateway::Method Properties: HttpMethod: GET AuthorizationType: NONE Integration: ConnectionType: VPC_LINK ConnectionId: "${stageVariables.vpclink}" IntegrationHttpMethod: GET PassthroughBehavior: WHEN_NO_MATCH TimeoutInMillis: 10000 Type: HTTP_PROXY Uri: !Sub - "http://${privateIP}" - privateIP: !GetAtt EC2.PrivateIp ResourceId: !GetAtt ApiGatewayRestApi.RootResourceId RestApiId: !Ref ApiGatewayRestApi ApiGatewayModel: DependsOn: ApiGatewayRestApi Type: AWS::ApiGateway::Model Properties: ContentType: 'application/json' RestApiId: !Ref ApiGatewayRestApi Schema: {} ApiGatewayStage: Type: AWS::ApiGateway::Stage DependsOn: ApiGatewayDeployment Properties: DeploymentId: !Ref ApiGatewayDeployment Description: API Stage v0 RestApiId: !Ref ApiGatewayRestApi StageName: 'v0' Variables: vpclink: !Ref VPCLink ApiGatewayDeployment: Type: 'AWS::ApiGateway::Deployment' DependsOn: ApiGatewayGetMethod Properties: RestApiId: !Ref ApiGatewayRestApi VPCLink: Type: AWS::ApiGateway::VpcLink DependsOn: NetworkLoadBalancer Properties: Name: NLB TargetArns: - !Join - '' - - 'arn:aws:elasticloadbalancing:' - !Ref AWS::Region - ':' - !Ref AWS::AccountId - ':loadbalancer/' - !GetAtt NetworkLoadBalancer.LoadBalancerFullName Outputs: WebsiteURL: Value: !Sub - "curl https://${ApiId}.execute-api.${AWS::Region}.amazonaws.com/v0" - ApiId: !Ref ApiGatewayRestApi Description: ApiGateway URL