aws/env-network.cf.yaml
AWSTemplateFormatVersion: "2010-09-09"
Description: Environment specific AWS resources
Parameters:
ApplicationName:
Type: String
Description: The name of the application
AllowedPattern: ^[a-z0-9\-]*$
EnvironmentName:
Type: String
Description: The name of the application environment
AllowedPattern: ^[a-z0-9\-]*$
ApplicationDomainNamespace:
Type: String
Description: The DNS domain namespace for the application (e.g. mycoolapplication.com)
AllowedPattern: ^[a-z0-9\-]*\.[a-z0-9\-]*$
Conditions:
IsProductionEnvironment: !Equals [ !Ref EnvironmentName, production ]
Resources:
PublicLoadBalancerSG:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Security Group for the load balancer
VpcId:
Fn::ImportValue:
!Sub ${ApplicationName}-VPCID
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
IpProtocol: "tcp"
FromPort: 80
ToPort: 80
- CidrIp: 0.0.0.0/0
IpProtocol: "tcp"
FromPort: 443
ToPort: 443
PrismaLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Type: application
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '30'
Subnets:
- Fn::ImportValue:
!Sub ${ApplicationName}-PublicSubnet01
- Fn::ImportValue:
!Sub ${ApplicationName}-PublicSubnet02
SecurityGroups:
- !Ref PublicLoadBalancerSG
Tags:
- Key: Name
Value: !Sub ${ApplicationName}-${EnvironmentName}-prisma
ApolloLoadBalancer:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Type: application
Scheme: internet-facing
LoadBalancerAttributes:
- Key: idle_timeout.timeout_seconds
Value: '30'
Subnets:
- Fn::ImportValue:
!Sub ${ApplicationName}-PublicSubnet01
- Fn::ImportValue:
!Sub ${ApplicationName}-PublicSubnet02
SecurityGroups:
- !Ref PublicLoadBalancerSG
Tags:
- Key: Name
Value: !Sub ${ApplicationName}-${EnvironmentName}-apollo
PrismaTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /status
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId:
Fn::ImportValue:
!Sub ${ApplicationName}-VPCID
TargetType: 'ip'
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: '10'
Tags:
- Key: Name
Value: !Sub ${ApplicationName}-${EnvironmentName}-prisma
ApolloTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /.well-known/apollo/server-health
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Port: 80
Protocol: HTTP
UnhealthyThresholdCount: 2
VpcId:
Fn::ImportValue:
!Sub ${ApplicationName}-VPCID
TargetType: 'ip'
TargetGroupAttributes:
- Key: deregistration_delay.timeout_seconds
Value: '10'
Tags:
- Key: Name
Value: !Sub ${ApplicationName}-${EnvironmentName}-apollo
PrismaLoadBalancerListenerHTTP:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: redirect
RedirectConfig:
Protocol: HTTPS
Port: '443'
Host: '#{host}'
Path: '/#{path}'
Query: '#{query}'
StatusCode: HTTP_301
LoadBalancerArn: !Ref 'PrismaLoadBalancer'
Protocol: HTTP
Port: 80
ApolloLoadBalancerListenerHTTP:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- Type: redirect
RedirectConfig:
Protocol: HTTPS
Port: '443'
Host: '#{host}'
Path: '/#{path}'
Query: '#{query}'
StatusCode: HTTP_301
LoadBalancerArn: !Ref 'ApolloLoadBalancer'
Protocol: HTTP
Port: 80
PrismaLoadBalancerListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Certificates:
- CertificateArn:
Fn::ImportValue:
!Sub ${ApplicationName}-${EnvironmentName}-Certificate
DefaultActions:
- TargetGroupArn: !Ref 'PrismaTargetGroup'
Type: 'forward'
LoadBalancerArn: !Ref 'PrismaLoadBalancer'
Protocol: HTTPS
Port: 443
ApolloLoadBalancerListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
Certificates:
- CertificateArn:
Fn::ImportValue:
!Sub ${ApplicationName}-${EnvironmentName}-Certificate
DefaultActions:
- TargetGroupArn: !Ref 'ApolloTargetGroup'
Type: 'forward'
LoadBalancerArn: !Ref 'ApolloLoadBalancer'
Protocol: HTTPS
Port: 443
ARecordApolloPublicAPI:
Type: AWS::Route53::RecordSet
Properties:
Comment: !Sub Apollo API A record for the ${EnvironmentName} environment of ${ApplicationName}
HostedZoneId:
Fn::ImportValue:
!Sub ${ApplicationName}-${EnvironmentName}-HostedZone
# Environment A records are added to a subdomain, production records are on the application domain
Name: !If [IsProductionEnvironment, !Sub "apollo.${ApplicationDomainNamespace}", !Sub "apollo.${EnvironmentName}.${ApplicationDomainNamespace}"]
Type: A
AliasTarget:
DNSName: !GetAtt ApolloLoadBalancer.DNSName
HostedZoneId: !GetAtt ApolloLoadBalancer.CanonicalHostedZoneID
ARecordPrismaPublicAPI:
Type: AWS::Route53::RecordSet
Properties:
Comment: !Sub Prisma API A record for the ${EnvironmentName} environment of ${ApplicationName}
HostedZoneId:
Fn::ImportValue:
!Sub ${ApplicationName}-${EnvironmentName}-HostedZone
# Environment A records are added to a subdomain, production records are on the application domain
Name: !If [IsProductionEnvironment, !Sub "prisma.${ApplicationDomainNamespace}", !Sub "prisma.${EnvironmentName}.${ApplicationDomainNamespace}"]
Type: A
AliasTarget:
DNSName: !GetAtt PrismaLoadBalancer.DNSName
HostedZoneId: !GetAtt PrismaLoadBalancer.CanonicalHostedZoneID
ECSCluster:
Type: "AWS::ECS::Cluster"
Properties:
ClusterName: !Sub ${ApplicationName}-${EnvironmentName}
Outputs:
PrismaTargetGroup:
Description: The target group for the Prisma service
Value: !Ref PrismaTargetGroup
Export:
Name: !Sub ${ApplicationName}-${EnvironmentName}-PrismaTargetGroup
ApolloTargetGroup:
Description: The target group for the Apollo service
Value: !Ref ApolloTargetGroup
Export:
Name: !Sub ${ApplicationName}-${EnvironmentName}-ApolloTargetGroup
ECSCluster:
Description: The ECS cluster
Value: !Ref ECSCluster
Export:
Name: !Sub ${ApplicationName}-${EnvironmentName}-ECSCluster