Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vercel and Terraform #55

Merged
merged 21 commits into from
Apr 12, 2022
Merged

Vercel and Terraform #55

merged 21 commits into from
Apr 12, 2022

Conversation

berekuk
Copy link
Collaborator

@berekuk berekuk commented Apr 12, 2022

This PR addresses #52 and #54.

Terraformed: Vercel; Postgres DB on DO; Heroku.

  • I wrote some documentation in docs/infra.md, check it out.
  • Our new source of truth for prod configuration is terraform vars and state (these are two separate entities! vars describe configuration which is entered by hand, e.g. tokens of various services and and fetcher cookies; state is «everything terraform knows about the stuff it configured in the cloud»; ).

On vars and state management:

  • Both vars and state are secret; I committed them in metaforecast-notes-and-secrets repo for now
    • that's pretty unhandy, since it means that for every prod change we'll have to git pull a different repo, copy these over to metaforecast/tf, edit, terraform apply, copy them back to notes-and-secrets
      • and also risk race conditions
  • It's not much worse than it was before (previously our source of truth for env was "whatever is configured on Heroku and Netlify, dunno which one is more correct"), but it is a bit worse since previously the workflow for updating prod env was "change the var in local .env, update it in Heroku and Netlify through web UI or through Heroku/Netlify CLI tools", and now it requires fetching and pushing back prod.auto.tfvars
  • We should probably just adopt Terraform Cloud, which solves the problem of managing Terraform state and vars in a centralized cloud repo
    • Terraform Cloud is free for <= 5 users
    • I don't have any previous experience with it, but generally Hashicorp products are high quality
  • I slightly dislike the idea of adding another cloud service to metaforecast's infra, and we could go a different way, e.g. use pg backend for state (Terraform supports many various backends for its state management, so it doesn't lock you in with Terraform Cloud), and, uh, maybe private git submodule for vars?
    • But, overall, Terraform Cloud seems easier to use and set up and I think we should just go with it
  • I've created quantified-uncertainty org on TC to check how it works, but I'm lacking the permissions to set up GitHub integration; @NunoSempere, if you're ok with using it, can you approve the request for integration? And I'll send you an invite to the org
    • Minor note: there's no distinction between members and owners on TC's free plan; probably not an issue, trusting someone with production vars and state is much more dangerous than trusting someone with access to web UI which manages those

Other notes on vars:

  • I put my own tokens and credentials (vercel_api_token, digital_ocean_token, heroku_api_key) in prod.auto.tfvars; not a big deal, since Vercel and DO separate tokens by teams; Heroku doesn't have fine-grained permissions, but I don't use Heroku and don't plan to ever use it in the future
  • All env is in metaforecast_env terraform variable, which is a single untyped key/value object for now; it'd be better to split it into separate vars for type checking

On Vercel:

@vercel
Copy link

vercel bot commented Apr 12, 2022

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/quantified-uncertainty/metaforecast/GiKJxR9LAWzcNM8QtuLvBDLJ7Hjp
✅ Preview: https://metaforecast-git-vercel-quantified-uncertainty.vercel.app

@netlify
Copy link

netlify bot commented Apr 12, 2022

Deploy Preview for metaforecast ready!

Name Link
🔨 Latest commit f64a5c0
🔍 Latest deploy log https://app.netlify.com/sites/metaforecast/deploys/6255da13f03faa0008590fab
😎 Deploy Preview https://deploy-preview-55--metaforecast.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@NunoSempere
Copy link
Collaborator

For Ozzie's benefit:

config

I worry that Terraform is a bit of overengineering. I'm fine with it and it probably leaves the project in a better position in the long term, but I'd prefer to have the graphql interface up first. thoughts?

@berekuk
Copy link
Collaborator Author

berekuk commented Apr 12, 2022

I worry that Terraform is a bit of overengineering.

Here are the reasons I did this now:

  • I wanted to complete Switch to Vercel #52 before starting on GraphQL since it affects prod performance significantly
  • I didn't want to configure Vercel project by hand and Terraform seemed like a good tool for documenting the configuration, so I posted Try Terraform #54 to get some feedback
  • I was on the fence about it still, but then Ozzie liked Try Terraform #54 and I considered it to be "just do it" signal :)

