Terraform provider quickstart

Last updated: June 5, 2026

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 the 0.1 line and upgrading deliberately:

hcl
terraform {
  required_providers {
    americancloud = {
      source  = "American-Cloud/americancloud"
      version = "~> 0.1"
    }
  }
}
 
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 needs both parts of an API key pair. Create and manage keys at console.americancloud.com/api-keys. The client secret is shown once at creation — store it securely. If it's lost, revoke the key and create a new one.

The default and recommended path is environment variables, which keeps secrets out of your .tf files and state:

sh
export AMERICANCLOUD_API_CLIENT_ID="your-client-id"
export AMERICANCLOUD_API_CLIENT_SECRET="your-client-secret"

The provider block accepts the same values as explicit arguments — api_client_id, api_client_secret, and an optional api_url override — but prefer the environment for credentials. Hard-coding a secret in api_client_secret puts it in version control and in plan output.

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

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.1 and upgrade deliberately.

Next steps