# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: MIT-0 Description: This template deploys the infrastructure stack for an AWS Client VPN demo. Parameters: Certificate: Description: Your AWS Certificate Manager (ACM) Certificate ARN Type: String Default: 'arn:aws:acm:[region]:[accountId]:certificate/########-####-####-####-############' LatestAmiId: Description: The AMI ID of your EC2-based web server Type: 'AWS::SSM::Parameter::Value' Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' Mappings: SubnetConfig: VPC: CIDR: "10.0.0.0/16" Public0: CIDR: "10.0.0.0/24" Public1: CIDR: "10.0.1.0/24" Private2: CIDR: "10.0.2.0/24" Private3: CIDR: "10.0.3.0/24" # This mapping accounts for the scenario when certain AZs # are not available to use (this differs on a per account # per customer basis). E.g., if the 'b' AZ is not available # in a specific region in one's account then updating the # list contained in the mapping below here will allow a # different AZ to be chosen. AZRegions: ap-northeast-1: AZs: ["a", "b"] ap-northeast-2: AZs: ["a", "b"] ap-south-1: AZs: ["a", "b"] ap-southeast-1: AZs: ["a", "b"] ap-southeast-2: AZs: ["a", "b"] ca-central-1: AZs: ["a", "b"] eu-central-1: AZs: ["a", "b"] eu-west-1: AZs: ["a", "b"] eu-west-2: AZs: ["a", "b"] sa-east-1: AZs: ["a", "b"] us-east-1: AZs: ["a", "b"] us-east-2: AZs: ["a", "b"] us-west-1: AZs: ["a", "b"] us-west-2: AZs: ["a", "b"] Resources: VPC: Type: "AWS::EC2::VPC" Properties: EnableDnsSupport: "true" EnableDnsHostnames: "true" CidrBlock: Fn::FindInMap: - "SubnetConfig" - "VPC" - "CIDR" PublicSubnet0: Type: "AWS::EC2::Subnet" Properties: VpcId: Ref: "VPC" AvailabilityZone: Fn::Sub: - "${AWS::Region}${AZ}" - AZ: !Select [ 0, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] CidrBlock: Fn::FindInMap: - "SubnetConfig" - "Public0" - "CIDR" PublicSubnet1: Type: "AWS::EC2::Subnet" Properties: VpcId: Ref: "VPC" AvailabilityZone: Fn::Sub: - "${AWS::Region}${AZ}" - AZ: !Select [ 1, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] CidrBlock: Fn::FindInMap: - "SubnetConfig" - "Public1" - "CIDR" PrivateSubnet2: Type: "AWS::EC2::Subnet" Properties: VpcId: Ref: "VPC" AvailabilityZone: Fn::Sub: - "${AWS::Region}${AZ}" - AZ: !Select [ 0, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] CidrBlock: Fn::FindInMap: - "SubnetConfig" - "Private2" - "CIDR" PrivateSubnet3: Type: "AWS::EC2::Subnet" Properties: VpcId: Ref: "VPC" AvailabilityZone: Fn::Sub: - "${AWS::Region}${AZ}" - AZ: !Select [ 1, !FindInMap [ "AZRegions", !Ref "AWS::Region", "AZs" ] ] CidrBlock: Fn::FindInMap: - "SubnetConfig" - "Private3" - "CIDR" InternetGateway: Type: "AWS::EC2::InternetGateway" InternetGatewayAttachment: Type: "AWS::EC2::VPCGatewayAttachment" Properties: VpcId: Ref: "VPC" InternetGatewayId: Ref: "InternetGateway" PublicRouteTable: Type: "AWS::EC2::RouteTable" Properties: VpcId: Ref: "VPC" PublicRoute: Type: "AWS::EC2::Route" DependsOn: "InternetGatewayAttachment" Properties: RouteTableId: Ref: "PublicRouteTable" DestinationCidrBlock: "0.0.0.0/0" GatewayId: Ref: "InternetGateway" PublicSubnetRouteTableAssociation0: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: SubnetId: Ref: "PublicSubnet0" RouteTableId: Ref: "PublicRouteTable" PublicSubnetRouteTableAssociation1: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: SubnetId: Ref: "PublicSubnet1" RouteTableId: Ref: "PublicRouteTable" PrivateRouteTable2: Type: "AWS::EC2::RouteTable" Properties: VpcId: Ref: "VPC" PrivateRouteTable3: Type: "AWS::EC2::RouteTable" Properties: VpcId: Ref: "VPC" PrivateSubnetRouteTableAssociation2: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: SubnetId: Ref: "PrivateSubnet2" RouteTableId: Ref: "PrivateRouteTable2" PrivateSubnetRouteTableAssociation3: Type: "AWS::EC2::SubnetRouteTableAssociation" Properties: SubnetId: Ref: "PrivateSubnet3" RouteTableId: Ref: "PrivateRouteTable3" NatEIP0: Type: AWS::EC2::EIP NatEIP1: Type: AWS::EC2::EIP NatGateway0: Type: AWS::EC2::NatGateway DependsOn: InternetGatewayAttachment Properties: AllocationId: !GetAtt NatEIP0.AllocationId SubnetId: !Ref PublicSubnet0 NatGateway1: Type: AWS::EC2::NatGateway DependsOn: InternetGatewayAttachment Properties: AllocationId: !GetAtt NatEIP1.AllocationId SubnetId: !Ref PublicSubnet1 NatRoute2: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PrivateRouteTable2 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway0 NatRoute3: Type: AWS::EC2::Route Properties: RouteTableId: !Ref PrivateRouteTable3 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway1 WebServer: Type: AWS::EC2::Instance DependsOn: NatRoute2 Properties: ImageId: !Ref LatestAmiId InstanceType: t3.micro SubnetId: !Ref PrivateSubnet2 UserData: Fn::Base64: !Sub | #!/bin/bash # install updates yum update -y # configure AWS CLI for ec2-user mkdir /home/ec2-user/.aws cat > /home/ec2-user/.aws/config<< EOF [default] region = ${AWS::Region} EOF chown -r ec2-user:ec2-user /home/ec2-user/.aws # set up web server yum install -y httpd echo "

Hello World from $(hostname -f)" > /var/www/html/index.html systemctl enable httpd.service systemctl start httpd.service ClientVpnEndpoint: Type: 'AWS::EC2::ClientVpnEndpoint' Properties: AuthenticationOptions: - Type: "certificate-authentication" MutualAuthentication: ClientRootCertificateChainArn: !Ref Certificate ClientCidrBlock: 10.192.0.0/22 ConnectionLogOptions: Enabled: false DnsServers: - "10.0.0.2" ServerCertificateArn: !Ref Certificate SplitTunnel: false VpcId: !Ref VPC ClientVpnTargetNetworkAssociation1: Type: "AWS::EC2::ClientVpnTargetNetworkAssociation" Properties: ClientVpnEndpointId: Ref: ClientVpnEndpoint SubnetId: Ref: PrivateSubnet2 ClientVpnTargetNetworkAssociation2: Type: "AWS::EC2::ClientVpnTargetNetworkAssociation" Properties: ClientVpnEndpointId: Ref: ClientVpnEndpoint SubnetId: Ref: PrivateSubnet3 ClientVpnAuthorizationRule: Type: "AWS::EC2::ClientVpnAuthorizationRule" Properties: ClientVpnEndpointId: Ref: ClientVpnEndpoint AuthorizeAllGroups: true TargetNetworkCidr: "10.0.0.0/16" Outputs: WebServerURL: Value: !Join [ '', [ 'http://', !GetAtt WebServer.PrivateDnsName ] ]