/ README.md
README.md
 1  # Description
 2  
 3  This repo configures infrastructure for the https://dap.ps/ service.
 4  
 5  The service is split into two stages:
 6  
 7  | Stage | With CDN | Without CDN |
 8  |-|-|-|
 9  | __`prod`__ | https://prod.dap.ps/ | https://raw.prod.dap.ps/ |
10  | __`dev`__  | https://dev.dap.ps/  | https://raw.dev.dap.ps/ |
11  
12  The `prod` environment is `CNAME`ed to `dap.ps` domain.
13  
14  # Technical Details
15  
16  ## Site
17  
18  The infrastructure is hosted on AWS and consists of 5 main elements:
19  
20  * [__ELB__](https://aws.amazon.com/elasticloadbalancing/) - Load balancers
21  * [__EB__](https://aws.amazon.com/elasticbeanstalk/) - Node.js App hosting
22  * [__EC2__](https://aws.amazon.com/ec2/) - [MongoDB](https://www.mongodb.com/) cluster
23  * [__S3__](https://aws.amazon.com/s3/) - [MongoDB](https://www.mongodb.com/) backups & [Terraform](https://www.terraform.io/) state
24  * [__SES__](https://aws.amazon.com/ses/) - Mail forwarding
25  * [__CF__](https://aws.amazon.com/cloudfront/) - [CDN](https://en.wikipedia.org/wiki/Content_delivery_network)
26  * [__R53__](https://aws.amazon.com/route53/) - Route53 DNS
27  
28  All the AWS parts are provisioned and managed with [Terraform](https://www.terraform.io/) and the MongoDB cluster configured with [Ansible](https://www.ansible.com/).
29  
30  The `dap.ps` domain is registered via [Gandi](https://www.gandi.net/) DNS provider and is managed with AWS [Route53](https://aws.amazon.com/route53/) [Hosted Zone](https://docs.aws.amazon.com/Route53/latest/DeveloperGuide/hosted-zones-working-with.html) by changing the Name Servers with help from Gandi support. See `dns.tf` for more details.
31  
32  ## EMail
33  
34  There are no mailboxes for `dap.ps` domain. We forward emails using AWS Lambda and AWS SES. You can change the forwarding rules by editing the `defaultConfig` object in [`files/sesforwarder.js`](files/sesforwarder/index.js) and adding [Verified Emails](https://www.terraform.io/docs/providers/aws/r/ses_email_identity.html) in [`mail.tf`](mail.tf).
35  
36  # Usage
37  
38  Creation of both `dev` and `prod` stages is as simple as:
39  ```
40  terraform init
41  terraform apply
42  ```
43  And then configure the MongoDB hosts using ansible:
44  ```
45  ansible-playbook ansible/dev.yml
46  ansible-playbook ansible/prod.yml
47  ```
48  
49  # Known Issues
50  
51  * The ElasticBeanstalk environments can fail when being recreated
52    - This is mostly due to AWS being slow at destorying resources and their race conditions
53  * There is no easy way of making ElasticBeanstalk spread geographically
54    - The only way seems to have multiple EB environments linked via ELB
55  * CDN can be slow to pick up updates to ElasticBeanstalk application
56    - Invalidating the CloudFront cache fixes the issue
57  
58  # TODO
59  
60  * [#4](https://github.com/dap-ps/infra-dapps/issues/4) - [prod] Geographically spread hosts
61  * [#11](https://github.com/dap-ps/infra-dapps/issues/11) - [prod] MongoDB Web UI
62  * [#13](https://github.com/dap-ps/infra-dapps/issues/13) - [prod] Stress test infrastructure
63  
64  # Links
65  
66  These helped me during work on this setup:
67  
68  * https://docs.aws.amazon.com/elasticbeanstalk/latest/dg/eb-cli3.html
69  * https://aws.amazon.com/getting-started/tutorials/deploy-app-command-line-elastic-beanstalk/
70  * https://medium.com/@vygandas/how-to-deploy-your-nodejs-app-on-amazon-elastic-beanstalk-aws-eb-with-circleci-short-tutorial-d8210d2a7f0c
71  * https://realpython.com/deploying-a-django-app-to-aws-elastic-beanstalk/