Skip to content

Latest commit

 

History

History
232 lines (179 loc) · 10.5 KB

README.md

File metadata and controls

232 lines (179 loc) · 10.5 KB

Deploying ClientComm to production

ClientComm uses a number of third-party services to operate. You will need to have credentials with all these services to run ClientComm in production.

Heroku, Twilio, AWS, and Mailgun are critical services; ClientComm cannot run without them. LastPass, Pingdom, Sentry, Skylight, Mixpanel, and Intercom are useful tools for developing, maintaining, and supporting ClientComm, but are not necessary for it to run. That said, the application as written expects to have all the services above available, so eliminating any of them will require editing application code.

NOTE: All command line examples assume bash as the default shell. If you are using zsh use =(command) instead of <(command).

Install and configure Terraform

We use Terraform to manage ClientComm's infrastructure. Install Terraform with Homebrew: brew install terraform; or by downloading the installer.

For each production instance of ClientComm you must provide a backend that points to an s3 terraform backend provider. We put our backend file in a LastPass secure note named terraform-backend:

bucket     = "[THE NAME OF YOUR TERRAFORM STATE BUCKET]"
region     = "[THE AWS REGION, i.e. us-west-1]"
access_key = "[THE AWS ACCESS KEY OF AN ACCOUNT WITH READ/WRITE ACCESS TO THE BUCKET]"
secret_key = "[THE AWS SECRET KEY OF AN ACCOUNT WITH READ/WRITE ACCESS TO THE BUCKET]"

On the command line, use the terraform init command to point to this backend and specify the key, or environment name, of the deployment you're managing. We use a deployment name that corresponds with the subdomain of the deploy; so a demo deployment name would correspond with an app deployed to demo.clientcomm.org:

terraform init -backend-config <(lpass show --notes terraform-backend) -backend-config 'key=[DEPLOYMENT NAME]'

Prepping a Twilio account

In Twilio, create a new subaccount (if you use them to manage your deploys), then buy an SMS-capable phone number in the appropriate area code. Configure the A CALL COMES IN webhook to point to https://[DEPLOYMENT NAME].clientcomm.org/incoming/voice/ and the A MESSAGE COMES IN webhook to point to https://[DEPLOYMENT NAME].clientcomm.org/incoming/sms/ (see the image below).

Twilio's interface for entering endpoint URLs

On the Alert Triggers page, set up the following triggers to send email to an alerts address (see image below):

  • Trigger on ANY alert, at value 1 (First alert of the day)
  • Trigger on ANY alert, at value 10 (Alert after 10 issues in a single day)

This will give you early warning if Twilio's having trouble delivering messages to ClientComm.

Twilio's interface for creating an alert trigger

Set up an Alerts Topic

We use AWS CloudWatch Alarms to monitor our job queue and alert us if there's activity (or lack of activity) that requires human attention. You will need to set up an SNS topic to send events to. Create a SNS topic called cc-alerts if it doesn't already exist, and add your alerts email to it as a subscriber. If you name it something other than cc-alerts, you must update the corresponding line in the terraform file.

Managing a ClientComm deployment

Create a secure note in LastPass called (for example) clientcomm-personal-terraform-secrets with the AWS access and secret keys of an account that has permission to create and destroy resources (Route 53 DNS records, s3 buckets, CloudWatch alarms). We use IAM credentials unique to each person who is authorized to deploy the application:

aws_access_key = "[DEPLOYER'S AWS ACCESS KEY]"
aws_secret_key = "[DEPLOYER'S AWS SECRET ACCESS KEY]"

Now you're ready to manage a production deployment. We use a secure note in LastPass to contain secrets and specific configuration for each deploy:

mailgun_api_key = ""
mailgun_domain = ""
mailgun_smtp_password = ""
mailgun_require_dkim = "false"

route53_app_zone_id = ""
route53_email_zone_id = ""

app_domain = ""
heroku_api_key = ""
heroku_app_name = ""
heroku_email = ""

papertrail_plan = "papertrail:choklad"

unclaimed_email = ""
unclaimed_password = ""

admin_email = ""
admin_password = ""
devise_secret_key_base = ""

