Skip to content

Kom igång med Terraform ​

Den här guiden sätter upp en minimal Frostmoln-konfiguration med Terraform.

1. Konfigurera providern ​

Skapa main.tf:

hcl
terraform {
  required_providers {
    frostmoln = {
      source = "registry.terraform.io/frostmoln/frostmoln"
    }
  }
}

provider "frostmoln" {
  # Uppgifter läses från provider-argument eller miljövariabler.
  # Generera en API-nyckel i portalen under Settings -> API Keys.
}

Använder du OpenTofu? Behåll den fullständiga källadressen — se noteringen i översikten över providern.

Tillhandahåll din API-nyckel via miljön så att den hålls utanför versionshantering:

bash
export FROSTMOLN_API_KEY=fmk_...

Välja en tenant ​

Som standard hanterar providern resurser i ditt kontos standard-tenant. För att rikta mot en annan tenant, ange tenant_id på providern — eller miljövariabeln FROSTMOLN_TENANT_ID:

hcl
provider "frostmoln" {
  tenant_id = "00000000-0000-0000-0000-000000000000"
}

Att rikta mot en annan tenant än din standard kräver en fm CLI- / OIDC-session (fm auth login) vars användare tillhör flera tenants — en API-nyckel är bunden till en enda tenant. En tenant per provider-instans; för att hantera fler än en tenant i samma konfiguration, deklarera en andra provider med ett alias. Peka inte om tenant_id på en provider som redan hanterar resurser — använd en separat provider med alias (och terraform state mv), annars försöker Terraform återskapa dem i den nya tenanten.

2. Definiera resurser ​

Den minsta konfiguration som faktiskt ger dig en maskin att logga in på är ett VPC, en gateway för det, ett subnät, en säkerhetsgrupp, en SSH-nyckel och själva instansen. Lägg till detta i main.tf:

hcl
resource "frostmoln_vpc" "main" {
  name = "tf-vpc"
  cidr = "10.0.0.0/16"
}

# A VPC is an isolated network until a gateway is declared for it: no outbound
# internet and no platform DNS. Leave this out and the instance below still
# boots, but cloud-init cannot reach anything and name resolution fails.
resource "frostmoln_gateway" "main" {
  vpc_id = frostmoln_vpc.main.id
  mode   = "public_ip"
}

resource "frostmoln_subnet" "main" {
  name   = "tf-subnet"
  vpc_id = frostmoln_vpc.main.id
  cidr   = "10.0.1.0/24"
  zone   = "falkenberg"
}

resource "frostmoln_security_group" "web" {
  name   = "tf-web"
  vpc_id = frostmoln_vpc.main.id
}

resource "frostmoln_security_group_rule" "ssh" {
  security_group_id = frostmoln_security_group.web.id
  direction         = "ingress"
  protocol          = "tcp"
  port_range_min    = 22
  port_range_max    = 22
  remote_cidr       = "203.0.113.4/32" # your own address, not 0.0.0.0/0
  description       = "SSH from the office"
}

resource "frostmoln_ssh_key" "laptop" {
  name       = "my-laptop"
  public_key = file(pathexpand("~/.ssh/id_ed25519.pub"))
}

data "frostmoln_image" "ubuntu" {
  name = "ubuntu-24.04"
}

resource "frostmoln_instance" "web" {
  name      = "tf-web"
  image_id  = data.frostmoln_image.ubuntu.id
  flavor_id = "gp1.small"
  zone      = "falkenberg"
  vpc_id    = frostmoln_vpc.main.id
  subnet_id = frostmoln_subnet.main.id

  security_groups = [frostmoln_security_group.web.id]
  ssh_key_names   = [frostmoln_ssh_key.laptop.name]
}

# An address of its own, so you can reach the instance from outside. The
# depends_on is what makes `terraform destroy` work: a gateway refuses to be
# removed while public IPs in its VPC still point at it, and without this edge
# nothing tells Terraform to release the address before the gateway.
resource "frostmoln_public_ip" "web" {
  instance_id = frostmoln_instance.web.id

  depends_on = [frostmoln_gateway.main]
}

output "web_address" {
  value = frostmoln_public_ip.web.address
}

Några saker i den konfigurationen är värda att känna till innan du kör den.

  • Ett VPC har ingen väg ut till internet förrän en gateway deklarerats för det. frostmoln_vpc har medvetet inget konnektivitetsargument — i Terraform är konnektivitetsvalet närvaron eller frånvaron av frostmoln_gateway. Ett VPC utan gateway är isolerat i båda riktningarna, och eftersom plattformens DNS och anslutningen till hanterade tjänster nås över samma väg kan instanser i det inte heller slå upp namn. Det är den vanligaste orsaken till att en första terraform apply ser ut att lyckas och cloud-init sedan misslyckas med varje paket den försöker installera. Se Gateway.
  • image_id och flavor_id tar ID:n, inte visningsnamn. En flavors ID är dess SKU, så gp1.small kan skrivas direkt — se vilka som erbjuds med fm compute flavor list, eller läs dem i Terraform med datakällorna frostmoln_flavor / frostmoln_flavors. Avbilder identifieras med UUID, så slå upp en på namn med datakällan frostmoln_image som ovan.
  • security_groups avgör vad som kan nå in. Utelämna den, eller sätt den till [], så faller instansen tillbaka på tenantens default-grupp, som tillåter all utgående trafik men bara släpper in inkommande trafik från instanser i samma grupp — alltså ingenting från internet, inte ens SSH. En grupp du skapar själv börjar på samma sätt: utgående tillåtet, inga inkommande regler alls, så den inkommande trafik du vill ha måste skrivas ut som frostmoln_security_group_rule.ssh gör ovan.
  • ssh_key_names tar nyckelnamn. frostmoln_ssh_key identifieras av sitt namn inom en tenant, så frostmoln_ssh_key.laptop.name är värdet att skicka in. Terraforms file() expanderar inte ~ på egen hand — omslut sökvägen med pathexpand() som ovan, eller ange en absolut sökväg.
  • zone är valfri. Utelämna den så väljer plattformen en tillgänglighetszon och sparar den i tillståndet. Håll subnätet och instansen i samma zon.

3. Applicera ​

bash
terraform init
terraform plan
terraform apply

Terraform spårar tillstånd, så efterföljande apply-körningar ändrar endast det som skiljer sig.

4. Riv ner ​

terraform destroy tar bort resurserna igen, med tre avsiktliga stopp på vägen:

  • Gatewayen vägrar att förstöras tills konfigurationen säger att förlusten av konnektivitet är avsiktlig. Lägg till acknowledge_connectivity_loss = true på frostmoln_gateway.main, kör terraform apply på det, och riv sedan ner — och lägg tillbaka raden först nästa gång du behöver den, eftersom ett kvarglömt true avväpnar skyddet under resursens hela livstid.
  • Gatewayen vägrar också så länge publika IP:er i dess VPC fortfarande beror på den. depends_on ovan löser det för den enda adressen i den här konfigurationen, men varje annan publik IP i samma VPC — en lastbalanserares, eller en som den här konfigurationen inte hanterar — måste kopplas bort först. Se Publika IP:er.
  • Att förstöra frostmoln_public_ip frigör adressen för gott. Den återgår till en delad pool och delas ut till nästa som frågar, så en adress som är publicerad i DNS eller ligger i någons tillåtelselista är värd att skydda med Terraforms egna lifecycle { prevent_destroy = true }.

Relaterat ​