Tooling to deploy Discourse on AWS.
- Postgres: RDS
- Rails + Redis: Docker container on Elastic Beanstalk Single Instance deployment
- Docker registry: ECR
- Files and backups: S3
- Outgoing email: SES
- Incoming email + bounce handling: SES + S3 + AWS Lambda
- Passwords for RDS and SES: credstash
- SSL: Let's Encrypt + nginx on the EC2 instance managed by Elastic Beanstalk
- Infrastructure management: Terraform
- Skips
db:migrate
andassets:precompile
on bootstrap - Uses a custom boot script to:
- Fetch passwords and export as environment variables
- Run
db:migrate
andassets:precompie
- Execute the original boot script
- We will have one Elastic Beanstalk application named
discourse
- and two Elastic Beanstalk environments:
discourse-dev
anddiscourse-prod
path/to/your/configs
discourse_aws/ # this repo
containers/app.yml # optional pups template to customize the Docker build
ebextensions/ # optional Elastic Beanstalk configs
dev/*.tf # mix and match modules from discourse_aws/tfmodules..
prod/*.tf # to build AWS resources according to your needs.
discourse_aws/
- bring in this repo in whatever way you like: git submodule, git subtree, or a plain git clone
./containers/app.yml
- this file, if present, will be merged with this repo's
./containers/app.yml
- useful for configuring plugins to install (see:
./samples/app.yml
)
- this file, if present, will be merged with this repo's
./ebextensions/*.config
- any file in here will be copied to the sourcebundle for Elastic Beanstalk
- useful for setting up SSH keys on the EC2 instance (see:
./samples/ssl.config
)
- install Terraform
- set up credstash
- set up your domain name of choice
- CNAME -> cname_prefix.your_aws_region.elasticbeanstalk.com
- MX -> inbound-smtp.your_ses_region.amazonaws.com
- set up SES
- make a new SES user/password
- verify your sender domain or email address
- make a receipt rule set and make it active
- request production access (this can be done later)
- write your own Terraform config by combining modules in
./tfmodules
(see:./samples/main.tf
)- consider setting
certbot_extra_args
to--staging
first to test SSL setup
- consider setting
- plug in Terraform variables
- domain name
- etc
- initial deploy strategy should be AllAtOnce
- plus whenever you expect certbot to create a new certificate
terraform apply
- change db password on RDS
credstash put discourse_db_password.discourse-dev
credstash put discourse_smtp_password.discourse-dev
credstash put discourse_smtp_username.discourse-dev
./build.sh
- builds and tags a Discourse docker image as
vYYYYmmdd-HHMMSS
- builds and tags a Discourse docker image as
- do a
docker push
: exact command will be printed out bybuild.sh
./deploy-dev.sh
- creates and deploys an application version using the latest docker image on ECR:
vYYYYmmdd-HHMMSS-bYYYYmmdd-HHMMSS
- creates and deploys an application version using the latest docker image on ECR:
- change deploy strategy to Immutable to avoid downtime during deploys
same as dev setup except for:
credstash put discourse_db_password.discourse-prod
credstash put discourse_smtp_password.discourse-prod
credstash put discourse_smtp_username.discourse-prod
- deploy script is
./deploy-prod.sh
- deploys the same application version as
discourse-dev
environment's
- deploys the same application version as
- setup s3 upload (otherwise your uploads will be wiped after the next deploy)
- setup s3 backup (optional)
- set up incoming email (advisable - to meet SES's bounce handling guidelines)
- generate a master API key under Admin > API, go to the Lambda function for receiving email, and set the API key as
DISCOURSE_API_KEY
enivonment variable - site setup
- manual polling enabled
- reply by email address
- reply by email enabled
- test email receiver by sending a test email to one of the test email addresses at http://docs.aws.amazon.com/ses/latest/DeveloperGuide/mailbox-simulator.html
- generate a master API key under Admin > API, go to the Lambda function for receiving email, and set the API key as
- go through the setup wizard
- ssh into the instance
- delete staging certs
sudo find /etc/letsencrypt -iname "$your_discourse_hostname*" | xargs rm -rf
- also delete on s3
- remove
--staging
fromcertbot_extra_args
. empty string is okay - redeploy through Elastic Beanstalk console or another
./deploy-dev.sh
/./deploy-prod.sh
- optional: update your
./containers/app.yml
./build.sh
: builds a docker image locallydocker push
: as instructed at the end of./build.sh
's output./deploy-dev.sh
: packages up a new application version and deploys todiscourse-dev
./deploy-prod.sh
: deploys the current application version deployed todiscourse-dev
SMTP credentials is tied to the AWS access key of the user you created.
- Create a new key pair for the existing user
- The access key is the SMTP username
- Calculate the SMTP password using one of the scripts in the AWS documentation
- Update the dev environment
- Update the SMTP credentials:
credstash put discourse_smtp_password.discourse-dev
credstash put discourse_smtp_username.discourse-dev
- Restart app servers of the dev environment through Elastic Beanstalk's console
- Send a test email through
https://<your dev discourse domain>/admin/email
- Update the SMTP credentials:
- Update the prod environment
- Update the SMTP credentials:
credstash put discourse_smtp_password.discourse-prod
credstash put discourse_smtp_username.discourse-prod
- Restart app servers of the prod environment through Elastic Beanstalk's console
- Send a test email through
https://<your prod discourse domain>/admin/email
- Update the SMTP credentials:
- Delete the old AWS access key once the new key's last used time is updated in the IAM console