intercom_app_id = ""
intercom_secret_key = ""
mixpanel_token = ""
sentry_deploy_hook = ""
sentry_endpoint = ""
skylight_authentication = ""
time_zone = "Pacific Time (US & Canada)"
twilio_account_sid = ""
twilio_auth_token = ""
twilio_phone_number = ""

report_day = "1"

Many of these variables are self-explanatory, but there are a few details that need further explanation:

  • route53_app_zone_id: this variable should point to a zone file that hosts the main domain you wish to use for your deployments. This will be used to create the [deployment].[main_domain].tld CNAME record in your route53 zone that points at Heroku
  • route53_email_zone_id: this variable behaves largely the same as app zone ID but is used to create the proper mx and TXT (for SPIF and DKIM) records for sending email with Mailgun, as HSTS prevents us from sharing a domain across the app and Mailgun.
  • app_domain: the full domain of your deploy, i.e. demo.clientcomm.org
  • heroku_email: currently, due to the behavior of the Terraform Heroku provider, you must provide an email associated with a Heroku account that has access to the pipeline you want to use.
  • heroku_app_name: This must begin with a letter. We recommend a name of the form "clientcomm-[your organizaion]", for example "clientcomm-cfa"
  • papertrail_plan: Papertrail is a Heroku add-on that manages application logs; papertrail:choklad is the free tier.
  • unclaimed_email, unclaimed_password: used to set up the unclaimed client ClientComm account in the new deploy.
  • admin_email, admin_password: used to set up a ClientComm account with admin permissions in the new deploy.
  • devise_secret_key_base: Devise is the user account authentication system that ClientComm uses; run rake secret on the command line to generate a value for this field.
  • sentry_deploy_hook: Used to organize Sentry alerts; set up instructions are here.
  • report_day: ClientComm will generate and email usage reports one day a week; use this variable to set which day that is. Set from "0" for Sunday to "6" for Saturday.

If you're maintaining multiple deploys, the variables that will definitely need to change between deploys are: mailgun_domain, app_domain, heroku_app_name, unclaimed_email, unclaimed_password, admin_email, admin_password, devise_secret_key_base, time_zone, twilio_account_sid, twilio_auth_token, and twilio_phone_number.

Once you have created and saved the secure note in LastPass you are ready to deploy. First get Terraform's plan for the deploy:

terraform plan -var-file <(lpass show --notes clientcomm-personal-terraform-secrets)

If you believe the plan accurately reflects the changes or additions you wish to make, run apply:

terraform apply -var-file <(lpass show --notes clientcomm-personal-terraform-secrets)

There is a manual step during the deploy; the Heroku Scheduler interface will launch. Add two jobs; one for the Twilio status update rake task to run every 10 minutes:

rake messages:update_twilio_statuses

And one for the usage report rake task to run once a day:

rake reports:generate_and_send_reports

Although generate_and_send_reports will run daily, it'll only send emails when the day of the week matches the value of the report_day variable mentioned above.

Finishing Touches

There are a few finishing touches that must be done manually.

Verify the domain in Mailgun

You'll need to log in to Mailgun to verify the email domain. Click on the Domains menu, click the new domain that was just created, and click the Check DNS Records Now button.

Set up Pingdom

On Pingdom, create a new uptime check to point to the new deploy's front page. It should check once a minute, alert after 2 minutes down; and the Slack webhook integration should be checked if you use Slack to manage alerts.

Add a help link to Heroku config

If you have a help page for your deploy, you can add a link to it in the menu bar by setting the HELP_LINK config variable like so:

heroku set:config HELP_LINK='https://example.com/' --app [APP-NAME]

Add an exit survey and responses

When clients are deactivated in ClientComm, the user is presented with a survey that must be filled out before the deactivation can proceed. To create this survey on your deploy, start up a rails console on the remote server with the Heroku CLI:

heroku run rails c --app [APP-NAME]

Then create a survey question:

SurveyQuestion.create!(text: 'What was the outcome for this client?')

...and the multiple-choice responses:

question = SurveyQuestion.last
response_texts = ['Successful termination', 'Unsuccessful termination', 'Other / not applicable']
response_texts.each do |text|
  SurveyResponse.create!(survey_question: question, text: text)
end