vpc_vpn_2az.yaml
---

EC2 Basic CloudFormation Deployment

This CloudFormation template will deploy a single EC2 instance with its own security group.

AWSTemplateFormatVersion: '2010-09-09'

Metadata

Metadata is mostly for organizing and presenting Parameters in a better way when using CloudFormation in the AWS Web UI.

Metadata: AWS::CloudFormation::Interface: ParameterGroups: - Label: default: VPC Settings Parameters: - VPCName - VPCcidr - VPCType - Label: default: Public Subnets Parameters: - SubnetPublicAcidr - SubnetPublicBcidr - Label: default: Private Subnets Parameters: - SubnetPrivateAcidr - SubnetPrivateBcidr - Label: default: VPN Settings Parameters: - VpnASR1IpAddress - VpnASR1BgpAsn - VpnASR2IpAddress - VpnASR2BgpAsn - Label: default: Tagging and Cost Management Parameters: - ServiceTag - EnvironmentTag - ContactNetidTag - AccountNumberTag - TicketNumberTag ParameterLabels: ServiceTag: default: "Service Name:" EnvironmentTag: default: 'Environment Type:' ContactNetidTag: default: 'Contact NetID:' AccountNumberTag: default: 'Financial Account Number:' TicketNumberTag: default: 'Ticket Number:'

Parameters

These are the input parameters for this template. All of these parameters must be supplied for this template to be deployed.

Parameters: VPCName: Type: String Description: Enter the name of the VPC. Used for descriptive purposes. VPCcidr: Type: String Description: VPC CIDR Block. i.e. 10.0.0.0/16 SubnetPublicAcidr: Type: String Description: Public Zone A Subnet Range. i.e. 10.0.1.0/24 SubnetPublicBcidr: Type: String Description: Public Zone B Subnet Range. i.e. 10.0.2.0/24 SubnetPrivateAcidr: Type: String Description: Private Zone A Subnet Range. i.e. 10.0.11.0/24 SubnetPrivateBcidr: Type: String Description: Private Zone B Subnet Range. i.e. 10.0.12.0/24 VpnASR1BgpAsn: Type: String Description: BGP ASN for ASR1, ie 65524 VpnASR1IpAddress: Type: String Description: IP Address for ASR1 connection, ie 206.207.227.86 VpnASR2BgpAsn: Type: String Description: BGP ASN for ASR2, ie 65525 VpnASR2IpAddress: Type: String Description: IP Address for ASR2 connection, ie 206.207.227.102

Prod or NonProd VPC.

VPCType: Description: Single VPN for NonProd, Dual VPN connections for Production. Type: String Default: Non-Production AllowedValues: - Non-Production - Production

Tags

The following tags are applied to all resources created by this template.

ServiceTag: Type: String Description: Exact name of the Service as defined in the service catalog. EnvironmentTag: Type: String Description: Used to distinguish between development, test, production,etc. environment types. AllowedValues: [dev, tst, prd, trn, stg, cfg, sup, rpt] Default: dev ContactNetidTag: Type: String Description: Used to identify the netid of the person most familiar with the usage of the resource. AccountNumberTag: Type: String Description: Identifies the financial system account number. TicketNumberTag: Type: String Description: Used to identify the Jira, Cherwell, or other ticketing system ticket number to link to more information about the need for the resource.

Conditions

Conditions:

From Parameters, is this a Prod or NonProd account? Determines what resources are created.

IsProdVPC: !Equals [!Ref VPCType, 'Production']

Resources

These are all of the resources deployed by this template.

Resources:

VPC

This is the VPC itself. Mostly just naming things here

VpcEcsEas: Type: AWS::EC2::VPC Properties: CidrBlock: Ref: VPCcidr

Be sure to enable DNS support, otherwise the EFS service doesn't work.

EnableDnsSupport: true EnableDnsHostnames: true Tags: - Key: Name Value: !Ref VPCName - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

InternetGateway

Create an InternetGateway

InternetGateway: Type: AWS::EC2::InternetGateway Properties: Tags: - Key: Name Value: !Sub "${VPCName} Internet Gateway" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

InternetGatewayAttachment

Attach the InternetGateway to the VPC

InternetGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: InternetGatewayId: !Ref InternetGateway VpcId: !Ref VpcEcsEas

SubnetPublicZoneA

Create a Public Subnet in Availability Zone A

SubnetPublicZoneA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VpcEcsEas CidrBlock: !Ref SubnetPublicAcidr AvailabilityZone: us-west-2a Tags: - Key: Name Value: !Sub "${VPCName} Public Zone A" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

SubnetPublicZoneB

Create a Public Subnet in Availability Zone B

SubnetPublicZoneB: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VpcEcsEas CidrBlock: !Ref SubnetPublicBcidr AvailabilityZone: us-west-2b Tags: - Key: Name Value: !Sub "${VPCName} Public Zone B" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

SubnetPrivateZoneA

