Dela via


Lås dina resurser för att skydda infrastrukturen

Som administratör kan du låsa en Azure-prenumeration, resursgrupp eller resurs för att skydda dem från oavsiktliga användarborttagningar och ändringar. Låset åsidosätter alla användarbehörigheter.

Du kan ställa in lås som förhindrar antingen raderingar eller ändringar. I portalen kallas dessa lås ta bort och skrivskyddade. På kommandoraden heter dessa lås CanNotDelete och ReadOnly.

  • CanNotDelete innebär att behöriga användare kan läsa och ändra en resurs, men de kan inte ta bort den.
  • ReadOnly innebär att behöriga användare kan läsa en resurs, men de kan inte ta bort eller uppdatera den. Att tillämpa det här låset liknar att begränsa alla behöriga användare till de behörigheter som rollen Läsare tillhandahåller.

Till skillnad från rollbaserad åtkomstkontroll (RBAC) använder du hanteringslås för att tillämpa en begränsning för alla användare och roller. Mer information om hur du anger behörigheter för användare och roller finns i Azure RBAC.

Lås arv

När du använder ett lås i ett överordnat omfång ärver alla resurser inom det omfånget samma lås. Även resurser som du lägger till senare ärver samma överordnade lås. Det mest restriktiva låset i arvet har företräde.

Tilläggsresurser ärver lås från den resurs som de tillämpas på. Microsoft.Insights/diagnosticSettings är till exempel en tilläggsresurstyp. Om du tillämpar en diagnostikinställning på en lagringsblob och låser lagringskontot kan du inte ta bort diagnostikinställningen. Det här arvet är meningsfullt eftersom det fullständiga resurs-ID:t för diagnostikinställningen är:

/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/{storage-name}/blobServices/default/providers/microsoft.insights/diagnosticSettings/{setting-name}"

Som matchar omfånget för resurs-ID:t för resursen som är låst:

/subscriptions/{sub-id}/resourceGroups/{rg-name}/providers/Microsoft.Storage/storageAccounts/{storage-name}

Om du har ett borttagningslås på en resurs och försöker ta bort resursgruppen blockerar funktionen hela borttagningsåtgärden. Även om resursgruppen eller andra resurser i resursgruppen är olåst, sker inte borttagningen. Du har aldrig en partiell borttagning.

När du avbryter en Azure-prenumeration:

  • Ett resurslås blockerar inte prenumerationens annullering.
  • Azure bevarar dina resurser genom att inaktivera dem i stället för att omedelbart ta bort dem.
  • Azure tar bara bort dina resurser permanent efter en väntetid.

Förstå omfång för lås

Kommentar

Lås gäller endast för kontrollplanets Azure-åtgärder och inte för dataplansåtgärder.

Åtgärder för Azure-kontrollplan går till https://management.azure.com. Azure-dataplansåtgärder går till din tjänstinstans, till exempel https://myaccount.blob.core.windows.net/. Se Azure-kontrollplan och dataplan. Information om vilka åtgärder som använder kontrollplanets URL finns i Azure REST API.

Skillnaden innebär att lås skyddar en resurs från ändringar, men de begränsar inte hur en resurs utför sina funktioner. Ett ReadOnly-lås, till exempel på en logisk SQL Database-server, skyddar det från borttagningar eller ändringar. Det gör att du kan skapa, uppdatera eller ta bort data i serverdatabasen. Dataplansåtgärder tillåter datatransaktioner. Dessa begäranden går inte till https://management.azure.com.

Saker att tänka på innan du använder låsen

