Skip to content

theonestack/hl-component-vpc-v2

Repository files navigation

vpc-v2 CfHighlander component

Base component in which to build AWS network based resources from such as EC2, RDS and ECS

kurgan add vpc-v2

Requirements

Parameters

Name Use Default Global Type Allowed Values
EnvironmentName Tagging dev true string
EnvironmentType Tagging development true string ['development','production']
DnsDomain create route53 zone true string
CIDR override vpc cidr config vpc_cidr: false CommaDelimitedList
SubnetBits The number of subnet bits for the each subnet CIDR. For example, specifying a value "8" for this parameter will create a CIDR with a mask of "/24" 32 - subnet_mask false string
GroupSubnets list of subnet ciders for each subnet group false string
AvailabiltiyZones set the az count for the stack max_availability_zones: false string
NatType Select the NAT type managed false string [managed,instances,disabled]
NatGateways NAT Gateway count. If larger than AvailabiltiyZones value, the smaller is used max_availability_zones: false string
NatGatewayEIPs List of EIP Ids, must be the same length as NatGateways' false CommaDelimitedList
NatInstanceType Ec2 instance type t3.micro false string
NatAmi Amazon Machine Image Id as a string or ssm parameter /aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-ebs false SSM Parameter
NatInstancesSpot Enable spot for the EC2 Nat Instances true false String ['true','false']
EnableTransitVPC Allows conditional creation of the the transit vpc resources true false String ['true','false']

Configuration

Selecting Availability Zones

By default the vpc-v2 component will automatically select the AZs. This is achieved by looping over the max_availability_zones count and using the Fn::GetAZs Cloudformation function to select the AZ id.

max_availability_zones.times |az|
  selected_az = FnSelect(az, FnGetAZs(Ref('AWS::Region')))
end

However if you wish to define which as AZs you want to use you can by configuring a map per AWS account with the AZs you wish to use. NOTE: the total count of AZ's defined in the map for each account has to be the same value as max_availability_zones.

To configure your AZ settings, set az_mapping to true

az_mapping: true

Then configure a Map in the following structure to define your AZs

Accounts:
  '000000000000': # AWS Account Id
    AZs: '3,5,0' # Comma delimited list of numerical values that maps to the Availability Zone for that account

the numerical values will map to the Availability Zone retuned from the Fn::GetAZs function in the AWS account. For example in us-east-1 returns

[ "us-east-1a", "us-east-1b", "us-east-1c", "us-east-1d", "us-east-1e", "us-east-1f" ]

therefore the mapping AZs: '3,5,0' will use AZs [ "us-east-1d", "us-east-1f", "us-east-1a" ]

the new function to retrieve the AZ becomes

max_availability_zones.times |az|
  selected_az = FnSelect(FnSelect(az, FnSplit(',', FnFindInMap('Accounts', Ref('AWS::AccountId'), 'AZs'))), FnGetAZs(Ref('AWS::Region')))
end

Subnetting

Subnet Allocation

There are 2 subnetting options defined by the subnet_parameters config option.

subnet_parameters: false
  • false False is the default value set in the config. This option will calculate the subnet cidrs for each subnet using the CloudFormation Fn::Cidr function. The CIDR and SubnetBits parameters can be changed at runtime when creating the stack. The subnets are allocated in sequential order per subnet group with the subnet_multiplyer config option determining how many cidrs are allocated per group.

  • true True uses a local cidr calculation function which exposes the subnet cidrs as a CommaDelimitedList for each subnet group. Useful if you want full control over your subnet cidr allocation. The SubnetBits parameter is not available with this option as it has not effect on the subnetting.

For example, the vpc cidr 192.168.0.0/24 used to generate 3 /27 subnets. The VPCCidr parameter default value is 192.168.0.0/24 and generates the parameter PublicSubnets with a default value of 192.168.0.0/27,192.168.0.32/27,192.168.0.64/27.

Take a look at the AWS documentation on the VPC subnetting restrictions.

The following subnet config bellow apply to both options

Subnet Groups

Default subnet groups that will be created in the VPC stack.

subnets:
  public:
    name: Public
    type: public
  compute:
    name: Compute
    type: private
    enable: true
  persistence:
    name: Persistence
    type: private
    enable: true
  cache:
    name: Cache
    type: private
    enable: true

each private default private group can be disabled with a cfhighlander project. The following example disables all the default private subnet groups and creates a new MyCustom subnet group. Note The public subnet group can't be disabled.

subnets:
  mycustom:
    name: MyCustom
    type: private
    enable: true
  compute:
    enable: false
  persistence:
    enable: true
  cache:
    enable: true

