--- AWSTemplateFormatVersion: 2010-09-09 Description: Reference Architecture to host Moodle on AWS - Creates New VPC Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: Amazon VPC Parameters Parameters: - NumberOfAZs - AvailabilityZones - VpcCidr - PublicSubnet0Cidr - PublicSubnet1Cidr - PublicSubnet2Cidr - AppSubnet0Cidr - AppSubnet1Cidr - AppSubnet2Cidr - DataSubnet0Cidr - DataSubnet1Cidr - DataSubnet2Cidr ParameterLabels: AvailabilityZones: default: Availability Zones NumberOfAZs: default: Number of Availability Zones VpcCidr: default: VpcCidr PublicSubnet0Cidr: default: Public Subnet 0 PublicSubnet1Cidr: default: Public Subnet 1 PublicSubnet2Cidr: default: Public Subnet 2 AppSubnet0Cidr: default: App Subnet 0 AppSubnet1Cidr: default: App Subnet 1 AppSubnet2Cidr: default: App Subnet 2 DataSubnet0Cidr: default: Data Subnet 0 DataSubnet1Cidr: default: Data Subnet 1 DataSubnet2Cidr: default: Data Subnet 2 Parameters: AvailabilityZones: Description: 'List of Availability Zones to use for the subnets in the VPC. Note: The logical order is preserved.' Type: List NumberOfAZs: AllowedValues: - 1 - 2 - 3 Default: 2 Description: Number of Availability Zones to use in the VPC. This must match your selections in the list of Availability Zones parameter. Type: Number 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 DataSubnet0Cidr: 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.100.0/24 Description: CIDR block for data subnet 0 located in Availability Zone 0 Type: String DataSubnet1Cidr: 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.101.0/24 Description: CIDR block for data subnet 1 located in Availability Zone 1 Type: String DataSubnet2Cidr: 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.102.0/24 Description: CIDR block for data subnet 2 located in Availability Zone 2 Type: String PublicSubnet0Cidr: 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.200.0/24 Description: CIDR block for Public subnet 0 located in Availability Zone 0 Type: String PublicSubnet1Cidr: 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.201.0/24 Description: CIDR block for Public subnet 1 located in Availability Zone 1 Type: String PublicSubnet2Cidr: 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.202.0/24 Description: CIDR block for Public subnet 2 located in Availability Zone 2 Type: String AppSubnet0Cidr: 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/22 Description: CIDR block for App Subnet 0 located in Availability Zone 0 Type: String AppSubnet1Cidr: 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/22 Description: CIDR block for App Subnet 1 located in Availability Zone 1 Type: String AppSubnet2Cidr: 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.8.0/22 Description: CIDR block for App Subnet 2 located in Availability Zone 2 Type: String Conditions: NumberOfAZs1: !Equals [ '1', !Ref NumberOfAZs ] NumberOfAZs2: !Equals [ '2', !Ref NumberOfAZs ] NumberOfAZs3: !Equals [ '3', !Ref NumberOfAZs ] AZ0: !Or - !Condition NumberOfAZs1 - !Condition NumberOfAZs2 - !Condition NumberOfAZs3 AZ1: !Or - !Condition NumberOfAZs2 - !Condition NumberOfAZs3 AZ2: !Condition NumberOfAZs3 Resources: AppSubnet0: Condition: AZ0 Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 0, !Ref AvailabilityZones ] CidrBlock: !Ref AppSubnet0Cidr MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Join [ '', [ 'AppSubnet0 / ', !Ref 'AWS::StackName' ] ] - Key: SubnetType Value: Private VpcId: !Ref Vpc AppSubnet1: Condition: AZ1 Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 1, !Ref AvailabilityZones ] CidrBlock: !Ref AppSubnet1Cidr MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Join [ '', [ 'AppSubnet1 / ', !Ref 'AWS::StackName' ] ] - Key: SubnetType Value: Private VpcId: !Ref Vpc AppSubnet2: Condition: AZ2 Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 2, !Ref AvailabilityZones ] CidrBlock: !Ref AppSubnet2Cidr MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Join [ '', [ 'AppSubnet2 / ', !Ref 'AWS::StackName' ] ] - Key: SubnetType Value: Private VpcId: !Ref Vpc AppSubnetRouteTableAssociation0: Condition: AZ0 Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref NatRouteTable0 SubnetId: !Ref AppSubnet0 AppSubnetRouteTableAssociation1: Condition: AZ1 Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref NatRouteTable1 SubnetId: !Ref AppSubnet1 AppSubnetRouteTableAssociation2: Condition: AZ2 Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref NatRouteTable2 SubnetId: !Ref AppSubnet2 DataSubnet0: Condition: AZ0 Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 0, !Ref AvailabilityZones ] CidrBlock: !Ref DataSubnet0Cidr MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Join [ '', [ 'DataSubnet0 / ', !Ref 'AWS::StackName' ] ] - Key: SubnetType Value: Private VpcId: !Ref Vpc DataSubnet1: Condition: AZ1 Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 1, !Ref AvailabilityZones ] CidrBlock: !Ref DataSubnet1Cidr MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Join [ '', [ 'DataSubnet1 / ', !Ref 'AWS::StackName' ] ] - Key: SubnetType Value: Private VpcId: !Ref Vpc DataSubnet2: Condition: AZ2 Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 2, !Ref AvailabilityZones ] CidrBlock: !Ref DataSubnet2Cidr MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Join [ '', [ 'DataSubnet2 / ', !Ref 'AWS::StackName' ] ] - Key: SubnetType Value: Private VpcId: !Ref Vpc DataSubnetRouteTableAssociation0: Condition: AZ0 Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref NatRouteTable0 SubnetId: !Ref DataSubnet0 DataSubnetRouteTableAssociation1: Condition: AZ1 Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref NatRouteTable1 SubnetId: !Ref DataSubnet1 DataSubnetRouteTableAssociation2: Condition: AZ2 Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref NatRouteTable2 SubnetId: !Ref DataSubnet2 InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Join [ '', [ 'InternetGateway / ', !Ref 'AWS::StackName' ] ] AttachInternetGateway: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref Vpc NatEIP0: Condition: AZ0 Type: AWS::EC2::EIP Properties: Domain: vpc NatGateway0: Condition: AZ0 Type: AWS::EC2::NatGateway DependsOn: AttachInternetGateway Properties: AllocationId: !GetAtt NatEIP0.AllocationId SubnetId: !Ref PublicSubnet0 NatRoute0: Condition: AZ0 Type: AWS::EC2::Route Properties: RouteTableId: !Ref NatRouteTable0 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway0 NatRouteTable0: Condition: AZ0 Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: !Join [ '', ['NatRouteTable0 / ', !Ref 'AWS::StackName' ] ] - Key: Network Value: Public VpcId: !Ref Vpc NatEIP1: Condition: AZ1 Type: AWS::EC2::EIP Properties: Domain: vpc NatGateway1: Condition: AZ1 Type: AWS::EC2::NatGateway DependsOn: AttachInternetGateway Properties: AllocationId: !GetAtt NatEIP1.AllocationId SubnetId: !Ref PublicSubnet1 NatRoute1: Condition: AZ1 Type: AWS::EC2::Route Properties: RouteTableId: !Ref NatRouteTable1 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway1 NatRouteTable1: Condition: AZ1 Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: !Join [ '', [ 'NatRouteTable1 / ', !Ref 'AWS::StackName' ] ] - Key: Network Value: Public VpcId: !Ref Vpc NatEIP2: Condition: AZ2 Type: AWS::EC2::EIP Properties: Domain: vpc NatGateway2: Condition: AZ2 Type: AWS::EC2::NatGateway DependsOn: AttachInternetGateway Properties: AllocationId: !GetAtt NatEIP2.AllocationId SubnetId: !Ref PublicSubnet2 NatRoute2: Condition: AZ2 Type: AWS::EC2::Route Properties: RouteTableId: !Ref NatRouteTable2 DestinationCidrBlock: 0.0.0.0/0 NatGatewayId: !Ref NatGateway2 NatRouteTable2: Condition: AZ2 Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: !Join [ '', [ 'NatRouteTable2 / ', !Ref 'AWS::StackName' ] ] - Key: Network Value: Public VpcId: !Ref Vpc PublicRoute: Type: AWS::EC2::Route DependsOn: AttachInternetGateway Properties: RouteTableId: !Ref PublicRouteTable DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway PublicRouteTable: Type: AWS::EC2::RouteTable Properties: Tags: - Key: Name Value: !Join [ '', [ 'PublicRouteTable / ', !Ref 'AWS::StackName' ] ] - Key: Network Value: Public VpcId: !Ref Vpc PublicRouteTableAssociation0: Condition: AZ0 Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet0 RouteTableId: !Ref PublicRouteTable PublicRouteTableAssociation1: Condition: AZ1 Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet1 RouteTableId: !Ref PublicRouteTable PublicRouteTableAssociation2: Condition: AZ2 Type: AWS::EC2::SubnetRouteTableAssociation Properties: SubnetId: !Ref PublicSubnet2 RouteTableId: !Ref PublicRouteTable PublicSubnet0: Condition: AZ0 Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 0, !Ref AvailabilityZones ] CidrBlock: !Ref PublicSubnet0Cidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Join [ '', [ 'PublicSubnet0 / ', !Ref 'AWS::StackName' ] ] - Key: SubnetType Value: Public VpcId: !Ref Vpc PublicSubnet1: Condition: AZ1 Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 1, !Ref AvailabilityZones ] CidrBlock: !Ref PublicSubnet1Cidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Join [ '', [ 'PublicSubnet1 / ', !Ref 'AWS::StackName' ] ] - Key: SubnetType Value: Public VpcId: !Ref Vpc PublicSubnet2: Condition: AZ2 Type: AWS::EC2::Subnet Properties: AvailabilityZone: !Select [ 2, !Ref AvailabilityZones ] CidrBlock: !Ref PublicSubnet2Cidr MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Join [ '', [ 'PublicSubnet2 / ', !Ref 'AWS::StackName' ] ] - Key: SubnetType Value: Public VpcId: !Ref Vpc Vpc: Type: AWS::EC2::VPC Properties: CidrBlock: !Ref VpcCidr EnableDnsHostnames: true EnableDnsSupport: true Tags: - Key: Name Value: !Join [ '', [ 'Vpc / ', !Ref 'AWS::StackName' ] ] VpcFlowLog: Type: AWS::EC2::FlowLog Properties: DeliverLogsPermissionArn: !GetAtt VpcFlowLogsRole.Arn LogGroupName: !Join [ '', [ !Ref 'AWS::StackName', '-FlowLog' ] ] ResourceId: !Ref Vpc ResourceType: VPC TrafficType: ALL VpcFlowLogsRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Action: - sts:AssumeRole Effect: Allow Principal: Service: - vpc-flow-logs.amazonaws.com Path: '/' Policies: - PolicyName: root PolicyDocument: Version: 2012-10-17 Statement: - Action: - logs:CreateLogGroup - logs:CreateLogStream - logs:DescribeLogGroups - logs:DescribeLogStreams - logs:PutLogEvents Effect: Allow Resource: '*' Outputs: Vpc: Value: !Ref Vpc VpcCidr: Value: !Ref VpcCidr PublicSubnet0: Condition: AZ0 Value: !Ref PublicSubnet0 PublicSubnet1: Condition: AZ1 Value: !Ref PublicSubnet1 PublicSubnet2: Condition: AZ2 Value: !Ref PublicSubnet2 AppSubnet0: Condition: AZ0 Value: !Ref AppSubnet0 AppSubnet1: Condition: AZ1 Value: !Ref AppSubnet1 AppSubnet2: Condition: AZ2 Value: !Ref AppSubnet2 DataSubnet0: Condition: AZ0 Value: !Ref DataSubnet0 DataSubnet1: Condition: AZ1 Value: !Ref DataSubnet1 DataSubnet2: Condition: AZ2 Value: !Ref DataSubnet2 DataSubnet: Value: !If [ NumberOfAZs1, !Ref DataSubnet0, !If [ NumberOfAZs2, !Join [ ',', [ !Ref DataSubnet0, !Ref DataSubnet1 ] ], !Join [ ',', [ !Ref DataSubnet0, !Ref DataSubnet1, !Ref DataSubnet2 ] ] ] ] AppSubnet: Value: !If [ NumberOfAZs1, !Ref AppSubnet0, !If [ NumberOfAZs2, !Join [ ',', [ !Ref AppSubnet0, !Ref AppSubnet1 ] ], !Join [ ',', [ !Ref AppSubnet0, !Ref AppSubnet1, !Ref AppSubnet2 ] ] ] ] PublicSubnet: Value: !If [ NumberOfAZs1, !Ref PublicSubnet0, !If [ NumberOfAZs2, !Join [ ',', [ !Ref PublicSubnet0, !Ref PublicSubnet1 ] ], !Join [ ',', [ !Ref PublicSubnet0, !Ref PublicSubnet1, !Ref PublicSubnet2 ] ] ] ]