Also, if you count the number of lines of code in this PR but subtract the number of lines in metaforecast-notes-and-secrets that can be removed, the diff size is probably negative; in a sense, terraform configuration is documentation, and it doesn't get stale since it's used as a source of truth.

@OAGr
Copy link

OAGr commented Apr 12, 2022

I was on the fence about it still, but then Ozzie liked #54 and I considered it to be "just do it" signal :)

This wasn't meant as a strong endorsement, sorry! I wasn't sure, but was showing support for discussing it, not for fully implementing it

@OAGr
Copy link

OAGr commented Apr 12, 2022

I'm really not familiar with Terraform.

However, my impression is that:

  1. Terraform helps organize the deployment.
  2. Using terraform would streamline the process and make deployments simpler and cleaner.
  3. Once iteration is done with terraform, it wouldn't be that much more difficult to go back on this, then it would be to just not begin with it. (Not much lock-in)

Are these three things correct? If so, I wouldn't mind much.

@berekuk
Copy link
Collaborator Author

berekuk commented Apr 12, 2022

I'm really not familiar with Terraform.

Yes, my priors about this for you and Nuño are why I went with implementation instead of discussion.

Are these three things correct?

Yes, all three are correct.


I'll give a short primer, since I suspect that my original description in this PR can be too terse to parse for someone who is not familiar with Terraform.

Terraform allows you to automate the configuration for any cloud service for which the "provider" exists, and there are providers for everything, including Dominos Pizza.

It's not so much for day-to-day code deployments as for wiring everything together at the higher level, and for reconfiguring the wiring whenever necessary (when we switch from Netlify to Vercel, or change env configuration, or move the database to another provider).

For example, terraform configs from this PR set up a Digital Ocean database and then add its URI to the metaforecast env on Heroku and Vercel. So if you move the DO database you don't have to 1) set it up in DO UI; 2) copy the postgres URI; 3) insert it into Vercel/Netlify env UI; 4) insert it into Heroku UI. Instead, you just add a resource for a new database in terraform config, apply the new config, and you're done (well, if you need to migrate the data then it's a bit more complicated, but still much easier).

Ideally, when/if we migrate everything to terraform, someone could roll up their own metaforecast2.org from scratch with a single command (after they set up API tokens for all cloud services in its tfvars config).


To be clear: this can be merged now even if we don't adopt terraform-centered workflow yet. What do you think about this roadmap?

  • we merge this and keep it as WIP
  • @NunoSempere, you keep doing prod configuration the old way if you don't have time to figure out terraform yet
  • I do Create a map of all services we are using. #56 and then set up Terraform Cloud later and document stuff (probably after I finish first graphql iteration)
  • then we switch to terraform and everyone is happy with how great it is (or not, if it still seems painful)

@OAGr
Copy link

OAGr commented Apr 12, 2022

That sounds fine to me, thanks for the summary there.

@NunoSempere
Copy link
Collaborator

NunoSempere commented Apr 12, 2022

Thanks as well. Before merging, could you add the latest commit from #53? E.g., https://deploy-preview-53--metaforecast.netlify.app/dashboards/embed/561472e0d2 works but
https://deploy-preview-55--metaforecast.netlify.app/dashboards/embed/561472e0d2 doesn't.

@berekuk
Copy link
Collaborator Author

berekuk commented Apr 12, 2022

Before merging, could you add the latest commit

I already did, in f64a5c0, but Netlify doesn't redeploy new commits for PRs (another reason to move to Vercel...)

@NunoSempere
Copy link
Collaborator

Great, merging

@NunoSempere NunoSempere merged commit 132deea into master Apr 12, 2022
@NunoSempere
Copy link
Collaborator

Ok, merged

@berekuk
Copy link
Collaborator Author

berekuk commented Apr 12, 2022

Minor note: I got rid of NEXT_PUBLIC_SITE_URL in this PR by replacing it with NEXT_PUBLIC_VERCEL_URL that Vercel provides automatically (see src/web/utils.ts and vercel docs). I realized just a minute ago that it won't work on Netlify... but it works fine for some reason. Probably because "http://" + req.headers.host; redirects to https.

The only place this code is used for now is on /dashboards/view/[id] page, in getServerSideProps. It's probably broken for POST requests, but we'll move to Vercel soon enough that it shouldn't be an issue.

@OAGr
Copy link

OAGr commented Apr 15, 2022

image

@berekuk berekuk deleted the vercel branch May 12, 2022 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants