I am trying to wrap my head around working with the Machines API.
It seems that, should I choose to work with the Machines API rather than using flyctl to launch and deploy an app, then fly.toml is no longer needed, because all configuration can happen via API calls.
Is this true? If I go the Machines route, I can safely ignore fly.toml and all this stuff?
Hey, that’s correct. flyctl reads your fly.toml and then calls the Machines API with the updates it needs to make (it’s open source!). If you call the Machines API yourself, you don’t need a fly.toml.
So perhaps I’m missing another approach, but this is blocking me for these use cases:
I am deploying a grafana instance, but I need to configure it with a config file. So I can’t just deploy grafana/grafana-enterprise, I need a very simple dockerfile that will let me inject the config.
I want to deploy one of my apps to a new environment. That would involve having my code repo available, including it’s dockerfile. so that I can deploy it pointing at the Dockerfile as well.
These use cases are very similar. The only real difference is that for grafana, since it won’t change much, I feel like it wouldn’t be arduous to generate that docker image and host it elsewhere, like hub.docker or something. But for my app, I’d really prefer that my images remain in the fly ecosystem. (Not to mention that I can’t build them on my M1 mac)
The sequence of events I assume I need is:
create the app, or whatever resource also gives me a docker repository
for use case 2: you can manually build/push images to our docker registry. login with fly auth docker command, or manually using x as the username and a Fly API token as the password.
if you can’t build the image locally, you can use this command, which also doesn’t need a fly.toml:
fly deploy -a appname --remote-only --build-only --push --image-label whateveryouwant
and then you get an image like registry.fly.io/appname:whateveryouwant.
Ahhhh, excellent. Ok, so I can script something out that would terraform the app in one step, build the image using the cli, and then pick up w/ terraform for the rest from there.
And then after that, I can just utilize fly deploy as usual.
Good stuff, and that gets me the path I need. Thanks @lillian
I think there is a misunderstanding here, if you set up the app with terraform, you can’t fly deploy on top of it, because flyctl will not have a fly.toml nor will it recognise the existing machines as its own.
You can manage the entire app lifecycle via TF, but there are significant limitations:
Shared IPv4 need to be provisioned via the GraphQL API (e.g. sullivtr/graphql).
If you plan to use kreuzwerker/docker you’ll have to downgrade to 2.25.0 (unless you plan to keep the locally build image).
Volumes can no longer be managed via the fly_volume resource due to an API change. You’ll have to use Mastercard/restapi instead and provision via the machines API.
Fly_machine is fairly limited. It might make sense to skip it and use the REST API here as well.
When destroying a machine there’s a delay of up to a minute until a previously attached volume registers as released. You may need to introduce an artificial delay via hashicorp/time.
Terraform does not play well with the pg_tls handler at all, neither when using Postgres as state backend nor when provisioning via cyrilgdn/postgresql.
(We use Fly for multi-app preview environments where we frequently create and tear down apps.)
Ahhh, ok. That’ll be a blocker there then. Particularly having just read the post about how you’re intending to bake more and more intelligence into the ctl itself. Good to know, thanks!
Ahhh, very interesting. Had to look up those docker refs. Interesting workaround strategy. I think I’ll heed your warning for now though, and only use terraform for simple and largely static aspects of my infrastructure. Thanks for the heads up!