Ga naar inhoud

Troubleshooting how-to's

Stapsgewijze handleidingen voor problemen die het platformteam tegenkomt in de pipelines, de build agents en bij lokale ontwikkeling. Voor een eerste blik op een incident, zie Waar je eerst kijkt. Voor bekende defecten, zie Bekende problemen.

Probleem Ga naar
Een plan of apply mislukt of blijft hangen zonder duidelijke foutmelding Terraform-logging aanzetten
Build agents zijn na een destroy hun route naar Azure DevOps kwijt Kapotte agent-connectiviteit herstellen
Pipeline jobs wachten op agents, of agents registreren zich nooit De agent pool controleren met de smoke tests
Je kunt vanaf je ontwikkelmachine geen private resources bereiken Private resources bereiken vanuit een dev container

Terraform-logging aanzetten

Gebruik dit als een Terraform-stap plan of apply mislukt of blijft hangen zonder duidelijke foutmelding, als je de API-calls wilt zien die een provider doet, of als support om Terraform-debuglogs vraagt.

Terraform heeft twee loginstellingen die je apart kunt aanzetten:

Instelling Omgevingsvariabele Wat het toont
Core-logniveau TF_LOG_CORE Het eigen log van Terraform: het opbouwen van de graph, de orkestratie van plan en apply
Provider-logniveau TF_LOG_PROVIDER Het log van de providerplugins (bijvoorbeeld azurerm), inclusief de requests en responses die ze doen

De waarden zijn TRACE, DEBUG, INFO, WARN en ERROR. Een pipelineparameter met de waarde DEFAULT laat de variabele ongezet, zodat logging zich normaal gedraagt.

Begin met het core-log op DEBUG: dat is meestal genoeg om te zien wat Terraform doet. Gebruik het provider-log alleen kort en alleen voor een specifiek probleem.

Providerlogs kunnen secrets bevatten

TF_LOG_PROVIDER op DEBUG of TRACE kan ongemaskeerde secrets uit de request- en responsepayloads van de provider printen. Zet het terug op DEFAULT zodra je hebt wat je nodig hebt. Behandel de logs van die run als gevoelig: beperk de toegang en verwijder ze als ze niet meer nodig zijn.

Azure DevOps

De oudere environment pipelines (pipelines/environment_canary.yaml en environment_prod.yaml) bieden twee runparameters, terraformLogCore en terraformLogProvider (default DEFAULT):

  1. Open de pipeline en kies Run pipeline.
  2. Stel in de parameters Terraform core log level of Terraform provider log level in.
  3. Draai hem. De plan- en apply-jobs zetten TF_LOG_CORE en TF_LOG_PROVIDER voor de duur van de run.

GitHub Actions

De herbruikbare workflows environment_canary.yml en environment_prod.yml accepteren dezelfde twee inputs. Geef ze door vanuit de aanroepende workflow:

jobs:
  deploy:
    uses: <organisation>/<code repository>/.github/workflows/environment_canary.yml@<version>
    with:
      environment: canary
      regions: '["weu"]'
      deployList: ${{ inputs.deployList }}
      defaultRunnerGroup: <runner group>
      terraformLogCore: DEBUG
      terraformLogProvider: DEFAULT

Controleer je entry pipeline

Deze parameters zijn gedocumenteerd voor de environment pipelines van de coderepository. Open de template die je entry pipeline (hub, spoke) aanroept en zoek naar terraformLogCore en terraformLogProvider. Staan ze er niet, vraag dan aan de eigenaar van de coderepository hoe je Terraform-logging voor jouw versie aanzet.

De logging controleren

In het joblog van Terraform Plan of Terraform Apply (Azure DevOps) of de stapoutput (GitHub) verschijnen Terraform-logregels met het niveau tussen haakjes, zoals [DEBUG], naast de normale output.

Verschijnt er geen extra output, dan staan beide parameters nog op DEFAULT, of is de waarde niet een van de bovenstaande niveaus. Draai opnieuw met een expliciet niveau.

Kapotte agent-connectiviteit herstellen na een destroy

Het probleem

Als de connectivity layer wordt gedestroyd, wordt de virtual hub connection tussen het virtual network van de agents en de hub verwijderd. Heeft de connection internet_security_enabled = true, dan gaat al het internetverkeer van de agents via de firewall van de hub, en die route verdwijnt met de connection. De agents verliezen dan hun pad naar Azure DevOps en melden geen joboutput meer, waardoor de run die de destroy deed lijkt te hangen.

