# Bicep

## Hvad det er

Bicep er et sprog fra Microsoft til at skrive Azure-infrastruktur ned som tekst:
hvilke ressourcer der findes, hvad de hedder, hvordan hver enkelt er sat op, og
hvordan de hænger sammen. En Bicep-fil indeholder ingen trin. Den beskriver
slutresultatet, og Azure Resource Manager, det administrationslag, som alle
forespørgsler til Azure passerer igennem, regner selv ud, hvad der skal
oprettes, ændres eller lades i fred for at nå dertil. Den, der spørger »hvad er
Bicep?«, vil som regel vide, om det kan afløse at klikke sig gennem
Azure-portalen. Det kan det, og det er det meste af værdien.

Under overfladen er Bicep en venligere måde at skrive noget, Azure allerede
forstod. Resource Manager har længe taget imod skabeloner skrevet i JSON, som er
fuldstændige, men svære at læse og endnu sværere at reviewe. Under en udrulning
oversætter Bicep-kommandolinjeværktøjet en `.bicep`-fil til sådan en
JSON-skabelon, og Resource Manager udruller den præcis, som var den skrevet i
hånden. Ifølge Microsoft understøtter Bicep alle ressourcetyper og
API-versioner, så snart en ressourceudbyder indfører dem, previews medregnet, så
en ny tjeneste kan tages i brug uden at vente på, at nogen opdaterer et plugin.
Eksisterende JSON-skabeloner kan dekompileres til Bicep, og det gør flytningen
af et ældre setup til et mekanisk stykke arbejde frem for en omskrivning.

En lille fil viser formen. Først parametre, så ressourcer, hver med et symbolsk
navn, som resten af filen kan henvise til:

```text
param env string
param location string = resourceGroup().location

resource store 'Microsoft.Storage/storageAccounts@2023-05-01' = {
  name: 'st${env}${uniqueString(resourceGroup().id)}'
  location: location
  sku: {
    name: 'Standard_LRS'
  }
  kind: 'StorageV2'
}
```

Når en anden ressource nævner `store.id`, udleder Bicep, at den skal vente på
lagerkontoen, så ingen skriver rækkefølgen i hånden, og Resource Manager
udruller alt, der ikke afhænger af noget andet, parallelt. En fil kan kalde en
anden fil som modul, så et team kan beskrive »en database med dens
netværksregler« én gang og genbruge den overalt. Værdier, der skifter fra miljø
til miljø, ligger i en separat `.bicepparam`-fil. Microsoft siger klart, at
Bicep er gratis, open source og ikke tænkt som et generelt programmeringssprog:
der er løkker, betingelser og funktioner, men kun til at beskrive ressourcer
med.

Hvordan står Bicep i forhold til alternativerne? Over for ARM-JSON er det den
samme motor med en langt kortere kildetekst. Over for Terraform handler
forskellen om rækkevidde og tilstand: Terraform dækker mange skyer og fører sin
egen tilstandsfil, mens Bicep kun dækker Azure og klarer sig uden tilstandsfil,
fordi Azure selv er registret over, hvad der findes. Over for Pulumi, der
beskriver infrastruktur i almindelige programmeringssprog som TypeScript eller
Go, bytter Bicep fleksibilitet for et mindre sprog, der er hurtigt at læse i et
review.

## Hvorfor det betyder noget

Infrastruktur bygget i hånden har ingen historik. En indstilling ændret i
portalen efterlader ingen begrundelse, ingen ser den igennem, før den sker, og
at genopbygge miljøet efter en dårlig dag afhænger af, at nogen husker hvert
eneste klik. Når infrastrukturen er et sæt filer i repositoriet, får den det,
applikationskoden allerede har: en pull request, en reviewer, en historik og en
vej tilbage.

Den anden gevinst er ensartethed. Udvikling, staging og produktion bygget fra de
samme filer med forskellige parametre adskiller sig kun dér, hvor parametrene
siger det. Bicep-filer er idempotente, hvilket ifølge Microsoft betyder, at den
samme fil udrullet mange gange giver de samme ressourcetyper i den samme
tilstand. En udrulning kan derfor trygt gentages, og et nyt miljø er den samme
kommando rettet mod en ny ressourcegruppe.

Den tredje er overblik, før noget ændres. What-if-operationen sammenligner en
fil med det, der kører, og lister hver ressource, den ville oprette, ændre eller
slette, inden noget bliver rørt. Sammen med en pull request gør den
forhåndsvisning »jeg tror kun, det ændrer firewallreglen« til noget, en reviewer
kan efterprøve.

Omkostningerne er værd at nævne. Bicep stopper ved Azures grænse: et produkt med
DNS hos en anden udbyder eller en ekstra sky skal bruge et andet værktøj til de
dele. Det beskriver ressourcer, ikke hvad der kører inde i dem, så pakker og
filer på en virtuel maskine hører hjemme i konfigurationsstyring som Ansible. Og
Resource Managers standardadfærd ved sletning og genudrulning overrasker dem,
der forventer, at et værktøj til ønsket tilstand fjerner det, filen ikke længere
nævner. Det vender vi tilbage til nedenfor.

## Sådan ser det ud i praksis

Flere af Azure-projekterne på dette site hviler på Bicep, og tre af dem viser,
hvad det gør for et team over tid.