Att tillämpa lås kan leda till oväntade resultat. Vissa åtgärder, som inte verkar ändra en resurs, kräver blockerade åtgärder. Lås förhindrar att POST-metoden skickar data till ARM-API:et (Azure Resource Manager). Några vanliga exempel på blockerade åtgärder är:

  • Ett skrivskyddat lås på ett lagringskonto hindrar användare från att visa kontonycklarna. En POST-begäran hanterar åtgärden Azure Storage List Keys för att skydda åtkomsten till kontonycklarna. Kontonycklarna ger fullständig åtkomst till data i lagringskontot. När ett skrivskyddat lås har konfigurerats för ett lagringskonto måste användare som inte har kontonycklarna använda Microsoft Entra-autentiseringsuppgifter för att komma åt blob- eller ködata. Ett skrivskyddat lås förhindrar också tilldelning av Azure RBAC-roller som är begränsade till lagringskontot eller till en datacontainer (blobcontainer eller kö).

  • Ett skrivskyddat lås på ett lagringskonto skyddar RBAC-tilldelningar som är begränsade till ett lagringskonto eller en datacontainer (blobcontainer eller kö).

  • Ett skrivskyddat lås på ett lagringskonto förhindrar att en blobcontainer skapas.

  • Ett skrivskyddat lås på ett lagringskonto förhindrar att en blobcontainer skapas. Du kan dock skapa åtgärder på ett lagringskonto via både kontrollplanet och dataplanet. Skrivskyddad låser endast blockkontrollplan skapa begäranden, men en användare kan fortfarande utföra en giltig skapandeåtgärd på resursen via dataplanet.

  • Ett skrivskyddat lås eller ett lås som inte kan tas bort på ett lagringskonto hindrar inte dess data från att tas bort eller ändras. Den skyddar inte heller data i en blob, kö, tabell eller fil.

  • API:et för lagringskonto exponerar dataplans- och kontrollplansåtgärder. Om en begäran använder dataplansåtgärder skyddar inte låset på lagringskontot blob-, kö-, tabell- eller fildata i lagringskontot. Om begäran använder kontrollplansåtgärder skyddar låset dock dessa resurser.

    Om en begäran till exempel använder filresurser – Ta bort, vilket är en kontrollplansåtgärd, misslyckas borttagningen. Om begäran använder Ta bort resurs, vilket är en dataplansåtgärd, lyckas borttagningen. Vi rekommenderar att du använder en kontrollplansåtgärd.

  • Ett skrivskyddat lås på en nätverkssäkerhetsgrupp (NSG) förhindrar att motsvarande NSG-flödeslogg skapas. Ett lås som inte kan tas bort i en nätverkssäkerhetsgrupp (NSG) förhindrar inte att motsvarande NSG-flödeslogg skapas eller ändras.

  • Ett skrivskyddat lås på en App Service-resurs hindrar Visual Studio Server Explorer från att visa filer för resursen eftersom den interaktionen kräver skrivåtkomst.

  • Ett skrivskyddat lås på en resursgrupp som innehåller en App Service-plan hindrar dig från att skala upp eller ut ur planen.

  • Ett skrivskyddat lås på en resursgrupp som innehåller en virtuell dator förhindrar att alla användare startar eller startar om en virtuell dator. Dessa åtgärder kräver en POST-metodbegäran.

  • Ett skrivskyddat lås på en resursgrupp hindrar dig från att flytta befintliga resurser till eller från resursgruppen. Observera dock att en resurs med skrivskyddat lås kan flyttas till en annan resursgrupp.

  • Ett skrivskyddat lås på en resursgrupp som innehåller ett automationskonto hindrar alla runbooks från att starta. Dessa åtgärder kräver en POST-metodbegäran.

  • Ett lås som inte kan tas bort på en resurs eller resursgrupp förhindrar borttagning av Azure RBAC-tilldelningar.

  • Ett lås som inte kan tas bort på en resursgrupp hindrar Azure Resource Manager från att automatiskt ta bort distributioner i historiken. Om du når 800 distributioner i historiken misslyckas dina distributioner.

  • Ett lås som inte kan tas bort på resursgruppen som skapats av Azure Backup Service gör att säkerhetskopieringar misslyckas. Tjänsten stöder högst 18 återställningspunkter. När den är låst kan säkerhetskopieringstjänsten inte rensa återställningspunkter. Mer information finns i Vanliga frågor och svar – Säkerhetskopiera virtuella Azure-datorer.

  • Ett lås som inte kan ta bort på en resursgrupp som innehåller Azure Machine Learning-arbetsytor förhindrar automatisk skalning av Azure Machine Learning-beräkningskluster från att fungera korrekt. Med låset kan autoskalning inte ta bort noder som inte används. Din lösning förbrukar fler resurser än vad som krävs för arbetsbelastningen.

  • Ett skrivskyddat lås på en Log Analytics-arbetsyta förhindrar att UEBA (User and Entity Behavior Analytics) aktiveras.

  • Ett lås som inte kan tas bort på en Log Analytics-arbetsyta förhindrar inte datarensningsåtgärder. Ta i stället bort datarensningsrollen från användaren.

  • Ett skrivskyddat lås för en prenumeration hindrar Azure Advisor från att fungera korrekt. Advisor kan inte lagra resultatet av sina frågor.

  • Ett skrivskyddat lås på en Application Gateway förhindrar att du får serverdelshälsan för programgatewayen. Den åtgärden använder en POST-metod, som ett skrivskyddat lås blockerar.

  • Ett skrivskyddat lås på ett AKS-kluster (Azure Kubernetes Service) begränsar hur du kan komma åt klusterresurser via portalen. Ett skrivskyddat lås hindrar dig från att använda avsnittet Kubernetes-resurser i AKS-klustret i Azure Portal för att välja en klusterresurs. Dessa åtgärder kräver en POST-metodbegäran för autentisering.

  • Ett lås som inte kan tas bort på en virtuell dator som skyddas av Site Recovery förhindrar att vissa resurslänkar som är relaterade till Site Recovery tas bort korrekt när du tar bort skyddet eller inaktiverar replikering. Om du planerar att skydda den virtuella datorn igen senare måste du ta bort låset innan du inaktiverar skyddet. Om du inte tar bort låset måste du följa vissa steg för att rensa inaktuella länkar innan du kan skydda den virtuella datorn. Mer information finns i Felsöka replikering av virtuella Azure-datorer.

  • För Postgresql bör det virtuella nätverket inte ha några resurslås inställda på det virtuella nätverket eller undernätet, eftersom lås kan störa nätverks- och DNS-åtgärder. Innan du skapar servern i ett virtuellt nätverk måste du ta bort alla borttagnings- eller skrivskyddade lås från ditt virtuella nätverk och alla undernät. Du kan använda låsen igen när servern har skapats.

