Martin Rylko
  • Služby
  • Blog
  • O mně
  • Kontakt
  • Spolupráce
Martin Rylko

Senior Cloud Architect & DevOps Engineer. Specializace na Microsoft Azure, IaC, Cloud Security a AI.

Navigace

  • Služby
  • Blog
  • O mně
  • Kontakt

Spolupráce

Hledáte zkušeného architekta pro Váš Azure projekt? Ozvěte se.

rylko@cloudmasters.cz

© 2026 Martin Rylko. Všechna práva vyhrazena.

Buduji v cloudu. Nasazuji přes Azure Static Web Apps.

Domů/Blog/Bicep CI/CD: GitHub Actions pipeline pro Azure
Všechny článkyRead in English

Bicep CI/CD: GitHub Actions pipeline pro Azure

15. 2. 2025 4 min
#Bicep#Azure#IaC#DevOps#CI/CD#GitHub Actions

V českých enterprise firmách pozoruji jeden opakující se vzorec: tým zvládne napsat Bicep šablony, ale nasazování běží ručně. Jeden člověk má na starosti deploymenty, zná správné parametry zpaměti a když je nemocný, nikdo jiný neví, jak nasadit do produkce. Tohle není DevOps -- tohle je single point of failure zabalený do Azure CLI.

Effort: 1-2 dny na počáteční pipeline, půl dne na každé další prostředí Cost: $0 za GitHub Actions (2 000 minut/měsíc zdarma na veřejných repozitářích), ~$0.008/min na Ubuntu runnerech pro privátní repozitáře Prerequisites: Azure subscription, GitHub repozitář s Bicep soubory, Azure AD app registration s federovanými přihlašovacími údaji

Co se změnilo v roce 2025

GitHub Actions pro Azure prošly v roce 2025 několika zásadními vylepšeními:

  • OIDC federace je nový standard. Akce azure/login@v2 už nevyžaduje JSON blob s klientským secretem. Nakonfigurujete federovanou identitu na Azure AD app registraci a runner se autentizuje krátkodobým tokenem.
  • Reusable workflows jsou v GA. Jeden workflow soubor sdílíte napříč repozitáři. Pro firmy s desítkami Bicep modulů to znamená konec kopírování YAML souborů.
  • az deployment group what-if výstup se dá automaticky vložit jako komentář do pull requestu. Reviewer vidí přesný diff infrastruktury ještě před schválením.
  • Environment protection rules nyní podporují povinné reviewery, časové prodlevy a omezení na konkrétní větve -- vše nativně v GitHubu.

Proč je to důležité

Ruční nasazování infrastruktury má jeden zásadní problém: škáluje lineárně s počtem prostředí. Jeden developer, jedno prostředí -- žádný problém. Tři prostředí a tým čtyř lidí? Začnou se dít věci.

Typický scénář z praxe: páteční odpoledne, developer spustí az deployment group create na staging, ale zapomene přepnout parametrový soubor. Staging dostane produkční CIDR rozsahy. V pondělí se staging VNet překrývá s produkcí a peering padá s chybou AddressOverlap. Debugging trvá půl dne, protože nikdo neví, kdo co nasadil a kdy.

CI/CD pipeline řeší tři věci najednou:

  1. Review před nasazením -- každá změna prochází PR s what-if náhledem
  2. Konzistence mezi prostředími -- stejná šablona, jiné parametry, žádná ruční improvizace
  3. Auditovatelnost -- Git historie je záznam kdo, co a kdy změnil

Implementace: GitHub Actions pipeline krok za krokem

OIDC federace -- autentizace bez secretů

Prvním krokem je nastavení OIDC federace. Vytvořte app registraci v Azure AD a přidejte federovaný přihlašovací údaj:

# Vytvoření app registrace
az ad app create --display-name "gh-actions-bicep-deployer"
 
# Zaznamenejte appId z výstupu, pak vytvořte service principal
az ad sp create --id <appId>
 
# Přidání federovaného přihlašovacího údaje pro main větev
az ad app federated-credential create --id <appId> --parameters '{
  "name": "github-main-deploy",
  "issuer": "https://token.actions.githubusercontent.com",
  "subject": "repo:contoso/infra-bicep:ref:refs/heads/main",
  "audiences": ["api://AzureADTokenExchange"]
}'
 
# Přiřazení role Contributor na cílovou resource group
az role assignment create \
  --assignee <appId> \
  --role "Contributor" \
  --scope "/subscriptions/a1b2c3d4-5678-90ab-cdef-1234567890ab/resourceGroups/rg-platform-prod-westeurope"

Do GitHub repository settings přidejte tři secrets: AZURE_CLIENT_ID, AZURE_TENANT_ID a AZURE_SUBSCRIPTION_ID. Žádný client secret -- to je celý smysl OIDC.

