AWSTemplateFormatVersion: 2010-09-09 Description: | This template deploys a VPC with a public and private subnet in one Availability Zone, an Internet Gateway with a default route to it on the public subnet. The template also deploys a NAT Gateway and a default route to it in the private subnet. Also, VPC security groups are created of the instances and FSxN file systems. **WARNING** This template creates AWS resources. You will be billed for the AWS resources used if you create a stack from this template. Metadata: Authors: Description: Matt Morris (morrmt@amazon.com) License: Description: | Copyright 2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.' Parameters: VpcAz: Description: Choose an availability zone for this compute environment. Type: 'AWS::EC2::AvailabilityZone::Name' LSFClusterName: Default: LSFCluster Description: An environment name that will be prefixed to resource names Type: String VpcCIDR: Default: 172.30.0.0/16 Description: Enter the IP range in CIDR notation for this VPC. This should be a /16. Type: String 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 PublicSubnet1CIDR: Default: 172.30.32.0/24 Description: Enter the IP range in CIDR notation for the public subnet. This should be a /24. Type: String 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 PrivateSubnet1CIDR: Default: 172.30.0.0/19 Description: Enter the IP range in CIDR notation for the private subnet. This should be a /19. Type: String 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 SshSource: Description: "CIDR range that can ssh into the infrastructure instances. Use your public IP address (http://checkip.amazonaws.com)." Type: String Default: 0.0.0.0/32 AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2}) ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x. Resources: EDAVPC: Type: 'AWS::EC2::VPC' Properties: CidrBlock: !Ref VpcCIDR EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: !Sub '${AWS::StackName}-${LSFClusterName}' DefaultPrivateRoute1: Type: 'AWS::EC2::Route' Properties: DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway1 RouteTableId: !Ref PrivateRouteTable1 DefaultPublicRoute: Type: 'AWS::EC2::Route' DependsOn: InternetGatewayAttachment Properties: DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway RouteTableId: !Ref PublicRouteTable InternetGateway: Type: 'AWS::EC2::InternetGateway' Properties: Tags: - Key: Name Value: !Ref LSFClusterName InternetGatewayAttachment: Type: 'AWS::EC2::VPCGatewayAttachment' Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref EDAVPC NatGateway1: Type: 'AWS::EC2::NatGateway' Properties: AllocationId: !GetAtt - NatGateway1EIP - AllocationId SubnetId: !Ref PublicSubnet1 NatGateway1EIP: Type: 'AWS::EC2::EIP' DependsOn: InternetGatewayAttachment Properties: Domain: vpc NoIngressSecurityGroup: Type: 'AWS::EC2::SecurityGroup' Properties: GroupDescription: Security group with no ingress rule GroupName: no-ingress-sg VpcId: !Ref EDAVPC # Explicit 'retain' required for this route table. # FSxN can't delete its file systems without a route table. PrivateRouteTable1: Type: 'AWS::EC2::RouteTable' DeletionPolicy: Retain UpdateReplacePolicy: Retain Properties: Tags: - Key: Name Value: !Sub '${LSFClusterName}PrivateRoutes' VpcId: !Ref EDAVPC PublicRouteTable: Type: 'AWS::EC2::RouteTable' Properties: Tags: - Key: Name Value: !Sub '${LSFClusterName}PublicRoutes' VpcId: !Ref EDAVPC PrivateSubnet1RouteTableAssociation: Properties: RouteTableId: !Ref PrivateRouteTable1 SubnetId: !Ref PrivateSubnet1 Type: 'AWS::EC2::SubnetRouteTableAssociation' PublicSubnet1RouteTableAssociation: Type: 'AWS::EC2::SubnetRouteTableAssociation' Properties: RouteTableId: !Ref PublicRouteTable SubnetId: !Ref PublicSubnet1 PrivateSubnet1: Type: 'AWS::EC2::Subnet' Properties: AvailabilityZone: !Ref VpcAz CidrBlock: !Ref PrivateSubnet1CIDR MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub '${LSFClusterName} Private Subnet' VpcId: !Ref EDAVPC PublicSubnet1: Type: 'AWS::EC2::Subnet' Properties: AvailabilityZone: !Ref VpcAz CidrBlock: !Ref PublicSubnet1CIDR MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub '${LSFClusterName} Public Subnet' VpcId: !Ref EDAVPC S3VPCEndpoint: Type: 'AWS::EC2::VPCEndpoint' Properties: PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: '*' Action: "*" Resource: "*" RouteTableIds: - !Ref PublicRouteTable ServiceName: !Sub 'com.amazonaws.${AWS::Region}.s3' VpcId: !Ref EDAVPC VPCFlowLog: Type: AWS::EC2::FlowLog Properties: DeliverLogsPermissionArn: !GetAtt FlowLogRole.Arn LogGroupName: !Ref FlowLogGroup ResourceId: !Ref EDAVPC ResourceType: VPC TrafficType: ALL FlowLogGroup: Type: 'AWS::Logs::LogGroup' Properties: RetentionInDays: 3 FlowLogRole: Type: 'AWS::IAM::Role' Properties: AssumeRolePolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: Service: 'vpc-flow-logs.amazonaws.com' Action: 'sts:AssumeRole' Policies: - PolicyName: 'flowlogs-policy' PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Action: - 'logs:CreateLogStream' - 'logs:PutLogEvents' - 'logs:DescribeLogGroups' - 'logs:DescribeLogStreams' Resource: !GetAtt 'FlowLogGroup.Arn' LSFMasterSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "SG for LSF Master" VpcId: !Ref EDAVPC SecurityGroupEgress: - CidrIp: 0.0.0.0/0 Description: Allows egress to all ports IpProtocol: "-1" LSFMasterSGRule01: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref LSFMasterSG Description: "SSH ingress" IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref SshSource LSFMasterSGRule02: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref LSFMasterSG Description: "All traffic from LSF Compute Nodes" IpProtocol: "-1" SourceSecurityGroupId: !Ref LSFComputeNodeSG LSFMasterSGRule03: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref LSFMasterSG Description: "All traffic from Login Server" IpProtocol: "-1" SourceSecurityGroupId: !Ref LoginServerSG LSFComputeNodeSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "SG for LSF Compute Nodes" VpcId: !Ref EDAVPC LSFComputeNodeSGRule01: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref LSFComputeNodeSG Description: "All traffic from LSF Master" IpProtocol: "-1" SourceSecurityGroupId: !Ref LSFMasterSG LSFComputeNodeSGRule02: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref LSFComputeNodeSG Description: "All traffic from other LSF exec hosts" IpProtocol: "-1" SourceSecurityGroupId: !Ref LSFComputeNodeSG LSFComputeNodeSGRule03: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref LSFComputeNodeSG Description: "SSH Ingress" IpProtocol: "tcp" FromPort: 22 ToPort: 22 CidrIp: !Ref SshSource LoginServerSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "SG for Login Servers" VpcId: !Ref EDAVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 CidrIp: !Ref SshSource Description: "SSH from remote client" - IpProtocol: tcp FromPort: 8443 ToPort: 8443 CidrIp: !Ref SshSource Description: "DCV WebSocket traffic" - IpProtocol: udp FromPort: 8443 ToPort: 8443 CidrIp: !Ref SshSource Description: "DCV QUIC UDP traffic" FSxOntapSG: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "SG for FSxN file systems" VpcId: !Ref EDAVPC SecurityGroupIngress: - IpProtocol: tcp FromPort: 22 ToPort: 22 SourceSecurityGroupId: !Ref LSFMasterSG Description: "SSH from LSF Mgmt Server" FSxOntapSGRule01: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref FSxOntapSG Description: "NFS traffic from LSF Mgmt Server" IpProtocol: -1 SourceSecurityGroupId: !Ref LSFMasterSG FSxOntapSGRule02: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref FSxOntapSG Description: "NFS traffic from LSF compute nodes" IpProtocol: -1 SourceSecurityGroupId: !Ref LSFComputeNodeSG FSxOntapSGRule03: Type: AWS::EC2::SecurityGroupIngress Properties: GroupId: !Ref FSxOntapSG Description: "NFS traffic from LSF login servers" IpProtocol: -1 SourceSecurityGroupId: !Ref LoginServerSG Outputs: NoIngressSecurityGroup: Description: Security group with no ingress rule Value: !Ref NoIngressSecurityGroup PrivateSubnet1: Description: A reference to the private subnet Value: !Ref PrivateSubnet1 PublicSubnet1: Description: A reference to the public subnet Value: !Ref PublicSubnet1 EnvVpc: Description: The ID of the VPC Value: !Ref EDAVPC Export: Name: !Join [ '-', [ !Ref LSFClusterName, "EDAVPC" ] ] VpcCIDR: Description: The CIDR of the VPC Value: !Ref VpcCIDR Export: Name: !Join [ '-', [ !Ref LSFClusterName, "VpcCIDR" ] ] PublicSubnet: Description: Public subnet exported for use by other stacks Value: Ref: PublicSubnet1 Export: Name: !Join [ '-', [ !Ref LSFClusterName,"PublicSubnet" ] ] PrivateSubnet: Description: Private subnet export for use by other stacks Value: Ref: PrivateSubnet1 Export: Name: !Join [ '-', [ !Ref LSFClusterName,"PrivateSubnet" ] ] PublicRouteTable: Description: Route Table for Public Subnet Value: Ref: PublicRouteTable Export: Name: !Join [ '-', [ !Ref LSFClusterName,"PublicRouteTable" ] ] PrivateRouteTable: Description: Route Table for Private Subnet Value: Ref: PrivateRouteTable1 Export: Name: !Join [ '-', [ !Ref LSFClusterName,"PrivateRouteTable" ] ] LSFMasterSG: Description: Security group for LSF Master Value: Ref: LSFMasterSG Export: Name: !Join [ '-', [ !Ref LSFClusterName,"LSFMasterSG" ] ] LSFComputeNodeSG: Description: Security group export for LSF Compute Nodes Value: Ref: LSFComputeNodeSG Export: Name: !Join [ '-', [ !Ref LSFClusterName,"LSFComputeNodeSG" ] ] LoginServerSG: Description: Security group export for Login Servers Value: Ref: LoginServerSG Export: Name: !Join [ '-', [ !Ref LSFClusterName,"LoginServerSG" ] ] FSxOntapSG: Description: Security group for NFS Servers Value: Ref: FSxOntapSG Export: Name: !Join [ '-', [ !Ref LSFClusterName,"FSxOntapSG" ] ]