Subnet Multiplyer

Determines how many subnets will allocated per subnet group. Update would require replacement of the whole VPC stack.

subnet_multiplyer: 4

Max Availability Zones

Determines the maximum amount of availability zones this stack can create. Cannot be a larger number than subnet_multiplyer. Update to a larger value would have no effect if the AvailabiltiyZones parameter stays the same. Update to a smaller value may remove az's if the value is smaller than the AvailabiltiyZones parameter.

max_availability_zones: 3

Subnet Mask

Determines the subnet size of the subnets

subnet_mask: 24

VPC Cidr

The value is used to generate the subnet bits for each subnet.

vpc_cidr: 10.0.0.0/16

NetworkACLs

2 NACLs are created, one for public subnets and the other for private subnets. The rules on these acls can be modified using the acl_rules config.

the default public rules are tcp ports 80, 443 and 1024-65535 from 0.0.0.0/0 the default private rules are allow everything

acl_rules:
  -
    # public or private nacl
    acl: public
    # the rule number. if multiple ips are used this value is incremented by 1 for each ip
    number: 100
    # the port range. if to: is not set from is is used
    from: 1024
    to: 65535
    # protocol, defaults to tcp
    protocol: tcp
    # specify a specific ip
    cidr: 0.0.0.0/0
    # specify a range of ips or ip_block or the vpc cidr using the term `stack`
    ips:
      - vpn
      - stack
      
ip_blocks:
  vpn:
    1.1.1.1/32

VPC Gateway Endpoints

S3 and DynamoDB VPC Gateway Endpoints are always created and added to all route tables.

VPC Interface Endpoints

List of aws service interface endpoints to enable access over the private network. See here for more info on available endpoints. Note: each vpce is priced per interface per az plus data throughput.

endpoints:
  - ec2
  - ec2.api

Override the default vpce interface subnets

endpoint_subnets: Compute

DNS

defines the dns format for the project using a Fn::Fub:. There a 2 common patterns

  1. use the same root domain across all environments and have the stack create a sub domain
dns_format: ${EnvironmentName}.${DnsDomain}
  1. have a different root zone for each environment
dns_format: ${DnsDomain}

DHCP

by default a dhcp option group is created using the provided dns name and the amazon provided dns name servers. this can be disabled by setting the following config to remove the DHCPOptions and VPCDHCPOptionsAssociation resources from the template.

enable_dhcp: false

NAT

NATs can be toggled between NAT Instances (EC2) and AWS managed NAT Gateways. Check out this table for comparison

Select the amount of nat's to deploy for the environment, max is 1 per az and min is 1. If less than the max az count is selected, the default route is directed out through Nat in AZ 0

Managed

  • AWS managed NAT Gateway
  • Attaches EIP
  • Can be more expensive
  • Can't be shut down
  • Easier to manage
  • Guaranteed high network throughput
  • Recommended for production type environments

Instances

  • EC2 instance in an ASG per availabiltiy zone
  • Attaches a secondary ENI with a EIP
  • Creates an extra attack surface
  • Network through put limited by the instance type
  • Can be cheaper using small instance sizes and utilising the spot market
  • Can be shutdown saving on cost
  • Recommended for development type environments

Disabled

  • No resources associated with NAT Gateways are created
  • Recommended for when no public access is required
  • If you want to move between Managed NAT and Instances you must update to disabled first. This is due to EIP's already being attached to the current NAT ENI or Gateway.

AMI Requirements

Transit VPC

To render the resources required in the template set the enable_transit_vpc config to true. The resources are conditional based upon the EnableTransitVPC runtime parameter, set the value to true to create the resources for the stack.

enable_transit_vpc: true

To set the Amazon side Asn for the VpnGateway set the following config with the desired value.

vgw_asn: 64512

Private VPC

A Private VPC is a vpc without its own access to the internet, it does not require an InternetGateway or NAT Gateway's/Instances.

Configure the NAT type as disabled as outlined here

By default an internet gateway is created and attached to the VPC, with a route out to the internet configured within the public route table. This can be disabled by setting the following config to remove the InternetGateway,VPCGatewayAttachment and Route resources from the template.

enable_internet_gateway: false

Outputs/Exports

Name Value Exported
VPCId VPCId true
VPCCidr VPCCidr true
HostedZone Hosted Zone Id true
GroupSubnets CommaDelimitedList of each subnet group true

Included Components

route53-zone

If your using environment sub domains and you want to automatically delegate the domain to the root, specify

manage_ns_records: true