Workflow soubor

Celý pipeline žije v .github/workflows/deploy-infra.yml. Na pull requestech spouští what-if náhled, na merge do main provádí deployment:

# .github/workflows/deploy-infra.yml
name: Deploy Bicep Infrastructure
 
on:
  pull_request:
    paths:
      - 'infra/**'
  push:
    branches:
      - main
    paths:
      - 'infra/**'
 
permissions:
  id-token: write   # Nutné pro OIDC
  contents: read
  pull-requests: write  # Komentář s what-if výstupem
 
env:
  RESOURCE_GROUP: rg-platform-prod-westeurope
  LOCATION: westeurope
  TEMPLATE: infra/main.bicep
  PARAMETERS: infra/parameters/prod.bicepparam
 
jobs:
  what-if:
    if: github.event_name == 'pull_request'
    runs-on: ubuntu-latest
    environment: preview
    steps:
      - uses: actions/checkout@v4
 
      - name: Přihlášení do Azure (OIDC)
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
 
      - name: Spuštění what-if
        id: whatif
        run: |
          result=$(az deployment group what-if \
            --resource-group ${{ env.RESOURCE_GROUP }} \
            --template-file ${{ env.TEMPLATE }} \
            --parameters ${{ env.PARAMETERS }} \
            --no-pretty-print 2>&1)
          echo "output<<EOF" >> $GITHUB_OUTPUT
          echo "$result" >> $GITHUB_OUTPUT
          echo "EOF" >> $GITHUB_OUTPUT
 
      - name: Vložení what-if do PR komentáře
        uses: actions/github-script@v7
        with:
          script: |
            const output = `### Bicep What-If náhled
            \`\`\`
            ${{ steps.whatif.outputs.output }}
            \`\`\`
            *Spuštěno uživatelem @${{ github.actor }}*`;
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: output
            });
 
  deploy-staging:
    if: github.ref == 'refs/heads/main' && github.event_name == 'push'
    runs-on: ubuntu-latest
    environment: staging
    steps:
      - uses: actions/checkout@v4
 
      - name: Přihlášení do Azure (OIDC)
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
 
      - name: Nasazení na staging
        run: |
          az deployment group create \
            --resource-group rg-platform-staging-westeurope \
            --template-file ${{ env.TEMPLATE }} \
            --parameters infra/parameters/staging.bicepparam \
            --name "staging-$(date +%Y%m%d-%H%M%S)"
 
  deploy-production:
    needs: deploy-staging
    runs-on: ubuntu-latest
    environment:
      name: production
      url: https://portal.azure.com
    steps:
      - uses: actions/checkout@v4
 
      - name: Přihlášení do Azure (OIDC)
        uses: azure/login@v2
        with:
          client-id: ${{ secrets.AZURE_CLIENT_ID }}
          tenant-id: ${{ secrets.AZURE_TENANT_ID }}
          subscription-id: ${{ secrets.AZURE_SUBSCRIPTION_ID }}
 
      - name: Nasazení na produkci
        run: |
          az deployment group create \
            --resource-group ${{ env.RESOURCE_GROUP }} \
            --template-file ${{ env.TEMPLATE }} \
            --parameters ${{ env.PARAMETERS }} \
            --name "prod-$(date +%Y%m%d-%H%M%S)"

Ochrana prostředí

V nastavení GitHub repozitáře pod Environments nastavte production:

  • Required reviewers: Minimálně jeden senior z týmu. Žádný deployment do produkce bez druhého páru očí.
  • Wait timer: 5 minut po schválení. Dostatečná doba na "počkej, vlastně ne."
  • Branch restriction: Pouze main. Feature větve nemůžou obejít staging.

Na co vás dokumentace nepřipraví

Pole subject ve federovaném přihlašovacím údaji je case-sensitive. Pokud váš repozitář je Contoso/Infra-Bicep ale vy nakonfigurujete contoso/infra-bicep, výměna tokenů tiše selže s generickou chybou AADSTS700024. Strávili jsme na tom dvě hodiny, než jsme si všimli rozdílu ve velikosti písmen v logu.

Další častý problém: pokud máte více subscription a OIDC identita má Contributor pouze na jedné resource group, ale šablona odkazuje Key Vault v jiné resource group, dostanete kryptickou chybu Forbidden bez jakéhokoliv náznaku, že problém je v chybějícím role assignment.

Výsledky z praxe

Po nasazení pipeline jsme sledovali metriky za prvních 30 běhů:

FázePrůměrná doba
What-if náhled (PR)1m 42s
Deployment staging3m 15s
Deployment produkce (po schválení)3m 22s
Celkem (staging + produkce)~7 min

