Provisioning Discourse with packer and AWS
Deployment on AWS is managed by cloudformation and all paramters are store on SSM.
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
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.
Steps to follow to update a new version of discourse
- 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
- 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
- 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
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
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
- 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
- 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!
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