Skip to content

Kom i gang med Terraform ​

Denne veiledningen setter opp en minimal Frostmoln-konfigurasjon med Terraform.

1. Konfigurer leverandøren ​

Opprett main.tf:

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

provider "frostmoln" {
  # Legitimasjon leses fra leverandørargumenter eller miljøvariabler.
  # Generer en API-nøkkel i portalen under Settings -> API Keys.
}

Bruker du OpenTofu? Behold den fullstendige kildeadressen — se notatet i oversikten over leverandøren.

Oppgi API-nøkkelen din via miljøet slik at den holder seg utenfor kildekontroll:

bash
export FROSTMOLN_API_KEY=fmk_...

Velge en tenant ​

Som standard håndterer leverandøren ressurser i kontoens standard-tenant. For å rette mot en annen tenant, sett tenant_id på leverandøren — eller miljøvariabelen FROSTMOLN_TENANT_ID:

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

Å rette mot en annen tenant enn standarden krever en fm CLI- / OIDC-økt (fm auth login) der brukeren tilhører flere tenanter — en API-nøkkel er bundet til én enkelt tenant. Én tenant per leverandørinstans; for å håndtere mer enn én tenant i samme konfigurasjon, deklarer en andre leverandør med et alias. Ikke pek tenant_id om på en leverandør som allerede håndterer ressurser — bruk en egen leverandør med alias (og terraform state mv), ellers prøver Terraform å opprette dem på nytt i den nye tenanten.

2. Definer ressurser ​

Den minste konfigurasjonen som faktisk gir deg en maskin du kan logge inn på, er et VPC, en gateway for det, et subnett, en sikkerhetsgruppe, en SSH-nøkkel og selve instansen. Legg dette til 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
}

Noen ting i den konfigurasjonen er verdt å kjenne til før du kjører den.

  • Et VPC har ingen vei ut til internett før en gateway er deklarert for det.frostmoln_vpc har bevisst ikke noe konnektivitetsargument — i Terraform er konnektivitetsvalget tilstedeværelsen eller fraværet av frostmoln_gateway. Et VPC uten gateway er isolert i begge retninger, og fordi plattformens DNS og tilkoblingen til administrerte tjenester nås over samme vei, kan instanser i det heller ikke slå opp navn. Det er den vanligste grunnen til at en første terraform apply ser ut til å lykkes, og cloud-init deretter feiler på hver pakke den prøver å installere. Se Gateway.
  • image_id og flavor_id tar ID-er, ikke visningsnavn. En flavors ID er SKU-en dens, så gp1.small kan skrives direkte — se hvilke som tilbys med fm compute flavor list, eller les dem i Terraform med datakildene frostmoln_flavor / frostmoln_flavors. Images identifiseres med UUID, så slå opp ett på navn med datakilden frostmoln_image som over.
  • security_groups avgjør hva som kan nå inn. Utelat den, eller sett den til [], og instansen faller tilbake på tenantens default-gruppe, som tillater all utgående trafikk, men bare slipper inn innkommende trafikk fra instanser i samme gruppe — altså ingenting fra internett, ikke engang SSH. En gruppe du lager selv starter på samme måte: utgående tillatt, ingen innkommende regler i det hele tatt, så den innkommende trafikken du vil ha må skrives ut slik frostmoln_security_group_rule.ssh gjør over.
  • ssh_key_names tar nøkkelnavn. frostmoln_ssh_key identifiseres av navnet sitt innenfor en tenant, så frostmoln_ssh_key.laptop.name er verdien som skal sendes inn. Terraforms file() utvider ikke ~ på egen hånd — pakk stien inn i pathexpand() som over, eller oppgi en absolutt sti.
  • zone er valgfri. Utelat den, så velger plattformen en tilgjengelighetssone og lagrer den i tilstanden. Hold subnettet og instansen i samme sone.

3. Bruk ​

bash
terraform init
terraform plan
terraform apply

Terraform sporer tilstand, så påfølgende apply-kjøringer endrer bare det som er forskjellig.

4. Riv det ned ​

terraform destroy fjerner ressursene igjen, med tre bevisste stopp på veien:

  • Gatewayen nekter å bli ødelagt til konfigurasjonen sier at tapet av tilkobling er tilsiktet. Legg til acknowledge_connectivity_loss = true på frostmoln_gateway.main, kjør terraform apply på det, og riv så ned — og sett linjen tilbake først neste gang du trenger den, siden en gjenglemt true avvæpner vernet for resten av ressursens levetid.
  • Gatewayen nekter også så lenge offentlige IP-er i VPC-en fortsatt avhenger av den. depends_on over ordner det for den ene adressen i denne konfigurasjonen, men enhver annen offentlig IP i samme VPC — en lastbalanserers, eller en denne konfigurasjonen ikke administrerer — må kobles fra først. Se Offentlige IPer.
  • Å ødelegge frostmoln_public_ip frigjør adressen for godt. Den går tilbake til en delt pool og deles ut til den neste som spør, så en adresse som er publisert i DNS eller ligger i noens tillatelsesliste er verdt å beskytte med Terraforms egen lifecycle { prevent_destroy = true }.

Relatert ​