Create a Private Subnet in Availability Zone A

SubnetPrivateZoneA: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VpcEcsEas CidrBlock: !Ref SubnetPrivateAcidr AvailabilityZone: us-west-2a Tags: - Key: Name Value: !Sub "${VPCName} Private Zone A" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

SubnetPrivateZoneB

Create a Private Subnet in Availability Zone B

SubnetPrivateZoneB: Type: AWS::EC2::Subnet Properties: VpcId: !Ref VpcEcsEas CidrBlock: !Ref SubnetPrivateBcidr AvailabilityZone: us-west-2b Tags: - Key: Name Value: !Sub "${VPCName} Private Zone B" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

Public Subnet Configurations

NetworkACLPublic

Create an ACL for the public subnets

NetworkACLPublic: Type: AWS::EC2::NetworkAcl Properties: VpcId: !Ref VpcEcsEas Tags: - Key: Name Value: !Sub "${VPCName} Public ACL" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

Allow in TCP traffic to the public subnet on port 443 (HTTPS)

ACLEntryPublicRuleAllowIn443: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkACLPublic RuleNumber: '100' CidrBlock: 0.0.0.0/0 Protocol: '6' RuleAction: allow Egress: 'false' PortRange: From: '443' To: '443'

Allow in TCP traffic to the public subnet on port 80 (HTTP)

ACLEntryPublicRuleAllowIn80: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkACLPublic RuleNumber: '105' CidrBlock: 0.0.0.0/0 Protocol: '6' RuleAction: allow Egress: 'false' PortRange: From: '80' To: '80'

Allow in TCP traffic to the public subnet on port 22 (SSH)

We allow it in here at the ACL level, but it should be further restricted by security groups.

ACLEntryPublicRuleAllowInSSH: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkACLPublic RuleNumber: '110' CidrBlock: 0.0.0.0/0 Protocol: '6' RuleAction: allow Egress: 'false' PortRange: From: '22' To: '22'

Allow in TCP traffic to the public subnet on port 3389 (RDP)

We allow it in here at the ACL level, but it should be further restricted by security groups.

ACLEntryPublicRuleAllowInRDP: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkACLPublic RuleNumber: '112' CidrBlock: 0.0.0.0/0 Protocol: '6' RuleAction: allow Egress: 'false' PortRange: From: '3389' To: '3389'

Allow in TCP return traffic on ephemeral ports

ACLEntryPublicRuleAllowInReturns: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkACLPublic RuleNumber: '120' CidrBlock: 0.0.0.0/0 Protocol: '6' RuleAction: allow Egress: 'false' PortRange: From: '1024' To: '65535'

Allow all TCP traffic out of the public ACL

ACLEntryPublicRuleAllowOutAll: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkACLPublic RuleNumber: '100' CidrBlock: 0.0.0.0/0 Protocol: '-1' RuleAction: allow Egress: 'true'

Associate The Public ACL with Public Subnet A

SUBNACLF9EG: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: NetworkAclId: !Ref NetworkACLPublic SubnetId: !Ref SubnetPublicZoneA

Associate The Public ACL with Public Subnet B

SUBNACL3MSJZ: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: NetworkAclId: !Ref NetworkACLPublic SubnetId: !Ref SubnetPublicZoneB

Public Subnet Configurations

NetworkACLPrivate

Create an ACL for the private subnets

NetworkACLPrivate: Type: AWS::EC2::NetworkAcl Properties: VpcId: !Ref VpcEcsEas Tags: - Key: Name Value: !Sub "${VPCName} Private ACL" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

Allow in all traffic to the private subnets

ACLEntryPrivateRuleAllowInAll: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkACLPrivate RuleNumber: '100' CidrBlock: 0.0.0.0/0 Protocol: '-1' RuleAction: allow Egress: 'false'

Allow all traffic out of the private subnets

ACLEntryPrivateRuleAllowOutAll: Type: AWS::EC2::NetworkAclEntry Properties: NetworkAclId: !Ref NetworkACLPrivate RuleNumber: '100' CidrBlock: 0.0.0.0/0 Protocol: '-1' RuleAction: allow Egress: 'true'

Associate the Private ACL with Private Subnet A

SUBNACL210V9: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: NetworkAclId: !Ref NetworkACLPrivate SubnetId: !Ref SubnetPrivateZoneA

Associate the Private ACL with Private Subnet B

SUBNACL3P89X: Type: AWS::EC2::SubnetNetworkAclAssociation Properties: NetworkAclId: !Ref NetworkACLPrivate SubnetId: !Ref SubnetPrivateZoneB

Route Tables

Create a Public Route table

RouteTablePublic: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VpcEcsEas Tags: - Key: Name Value: !Sub "${VPCName} Public Route Table" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

Default route for the public subnets

RoutePublicDefault: Type: AWS::EC2::Route Properties: RouteTableId: !Ref RouteTablePublic DestinationCidrBlock: 0.0.0.0/0 GatewayId: !Ref InternetGateway

