aws/app-network.cf.yaml
AWSTemplateFormatVersion: '2010-09-09'
Description: A very simple VPC for hosting an application
Parameters:
ApplicationName:
Type: String
Description: The name of the application
AllowedPattern: ^[a-z0-9\-]*$
VPCCidrBlock:
Type: String
AllowedPattern: '((\d{1,3})\.){3}\d{1,3}/\d{1,2}'
Default: 10.0.0.0/16
ApplicationDomainNamespace:
Type: String
Description: The DNS domain namespace for the application (e.g. mycoolapplication.com)
AllowedPattern: ^[a-z0-9\-\.]*$
ApolloServicePort:
Type: Number
Description: The port that the Apollo service will be listening on
PrismaServicePort:
Type: Number
Description: The port that the Prisma service will be listening on
Resources:
VPC:
Type: AWS::EC2::VPC
Properties:
CidrBlock: !Ref VPCCidrBlock
EnableDnsHostnames: true
EnableDnsSupport: true
FlowLogsLogGroup:
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 14
FlowLog:
Type: AWS::EC2::FlowLog
Properties:
DeliverLogsPermissionArn:
Fn::ImportValue: !Sub ${ApplicationName}-LoggingRoleArn
LogGroupName: !Ref FlowLogsLogGroup
ResourceId: !Ref VPC
ResourceType: VPC
TrafficType: ALL
CloudTrailBucket:
Type: AWS::S3::Bucket
Properties:
LifecycleConfiguration:
Rules:
- Status: Enabled
ExpirationInDays: 14
CloudTrailBucketPolicy:
Type: AWS::S3::BucketPolicy
Properties:
Bucket:
Ref: CloudTrailBucket
PolicyDocument:
Version: '2012-10-17'
Statement:
- Sid: 'AWSCloudTrailAclCheck'
Effect: 'Allow'
Principal:
Service: 'cloudtrail.amazonaws.com'
Action: 's3:GetBucketAcl'
Resource: !Sub arn:aws:s3:::${CloudTrailBucket}
- Sid: 'AWSCloudTrailWrite'
Effect: 'Allow'
Principal:
Service: 'cloudtrail.amazonaws.com'
Action: 's3:PutObject'
Resource: !Sub arn:aws:s3:::${CloudTrailBucket}/AWSLogs/${AWS::AccountId}/*
Condition:
StringEquals:
s3:x-amz-acl: 'bucket-owner-full-control'
CloudTrailLogGroup:
Type: AWS::Logs::LogGroup
Properties:
RetentionInDays: 14
CloudTrail:
Type: AWS::CloudTrail::Trail
DependsOn:
- CloudTrailBucketPolicy
Properties:
S3BucketName: !Ref CloudTrailBucket
CloudWatchLogsLogGroupArn: !GetAtt CloudTrailLogGroup.Arn
CloudWatchLogsRoleArn:
Fn::ImportValue: !Sub ${ApplicationName}-LoggingRoleArn
IsLogging: true
InternetGateway:
Type: AWS::EC2::InternetGateway
DependsOn: VPC
AttachGateway:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref VPC
InternetGatewayId: !Ref InternetGateway
PublicSubnet01:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: '10.0.10.0/24'
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref 'AWS::Region'
Tags:
- Key: Name
Value: Public01
PublicSubnet02:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: '10.0.20.0/24'
AvailabilityZone: !Select
- 1
- Fn::GetAZs: !Ref 'AWS::Region'
Tags:
- Key: Name
Value: Public02
PublicSubnetNACL:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref VPC
PublicSubnetNACLIngressHTTP:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PublicSubnetNACL
RuleNumber: 1000
Protocol: 6
RuleAction: allow
Egress: false
CidrBlock: 0.0.0.0/0
PortRange:
From: 80
To: 80
PublicSubnetNACLIngressHTTPS:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PublicSubnetNACL
RuleNumber: 2000
Protocol: 6
RuleAction: allow
Egress: false
CidrBlock: 0.0.0.0/0
PortRange:
From: 443
To: 443
PublicSubnetNACLEntryEphemeralWithNAT:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PublicSubnetNACL
RuleNumber: 200
Protocol: 6
RuleAction: allow
Egress: false
CidrBlock: 0.0.0.0/0
PortRange:
From: 1024
To: 65535
PublicSubnetNACLEntryEgressToVPC:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PublicSubnetNACL
RuleNumber: 1000
Protocol: -1
RuleAction: allow
Egress: true
CidrBlock: 0.0.0.0/0
PortRange:
From: 0
To: 65535
PublicSubnet01NACLAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PublicSubnet01
NetworkAclId: !Ref PublicSubnetNACL
PublicSubnet02NACLAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PublicSubnet02
NetworkAclId: !Ref PublicSubnetNACL
PublicRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Public
PublicRoute01:
Type: AWS::EC2::Route
DependsOn: AttachGateway
Properties:
RouteTableId: !Ref PublicRouteTable
DestinationCidrBlock: 0.0.0.0/0
GatewayId: !Ref InternetGateway
PublicSubnet01RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet01
RouteTableId: !Ref PublicRouteTable
PublicSubnet02RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PublicSubnet02
RouteTableId: !Ref PublicRouteTable
EIP:
Type: 'AWS::EC2::EIP'
Properties:
Domain: vpc
NATGateway:
Type: AWS::EC2::NatGateway
Properties:
AllocationId: !GetAtt 'EIP.AllocationId'
SubnetId: !Ref PublicSubnet01
PrivateRouteTable:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref VPC
Tags:
- Key: Name
Value: Private
PrivateRoute01:
Type: AWS::EC2::Route
Properties:
RouteTableId: !Ref PrivateRouteTable
DestinationCidrBlock: 0.0.0.0/0
NatGatewayId: !Ref NATGateway
PrivateSubnet01:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: '10.0.30.0/24'
AvailabilityZone: !Select
- 0
- Fn::GetAZs: !Ref 'AWS::Region'
Tags:
- Key: Name
Value: Private01
PrivateSubnet01RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet01
RouteTableId: !Ref PrivateRouteTable
PrivateSubnet02:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref VPC
CidrBlock: '10.0.40.0/24'
AvailabilityZone: !Select
- 1
- Fn::GetAZs: !Ref 'AWS::Region'
Tags:
- Key: Name
Value: Private02
PrivateSubnet02RouteTableAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
SubnetId: !Ref PrivateSubnet02
RouteTableId: !Ref PrivateRouteTable
PrivateSubnetNACL:
Type: AWS::EC2::NetworkAcl
Properties:
VpcId: !Ref VPC
PrivateSubnetNACLEntryIngressFromVPC:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PrivateSubnetNACL
RuleNumber: 100
Protocol: 6
RuleAction: allow
Egress: false
CidrBlock: !GetAtt VPC.CidrBlock
PortRange:
From: 0
To: 65535
PrivateSubnetNACLEntryIngressEphemeralWithNAT:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PrivateSubnetNACL
RuleNumber: 200
Protocol: 6
RuleAction: allow
Egress: false
CidrBlock: 0.0.0.0/0
PortRange:
From: 1024
To: 65535
PrivateSubnetNACLEntryEgress:
Type: AWS::EC2::NetworkAclEntry
Properties:
NetworkAclId: !Ref PrivateSubnetNACL
RuleNumber: 1000
Protocol: 6
RuleAction: allow
Egress: true
CidrBlock: 0.0.0.0/0
PortRange:
From: 0
To: 65535
PrivateSubnet01NACLAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PrivateSubnet01
NetworkAclId: !Ref PrivateSubnetNACL
PrivateSubnet02NACLAssociation:
Type: AWS::EC2::SubnetNetworkAclAssociation
Properties:
SubnetId: !Ref PrivateSubnet02
NetworkAclId: !Ref PrivateSubnetNACL
ServiceSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for the Mission Control API ELB
VpcId: !Ref VPC
SecurityGroupIngress:
- CidrIp: !GetAtt VPC.CidrBlock
IpProtocol: 'tcp'
FromPort: !Ref ApolloServicePort
ToPort: !Ref ApolloServicePort
- CidrIp: !GetAtt VPC.CidrBlock
IpProtocol: 'tcp'
FromPort: !Ref PrismaServicePort
ToPort: !Ref PrismaServicePort
ProductionHostedZone:
Type: 'AWS::Route53::HostedZone'
Properties:
HostedZoneConfig:
Comment: !Sub Hosted zone for the production environment of ${ApplicationName}
Name: !Ref ApplicationDomainNamespace
PrivateNamespace:
Type: AWS::ServiceDiscovery::PrivateDnsNamespace
Properties:
Name: !Sub private.${ApplicationDomainNamespace}
Vpc: !Ref VPC
Outputs:
VPCID:
Description: The ID of the VPC
Value: !Ref VPC
Export:
Name: !Sub ${ApplicationName}-VPCID
VPCCIDR:
Description: The CIDR block for the VPC
Value: !GetAtt VPC.CidrBlock
Export:
Name: !Sub ${ApplicationName}-VPCCIDR
PublicSubnet01:
Description: ID for public subnet 01
Value: !Ref PublicSubnet01
Export:
Name: !Sub ${ApplicationName}-PublicSubnet01
PublicSubnet02:
Description: ID for public subnet 02
Value: !Ref PublicSubnet02
Export:
Name: !Sub ${ApplicationName}-PublicSubnet02
PrivateSubnet01:
Description: ID for private subnet 01
Value: !Ref PrivateSubnet01
Export:
Name: !Sub ${ApplicationName}-PrivateSubnet01
PrivateSubnet02:
Description: ID for private subnet 02
Value: !Ref PrivateSubnet02
Export:
Name: !Sub ${ApplicationName}-PrivateSubnet02
ServiceSG:
Description: Security group for ECS services
Value: !Ref ServiceSG
Export:
Name: !Sub ${ApplicationName}-ServiceSG
ProductionHostedZone:
Description: HostedZone ID for the production hosted zone
Value: !Ref ProductionHostedZone
Export:
Name: !Sub ${ApplicationName}-production-HostedZone
ProductionPrivateNamespace:
Description: Private namespace for the production environment
Value: !Ref PrivateNamespace
Export:
Name: !Sub ${ApplicationName}-production-PrivateNamespace