Pro srovnání: ruční proces zahrnoval přihlášení přes VPN, az login s osobními credentials, navigaci do správného adresáře, vzpomínání na správný parametrový soubor a ruční spuštění. Minimálně 20 minut na prostředí, plus riziko lidské chyby.

Za první měsíc provozu pipeline zachytil:

  • 3 konflikty CIDR rozsahů ve what-if náhledech (dříve by se projevily až v produkci)
  • 1 chybějící role assignment pro OIDC identitu na cross-resource-group Key Vault
  • 2 pokusy o deployment z feature větve přímo do produkce (zablokováno branch restriction)

Klíčové poznatky

  • OIDC federace místo client secrets. Eliminuje rotaci secrets a zmenšuje attack surface. Dávejte pozor na case-sensitivity pole subject.
  • What-if na každém PR. Infrastrukturní diff by měl být stejně viditelný jako diff v kódu. Automatický PR komentář zajistí, že ho reviewer nemůže přehlédnout.
  • Environment gates nejsou luxus. Pětiminutová prodleva před produkčním deploymentem nás za první měsíc zachránila dvakrát.
  • Pojmenované deploymenty. Vzor --name "prod-$(date +%Y%m%d-%H%M%S)" umožňuje jednoduché korelace mezi GitHub Actions a Azure portálem.

Pokud pracujete s Terraformem a zajímá vás srovnání přístupů, podívejte se na náš přehled Terraform best practices pro Azure. Volba mezi Bicep a Terraform často závisí na tom, zda je váš tým čistě na Azure, nebo pracuje multi-cloud.

Potřebujete pomoct s nastavením CI/CD pipeline pro vaši Azure infrastrukturu? Podívejte se na naše konzultační služby v oblasti infrastruktury a DevOps -- tyto pipeline jsme stavěli pro týmy od tříčlenných startupů po enterprise platformní týmy.

Tagy:#Bicep#Azure#IaC#DevOps#CI/CD#GitHub Actions
LinkedInX / Twitter

O autorovi

Martin Rylko

Martin Rylko

Senior Cloud Architect & DevOps Engineer

Více než 14 let v IT – od on-premises datacenter a Hyper-V clusteringu po cloudovou infrastrukturu v Microsoft Azure. Specializuji se na Landing Zones, IaC automatizaci, Kubernetes a bezpečnostní compliance.

Email LinkedInCelý profil

Nejcastejsi dotazy

Mám použít OIDC federaci nebo service principal secret pro GitHub Actions do Azure?▾
Vždy používejte OIDC (OpenID Connect) federaci. Eliminuje uložené tajné klíče -- GitHub Actions získá krátkodobý token od Entra ID pro každý běh workflow. Service principal secrets expirují, mohou uniknout a vyžadují ruční rotaci. OIDC federace se konfiguruje jednorázově přes az ad app federated-credential create a funguje s environment-scoped deploymenty.
Jaký deployment scope mám použít pro Bicep v CI/CD -- subskripci nebo resource group?▾
Záleží na tom, co nasazujete. Resource group scope (az deployment group create) funguje pro aplikační zdroje v rámci jedné RG. Subscription scope (az deployment sub create) je potřeba pro vytváření resource group, přiřazení politik nebo přiřazení rolí. Landing Zone nasazení typicky používají subscription nebo management group scope.
Jak řešit rollback, když deployment Bicepu selže v pipeline?▾
Bicep deploymenty jsou idempotentní, ale nemají auto-rollback. Používejte what-if preview krok jako bránu před produkčním nasazením. Pro kritické rollbacky udržujte poslední funkční Bicep parameter soubory verzované a opětovně nasaďte z předchozího commitu. Azure také podporuje deployment stacks (GA od 2024), které dokážou smazat zdroje odebrané ze šablony.
Lze spustit Bicep what-if jako check v pull requestu před mergem?▾
Ano, a měli byste. Přidejte PR-triggered workflow, který spustí az deployment group what-if a výstup postne jako komentář do PR. Revieweři tak vidí přesný diff infrastrukturních změn před mergem. Použijte přepínač --no-pretty-print pro strojově parsovatelný JSON výstup vhodný pro vlastní formátování.

Mohlo by vás zajímat

Terraform Azure moduly: Privátní registr a testování

Znovupoužitelné Terraform moduly pro Azure s publikací do privátního registru, automatizované testování Terratest a verzovaná spotřeba modulů v produkci.

Číst

Terraform Azure: Best practices pro produkci

Terraform Azure best practices pro produkční projekty. Remote state locking, modulární struktura, drift detection, naming konvence a testování.

Číst

Azure Landing Zone v Bicepu: Enterprise nasazení

Nasaďte enterprise-ready Azure Landing Zone pomocí Bicep modulů. Hub-spoke síťová architektura, governance politiky a integrace do CI/CD pipeline.

Číst