Vem kan skapa eller ta bort lås

Du måste ha åtkomst till åtgärderna Microsoft.Authorization/* eller Microsoft.Authorization/locks/* för att kunna skapa eller ta bort hanteringslås. Användare som tilldelats rollen Ägare och Administratör för användaråtkomst har nödvändig åtkomst. Vissa specialiserade inbyggda roller beviljar också den här åtkomsten. Du kan skapa en anpassad roll med behörigheterna som krävs.

Hanterade program och lås

Vissa Azure-tjänster, till exempel Azure Databricks, använder hanterade program för att implementera tjänsten. I så fall skapar tjänsten två resursgrupper. Den ena är en olåst resursgrupp som innehåller en tjänstöversikt. Den andra är en låst resursgrupp som innehåller tjänstinfrastrukturen.

Om du försöker ta bort infrastrukturresursgruppen får du ett felmeddelande om att resursgruppen är låst. Om du försöker ta bort låset för infrastrukturresursgruppen får du ett felmeddelande om att låset inte kan tas bort eftersom ett systemprogram äger det.

Ta i stället bort tjänsten, som även tar bort infrastrukturresursgruppen.

För hanterade program väljer du den tjänst som du distribuerade.

Skärmbild av Azure Portal med en instans av Azure Databricks markerad.

Observera att tjänsten innehåller en länk för en hanterad resursgrupp. Resursgruppen innehåller infrastrukturen och är låst. Du kan bara ta bort den indirekt.

Skärmbild som visar länken Hanterad resursgrupp i Azure Portal.

Om du vill ta bort allt för tjänsten, inklusive resursgruppen för låst infrastruktur, väljer du Ta bort för tjänsten.

Skärmbild av Azure Portal med alternativet Ta bort för den valda tjänsten.

Konfigurera lås

Portalen

I den vänstra navigeringspanelen är prenumerationslåsfunktionens namn Resurslås, medan resursgruppslåsfunktionens namn är Lås.

  1. På bladet Inställningar för den resurs, resursgrupp eller prenumeration som du vill låsa upp väljer du Lås.

    Välj lås.

    Kommentar

    Du kan inte lägga till ett lås i hanteringsgrupper.

  2. Om du vill lägga till ett lås väljer du Lägg till. Om du vill skapa ett lås på överordnad nivå väljer du överordnad. Den markerade resursen ärver låset från den överordnade resursen. Du kan till exempel låsa resursgruppen för att tillämpa ett lås på alla dess resurser.

    Lägg till lås.

  3. Ge låset ett namn och en låsnivå. Om du vill kan du lägga till anteckningar som beskriver låset.

    Ange lås.

  4. Om du vill ta bort låset väljer du knappen Ta bort.

    Ta bort lås.

Template

När du använder en ARM-mall eller en Bicep-fil för att distribuera ett lås är det bra att förstå hur distributionsomfånget och låsomfånget fungerar tillsammans. Om du vill tillämpa ett lås i distributionsomfånget, till exempel låsa en resursgrupp eller en prenumeration, lämnar du omfångsegenskapen oetig. När du låser en resurs inom distributionsomfånget anger du omfångsegenskapen på låset.

Följande mall tillämpar ett lås på resursgruppen. Observera att det inte finns någon omfångsegenskap för låsresursen eftersom låsomfånget matchar distributionsomfånget. Distribuera den här mallen på resursgruppsnivå.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
  },
  "resources": [
    {
      "type": "Microsoft.Authorization/locks",
      "apiVersion": "2016-09-01",
      "name": "rgLock",
      "properties": {
        "level": "CanNotDelete",
        "notes": "Resource group should not be deleted."
      }
    }
  ]
}

Om du vill skapa en resursgrupp och låsa den distribuerar du följande mall på prenumerationsnivå.

{
  "$schema": "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "rgName": {
      "type": "string"
    },
    "rgLocation": {
      "type": "string"
    }
  },
  "variables": {},
  "resources": [
    {
      "type": "Microsoft.Resources/resourceGroups",
      "apiVersion": "2021-04-01",
      "name": "[parameters('rgName')]",
      "location": "[parameters('rgLocation')]",
      "properties": {}
    },
    {
      "type": "Microsoft.Resources/deployments",
      "apiVersion": "2021-04-01",
      "name": "lockDeployment",
      "resourceGroup": "[parameters('rgName')]",
      "dependsOn": [
        "[resourceId('Microsoft.Resources/resourceGroups/', parameters('rgName'))]"
      ],
      "properties": {
        "mode": "Incremental",
        "template": {
          "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
          "contentVersion": "1.0.0.0",
          "parameters": {},
          "variables": {},
          "resources": [
            {
              "type": "Microsoft.Authorization/locks",
              "apiVersion": "2016-09-01",
              "name": "rgLock",
              "properties": {
                "level": "CanNotDelete",
                "notes": "Resource group and its resources should not be deleted."
              }
            }
          ],
          "outputs": {}
        }
      }
    }
  ],
  "outputs": {}
}

När du tillämpar ett lås på en resurs i resursgruppen lägger du till omfångsegenskapen. Ange omfånget till namnet på resursen som ska låsas.

I följande exempel visas en mall som skapar en App Service-plan, en webbplats och ett lås på webbplatsen. Låsets omfång är inställt på webbplatsen.

{
  "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
  "contentVersion": "1.0.0.0",
  "parameters": {
    "hostingPlanName": {
      "type": "string"
    },
    "location": {
      "type": "string",
      "defaultValue": "[resourceGroup().location]"
    }
  },
  "variables": {
    "siteName": "[concat('ExampleSite', uniqueString(resourceGroup().id))]"
  },
  "resources": [
    {
      "type": "Microsoft.Web/serverfarms",
      "apiVersion": "2020-12-01",
      "name": "[parameters('hostingPlanName')]",
      "location": "[parameters('location')]",
      "sku": {
        "tier": "Free",
        "name": "f1",
        "capacity": 0
      },
      "properties": {
        "targetWorkerCount": 1
      }
    },
    {
      "type": "Microsoft.Web/sites",
      "apiVersion": "2020-12-01",
      "name": "[variables('siteName')]",
      "location": "[parameters('location')]",
      "dependsOn": [
        "[resourceId('Microsoft.Web/serverfarms', parameters('hostingPlanName'))]"
      ],
      "properties": {
        "serverFarmId": "[parameters('hostingPlanName')]"
      }
    },
    {
      "type": "Microsoft.Authorization/locks",
      "apiVersion": "2016-09-01",
      "name": "siteLock",
      "scope": "[concat('Microsoft.Web/sites/', variables('siteName'))]",
      "dependsOn": [
        "[resourceId('Microsoft.Web/sites', variables('siteName'))]"
      ],
      "properties": {
        "level": "CanNotDelete",
        "notes": "Site should not be deleted."
      }
    }
  ]
}

Azure PowerShell

Du låser distribuerade resurser med Azure PowerShell med hjälp av kommandot New-AzResourceLock .

Om du vill låsa en resurs anger du namnet på resursen, dess resurstyp och dess resursgruppsnamn.

New-AzResourceLock -LockLevel CanNotDelete -LockName LockSite -ResourceName examplesite -ResourceType Microsoft.Web/sites -ResourceGroupName exampleresourcegroup

Om du vill låsa en resursgrupp anger du namnet på resursgruppen.

New-AzResourceLock -LockName LockGroup -LockLevel CanNotDelete -ResourceGroupName exampleresourcegroup

Om du vill få information om ett lås använder du Get-AzResourceLock. Om du vill hämta alla lås i din prenumeration använder du:

Get-AzResourceLock

Om du vill hämta alla lås för en resurs använder du:

Get-AzResourceLock -ResourceName examplesite -ResourceType Microsoft.Web/sites -ResourceGroupName exampleresourcegroup

Om du vill hämta alla lås för en resursgrupp använder du:

Get-AzResourceLock -ResourceGroupName exampleresourcegroup

Om du vill ta bort ett lås för en resurs använder du:

$lockId = (Get-AzResourceLock -ResourceGroupName exampleresourcegroup -ResourceName examplesite -ResourceType Microsoft.Web/sites).LockId
Remove-AzResourceLock -LockId $lockId

Om du vill ta bort ett lås för en resursgrupp använder du:

$lockId = (Get-AzResourceLock -ResourceGroupName exampleresourcegroup).LockId
Remove-AzResourceLock -LockId $lockId

Azure CLI

Du låser distribuerade resurser med Azure CLI med kommandot az lock create .

Om du vill låsa en resurs anger du namnet på resursen, dess resurstyp och dess resursgruppsnamn.

az lock create --name LockSite --lock-type CanNotDelete --resource-group exampleresourcegroup --resource-name examplesite --resource-type Microsoft.Web/sites

Om du vill låsa en resursgrupp anger du namnet på resursgruppen.

az lock create --name LockGroup --lock-type CanNotDelete --resource-group exampleresourcegroup

Om du vill få information om ett lås använder du az lock list. Om du vill hämta alla lås i din prenumeration använder du:

az lock list

Om du vill hämta alla lås för en resurs använder du:

az lock list --resource-group exampleresourcegroup --resource-name examplesite --namespace Microsoft.Web --resource-type sites --parent ""

Om du vill hämta alla lås för en resursgrupp använder du:

az lock list --resource-group exampleresourcegroup

Om du vill ta bort ett lås för en resurs använder du:

lockid=$(az lock show --name LockSite --resource-group exampleresourcegroup --resource-type Microsoft.Web/sites --resource-name examplesite --output tsv --query id)
az lock delete --ids $lockid

Om du vill ta bort ett lås för en resursgrupp använder du:

lockid=$(az lock show --name LockSite --resource-group exampleresourcegroup  --output tsv --query id)
az lock delete --ids $lockid

Python

Du låser distribuerade resurser med Python med hjälp av kommandot ManagementLockClient.management_locks.create_or_update_at_resource_group_level .

Om du vill låsa en resurs anger du namnet på resursen, dess resurstyp och dess resursgruppsnamn.

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

lock_client = ManagementLockClient(credential, subscription_id)

lock_result = lock_client.management_locks.create_or_update_at_resource_level(
    "exampleGroup",
    "Microsoft.Web",
    "",
    "sites",
    "examplesite",
    "lockSite",
    {
        "level": "CanNotDelete"
    }
)

Om du vill låsa en resursgrupp anger du namnet på resursgruppen.

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

lock_client = ManagementLockClient(credential, subscription_id)

lock_result = lock_client.management_locks.create_or_update_at_resource_group_level(
    "exampleGroup",
    "lockGroup",
    {
        "level": "CanNotDelete"
    }
)

Om du vill få information om alla lås i din prenumeration använder du ManagementLockClient.management_locks.get. Om du vill hämta alla lås i din prenumeration använder du:

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

lock_client = ManagementLockClient(credential, subscription_id)

lock_result = lock_client.management_locks.list_at_subscription_level()

for lock in lock_result:
    print(f"Lock name: {lock.name}")
    print(f"Lock level: {lock.level}")
    print(f"Lock notes: {lock.notes}")

Om du vill hämta ett lås för en resurs använder du:

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

lock_client = ManagementLockClient(credential, subscription_id)

lock_result = lock_client.management_locks.get_at_resource_level(
    "exampleGroup",
    "Microsoft.Web",
    "",
    "sites",
    "examplesite",
    "lockSite"
)

print(f"Lock ID: {lock_result.id}")
print(f"Lock Name: {lock_result.name}")
print(f"Lock Level: {lock_result.level}")

Om du vill hämta ett lås för en resursgrupp använder du:

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

lock_client = ManagementLockClient(credential, subscription_id)

lock_result = lock_client.management_locks.get_at_resource_group_level(
    "exampleGroup",
    "lockGroup"
)

print(f"Lock ID: {lock_result.id}")
print(f"Lock Level: {lock_result.level}")

Om du vill ta bort ett lås för en resurs använder du:

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

lock_client = ManagementLockClient(credential, subscription_id)

lock_client.management_locks.delete_at_resource_level(
    "exampleGroup",
    "Microsoft.Web",
    "",
    "sites",
    "examplesite",
    "lockSite"
)

Om du vill ta bort ett lås för en resursgrupp använder du:

import os
from azure.identity import AzureCliCredential
from azure.mgmt.resource import ManagementLockClient

credential = AzureCliCredential()
subscription_id = os.environ["AZURE_SUBSCRIPTION_ID"]

lock_client = ManagementLockClient(credential, subscription_id)

lock_client.management_locks.delete_at_resource_group_level("exampleGroup", "lockGroup")

REST-API

Du kan låsa distribuerade resurser med REST API för hanteringslås. Med REST-API:et kan du skapa och ta bort lås och hämta information om befintliga lås.

Om du vill skapa ett lås kör du:

PUT https://management.azure.com/{scope}/providers/Microsoft.Authorization/locks/{lock-name}?api-version={api-version}

Omfånget kan vara en prenumeration, resursgrupp eller resurs. Låsnamnet kan vara vad du vill kalla det. För API-versionen använder du 2016-09-01.

I begäran ska du inkludera ett JSON-objekt som anger låsegenskaperna.

{
  "properties": {
  "level": "CanNotDelete",
  "notes": "Optional text notes."
  }
}

Nästa steg