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 = "frostmoln/frostmoln"
    }
  }
}

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

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 = truefrostmoln_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