Enhance the Makefile
in the infrastructure git project with the following content:
AWS_REGION := eu-central-1
APP_STAGING_VPC_CIDR := 172.16.64.0/18
###############################################################################################
.PHONY: app-staging-vpc
app-staging-vpc:
aws cloudformation deploy \
--no-fail-on-empty-changeset \
--template-file app-staging/vpc.yml \
--stack-name vpc \
--parameter-overrides VpcCidr=$(APP_STAGING_VPC_CIDR) \
--region $(AWS_REGION)
Make sure to use the correct cidr in the APP_STAGING_VPC_CIDR
variable.
Create a new cloudformation template in app-staging/vpc.yml
and define the VPC in there:
---
AWSTemplateFormatVersion: 2010-09-09
Description: VPC setup for account
Parameters:
VpcName:
Description: 'Name of the VPC'
Type: String
Default: 'MainVPC'
VpcCidr:
Description: 'VPC CIDR (eg. 172.16.0.0/18)'
Type: String
Default: '172.16.0.0/18'
Resources:
VPC:
Type: 'AWS::EC2::VPC'
Properties:
CidrBlock: !Ref VpcCidr
EnableDnsSupport: true
EnableDnsHostnames: true
InstanceTenancy: default
Tags:
- Key: Name
Value: !Ref VpcName
InternetGateway:
Type: 'AWS::EC2::InternetGateway'
Properties:
Tags:
- Key: Name
Value: !Ref VpcName
VPCGatewayAttachment:
Type: 'AWS::EC2::VPCGatewayAttachment'
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
SubnetA:
Type: 'AWS::EC2::Subnet'
Properties:
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: !Select [ 0, !Cidr [ !GetAtt VPC.CidrBlock, 8, 9 ]]
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} A private'
SubnetB:
Type: 'AWS::EC2::Subnet'
Properties:
AvailabilityZone: !Select [1, !GetAZs '']
CidrBlock: !Select [ 1, !Cidr [ !GetAtt VPC.CidrBlock, 8, 9 ]]
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} B private'
SubnetC:
Type: 'AWS::EC2::Subnet'
Properties:
AvailabilityZone: !Select [2, !GetAZs '']
CidrBlock: !Select [ 2, !Cidr [ !GetAtt VPC.CidrBlock, 8, 9 ]]
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} C private'
SubnetAPublic:
Type: 'AWS::EC2::Subnet'
Properties:
AvailabilityZone: !Select [0, !GetAZs '']
CidrBlock: !Select [ 3, !Cidr [ !GetAtt VPC.CidrBlock, 8, 9 ]]
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} A public'
SubnetBPublic:
Type: 'AWS::EC2::Subnet'
Properties:
AvailabilityZone: !Select [1, !GetAZs '']
CidrBlock: !Select [ 4, !Cidr [ !GetAtt VPC.CidrBlock, 8, 9 ]]
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} B public'
SubnetCPublic:
Type: 'AWS::EC2::Subnet'
Properties:
AvailabilityZone: !Select [2, !GetAZs '']
CidrBlock: !Select [ 5, !Cidr [ !GetAtt VPC.CidrBlock, 8, 9 ]]
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} C public'
RouteTableA:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} A private'
RouteTableB:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} B private'
RouteTableC:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} C private'
RouteTableAPublic:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} A public'
RouteTableBPublic:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} B public'
RouteTableCPublic:
Type: 'AWS::EC2::RouteTable'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} C public'
RouteTableAssociationA:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetA
RouteTableId: !Ref RouteTableA
RouteTableAssociationB:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetB
RouteTableId: !Ref RouteTableB
RouteTableAssociationC:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetC
RouteTableId: !Ref RouteTableC
RouteTableAssociationAPublic:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetAPublic
RouteTableId: !Ref RouteTableAPublic
RouteTableAssociationBPublic:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetBPublic
RouteTableId: !Ref RouteTableBPublic
RouteTableAssociationCPublic:
Type: 'AWS::EC2::SubnetRouteTableAssociation'
Properties:
SubnetId: !Ref SubnetCPublic
RouteTableId: !Ref RouteTableCPublic
RouteTablePublicAInternetRoute:
Type: 'AWS::EC2::Route'
DependsOn: VPCGatewayAttachment
Properties:
RouteTableId: !Ref RouteTableAPublic
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref InternetGateway
RouteTablePublicBInternetRoute:
Type: 'AWS::EC2::Route'
DependsOn: VPCGatewayAttachment
Properties:
RouteTableId: !Ref RouteTableBPublic
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref InternetGateway
RouteTablePublicCInternetRoute:
Type: 'AWS::EC2::Route'
DependsOn: VPCGatewayAttachment
Properties:
RouteTableId: !Ref RouteTableCPublic
DestinationCidrBlock: '0.0.0.0/0'
GatewayId: !Ref InternetGateway
NetworkAcl:
Type: 'AWS::EC2::NetworkAcl'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} private'
NetworkAclPublic:
Type: 'AWS::EC2::NetworkAcl'
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: !Sub '${VpcName} public'
SubnetNetworkAclAssociationA:
Type: 'AWS::EC2::SubnetNetworkAclAssociation'
Properties:
SubnetId: !Ref SubnetA
NetworkAclId: !Ref NetworkAcl
SubnetNetworkAclAssociationB:
Type: 'AWS::EC2::SubnetNetworkAclAssociation'
Properties:
SubnetId: !Ref SubnetB
NetworkAclId: !Ref NetworkAcl
SubnetNetworkAclAssociationC:
Type: 'AWS::EC2::SubnetNetworkAclAssociation'
Properties:
SubnetId: !Ref SubnetC
NetworkAclId: !Ref NetworkAcl
SubnetNetworkAclAssociationAPublic:
Type: 'AWS::EC2::SubnetNetworkAclAssociation'
Properties:
SubnetId: !Ref SubnetAPublic
NetworkAclId: !Ref NetworkAclPublic
SubnetNetworkAclAssociationBPublic:
Type: 'AWS::EC2::SubnetNetworkAclAssociation'
Properties:
SubnetId: !Ref SubnetBPublic
NetworkAclId: !Ref NetworkAclPublic
SubnetNetworkAclAssociationCPublic:
Type: 'AWS::EC2::SubnetNetworkAclAssociation'
Properties:
SubnetId: !Ref SubnetCPublic
NetworkAclId: !Ref NetworkAclPublic
NetworkAclEntryInAllowVPC:
Type: 'AWS::EC2::NetworkAclEntry'
Properties:
NetworkAclId: !Ref NetworkAcl
RuleNumber: 99
Protocol: -1
RuleAction: allow
Egress: false
CidrBlock: '0.0.0.0/0'
NetworkAclEntryOutAllowVPC:
Type: 'AWS::EC2::NetworkAclEntry'
Properties:
NetworkAclId: !Ref NetworkAcl
RuleNumber: 99
Protocol: -1
RuleAction: allow
Egress: true
CidrBlock: '0.0.0.0/0'
NetworkAclEntryInPublicAllowAll:
Type: 'AWS::EC2::NetworkAclEntry'
Properties:
NetworkAclId: !Ref NetworkAclPublic
RuleNumber: 99
Protocol: -1
RuleAction: allow
Egress: false
CidrBlock: '0.0.0.0/0'
NetworkAclEntryOutPublicAllowAll:
Type: 'AWS::EC2::NetworkAclEntry'
Properties:
NetworkAclId: !Ref NetworkAclPublic
RuleNumber: 99
Protocol: -1
RuleAction: allow
Egress: true
CidrBlock: '0.0.0.0/0'
Outputs:
SubnetsPrivate:
Description: 'Subnets.'
Value: !Join [',', [!Ref SubnetA, !Ref SubnetB, !Ref SubnetC]]
Export:
Name: !Sub '${AWS::StackName}-SubnetsPrivate'
SubnetsPublic:
Description: 'Subnets public.'
Value: !Join [',', [!Ref SubnetAPublic, !Ref SubnetBPublic, !Ref SubnetCPublic]]
Export:
Name: !Sub '${AWS::StackName}-SubnetsPublic'
SubnetA:
Description: 'Subnet A.'
Value: !Ref SubnetA
Export:
Name: !Sub '${AWS::StackName}-SubnetA'
SubnetB:
Description: 'Subnet B.'
Value: !Ref SubnetB
Export:
Name: !Sub '${AWS::StackName}-SubnetB'
SubnetC:
Description: 'Subnet C.'
Value: !Ref SubnetC
Export:
Name: !Sub '${AWS::StackName}-SubnetC'
VPC:
Description: 'VPC.'
Value: !Ref VPC
Export:
Name: !Sub '${AWS::StackName}-VPC'
VPCCIDRBlock:
Description: 'VPC CIDR block.'
Value: !GetAtt VPC.CidrBlock
Export:
Name: !Sub '${AWS::StackName}-VPCCIDRBlock'
RouteTableAPrivate:
Description: 'Route table A private.'
Value: !Ref RouteTableA
Export:
Name: !Sub '${AWS::StackName}-RouteTableAPrivate'
RouteTableBPrivate:
Description: 'Route table B private.'
Value: !Ref RouteTableB
Export:
Name: !Sub '${AWS::StackName}-RouteTableBPrivate'
RouteTableCPrivate:
Description: 'Route table C private.'
Value: !Ref RouteTableC
Export:
Name: !Sub '${AWS::StackName}-RouteTableCPrivate'
Create the Cloudformation stack with the following command in the app-staging AWS account
AWS_PROFILE=myorg-app-staging make app-staging-vpc
The VPC should be created.