« Back to Index

Fastly: Terraform CLI with Terraform

View original Gist on GitHub

Tags: #fastly #cli #terraform #wasm

1. README.md

NOTE: The example is for an older version of the Fastly Terraform provider, a more recent version (e.g. 5.4.0 at the time of writing) uses a different setup (shown below) so you’ll need to tweak the older examples.

terraform {
  required_providers {
    fastly = {
      source  = "fastly/fastly"
      version = "5.4.0"
    }
  }
}

data "fastly_package_hash" "example" {
  filename = "./pkg/testing-fastly-tf-cli-deploys.tar.gz"
}

resource "fastly_service_compute" "testing-fastly-tf-cli-deploys" {
  name = "testing-fastly-tf-cli-deploys"

  domain {
    name = "testing-fastly-tf-cli-deploys.edgecompute.app"
  }

  package {
    filename         = "./pkg/testing-fastly-tf-cli-deploys.tar.gz"
    source_code_hash = data.fastly_package_hash.example.hash
  }

  force_destroy = true
}

We use the Fastly CLI (v0.28.0) to initialize a new project, and to build a wasm package.

Once we have built the wasm package, we use Terraform to manage the creation of an actual service and the deployment of the package to that service.

Here is the directory structure:

├── Cargo.lock
├── Cargo.toml
├── README.md
├── bin
│   └── main.wasm
├── fastly.toml
├── pkg
│   └── testing-cli-noservicecreationtilldeploy.tar.gz
├── rust-toolchain
├── src
│   └── main.rs
└── terraform
    ├── main.tf
    ├── provider.tf
    └── variables.tf

NOTE: there is a way to get Terraform to build the package for you (i.e. rather than you manually calling fastly compute build Terraform will do it), but it’s a messy solution (reference).

Running terraform apply from within the terraform directory will display:

Terraform will perform the following actions:

  # fastly_service_compute.test_service will be created
  + resource "fastly_service_compute" "test_service" {
      + activate       = true
      + active_version = (known after apply)
      + cloned_version = (known after apply)
      + comment        = "Managed by Terraform"
      + force_destroy  = true
      + id             = (known after apply)
      + name           = "testing-cli-to-tf-compute"

      + backend {
          + address               = "127.0.0.1"
          + auto_loadbalance      = true
          + between_bytes_timeout = 10000
          + connect_timeout       = 1000
          + error_threshold       = 0
          + first_byte_timeout    = 15000
          + max_conn              = 200
          + name                  = "originless"
          + port                  = 80
          + ssl_check_cert        = true
          + use_ssl               = false
          + weight                = 100
        }

      + domain {
          + comment = "test domain"
          + name    = "testing-cli-to-tf-compute.edgecompute.app"
        }

      + package {
          + filename         = "../pkg/testing-cli-noservicecreationtilldeploy.tar.gz"
          + source_code_hash = "21c8218135b2f4f97f559719af3d03d05bd39336a45c5ce50fd91e8f8654778bf7b49dbe1743e64d3607fc0e80ae3d5d0e9f1f46bb731f34ee76a2cc02a61688"
        }
    }

NOTE: For testing purposes of the CLI logic I had to keep re-initialising my CLI project, which meant having to rebuild the rust dependency tree each time (very slow). To avoid doing that, don’t rm -rf * but instead only rm -r bin/ pkg/ src/ fastly.toml and so long as you’re going to use the same rust starter kit, then you’ll get a much quicker build step.

main.tf

locals {
  pkg = regex("name = \"(?P<name>[^\"]+)", file("../fastly.toml"))
}

resource "fastly_service_compute" "test_service" {
  name = var.name

  domain {
    name    = "${var.name}.edgecompute.app"
    comment = "test domain"
  }

  package {
    filename         = "../pkg/${local.pkg.name}.tar.gz"
    source_code_hash = filesha512("../pkg/${local.pkg.name}.tar.gz")
  }

  backend {
    name    = "originless"
    address = "127.0.0.1"
    port    = 80
  }

  force_destroy = true
}

provider.tf

terraform {
  required_providers {
    fastly = {
      source  = "fastly/fastly"
      version = "0.29.1"
    }
  }
}

variables.tf

variable "name" {
  type    = string
  default = "testing-cli-to-tf-compute"
}