Using the GraphQL API to do idempotent deploys

Hi everyone,

I’ve put together a small go program that I’m using to deploy fly apps for both CI and production.

Here’s the core bit of logic: ensure-fly-app.go · GitHub

With a few (fairly boring) exceptions most of the supporting logic is copypasta from the source of flyctl itself.

The idea here is to have a single program that can be executed to create/deploy/update a fly application. It makes a few simplifying assumptions:

  • the app is based on a docker image that’s already been pushed to an app repository in your fly organization (I use a dummy app for this that has no services of its own)
  • there’s a command that can be run that will write all secrets needed by your fly app to stdout as a simple JSON object (in my case these secrets are read from the outputs of a terraform workspace that does things like create S3 buckets and AWS access keys)

This program tries to do the minimum work necessary and only update the application if strictly required. For example if the secrets are already up-to-date, it won’t bother to set them. If it can’t read the secrets or there’s something wrong with the configuration it will fail before starting a deploy.

I’m running this in a simple github action workflow that triggers on updates to pull_request and on merge to the default branch. I use a different prefix for the application name based on the name of the branch.

This has made it much easier to combine my fly apps with the rest of my gitops workflow as well as do more advanced things like generate my fly.toml files automatically without having to write more complex automation.

Happy to share more of the implementation or even contribute it to flyctl proper if that’s interesting to folks.

Either way, hope it helps the community!

1 Like