Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 5 additions & 18 deletions chat-service.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ Resources:
Value: !Join ['.', ['https://dynamodb', !Ref 'AWS::Region', 'amazonaws.com']]
- Name: ENV_NAME
Value: !Ref 'EnvironmentName'
- Name: LOCAL
Value: false
PortMappings:
- ContainerPort: !Ref 'ContainerPort'
LogConfiguration:
Expand All @@ -102,7 +104,6 @@ Resources:
Type: AWS::ECS::Service
DependsOn:
- HTTPRule
- HTTPSRule
Properties:
ServiceName: !Ref 'ServiceName'
Cluster:
Expand Down Expand Up @@ -141,7 +142,7 @@ Resources:
HealthCheckIntervalSeconds: 6
HealthCheckPath: /
Matcher:
HttpCode: 301
HttpCode: 200
HealthCheckProtocol: HTTP
HealthCheckTimeoutSeconds: 5
HealthyThresholdCount: 2
Expand All @@ -159,9 +160,8 @@ Resources:
Fn::ImportValue:
!Join [':', [!Ref 'EnvironmentName', 'VPCId']]

# Create rules to forward both HTTP and HTTPS traffic to the service's
# target group. The service itself will handle redirecting HTTP traffic
# to HTTPS
# Create rules to forward HTTP traffic to the service's
# target group.
HTTPRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Expand All @@ -175,19 +175,6 @@ Resources:
Fn::ImportValue:
!Join [':', [!Ref 'EnvironmentName', 'PublicListenerHTTP']]
Priority: !Ref 'Priority'
HTTPSRule:
Type: AWS::ElasticLoadBalancingV2::ListenerRule
Properties:
Actions:
- TargetGroupArn: !Ref 'TargetGroup'
Type: 'forward'
Conditions:
- Field: path-pattern
Values: [!Ref 'Path']
ListenerArn:
Fn::ImportValue:
!Join [':', [!Ref 'EnvironmentName', 'PublicListenerHTTPS']]
Priority: !Ref 'Priority'

# Enable autoscaling for this service
ScalableTarget:
Expand Down
21 changes: 0 additions & 21 deletions cluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@ Parameters:
Type: String
Default: production
Description: A name for the environment that this cloudformation will be part of.
CertificateArn:
Type: String
Description: ARN of the Amazon Certificate Manager SSL certificate to use for this app

Mappings:
# Hard values for the subnet masks. These masks define
Expand Down Expand Up @@ -184,19 +181,6 @@ Resources:
LoadBalancerArn: !Ref 'PublicLoadBalancer'
Port: 80
Protocol: HTTP
PublicLoadBalancerListenerHTTPS:
Type: AWS::ElasticLoadBalancingV2::Listener
DependsOn:
- PublicLoadBalancer
Properties:
DefaultActions:
- TargetGroupArn: !Ref 'DummyTargetGroupPublic'
Type: 'forward'
LoadBalancerArn: !Ref 'PublicLoadBalancer'
Port: 443
Protocol: HTTPS
Certificates:
- CertificateArn: !Ref 'CertificateArn'

# This is an IAM role which authorizes ECS to manage resources on your
# account on your behalf, such as updating your load balancer with the
Expand Down Expand Up @@ -324,11 +308,6 @@ Outputs:
Value: !Ref PublicLoadBalancerListenerHTTP
Export:
Name: !Join [ ':', [ !Ref 'EnvironmentName', 'PublicListenerHTTP' ] ]
HTTPSListener:
Description: The ARN of the public load balancer's HTTPS Listener
Value: !Ref PublicLoadBalancerListenerHTTPS
Export:
Name: !Join [ ':', [ !Ref 'EnvironmentName', 'PublicListenerHTTPS' ] ]
VPCId:
Description: The ID of the VPC that this stack is deployed in
Value: !Ref 'VPC'
Expand Down
60 changes: 4 additions & 56 deletions docs/deploy.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,6 @@
# How to deploy this application on AWS

The guide walks you through the process of deploying a production grade copy of this software on your own AWS account. The deployed application will have:

- High availability and autoscaling
- A custom Route 53 powered domain name and an SSL certificate for HTTPS
- A CI/CD pipeline so that you can deploy or redeploy changes to the application with a simple `git commit` + `git push`

## 1. Create a domain name to host the application

Go to [Route 53](https://console.aws.amazon.com/route53/home) and you'll see a box to "Register a domain". Go ahead and purchase a domain name of your choice.

<img src='https://github.com/nathanpeck/socket.io-chat-fargate/raw/master/docs/images/buy-domain.png' width='50%' />

Once your domain is purchased and processed you'll see it show up on [your list of domains](https://console.aws.amazon.com/route53/home?#DomainListing:):

<img src='https://github.com/nathanpeck/socket.io-chat-fargate/raw/master/docs/images/domain-list.png' width='50%' />

## 2. Register an SSL certificate for the domain

Now go to [Amazon Certificate Manager](https://console.aws.amazon.com/acm/home) to get a free SSL certificate for the domain. Click the "Request a certificate" button.

<img src='https://github.com/nathanpeck/socket.io-chat-fargate/raw/master/docs/images/certificate-list.png' width='50%' />

Then we need to select that we want a "public certificate" because this is a certificate public web browsers will use for communicating securely with the chat app.

<img src='https://github.com/nathanpeck/socket.io-chat-fargate/raw/master/docs/images/public-certificate.png' width='50%' />

Then add the list of domains that should be covered by the SSL certificate. For maximum flexibility I prefer to have both the bare domain and a wildcard domain in the same certificate:

<img src='https://github.com/nathanpeck/socket.io-chat-fargate/raw/master/docs/images/cert-domain-list.png' width='50%' />

This allows me to serve HTTPS traffic on https://fargate.chat as well as on any subdomains if for example I want to have https://beta.fargate.chat

ACM can take care of automatically validating the certificate for you if you are also hosting the domain on Route 53. After a few mins I am able to view the details of the created certificate and get the certificate ARN (Amazon Resource Name):

<img src='https://github.com/nathanpeck/socket.io-chat-fargate/raw/master/docs/images/cert-details.png' width='50%' />

Copy that ARN value for usage later.

## 3. Setup a copy of the Github repo for CI/CD
## 1. Setup a copy of the Github repo for CI/CD

First clone this repo onto your Github account by clicking the "Fork" button in the upper right:

Expand All @@ -51,7 +13,7 @@ Then go to your [Github settings to generate a new token](https://github.com/set

These two permissions will allow AWS CodePipeline to monitor the Github repo for changes, and react to updates by redeploying the application.

## 4. Deploy the CodePipeline on your account
## 2. Deploy the CodePipeline on your account

Download the repository using `git clone` and once the source is on your machine look for the file `pipeline.yml` in the top directory of the repo. This is a CloudFormation template which creates a CI/CD pipeline.

Expand Down Expand Up @@ -85,27 +47,13 @@ Once the stages are all done you will see a list of CloudFormation templates tha

<img src='https://github.com/nathanpeck/socket.io-chat-fargate/raw/master/docs/images/cloudformation-template-list.png' width='50%' />

## 5. Create a Route 53 alias for the load balancer.

View the details of the `BaseResources` template. Click the "Outputs" tab and find the output `ExternalUrl`. This is the public facing URL of the load balancer that is in front of the application. However if you just try to access this URL directly you will get an ugly SSL error:

<img src='https://github.com/nathanpeck/socket.io-chat-fargate/raw/master/docs/images/ssl-error.png' width='50%' />

The reason for this is that the load balancer is configured to use an SSL certificate for `*.fargate.chat`. So we need to create a Route 53 alias that points at the load balancer.

Open up [Route 53](https://console.aws.amazon.com/route53/home) again click "Hosted Zones" on the left hand side. Locate the hosted zone for the domain name you created in step #1 and click into it. Then click "Create Record Set". We need to create an A record which points at the load balancer:

<img src='https://github.com/nathanpeck/socket.io-chat-fargate/raw/master/docs/images/create-dns-record.png' width='50%' />

Here I am creating an alias `beta.fargate.chat` of the Alias type and I am configuring the Alias to point at the DNS name of the load balancer for my application stack. I click "Create" and now need to wait a few minutes for DNS to propagate. Route 53 propagates the new record to its DNS servers worldwide within 60 seconds, but sometimes it may take a little while longer for your ISP or other parties to pick up the changes.

## 6. Load up the application
## 3. Load up the application

After you wait a while for DNS to propagate you can then type in the DNS name that you just created in your browser and see your running copy of the chat app!

![running app](./images/running-app.png)

## 7. Make a change!
## 4. Make a change!

Feel free to modify your local copy of the application in your repository. Do a `git commit` and `git push` to push your changes up to Github. CodePipeline will pick up the changes and rereun the pipeline to rebuild the application and roll out your updates with zero downtime.

Expand Down
11 changes: 5 additions & 6 deletions pipeline.yml
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
Parameters:
GitHubRepo:
Type: String
Default: socket.io-chat-fargate
GitHubBranch:
Type: String
Default: master
GitHubToken:
Type: String
NoEcho: true
GitHubUser:
Type: String
EnvironmentName:
Type: String
CertificateArn:
Type: String
Description: ARN of the Amazon Certificate Manager SSL certificate to use for this app
Default: fargate-chat

Resources:
# Create the ECR respository to hold built docker images
# Create the ECR repository to hold built docker images
Repository:
Type: AWS::ECR::Repository
DeletionPolicy: Retain
Expand Down Expand Up @@ -229,8 +229,7 @@ Resources:
Capabilities: CAPABILITY_IAM
ParameterOverrides: !Sub |
{
"EnvironmentName": "${EnvironmentName}",
"CertificateArn": "${CertificateArn}"
"EnvironmentName": "${EnvironmentName}"
}
InputArtifacts:
- Name: Source
Expand Down
4 changes: 2 additions & 2 deletions services/client/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -129,15 +129,15 @@ io.on('connection', function(socket) {
},
{
id: 'eks',
name: 'AWS EKS',
name: 'Amazon EKS',
preview: 'AWS managed Kubernetes masters',
image: '/images/eks.png',
status: 'none',
onlineCount: 0
},
{
id: 'ecs',
name: 'AWS ECS',
name: 'Amazon ECS',
preview: 'AWS container orchestrator',
image: '/images/ecs.png',
status: 'none',
Expand Down