Terraform provider quickstart

Last updated:

The American Cloud Terraform provider lets you declare your infrastructure — VMs, block storage, networking, Kubernetes, and DNS — as code and reconcile it with terraform apply. It's built on the same Go SDK and platform API as the other clients, so the resources map directly to the API surface. For the bigger picture on how the SDKs relate and how auth works, see the SDKs overview.

This page gets you from an empty directory to a running VM. For the full, attribute-by-attribute reference of every resource and data source, see the provider page on the Terraform Registry.

Install

Declare the provider in a terraform block and run terraform init. We recommend pinning to 0.8 or later, the first release with API token support, and upgrading deliberately:

hcl
terraform {
  required_providers {
    americancloud = {
      source  = "American-Cloud/americancloud"
      version = "~> 0.8"
    }
  }
}
 
provider "americancloud" {
  # Credentials are read from the environment by default — see below.
}
sh
terraform init

init downloads the provider from the Terraform Registry and records it in your lock file.

Authenticate

The provider authenticates with an API token. Create and manage tokens at console.americancloud.com/api-tokens. The provider creates and deletes resources, so use a token with the Full access preset, or a Custom token with manage permission for the services in your configuration. The token is shown once at creation — store it securely. If it's lost, revoke the token and create a new one.

The default and recommended path is an environment variable, which keeps the token out of your .tf files:

sh
export AMERICANCLOUD_API_TOKEN="your-api-token"

The provider block accepts the same value as an explicit api_token argument, plus an optional api_url override, but prefer the environment for credentials. Hard-coding a token in api_token puts it in version control.

hcl
provider "americancloud" {
  # Optional overrides; credentials are best left to the environment.
  # api_token = "..."
  # api_url   = "https://api.americancloud.com"
}

A legacy API key still works: set AMERICANCLOUD_API_CLIENT_ID and AMERICANCLOUD_API_CLIENT_SECRET (or api_client_id and api_client_secret) instead of the token. Set one or the other, not both. For new configurations, replace the key with a token.

A first configuration

This config looks up a region and image, registers an SSH key, and provisions a reachable VM. Omitting network has the platform auto-create an isolated network, and network_access opens inbound ports on that network's public IP. Use real label values from the registry's data sources (americancloud_region, americancloud_image, americancloud_vm_package).

hcl
data "americancloud_region" "west" {
  label = "us-west-0"
}
 
data "americancloud_image" "ubuntu" {
  label = "ubuntu-24.04-050826"
}
 
resource "americancloud_ssh_key" "deploy" {
  name       = "deploy-key"
  public_key = file("~/.ssh/id_ed25519.pub")
}
 
resource "americancloud_vm" "web" {
  name                = "web-1"
  region              = data.americancloud_region.west.label
  image               = data.americancloud_image.ubuntu.label
  vm_package          = "standard-custom"
  vcpu                = 1
  memory_mb           = 2048
  root_disk_gb        = 25
  subscription_period = "hourly"
 
  keypairs = [americancloud_ssh_key.deploy.name]
 
  network_access = {
    allow_egress_all = true
    inbound_ports = [
      { port = 22, protocol = "TCP" },
      { port = 443, protocol = "TCP" },
    ]
  }
}
 
output "vm_ip" {
  value = americancloud_vm.web.ip_address
}

Plan and apply

Preview the changes, then apply them. A VM provisions asynchronously, so apply blocks until it's running.

sh
terraform plan      # review what will be created
terraform apply     # provision it

When you're done, terraform destroy tears the stack back down. Note that an auto-created network (from omitting network) is not managed by Terraform and survives the VM.

[ terraform apply · american cloud provider ]
Apply, then re-plan: 'No changes' — typed attributes in and out, nothing drifts.

Create-only attributes and import

A few VM attributes are create-only (they force replacement if changed): keypairs, user_data, tags, and network_access. The platform applies them at create time, but the read API doesn't echo them back. As a practical consequence, terraform import can't recover these four — importing a VM under a config that sets them will plan a replacement, because there's nothing on the read side to match your config against. This is expected: import recovers the VM's identity and computed fields, but you'll want to align create-only attributes deliberately rather than relying on import to round-trip them. Plain resources like SSH keys, DNS records, and networks import cleanly.

State and secrets hygiene

Terraform state can contain sensitive values — a generated SSH private_key, for example, is returned once at creation and stored in state. Treat state as a secret:

  • Keep API credentials in environment variables, never in .tf files committed to version control.
  • Use a remote state backend with encryption at rest and access controls, rather than a local terraform.tfstate in a shared repo.
  • Avoid printing sensitive outputs in CI logs; mark outputs sensitive = true where appropriate.

Versioning

The provider carries its own semantic version, independent of the SDK and API version numbers. Its compatibility contract is the exact-pinned Go SDK it's built on — which is itself in lockstep with the API platform version — so the provider release transitively states the API surface it was built and tested against. Patch releases are documentation or internal fixes, minor releases add resources or absorb additive SDK changes, and major releases cover removed or renamed resources and changed attribute shapes. Breaking attribute changes that could force resource replacement are called out prominently in the changelog. Pin to a range like ~> 0.8 and upgrade deliberately.

Next steps

Contact us