Getting Started with Terraform and Machines

Fly Machines are Firecracker VMs with a fast REST API that can boot instances in about 300ms, in any region supported by

Terraform is a popular infrastructure-as-code tool, used by many companies and organizations.

terraform-provider-fly is a best-effort, community-contributed Terraform provider that enables Terraform to manage resources such as apps, volumes, certificates, IPs, machines, and so on.

In this guide we'll use Terraform to deploy a very simple demo app from a Docker image onto two Fly Machines VMs.


Go ahead and download Terraform if you haven't yet.

Set API Key

export FLY_API_TOKEN=$(fly auth token)

This gets your token into an environment variable Terraform can use to authenticate us.

Set Up the Terraform Project

Let's make a directory for this project and set up a Terraform file for us to work in.

mkdir fly-tf-example && cd fly-tf-example

In this directory, create the Terraform file In it, specify that you want to use the provider:

terraform {
  required_providers {
    fly = {
      source = "fly-apps/fly"
      version = "0.0.20"

provider "fly" {
  useinternaltunnel    = true
  internaltunnelorg    = "personal"
  internaltunnelregion = "ewr"

Now kick off your Terraform project:

 terraform init

This will download the provider and get it ready to use.

Create Resources

In your, use the fly_app resource to create a new app and the fly_ip resource to make it publicly accessible.

resource "fly_app" "exampleApp" {
  name = "flyiac" #Replace this with your own app name
  org  = "personal"

resource "fly_ip" "exampleIp" {
  app        =
  type       = "v4"
  depends_on = [fly_app.exampleApp]

resource "fly_ip" "exampleIpv6" {
  app        =
  type       = "v6"
  depends_on = [fly_app.exampleApp]

To tell Terraform to actually create these resources, use

terraform apply

Terraform will show you what it plans on doing: in this case, creating one app and two IPs, and prompt to see if you want to continue. If everything looks right, type in yes and hit enter. In just a few seconds you should see the successful output:

Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

At this point you have an app configured on the platform, but no VMs deployed.

Create Machines

This example creates machines running in ewr (Secaucus, NJ) and lax (Los Angeles, CA).

resource "fly_machine" "exampleMachine" {
  for_each = toset(["ewr", "lax"])
  app    =
  region = each.value
  name   = "flyiac-${each.value}"
  image  = "flyio/iac-tutorial:latest"
  services = [
      ports = [
          port     = 443
          handlers = ["tls", "http"]
          port     = 80
          handlers = ["http"]
      "protocol" : "tcp",
      "internal_port" : 80
  cpus = 1
  memorymb = 256
  depends_on = [fly_app.exampleApp]

Once again run terraform apply and confirm with yes. You'll get confirmation once your machines have been created!

Apply complete! Resources: 2 added, 0 changed, 0 destroyed.

To test it out go to https://<yourappname> In this example, the appname is flyiac so it would be Once the page has loaded, play around with the buttons to try loading your machines in both regions!

Destroy Resources

When you are done, run terraform destroy to delete all the resources you created for this tutorial.