Upgrade to Pro — share decks privately, control downloads, hide ads and more …

February 2021: Azure IaC with Azure DevOps by Marc Müller

February 2021: Azure IaC with Azure DevOps by Marc Müller

Check out the video to this session here:

In this meetup, Marc shows us what the Azure DevOps offering has in store for us and how we can use it to build release pipelines to release our Infrastructure (as code) to different Azure environments. Get ready to learn everything about Azure DevOps pipelines to take your Azure IaC game to the next level.

Marc Müller is a Principal Consultant for Microsoft DevOps and. NET solutions at 4tecture. In recent years, he was able to bring his expertise in DevOps and his know-how in enterprise architectures into many projects. Training and coaching project teams in DevOps and .NET is one of his main tasks. He is a board member and organizer of the .NET User Group Zurich.

You can find him at:



Azure Zurich User Group

February 02, 2021


  1. None
  2. None
  3. None
  4. None
  5. None
  6. Azure Pipelines Azure Artifacts Service Connection Environments Hosted / private

    Agent Container Jobs Pipeline Secrets Azure KeyVault Azure Repo App Code IaC Azure Resources Version / Branch Compile / Package Deploy Tasks Stages Variables / Secrets Pipeline Infrastructure Execution on target Approvals Checks Deployment Strategy Templates Tests / Test-Results
  7. Azure Resource Group Resource Group VM Storage vNet Azure AD

    Azure DevOps Repo Pipeline Service Connection Agent Pool Pipelines Agent Agent
  8. Base Infrastructure CD Service CD Base Infrastructure Template Resource Template

    Resource Template Dev/Test Prod Service CI Build Stage PR Stage Testing PreProd Prod Compile Service DB Schema Compile System Tests Infrastructure Artifacts Pipeline Artifacts Task / Job Templates Task / Job Templates Resource Groups, vNets, VMs, Azure SQL, CosmosDB, … App Deployment, DB instance, DB Schema, Managed Identities, Storage, … Deplyoment Verification
  9. None
  10. ▪ ▪ ▪ ▪ ▪ ▪ ▪ → ▪ ▪

  11. Build Pipeline Job Job Task Task Task Task Task Task

    Task Task Task Task Task Task Task Task Task
  12. Stage Job Task Task Task Task Task Stage Stage Stage

  13. Release Pipeline Stage Build Pipeline Job Task Task Job Task

    Task Stage Job Task Task Job Task Task YAML Build Pipeline Job Task Task Job Task Task
  14. Multi-Stage Yaml Pipeline Stage Job Task Task Job Task Task

    Stage Job Task Task Stage Job Task Task Stage Job Task Task Job Task Task Job Task Task
  15. None
  16. Stage Job Task Task Job Task Task Agent Agent

  17. ▪ ▪ ▪ ▪ ▪

  18. ▪ ▪ ▪ ▪ ▪ ▪ ▪ → ▪ ▪

    ▪ ▪ ▪
  19. None
  20. None
  21. None
  22. None
  23. None
  24. None
  25. None
  26. None
  27. https://github.com/microsoft/azure-pipelines-vscode

  28. None
  29. None
  30. None
  31. ▪ ▪ ▪ ▪ Source: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops

  32. Source: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops

  33. Source: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops

  34. Source: https://docs.microsoft.com/en-us/azure/devops/pipelines/process/templates?view=azure-devops

  35. ▪ ▪ ▪ ▪

  36. None
  37. None
  38. None
  39. None
  40. None
  41. None
  42. None
  43. ▪ → ▪ →

  44. None
  45. dedicated Agent* Shared (30 h/month) VM in a public cloud

    In your own data center 30 hours/month included Self-Hosted CI/CD Microsoft-Hosted CI/CD Run your own agents? 1 Parallel Job license included * additional costs Buy additional parallel jobs licenses * Buy additional hosted agents*
  46. Environment VM Agent VM Agent Pool Agent (with capabilities) Agent

    (with capabilities) Agent (with capabilities) Agent (with capabilities) Agent (with capabilities) Agent (with capabilities) Azure DevOps No agent, only execute api calls Agent VM Agent Job Deployment Job Server Job Hosted Agent Pool Agent Windows Agent Linux Agent Mac Environment with resourceType: VirtualMachine
  47. None
  48. None
  49. None
  50. None
  51. $ErrorActionPreference="Stop";If(-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent() ).IsInRole( [Security.Principal.WindowsBuiltInRole] "Administrator")){ throw "Run command in an

    administrator PowerShell prompt"};If($PSVersionTable.PSVersion -lt (New-Object System.Version("3.0"))){ throw "The minimum version of Windows PowerShell that is required by the script (3.0) does not match the currently running version of Windows PowerShell." };If(-NOT (Test-Path $env:SystemDrive\'azagent')){mkdir $env:SystemDrive\'azagent'}; cd $env:SystemDrive\'azagent'; for($i=1; $i -lt 100; $i++){$destFolder="A"+$i.ToString();if(-NOT (Test-Path ($destFolder))){mkdir $destFolder;cd $destFolder;break;}}; $agentZip="$PWD\agent.zip";$DefaultProxy=[System.Net.WebRequest]::DefaultWebProxy;$securityProt ocol=@();$securityProtocol+=[Net.ServicePointManager]::SecurityProtocol;$securityProtocol+=[Net .SecurityProtocolType]::Tls12;[Net.ServicePointManager]::SecurityProtocol=$securityProtocol;$We bClient=New-Object Net.WebClient; $Uri='https://vstsagentpackage.azureedge.net/agent/2.181.1/vsts-agent-win-x64- 2.181.1.zip';if($DefaultProxy -and (-not $DefaultProxy.IsBypassed($Uri))){$WebClient.Proxy= New-Object Net.WebProxy($DefaultProxy.GetProxy($Uri).OriginalString, $True);}; $WebClient.DownloadFile($Uri, $agentZip);Add-Type -AssemblyName System.IO.Compression.FileSystem;[System.IO.Compression.ZipFile]::ExtractToDirectory( $agentZip, "$PWD");.\config.cmd --environment --environmentname "Demo Environment" --agent $env:COMPUTERNAME --runasservice --work '_work' --url 'https://dev.azure.com/4tecture-demo/' -- projectname 'YamlPipelinesDemo' --auth PAT --token xxxx; Remove-Item $agentZip; jobs: - deployment: VMDeploy displayName: web environment: name: VMenv resourceType: VirtualMachine tags: web1 strategy:
  52. None
  53. ▪ ▪ ▪

  54. None
  55. FROM microsoft/dotnet:2.1-aspnetcore- runtime WORKDIR /app COPY output/app . ENTRYPOINT ["dotnet",

    "HelloWorld.dll"] FROM microsoft/dotnet:2.1-aspnetcore-runtime AS base WORKDIR /app EXPOSE 80 FROM microsoft/dotnet:2.1-sdk AS build WORKDIR /src COPY ["HelloWorld/HelloWorld.csproj", "HelloWorld/"] RUN dotnet restore "HelloWorld/HelloWorld.csproj" COPY . . WORKDIR "/src/HelloWorld" RUN dotnet build "HelloWorld.csproj" -c Release -o /app FROM build AS publish RUN dotnet publish "HelloWorld.csproj" -c Release -o /app FROM base AS final WORKDIR /app COPY --from=publish /app . ENTRYPOINT ["dotnet", "HelloWorld.dll"]
  56. resources: containers: - container: my_container image: ubuntu:16.04 - container: nginx

    image: nginx - container: redis image: redis pool: vmImage: 'ubuntu-16.04' container: my_container services: nginx: nginx redis: redis steps: - script: | apt install -y curl curl nginx apt install redis-tools redis-cli -h redis ping resources: containers: - container: nginx image: nginx ports: - 8080:80 env: NGINX_PORT: 80 - container: redis image: redis ports: - 6379 pool: vmImage: 'ubuntu-16.04' services: nginx: nginx redis: redis steps: - script: | curl localhost:8080 redis-cli -p "${AGENT_SERVICES_REDIS_PORTS_6379}" ping
  57. resources: containers: - container: my_container image: ubuntu:16.04 - container: pg11

    image: postgres:11 - container: pg10 image: postgres:10 pool: vmImage: 'ubuntu-16.04' strategy: matrix: postgres11: postgresService: pg11 postgres10: postgresService: pg10 container: my_container services: postgres: $[ variables['postgresService'] ] steps: - script: | apt install -y postgresql-client psql --host=postgres --username=postgres --command="SELECT 1;"
  58. Pipeline Agent Docker Network Container Pipeline Job Build Container Publish

    Container Container Job Container API App Container SQL Server Deploy DB Run Test Docker Registry
  59. None
  60. None
  61. None
  62. None