Voorkom het

Zet internet_security_enabled = false op elke hub connection waarvan het netwerk pipeline-agents host. De agents bereiken Azure DevOps dan rechtstreeks via het internet, los van de hub. In environments/<env>/<region>/connectivity.auto.tfvars:

virtual_hub_connections = {
  <connection name> = {
    internet_security_enabled = false   # agents use direct internet, not the hub firewall
    remote_virtual_network_id = "/subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Network/virtualNetworks/<agents vnet>"
    routings                  = null
    virtual_hub_id            = null
  }
}

Zie ook de instelling voor spokes in de Spoke JSON-naslag (InternetSecurityEnabled). De agents van het platform zelf draaien in het netwerk van de job runners, zie Provisioning.

Herstellen zonder Terraform apply

Is de connectiviteit al kapot, wijzig de connection dan rechtstreeks via de Azure REST API. De optie az network vhub connection update --internet-security wordt in oudere Azure CLI-versies niet ondersteund, en de resource provider accepteert geen PATCH op hub connections. Lees de connection, wijzig hem en schrijf hem terug (GET en PUT).

  1. Zoek de virtual hub en zijn resource group.

    az network vhub list `
      --subscription <connectivity-subscription-id> `
      --query "[].{name:name, rg:resourceGroup}" `
      -o table
    
  2. Controleer of de connection bestaat.

    az network vhub connection list `
      --vhub-name <vhub-name> `
      --resource-group <resource-group> `
      --subscription <connectivity-subscription-id> `
      --query "[].{name:name, internetSecurity:properties.enableInternetSecurity}" `
      -o table
    
  3. Zet internet security uit met GET en PUT.

    $url = "https://management.azure.com/subscriptions/<connectivity-subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.Network/virtualHubs/<vhub-name>/hubVirtualNetworkConnections/<connection-name>?api-version=2023-09-01"
    
    $conn = az rest --method get --url $url | ConvertFrom-Json
    $conn.properties.enableInternetSecurity = $false
    az rest --method put --url $url --body ($conn | ConvertTo-Json -Depth 20 -Compress)
    
  4. Wacht tot de update klaar is.

    do {
        Start-Sleep -Seconds 10
        $state = az rest --method get --url $url | ConvertFrom-Json
        Write-Host "$(Get-Date -Format 'HH:mm:ss') - provisioningState: $($state.properties.provisioningState)"
    } until ($state.properties.provisioningState -ne 'Updating')
    
  5. Leg de fix vast in code. Zet internet_security_enabled = false in de connectivity.auto.tfvars van de betrokken regio, zodat de volgende apply je wijziging niet ongedaan maakt (Wijzigingsworkflow). Een wijziging in Azure zonder bijbehorende wijziging in code is drift (Afhandeling van incidenten).

De Managed DevOps Pool controleren met de smoke tests

De eigen job runners van het platform draaien op een Managed DevOps Pool (MDP) (Provisioning). De smoke tests controleren of de pool correct is uitgerold en VM's kan starten en agents kan registreren bij Azure DevOps. Draai ze na elke infrastructuur-deployment, en als jobs op agents wachten.

Wat ze controleren

Gebied Controles
Azure Resource Manager De pool bestaat in de resource group. De provisioning state is Succeeded. De maximale concurrency is hoger dan 0. De SKU is geldig. Statusinformatie is beschikbaar (een null-status wijst op netwerkproblemen)
Azure DevOps-registratie De pool is geregistreerd in de organisatie, heeft het type automation (managed pool) en is gemarkeerd als hosted
Images De verwachte images zijn geconfigureerd: Windows Server 2025 en 2022, Ubuntu 24.04 en 22.04 (elk als <image>/latest)
Agent-connectiviteit Agents kunnen worden opgevraagd via de Azure DevOps API, en geen enkele zit vast in de status never connected (een teken van een mislukte bootstrap)
Netwerk Het agent-subnet is geconfigureerd en gerefereerd. Het DevCenter-project bestaat en is gekoppeld. Het organisatieprofiel wijst naar de juiste Azure DevOps-organisatie. Parallelism is geconfigureerd

Draai ze

