#Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved. #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. AWSTemplateFormatVersion: "2010-09-09" Description: "AWS Network Firewall Demo using distributed model." Metadata: "AWS::CloudFormation::Interface": ParameterGroups: - Label: default: "VPC Parameters" Parameters: - AvailabilityZoneSelection - Label: default: "EC2 Parameters" Parameters: - LatestAmiId Parameters: AvailabilityZoneSelection: Description: Availability Zone Type: AWS::EC2::AvailabilityZone::Name Default: us-east-1a LatestAmiId: Description: Latest EC2 AMI from Systems Manager Parameter Store Type: 'AWS::SSM::Parameter::Value' Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2' Resources: VPCB: Type: AWS::EC2::VPC Properties: CidrBlock: "10.2.0.0/16" EnableDnsSupport: "true" EnableDnsHostnames: "true" InstanceTenancy: default Tags: - Key: Name Value: !Sub "${AWS::StackName}-vpc" SubnetBWorkload: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPCB CidrBlock: "10.2.1.0/24" AvailabilityZone: Ref: AvailabilityZoneSelection MapPublicIpOnLaunch: true Tags: - Key: Name Value: !Sub "${AWS::StackName}-public-subnet" SubnetBTGW: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPCB CidrBlock: "10.2.0.0/28" AvailabilityZone: Ref: AvailabilityZoneSelection MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub "${AWS::StackName}-private-subnet" SubnetBFirewall: Type: AWS::EC2::Subnet Properties: VpcId: Ref: VPCB CidrBlock: "10.2.16.0/28" AvailabilityZone: Ref: AvailabilityZoneSelection MapPublicIpOnLaunch: false Tags: - Key: Name Value: !Sub "${AWS::StackName}-firewall-subnet" InternetGatewayVPCB: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub "vpcb-igw-${AWS::StackName}" AttachGatewayVPCB: Type: AWS::EC2::VPCGatewayAttachment Properties: VpcId: !Ref VPCB InternetGatewayId: !Ref InternetGatewayVPCB VPCBEndpointSecurityGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: Allow instances to get to SSM Systems Manager VpcId: !Ref VPCB SecurityGroupIngress: - IpProtocol: tcp FromPort: 443 ToPort: 443 CidrIp: 10.2.0.0/16 VPCBSSMEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: true SecurityGroupIds: - !Ref VPCBEndpointSecurityGroup ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssm" SubnetIds: - !Ref SubnetBWorkload VpcEndpointType: Interface VpcId: !Ref VPCB VPCBEC2MessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: true SecurityGroupIds: - !Ref VPCBEndpointSecurityGroup ServiceName: !Sub "com.amazonaws.${AWS::Region}.ec2messages" SubnetIds: - !Ref SubnetBWorkload VpcEndpointType: Interface VpcId: !Ref VPCB VPCBSSMMessagesEndpoint: Type: AWS::EC2::VPCEndpoint Properties: PrivateDnsEnabled: true SecurityGroupIds: - !Ref VPCBEndpointSecurityGroup ServiceName: !Sub "com.amazonaws.${AWS::Region}.ssmmessages" SubnetIds: - !Ref SubnetBWorkload VpcEndpointType: Interface VpcId: !Ref VPCB SubnetBRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "subnet-b-role-${AWS::StackName}" Path: "/" ManagedPolicyArns: - "arn:aws:iam::aws:policy/service-role/AmazonEC2RoleforSSM" AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole SubnetBInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: "/" Roles: - !Ref SubnetBRole SubnetBSecGroup: Type: AWS::EC2::SecurityGroup Properties: GroupDescription: "ICMP acess from 10.0.0.0/8" GroupName: !Sub "${AWS::StackName}-test-instance-sec-group" VpcId: !Ref VPCB SecurityGroupIngress: - IpProtocol: icmp CidrIp: 10.0.0.0/8 FromPort: "-1" ToPort: "-1" EC2SubnetB: Type: 'AWS::EC2::Instance' Properties: ImageId: !Ref LatestAmiId SubnetId: !Ref SubnetBWorkload InstanceType: t2.micro SecurityGroupIds: - !Ref SubnetBSecGroup IamInstanceProfile: !Ref SubnetBInstanceProfile Tags: - Key: Name Value: !Sub "${AWS::StackName}-test-instance" VPCBFirewall: Type: AWS::NetworkFirewall::Firewall Properties: FirewallName: !Sub "${AWS::StackName}-firewall" FirewallPolicyArn: !Ref EgressFirewallPolicy VpcId: !Ref VPCB SubnetMappings: - SubnetId: !Ref SubnetBFirewall Tags: - Key: Name Value: !Sub "${AWS::StackName}-firewall" ICMPAlertStatefulRuleGroup: Type: 'AWS::NetworkFirewall::RuleGroup' Properties: RuleGroupName: !Sub "icmp-alert-${AWS::StackName}" Type: STATEFUL Capacity: 100 RuleGroup: RulesSource: StatefulRules: - Action: ALERT Header: Direction: ANY Protocol: ICMP Destination: ANY Source: ANY DestinationPort: ANY SourcePort: ANY RuleOptions: - Keyword: "sid:1" Tags: - Key: Name Value: !Sub "icmp-alert-${AWS::StackName}" DomainAllowStatefulRuleGroup: Type: 'AWS::NetworkFirewall::RuleGroup' Properties: RuleGroupName: !Sub "domain-allow-${AWS::StackName}" Type: STATEFUL Capacity: 100 RuleGroup: RuleVariables: IPSets: HOME_NET: Definition: - "10.0.0.0/8" RulesSource: RulesSourceList: TargetTypes: - HTTP_HOST - TLS_SNI Targets: - ".amazon.com" GeneratedRulesType: "ALLOWLIST" Tags: - Key: Name Value: !Sub "domain-allow-${AWS::StackName}" EgressFirewallPolicy: Type: AWS::NetworkFirewall::FirewallPolicy Properties: FirewallPolicyName: !Sub "${AWS::StackName}-firewall-policy" FirewallPolicy: StatelessDefaultActions: - 'aws:forward_to_sfe' StatelessFragmentDefaultActions: - 'aws:forward_to_sfe' StatefulRuleGroupReferences: - ResourceArn: !Ref DomainAllowStatefulRuleGroup - ResourceArn: !Ref ICMPAlertStatefulRuleGroup Tags: - Key: Name Value: !Sub "${AWS::StackName}-firewall-policy" VPCBFirewallLogFlowGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/${AWS::StackName}/anfw/flow" VPCBFirewallLogAlertGroup: Type: AWS::Logs::LogGroup Properties: LogGroupName: !Sub "/${AWS::StackName}/anfw/alert" VPCBFirewallLog: Type: AWS::NetworkFirewall::LoggingConfiguration Properties: FirewallArn: !Ref VPCBFirewall LoggingConfiguration: LogDestinationConfigs: - LogType: FLOW LogDestinationType: CloudWatchLogs LogDestination: logGroup: !Sub "/${AWS::StackName}/anfw/flow" - LogType: ALERT LogDestinationType: CloudWatchLogs LogDestination: logGroup: !Sub "/${AWS::StackName}/anfw/alert" SubnetBWorkloadRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPCB Tags: - Key: Name Value: !Sub "subnet-b-workload-route-table-${AWS::StackName}" SubnetBWorkloadRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation DependsOn: SubnetBWorkload Properties: RouteTableId: !Ref SubnetBWorkloadRouteTable SubnetId: !Ref SubnetBWorkload SubnetBWorkloadDefaultRoute: Type: AWS::EC2::Route DependsOn: VPCBFirewall Properties: DestinationCidrBlock: "0.0.0.0/0" VpcEndpointId: !Select [1, !Split [":", !Select [0, !GetAtt VPCBFirewall.EndpointIds]]] RouteTableId: !Ref SubnetBWorkloadRouteTable SubnetBFirewallRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPCB Tags: - Key: Name Value: !Sub "subnet-b-firewall-route-table-${AWS::StackName}" SubnetBFirewallRouteTableAssociation: Type: AWS::EC2::SubnetRouteTableAssociation DependsOn: SubnetBFirewall Properties: RouteTableId: !Ref SubnetBFirewallRouteTable SubnetId: !Ref SubnetBFirewall SubnetBFirewallDefaultRoute: Type: AWS::EC2::Route DependsOn: InternetGatewayVPCB Properties: DestinationCidrBlock: "0.0.0.0/0" GatewayId: !Ref InternetGatewayVPCB RouteTableId: !Ref SubnetBFirewallRouteTable SubnetBIngressRouteTable: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VPCB Tags: - Key: Name Value: !Sub "subnet-b-ingress-route-table-${AWS::StackName}" SubnetBIngressRouteTableAssociation: Type: AWS::EC2::GatewayRouteTableAssociation DependsOn: InternetGatewayVPCB Properties: RouteTableId: !Ref SubnetBIngressRouteTable GatewayId: !Ref InternetGatewayVPCB SubnetBIngressRoute: Type: AWS::EC2::Route DependsOn: VPCBFirewall Properties: DestinationCidrBlock: "10.2.1.0/24" VpcEndpointId: !Select [1, !Split [":", !Select [0, !GetAtt VPCBFirewall.EndpointIds]]] RouteTableId: !Ref SubnetBIngressRouteTable