På én platform er hele Azure-setuppet skrevet i Bicep.
[Hvert miljø kommer ud af de samme skabeloner](/da/portfolio/provisioned-azure-infrastructure-as-code-with-bicep-container-68/):
api'et og www som Azure Container Apps, en PostgreSQL Flexible Server, Redis til
caching, Front Door med en WAF-politik foran og netværket nedenunder (VNet, NSG,
private DNS), med Log Analytics koblet på til diagnostik og images hentet fra
projektets Azure Container Registry. Fordi det hele er parametriseret, er et nyt
miljø eller en ændring af et eksisterende en pull request. Siden beskriver
resultatet som miljøer, der blev reproducerbare og reviderbare, og afvigelser
mellem dem, der holdt op med at være et mysterium, fordi koden er kilden til
sandhed.

De samme skabeloner bærer releasevejen.
[Releases bevæger sig fra udvikling til staging til produktion](/da/portfolio/owned-end-to-end-deployments-of-the-platform-71/),
og Bicep holder målinfrastrukturen ens fra det ene miljø til det næste, så et
build aldrig promoveres ind i et lidt anderledes sted. Ved siden af skabelonerne
er konfigurationen for hvert miljø adskilt fra secrets, så ét bygget artefakt
kan passere alle trin uden at blive bygget om.

Og Bicep rummer en del af genopretningsplanen.
[Backup-retention er konfigureret i Bicep ved siden af den database, den beskytter](/da/portfolio/configured-database-backup-retention-as-infrastructure-as-code-72/),
så gendannelse til et tidspunkt er en egenskab ved skabelonen frem for en
indstilling, nogen engang klikkede. Miljøet omkring databasen er også kode, og
det tæller, for at gendanne data i et miljø, der skal genopbygges efter
hukommelsen, er næppe genopretning. Siden navngiver derefter, hvad der står
åbent: geo-redundans er slået fra, og målet for genopretningstid er foreslået
frem for målt. En skabelon viser, hvad der er konfigureret; kun en øvelse viser,
hvor lang tid en gendannelse tager.

## Hvor det går galt

Det meste besvær med Bicep kommer af at forvente, at det opfører sig som et
værktøj, der ejer alt i en ressourcegruppe. Som standard ejer det kun det, filen
nævner, og kun på den måde, filen siger.

**En indstilling ændret i portalen forsvinder ved næste udrulning.** Når en
ressource udrulles igen, anvendes alle dens egenskaber på ny, og enhver
egenskab, skabelonen udelader, nulstilles til standardværdien. Et hotfix lavet i
hånden under en hændelse bliver rullet tilbage af den næste rutinemæssige
release. Behandl filen som den fulde sluttilstand for hver ressource, skriv alle
værdier, der afviger fra standarden, ind i den, og lav hasteændringer gennem en
pull request. Deny-indstillingerne i en deployment stack kan helt spærre for
ændringer uden om udrulningen.

**En ressource, der er fjernet fra skabelonen, kører videre og koster stadig
penge.** Standardtilstanden er inkrementel: ressourcer i ressourcegruppen, som
filen ikke nævner, får lov at blive. Slet en database fra koden, og den bliver i
Azure. Microsofts svar er deployment stacks. En stack registrerer de ressourcer,
den styrer, og dens indstilling `actionOnUnmanage` afgør, om en ressource, der
forsvinder fra filen, bliver koblet fra eller slettet. Complete-tilstanden
sletter også det, filen udelader, men Microsoft fraråder den og udfaser den
gradvist.

**What-if-forhåndsvisningen lister ændringer, ingen har lavet.** En egenskab,
som filen udelader, men som Azure udfylder med en standardværdi under
udrulningen, kan blive vist som slettet, og Microsoft kalder det støj. En
egenskab sat ud fra funktionen `reference` vises som ændret hver gang, og
værdier som `utcNow()` eller en sikker parameter findes kun under selve
udrulningen, så what-if viser dem uevaluerede. Kør den på hver pull request, læs
den som et udkast, og sæt de støjende egenskaber eksplicit, så de rigtige
ændringer træder frem:

```sh
az deployment group what-if \
  --resource-group rg-staging \
  --template-file main.bicep \
  --parameters staging.bicepparam
```

**En adgangskode dukker op i udrulningshistorikken.** En almindelig
strengparameter gemmes sammen med udrulningen, hvor alle med læseadgang til
historikken kan se den. Markér hemmelige parametre med dekoratoren `@secure()`,
som holder værdien ude af historik og logs, og opbevar selve hemmeligheden i Key
Vault frem for i en parameterfil i repositoriet.

## Læs mere

- [What is Bicep?](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/overview)
  — Microsofts egen oversigt: sproget, fordelene og det, det ikke forsøger at
  være.
- [Bicep modules](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/modules)
  — sådan deles en udrulning op i filer, der kalder hinanden.
- [Parameters in Bicep files](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/parameters)
  — typer, dekoratorer, standardværdier, og hvad `@secure()` holder ude af
  historikken.
- [Deployment modes](https://learn.microsoft.com/en-us/azure/azure-resource-manager/templates/deployment-modes)
  — inkrementel over for complete, og hvad hver af dem gør med ressourcer, filen
  ikke nævner.
- [Bicep deployment what-if operation](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deploy-what-if)
  — forhåndsvisning af en udrulning, ændringstyperne og de kendte kilder til
  støj.
- [Deployment stacks](https://learn.microsoft.com/en-us/azure/azure-resource-manager/bicep/deployment-stacks)
  — ressourcer styret som én enhed, med sletning og deny-indstillinger.

<https://engineer.company/da/glossary/bicep/>