De smoke tests draaien automatisch na Invoke-XebiaInfrastructure -Action Apply, dat de infrastructure pipeline aanroept. Om ze apart te draaien, bijvoorbeeld bij troubleshooting, gebruik je de dev container (De tests lokaal draaien):

# In the dev container, from the root of the code repository
Import-Module ./src/Xebia.Mcp/Xebia.Mcp.psd1 -Force
Initialize-XebiaDotEnv
$config = Resolve-XebiaMcpConfiguration -Path $env:MCP_CONFIG
Test-XebiaMcpSmoke -Config $config

Je moet ingelogd zijn met az login en toegang hebben tot de subscription van de pool, plus de permissie Agent Pools (Read & manage) in Azure DevOps. Het resultaat wordt op de console getoond en weggeschreven als NUnit XML-bestand (artifacts/testresults-smoke.xml), dat een pipeline kan publiceren.

Voor uitgebreide output zet je $VerbosePreference = 'Continue' voor de aanroep.

Veelvoorkomende fouten

Symptoom Oorzaak Oplossing
statuses: null of resources: [] De firewall blokkeert de CIDR van het agent-subnet Voeg het agent-subnet toe aan een firewall-IP-groep met outbound allow-regels voor poort 443 (en poort 80 als je agents gewone HTTP nodig hebben). Controleer ip_groups/ en firewall_rule_configuration/ van de regio (Toegang voor build agents)
agentConnectedTime: null en receiveTime: null De NAT gateway staat uit, of de firewall blokkeert het uitgaande verkeer van de agents Zet de NAT gateway aan op het agent-subnet, of sta het agent-subnet op de firewall toe naar het internet. Is het netwerk met internet security aan met de hub verbonden, dan gaat al het internetverkeer via de firewall en wordt de NAT gateway omzeild
Agents starten maar kunnen Azure-hostnamen niet oplossen Een catch-all forwarding rule (.) in de DNS resolver stuurt elke query naar een publieke DNS-server. Azure-interne namen die de pool gebruikt, worden alleen opgelost via Azure DNS (168.63.129.16) Verwijder de catch-all rule. Maak alleen forwarding rules per domein, nooit een catch-all (DNS-ontwerp)
MDP quota preflight failed Onvoldoende quota voor de SKU-familie Vraag meer quota aan bij Azure support voor Microsoft.DevOpsInfrastructure

Verder gaan

  • Lees de poolresource rechtstreeks met az rest op Microsoft.DevOpsInfrastructure/pools/<pool> van de resource group van de job runners (API-versie 2024-10-19).
  • Lijst de agents op met de Azure DevOps REST API: haal de pool-ID op via _apis/distributedtask/pools?poolName=<pool>, lees dan _apis/distributedtask/pools/<id>/agents?includeCapabilities=true, met een token voor de Azure DevOps-resource.
  • End-to-end test. Zet een kleine testpipeline in de queue die één job per image op de pool draait. Elke job hoort binnen 5 tot 10 minuten een agent te krijgen en af te ronden, en de agent hoort daarna gedealloceerd te worden.

Private resources bereiken vanuit een dev container

Spoke-werk vraagt vaak toegang tot private resources (Key Vaults, storage accounts) vanuit een ontwikkelcontainer. Deze handleiding verbindt een Windows-machine met WSL2 en Docker Desktop via point-to-site VPN met de hub, en herstelt DNS in de container zodat private namen worden opgelost.

Voordat je begint

  • Een Windows-host met WSL2 en Docker Desktop, en lokale beheerdersrechten om de Azure VPN Client te installeren.
  • Toegang tot de subscription en resource group van de point-to-site VPN-gateway, en permissie om VPN-clientprofielen te genereren.
  • De Xebia.Mcp-module in de dev container.
  • Een point-to-site VPN-gateway in de hub. Die is optioneel, staat standaard uit en wordt ingericht met een standaardwijziging (Point-to-site VPN inschakelen hieronder, en Toegang voor ontwikkelaars).

1. Controleer de point-to-site-gateway

Open in de Azure-portal de point-to-site VPN-gateway in de connectivity resource group en ga naar Point-to-site configuration. Controleer de client address pool, de authenticatiemethode (bijvoorbeeld Microsoft Entra ID of certificaten) en het tunneltype. Als platformautomatisering dit heeft geconfigureerd, controleer dan alleen de instellingen.