Associate the public route table with Public Subnet A

SUBRTE3P0OZ: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTablePublic SubnetId: !Ref SubnetPublicZoneA

Associate the public route table with Public Subnet B

SUBRTE8PIH: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTablePublic SubnetId: !Ref SubnetPublicZoneB

Create a Private Route Table

RouteTablePrivate: Type: AWS::EC2::RouteTable Properties: VpcId: !Ref VpcEcsEas Tags: - Key: Name Value: !Sub "${VPCName} Private Route Table"

Enable route propagation between the VGW and the private route table

VPGRoutePropagation: Type: AWS::EC2::VPNGatewayRoutePropagation DependsOn: VGWGatewayAttachment Properties: RouteTableIds: - Ref: RouteTablePrivate VpnGatewayId: !Ref VirtualGateway

Associate the private route table with Private Subnet A

SUBRTE15ME9: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTablePrivate SubnetId: !Ref SubnetPrivateZoneA

Associate the private route table with Private Subnet A

SUBRTE4K7YA: Type: AWS::EC2::SubnetRouteTableAssociation Properties: RouteTableId: !Ref RouteTablePrivate SubnetId: !Ref SubnetPrivateZoneB

Create a VPC Endpoint for S3 access

S3Enpoint: Type: AWS::EC2::VPCEndpoint Properties: VpcId: !Ref VpcEcsEas PolicyDocument: Version: '2012-10-17' Statement: - Effect: Allow Principal: "*" Action: - "*" Resource: - "*" RouteTableIds: - Ref: RouteTablePublic - Ref: RouteTablePrivate ServiceName: !Sub "com.amazonaws.${AWS::Region}.s3"

VPN Configurations

VirtualGateway

Create an Virtual Gateway for the VPN tunnels to use

VirtualGateway: Type: AWS::EC2::VPNGateway Properties: Type: ipsec.1 Tags: - Key: Name Value: !Sub "${VPCName} VPN Gateway" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

Attach the VGW to our VPC

VGWGatewayAttachment: Type: AWS::EC2::VPCGatewayAttachment Properties: VpnGatewayId: !Ref VirtualGateway VpcId: !Ref VpcEcsEas

Create a Customer Gateway to connect to campus (ASR1)

CustomerGatewayASR1: Type: AWS::EC2::CustomerGateway Properties: BgpAsn: !Ref VpnASR1BgpAsn IpAddress: !Ref VpnASR1IpAddress Type: ipsec.1 Tags: - Key: Name Value: !Sub "${VPCName} Gateway ASR1" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

Create a Customer Gateway to connect to campus (ASR2)

CustomerGatewayASR2: Type: AWS::EC2::CustomerGateway Condition: IsProdVPC Properties: BgpAsn: !Ref VpnASR2BgpAsn IpAddress: !Ref VpnASR2IpAddress Type: ipsec.1 Tags: - Key: Name Value: !Sub "${VPCName} Gateway ASR2" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

Create a VPN connection for the ASR1 CustomerGateway

VPNConnectionASR1: Type: AWS::EC2::VPNConnection Properties: Type: ipsec.1 StaticRoutesOnly: 'false' CustomerGatewayId: !Ref CustomerGatewayASR1 VpnGatewayId: !Ref VirtualGateway Tags: - Key: Name Value: !Sub "${VPCName} VPNConnection ASR1" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

Create a VPN connection for the ASR2 CustomerGateway

VPNConnectionASR2: Type: AWS::EC2::VPNConnection Condition: IsProdVPC Properties: Type: ipsec.1 StaticRoutesOnly: 'false' CustomerGatewayId: !Ref CustomerGatewayASR2 VpnGatewayId: !Ref VirtualGateway Tags: - Key: Name Value: !Sub "${VPCName} VPNConnection ASR2" - Key: service Value: !Ref ServiceTag - Key: environment Value: !Ref EnvironmentTag - Key: contactnetid Value: !Ref ContactNetidTag - Key: accountnumber Value: !Ref AccountNumberTag - Key: ticketnumber Value: !Ref TicketNumberTag

Outputs

Output values that can be viewed from the AWS CloudFormation console. Exported names can be used by other stacks via Fn::ImportValue

Outputs: VPCID: Value: !Ref VpcEcsEas Export: Name: !Sub "${AWS::StackName}-vpcid" PublicSubnetA: Value: !Ref SubnetPublicZoneA Export: Name: !Sub "${AWS::StackName}-public-subnet-a" PublicSubnetB: Value: !Ref SubnetPublicZoneB Export: Name: !Sub "${AWS::StackName}-public-subnet-b" PrivateSubnetA: Value: !Ref SubnetPrivateZoneA Export: Name: !Sub "${AWS::StackName}-private-subnet-a" PrivateSubnetB: Value: !Ref SubnetPrivateZoneB Export: Name: !Sub "${AWS::StackName}-private-subnet-b"