Upgrading to Caddy Cluster
In previous chapter, we provisioned just a single Caddy instance, and the TLS certificate is stored on the instance. In this chapter we will build a Caddy cluster so each Caddy instance is load-balanced. We will also build a Redis server, TLS certificates will be stored on Redis and can be retrieved by Caddy cluster.
manifest.yml |
---|
| # The manifest for the "caddy-webserver" service.
# Read the full specification for the "Load Balanced Web Service" type at:
# https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/
# Your service name will be used in naming your resources like log groups, ECS services, etc.
name: nlb
type: Load Balanced Web Service
# Distribute traffic to your service.
# Configuration for your containers and service.
image:
# Docker build arguments. For additional overrides: https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#image-build
build: Dockerfile
# Port exposed through your container to route traffic to it.
port: 443
http: false
nlb:
port: 443/tcp
additional_listeners:
- port: 80/tcp
cpu: 256 # Number of CPU units for the task.
memory: 512 # Amount of memory in MiB used by the task.
platform: linux/x86_64 # See https://aws.github.io/copilot-cli/docs/manifest/lb-web-service/#platform
count: 3 # Number of tasks that should be running in your service.
exec: true # Enable running commands in your container.
network:
connect: true # Enable Service Connect for intra-environment traffic between services.
|
line 28: change task count from 1 to 3.
Adding a Redis server
copilot/caddy/addons/template.yml |
---|
| Parameters:
App:
Type: String
Description: Your application's name.
Env:
Type: String
Description: The environment name your service, job, or workflow is being deployed to.
Name:
Type: String
Description: The name of the service, job, or workflow being deployed.
Resources:
# Subnet group to control where the Redis gets placed
RedisSubnetGroup:
Type: AWS::ElastiCache::SubnetGroup
Properties:
Description: Group of subnets to place Redis into
SubnetIds: !Split [ ',', { 'Fn::ImportValue': !Sub '${App}-${Env}-PrivateSubnets' } ]
# Security group to add the Redis cluster to the VPC,
# and to allow the Fargate containers to talk to Redis on port 6379
RedisSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: "Redis Security Group"
VpcId: { 'Fn::ImportValue': !Sub '${App}-${Env}-VpcId' }
# Enable ingress from other ECS services created within the environment.
RedisIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
Description: Ingress from Fargate containers
GroupId: !Ref 'RedisSecurityGroup'
IpProtocol: tcp
FromPort: 6379
ToPort: 6379
SourceSecurityGroupId: { 'Fn::ImportValue': !Sub '${App}-${Env}-EnvironmentSecurityGroup' }
# The cluster itself.
Redis:
Type: AWS::ElastiCache::CacheCluster
Properties:
Engine: redis
CacheNodeType: cache.t2.micro
NumCacheNodes: 1
CacheSubnetGroupName: !Ref 'RedisSubnetGroup'
VpcSecurityGroupIds:
- !GetAtt 'RedisSecurityGroup.GroupId'
# Redis endpoint stored in SSM so that other services can retrieve the endpoint.
RedisEndpointAddressParam:
Type: AWS::SSM::Parameter
Properties:
Name: !Sub '/${App}/${Env}/${Name}/redis' # Other services can retrieve the endpoint from this path.
Type: String
Value: !GetAtt 'Redis.RedisEndpoint.Address'
Outputs:
RedisEndpoint:
Description: The endpoint of the redis cluster
Value: !GetAtt 'Redis.RedisEndpoint.Address'
Export:
Name: RedisEndpoint
|
Adding environment variables to Network Load Balancer Manifest
copilot/nlb/manifest.yml |
---|
| variables:
CADDY_CLUSTERING_REDIS_HOST:
from_cfn: RedisEndpoint
CADDY_CLUSTERING_REDIS_TLS: false
CADDY_CLUSTERING_REDIS_TLS_INSECURE: true
|
Updating Caddyfile to store TLS certs in Redis
| {
debug
on_demand_tls {
ask https://portfolio-starter-kit-beta-six.vercel.app/api/tls_authoriser
burst 5
interval 2m
}
storage redis {
host {$CADDY_CLUSTERING_REDIS_HOST}
tls_enabled {$CADDY_CLUSTERING_REDIS_TLS}
tls_insecure {$CADDY_CLUSTERING_REDIS_TLS_INSECURE}
}
}
https:// {
tls {
on_demand
}
reverse_proxy https://portfolio-starter-kit-beta-six.vercel.app {
header_down Strict-Transport-Security max-age=31536000
header_up X-Real-IP {remote}
header_up Host {upstream_hostport}
}
}
|