2. Download het VPN-clientprofiel

Vanuit de portal: kies in de gateway Download VPN client en sla de zip op. Of vanuit de dev container:

$profile = Invoke-XebiaAzureCli -ScriptBlock {
    az network p2s-vpn-gateway vpn-client generate `
    --subscription '<subscription-id>' `
    --resource-group '<resource-group-name>' `
    --name '<p2s-gateway-name>'
} -WhatIf:$false | ConvertFrom-Json

Invoke-WebRequest -Uri $profile.profileUrl -OutFile ./vpn-client-profile.zip
Expand-Archive -Path ./vpn-client-profile.zip -DestinationPath ./vpn-client-profile -Force

3. Installeer de Azure VPN Client en importeer het profiel

  1. Installeer Azure VPN Client uit de Microsoft Store, of via de softwaredistributie van je organisatie.
  2. Start hem en kies Import. Kies de zip, of blader naar de uitgepakte AzureVPN/VpnSettings.xml.
  3. Selecteer het geïmporteerde profiel en kies Connect. Log in als daarom wordt gevraagd. De status moet Connected zijn.

Snelle controles in Windows:

Resolve-DnsName '<private-resource-name>'
Test-NetConnection '<private-ip-or-fqdn>' -Port 443

Test-NetConnection bevestigt alleen dat TCP-poort 443 openstaat. Om te bevestigen dat het endpoint het verwachte servicecertificaat presenteert, draai je de TLS-controle in De verbinding controleren.

4. Configureer het WSL-netwerk

Werk WSL bij vanuit Windows PowerShell met wsl --update en controleer wsl --version. Maak %UserProfile%\.wslconfig aan of bewerk het:

[wsl2]
networkingMode=mirrored
dnsTunneling=true
firewall=true
autoProxy=true

Pas het toe: sluit alle WSL-terminals, draai wsl --shutdown in Windows PowerShell, verbind de Azure VPN Client opnieuw, open daarna WSL en de dev container opnieuw.

5. Laat de container naar de DNS van de hub wijzen

Als namen in de container nog steeds naar publieke adressen worden opgelost, forceer dan tijdelijk de DNS-server van de hub:

Import-Module Xebia.Mcp -Force
Set-XebiaLocalDns -NameServer <hub DNS server IP>

Herstel de oorspronkelijke DNS als je klaar bent met de taak:

Set-XebiaLocalDns -Restore

Set-XebiaLocalDns bewaart één back-upbestand van resolv.conf (/tmp/xebia-localdns-resolv.conf.bak). Het opnieuw draaien met -NameServer terwijl de back-up bestaat, wordt bewust geblokkeerd: herstel eerst. -Restore herstelt het bestand en verwijdert de back-up.

De verbinding controleren

Draai dit in de dev container nadat de VPN verbonden is. Vervang de vaultnaam en het private IP-adres door die van de resource die je test.

# 1. The name resolves to the private endpoint address
[System.Net.Dns]::GetHostAddresses('<vault-name>.vault.azure.net') | Select-Object -ExpandProperty IPAddressToString

# 2. TCP port 443 is open
$tcpClient = [System.Net.Sockets.TcpClient]::new(); $tcpClient.Connect('<private-ip>', 443); "TCP OK"; $tcpClient.Dispose()

# 3. The endpoint presents the expected certificate
$tcpClient = [System.Net.Sockets.TcpClient]::new('<private-ip>', 443)
$callback = [System.Net.Security.RemoteCertificateValidationCallback] { param($sender, $certificate, $chain, $errors) $true }
$sslStream = [System.Net.Security.SslStream]::new($tcpClient.GetStream(), $false, $callback)
$sslStream.AuthenticateAsClient('<vault-name>.vault.azure.net')
$sslStream.RemoteCertificate.Subject
$sslStream.RemoteCertificate.Issuer
$sslStream.Dispose(); $tcpClient.Dispose()
# 4. A real call
az keyvault secret list --vault-name <vault-name> --maxresults 1 -o table

Verwacht: de naam wordt opgelost naar het private IP-adres, TCP OK wordt geprint, een door Microsoft uitgegeven certificaat voor vault.azure.net wordt getoond, en het laatste commando mislukt niet met SSL: UNEXPECTED_EOF_WHILE_READING. Een lege vault geeft lege output, wat nog steeds het netwerk- en TLS-pad bewijst. Mislukt de TLS-controle met een EOF of komt er geen certificaat terug, dan wijst DNS naar een private IP, maar bereikt de container het private endpoint niet.

Problemen

Symptoom Wat te doen
De VPN is verbonden maar private namen worden naar publieke adressen opgelost Controleer of de Windows-VPN verbonden is. Controleer of mirrored networking actief is na wsl --shutdown. Draai Set-XebiaLocalDns -NameServer <hub DNS server IP> in de container
Set-XebiaLocalDns meldt dat de back-up al bestaat Draai Set-XebiaLocalDns -Restore en stel daarna de nieuwe name server in
Geen route vanuit de container naar de private DNS-server Controleer of de routes van het VPN-profiel de hub en de private DNS-bereiken bevatten. Verbind het profiel opnieuw. Herstart WSL en open de container opnieuw
DNS wordt opgelost naar het private endpoint en TCP 443 staat open, maar TLS mislukt met EOF Zie hieronder

TLS mislukt met EOF terwijl TCP slaagt, vanuit Windows en vanuit de container. Dit is niet alleen een WSL-probleem: de TCP- verbinding gaat open, maar de TLS-handshake met de Azure-service wordt niet voltooid. Controleer in deze volgorde:

  1. Het IP-adres van het private endpoint overlapt niet met een lokaal of bedrijfsnetwerk. Een lokaal netwerk 192.168.123.0/24 botst bijvoorbeeld met een private endpoint-bereik van een spoke dat erbinnen valt.
  2. Het VPN-profiel routeert het hele adresbereik van het spoke virtual network, niet alleen het bereik van de DNS-server.
  3. DNS lost de naam zowel vanuit Windows als vanuit de container op naar het IP-adres van het private endpoint.
  4. De connection van het private endpoint is goedgekeurd en wijst naar de verwachte resource.
  5. Mislukt het nog steeds, escaleer dan naar de netwerkeigenaar met het DNS-resultaat, het bron-IP in Windows, de naam van de VPN-interface, het IP-adres van het private endpoint en de TLS EOF-fout.

Point-to-site VPN inschakelen

Het platform kan een point-to-site VPN-gateway in de hub aanmaken. Het is een standaardwijziging: Platformfeatures bijwerken (Platformfeatures). De stappen voor deze feature:

  1. Maak in de configuratierepository een branch aan. Doe in <env-folder>/<region>/connectivity.auto.tfvars van de omgeving het volgende:
    • Zet create_point_to_site_vpn_gateway = true.
    • Stel point_to_site_vpn_gateway_connection_configuration in: een name die je naamgevingsconventie volgt (het oudere runbook gebruikt vpnconf-<company>-connectivity-<env>-<region>-001), en een vpn_client_address_pool met address_prefixes (de CIDR voor de VPN-clients) en internet_security_enabled (het oudere runbook zet dit op true).
    • Zet entra_tenant_id op de tenant-ID van de organisatie.
    • Zet point_to_site_vpn_enterprise_app_id op de application ID van de Azure VPN-applicatie (zie de opmerking hieronder).
  2. Controleer de bijbehorende variabelen in variables_point_to_site_vpn_gateway.tf (de DNS-server van de gateway moet gelijk zijn aan virtual_network_dns_servers, zoals een config test vereist).
  3. Draai hub in de modus Plan voor de gewijzigde omgeving en regio. Alleen de connectivity layer hoort wijzigingen te tonen. Apply naar canary, daarna prod, met goedkeuring voor prod.
  4. Controleer in de portal: Virtual WAN > Hubs > de hub van de regio > Point-to-site configuration. Download het configuratiebestand en test de verbinding met Azure VPN Client.
  5. Merge de pull request.

Om de VPN voor ontwikkeling te gebruiken, ga je verder met Private resources bereiken vanuit een dev container. Voor forced tunnelling en het ontwerp van toegang per workload, zie Toegang voor ontwikkelaars.

De application ID van Azure VPN

Het oudere runbook gebruikt 41b23e61-6c1e-4545-b367-cd054e0ed4b4 voor point_to_site_vpn_enterprise_app_id. Controleer dit aan de hand van de actuele documentatie van Microsoft over Azure VPN met Entra ID-authenticatie voordat je het gebruikt, omdat de waarde afhangt van de cloud.