XPeppers Discourse
Provisioning Discourse with packer and AWS
Deployment on AWS
Deployment on AWS is managed by cloudformation and all paramters are store on SSM.
Prerequisities
Cloudformation Template
Here the cloudformation templates present in cloudformation folder:
- application-tier.yml: application load balancer, autoscaling with golden AMI and route53 record set
- blue-green-update-codepipeline.yml: codepipeline and codebuild
- rds.yml: postgres database
- vpc.yml: vpc and all related resources
- ssm-parameters.yml: all ssm parameters used by the other template
First installation
The first 3 steps are necessary only the first time you init the project.
- Create an empty RDS with version v0 using the template
- Populate file ssm-parameters-default-value.json that creates all parameters used by pipeline.
- Create pipeline using blue-green-update-codepipeline.yml
- Run pipeline
All the next deployment will be managed by codepipeline and the previous step are no more necessary.
Blue-Green deployment
Steps to follow to update a new version of discourse
Creation of green environment
- Read-only mode on discourse:
admin->backup->Enable readonly
- Create RDS snapshot of the discourse database
- Edit parameters in rds-parameters.json updating the snapshot name and db version
- Create new RDS:
⚠️ use the same version set before in the stack name:aws cloudformation create-stack --profile xpeppers --stack-name discourse-rds-v10 --template-body file://rds.yml --region eu-west-1 --enable-termination-protection --capabilities CAPABILITY_NAMED_IAM --parameters file://rds-parameters.json
- Wait the database is created and ready ☕
- Are you sure the database is ready?
- Run packer changing AWS_MFA and DB_URL value:
AWS_PROFILE=xpeppers AWS_MFA=752390 DB_URL='discoursedb-v11.xpeppers.com.' packer build packer-silver-image.json
- Wait again packer finishing
- Get the AMI id resulting in the previous packer build
- Change parameters in application-tier-parameters.json: EnvironmentVersion and AMIid, using a progressive number for version and the previous command AMI id
- Create application layer with cloudformation:
⚠️ use the same version set before in the stack name:aws cloudformation create-stack --profile xpeppers --stack-name discourse-application-tier-v5 --template-body file://application-tier.yml --region eu-west-1 --capabilities CAPABILITY_NAMED_IAM --parameters file://application-tier-parameters.json
Testing the green environment
- Resolve the DNS of the new create load balancer:
dig +short ALB-discourse-v5-596837878.eu-west-1.elb.amazonaws.com
and copy one of the IPs - Open your local /etc/hosts file and append this line:
<ip_previous_command> discourse.xpeppers.com
- Open a new browser and try to connect to discourse.xpeppers.com checking if the answer are coming from the previous address and checking if the new version is ok
- If ok go to the next steps
Switching the environment
- Go to route53 and open xpeppers.com hosted zone name
- Change the value of record discourse.xpeppers.com setting the alias of the new load balancer version
- Disable read-only mode and try again to pusblish something and navigate
- Evaluate if perform a rollback or the keep the new version. This evaluation could be done in some hours of works
Rollback
If new version doesn't work correctly revert the previous version:
- Go to route53 and open xpeppers.com hosted zone name
- Change the value of record discourse.xpeppers.com setting the alias of the OLD load balancer version
- Some contents should be lost
New version is ok
If the new version is ok and you are sure to delete the old version:
- Delete the old application cloudformation stack
- Delete the old RDS cloudformation stack
Discourse operations
Enable-Disable read mode da cli:
- Enter into instance console
cd /var/discourse
sudo ./launcher enter app
RAILS_ENV=production bundle exec rails c
Discourse.disable_readonly_mode(Discourse::USER_READONLY_MODE_KEY)
- Link
Change secret azure app
- Enter into instance console
cd /var/discourse
sudo ./launcher enter app
RAILS_ENV=production bundle exec rails c
- In the rails console:
s = SiteSetting.find_by(name: 'office365_secret')
s.value='<new-token>'
s.save!
Change database password
The next steps are to change the password of postgres and update it directly inside container but it's temporary solution becuase the container gets password externally. To a have a final solution you must rebuild container app.
- Enter the instance
cd /var/discourse
psql -U discourse -h <db-url>
- into postgres db:
\password discourse
- Set new password and exit
\q
sudo ./launcher enter app
- Update password in file
config/discourse.conf
- Restart rails:
rails restart
- Rebuild container or instance with new password