[{"data":1,"prerenderedAt":4539},["Reactive",2],{"navigation":3,"/posts/ado-workload-identity-federation":204,"/posts/ado-workload-identity-federation-surround":4515},[4,192,200],{"title":5,"_path":6,"children":7,"icon":191},"Blog","/posts",[8,11,14,17,20,23,26,29,32,35,38,41,44,47,50,53,56,59,62,65,68,71,74,77,80,83,86,89,92,95,98,101,104,107,110,113,116,119,122,125,128,131,134,137,140,143,146,149,152,155,158,161,164,167,170,173,176,179,182,185,188],{"title":9,"_path":10},"Testing your API with REST Client","/posts/testing-your-api-with-rest-client",{"title":12,"_path":13},"HTML templating in Xamarin","/posts/html-templating-in-xamarin",{"title":15,"_path":16},"Goodbye Azure Portal, Welcome Azure CLI","/posts/welcome-azure-cli",{"title":18,"_path":19},"Coming across Gitpod","/posts/gitpod",{"title":21,"_path":22},"Handle token retrieval while querying an API","/posts/delegating-handler",{"title":24,"_path":25},"Clean up your local git branches.","/posts/cleaning-git-branches",{"title":27,"_path":28},"Automate configuration of Teams Tab SSO with PowerShell.","/posts/teams-sso-powershell",{"title":30,"_path":31},"How to do a technology watch? - Part 1","/posts/technology-watch-part1",{"title":33,"_path":34},"How to do a technology watch? - Part 2","/posts/technology-watch-part2",{"title":36,"_path":37},"You almost no longer need Key Vault references for Azure Functions.","/posts/azure-functions-custom-configuration",{"title":39,"_path":40},"How to do a technology watch? - Part 3","/posts/technology-watch-part3",{"title":42,"_path":43},"Forget DevOps, the future is already here!","/posts/devops-future",{"title":45,"_path":46},"Week 9, 2021 - Tips I learned this week","/posts/w09-2021-tips-learned-this-week",{"title":48,"_path":49},"Week 12, 2021 - Tips I learned this week","/posts/w12-2021-tips-learned-this-week",{"title":51,"_path":52},"Week 14, 2021 - Tips I learned this week","/posts/w14-2021-tips-learned-this-week",{"title":54,"_path":55},"Once upon a time in .NET","/posts/once-upon-a-time-in-dotnet",{"title":57,"_path":58},"Install your applications with winget","/posts/winget-import",{"title":60,"_path":61},"Customize your applications when installing them with winget","/posts/winget-override",{"title":63,"_path":64},"Week 22, 2021 - Tips I learned this week","/posts/w22-2021-tips-learned-this-week",{"title":66,"_path":67},"How to connect to an Azure SQL Database from C# using Azure AD","/posts/sqlclient-active-directory-authent",{"title":69,"_path":70},"Producing packages for Windows Package Manager","/posts/wingetcreate",{"title":72,"_path":73},"4 tips about GitHub Actions environment variables and contexts","/posts/github-actions-var-and-context",{"title":75,"_path":76},"AzureWebJobsStorage, the secret you don't need in your Function App.","/posts/azure-functions-without-azurewebjobsstorage",{"title":78,"_path":79},"ASP.NET Core - Lost in configuration","/posts/lost-in-configuration",{"title":81,"_path":82},"Week 39, 2021 - Tips I learned this week","/posts/w39-2021-tips-learned-this-week",{"title":84,"_path":85},"Week 41, 2021 - Tips I learned this week","/posts/w41-2021-tips-learned-this-week",{"title":87,"_path":88},"Migrating and open-sourcing my blog","/posts/migrating-blog",{"title":90,"_path":91},"Week 45, 2021 - Tips I learned this week","/posts/w45-2021-tips-learned-this-week",{"title":93,"_path":94},"Organize your GitHub stars with Astral","/posts/astral",{"title":96,"_path":97},"Pulumi with an Azure Blob Storage backend","/posts/pulumi-azure-backend",{"title":99,"_path":100},"IaC Hot Reload with Pulumi Watch","/posts/pulumi-watch",{"title":102,"_path":103},"Week 2, 2022 - Tips I learned this week","/posts/w02-2022-tips-learned-this-week",{"title":105,"_path":106},"Week 3, 2022 - Tips I learned this week","/posts/w03-2022-tips-learned-this-week",{"title":108,"_path":109},"Week 5, 2022 - Tips I learned this week","/posts/w05-2022-tips-learned-this-week",{"title":111,"_path":112},"How to provision an Azure SQL Database with Active Directory authentication","/posts/sqldatabase-active-directory-authent",{"title":114,"_path":115},"Why will I choose Pulumi over Terraform for my next project?","/posts/pulumi-vs-terraform",{"title":117,"_path":118},"Week 19, 2022 - Tips I learned this week","/posts/w19-2022-tips-learned-this-week",{"title":120,"_path":121},"Week 20, 2022 - Tips I learned this week","/posts/w20-2022-tips-learned-this-week",{"title":123,"_path":124},"Keeping secrets secure when using API Clients","/posts/http-clients-secrets",{"title":126,"_path":127},"What made me want to be a developer?","/posts/be-a-developer",{"title":129,"_path":130},"What can we do when stuck with a programming problem?","/posts/get-unstuck",{"title":132,"_path":133},"How did I automate the setup of my developer Windows laptop?","/posts/automate-developer-machine",{"title":135,"_path":136},"Discussion about API clients","/posts/http-clients",{"title":138,"_path":139},"Week 46, 2022 - Tips I learned this week","/posts/w46-2022-tips-learned-this-week",{"title":141,"_path":142},"When Pulumi met Nuke: a .NET love story","/posts/when-pulumi-met-nuke",{"title":144,"_path":145},"A year of learning and sharing - Dev Retro 2022","/posts/2022-retro",{"title":147,"_path":148},"Perform Dynamic Execution of an npm Package","/posts/pnpm-dlx",{"title":150,"_path":151},"Manage multiple Node.js versions","/posts/pnpm-env",{"title":153,"_path":154},"Introducing the Vue.js CI/CD series","/posts/vuecicd-introduction",{"title":156,"_path":157},"Execute commands using your project dependencies","/posts/pnpm-exec",{"title":159,"_path":160},"Vue.js CI/CD: Continuous Integration","/posts/vuecicd-ci",{"title":162,"_path":163},"Who is using pnpm?","/posts/pnpm-who-is-using",{"title":165,"_path":166},"Create an Azure-Ready GitHub Repository using Pulumi","/posts/azure-ready-github-repository",{"title":168,"_path":169},"Deploying to Azure from Azure DevOps without secrets","/posts/ado-workload-identity-federation",{"title":171,"_path":172},"Effortlessly Configure GitHub Repositories for Azure Deployment via OIDC","/posts/scripting-azure-ready-github-repository",{"title":174,"_path":175},"Playing with the .NET 8 Web API template","/posts/playing-with-dotnet8",{"title":177,"_path":178},"Another year of sharing and learning - Dev Retro 2023","/posts/2023-retro",{"title":180,"_path":181},"Week 4, 2024 - Tips I learned this week","/posts/w04-2024-tips-learned-this-week",{"title":183,"_path":184},"Using dependency injection with Azure .NET SDK","/posts/azure-sdk-di",{"title":186,"_path":187},"Having Fun With IT Event Calendars","/posts/it-event-calendars",{"title":189,"_path":190},"Call your Azure AD B2C protected API with authenticated HTTP requests from your JetBrains IDE","/posts/http-clients-oauth2","i-heroicons-newspaper",{"title":193,"_path":194,"children":195,"icon":199},"Goodies","/goodies",[196],{"title":197,"_path":198},"My Git Cheat Sheet","/goodies/gitcheatsheet","i-heroicons-gift-solid",{"title":201,"_path":202,"icon":203},"About","/about","i-heroicons-user-circle-solid",{"_path":169,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":168,"description":208,"lead":209,"date":210,"image":211,"badge":213,"tags":215,"body":224,"_type":4510,"_id":4511,"_source":4512,"_file":4513,"_extension":4514},"posts",false,"","If you are deploying your application to Azure from Azure Pipelines, you might want to leverage the ability to do so without using secrets thanks to Workload identity federation. In this article, I will demonstrate how to automate the configuration of your Azure DevOps project, with everything pre-configured to securely deploy applications to Azure.","Azure DevOps Workload identity federation (OIDC) with Pulumi","2023-09-21T00:00:00.000Z",{"src":212},"/images/azuredevopsoidc.webp",{"label":214},"DevOps",[216,217,218,219,220,221,222,223],"Azure","GitHub","GitHub Actions","OpenID Connect","Pulumi","IaC","security",".NET",{"type":225,"children":226,"toc":4497},"root",[227,234,241,257,272,277,298,310,329,341,346,360,365,370,379,388,393,398,408,414,421,426,501,514,573,578,617,622,667,673,678,717,731,767,791,796,1171,1176,1190,1302,1307,1573,1614,1620,1634,1924,1937,2095,2100,2123,2351,2357,2362,2380,2385,2870,2885,2890,3211,3224,3230,3235,3248,3487,3492,3747,3752,4023,4028,4213,4218,4382,4395,4427,4436,4441,4447,4460,4465,4470,4475,4491],{"type":228,"tag":229,"props":230,"children":231},"element","p",{},[232],{"type":233,"value":208},"text",{"type":228,"tag":235,"props":236,"children":238},"h2",{"id":237},"why-should-you-use-workload-identity-federation-for-your-deployment-pipelines",[239],{"type":233,"value":240},"Why should you use Workload Identity Federation for your deployment pipelines?",{"type":228,"tag":229,"props":242,"children":243},{},[244,246,255],{"type":233,"value":245},"I already wrote about the ",{"type":228,"tag":247,"props":248,"children":252},"a",{"href":249,"rel":250},"https://www.techwatching.dev/posts/azure-ready-github-repository#the-problem-with-secret-credentials",[251],"nofollow",[253],{"type":233,"value":254},"problem of secret credentials",{"type":233,"value":256},", but let me remind you 2 reasons why I think you should always avoid using secrets in your deployment pipelines:",{"type":228,"tag":258,"props":259,"children":260},"ul",{},[261,267],{"type":228,"tag":262,"props":263,"children":264},"li",{},[265],{"type":233,"value":266},"It's more secure if you don't need a secret to authenticate to Azure",{"type":228,"tag":262,"props":268,"children":269},{},[270],{"type":233,"value":271},"It's more practical if you don't need to handle secret rotation when secrets expire",{"type":228,"tag":229,"props":273,"children":274},{},[275],{"type":233,"value":276},"This is true whatever the CI/CD platform you are using.",{"type":228,"tag":229,"props":278,"children":279},{},[280,287,289,296],{"type":228,"tag":247,"props":281,"children":284},{"href":282,"rel":283},"https://learn.microsoft.com/en-us/azure/active-directory/workload-identities/workload-identity-federation",[251],[285],{"type":233,"value":286},"Workload identity federation",{"type":233,"value":288}," leverages OpenID Connect to solve these problems and avoid using secrets in your pipelines to authenticate to Azure. I previously published ",{"type":228,"tag":247,"props":290,"children":293},{"href":291,"rel":292},"https://www.techwatching.dev/posts/azure-ready-github-repository",[251],[294],{"type":233,"value":295},"an article about using Azure OpenID Connect with Pulumi in GitHub Actions",{"type":233,"value":297},", but that also works with Azure Pipelines.",{"type":228,"tag":229,"props":299,"children":300},{},[301],{"type":228,"tag":302,"props":303,"children":309},"img",{"alt":304,"className":305,"src":308},"Workload Identity Federation for Azure DevOps",[306,307],"rounded-lg","mx-auto","/posts/images/azuredevopsoidc_schema_1.webp",[],{"type":228,"tag":311,"props":312,"children":314},"callout",{"icon":313},"i-heroicons-information-circle",[315],{"type":228,"tag":229,"props":316,"children":317},{},[318,320,327],{"type":233,"value":319},"Microsoft has announced the ",{"type":228,"tag":247,"props":321,"children":324},{"href":322,"rel":323},"https://devblogs.microsoft.com/devops/public-preview-of-workload-identity-federation-for-azure-pipelines/",[251],[325],{"type":233,"value":326},"public preview of Workload identity federation for Azure Pipelines",{"type":233,"value":328}," on the 11th September 2023.",{"type":228,"tag":235,"props":330,"children":332},{"id":331},"how-can-you-use-workload-identity-federation-to-deploy-to-azure-from-azure-pipelines",[333,335],{"type":233,"value":334},"How can you use ",{"type":228,"tag":336,"props":337,"children":338},"strong",{},[339],{"type":233,"value":340},"Workload Identity Federation to deploy to Azure from Azure Pipelines?",{"type":228,"tag":229,"props":342,"children":343},{},[344],{"type":233,"value":345},"Azure Pipelines tasks use service connections to authenticate with external services. Specifically, for Azure, it is necessary to create an Azure Resource Manager service connection.",{"type":228,"tag":229,"props":347,"children":348},{},[349,351,358],{"type":233,"value":350},"You can create an Azure Resource Manager service connection that uses workload identity federation by configuring it in your Azure DevOps organization portal (check the documentation ",{"type":228,"tag":247,"props":352,"children":355},{"href":353,"rel":354},"https://learn.microsoft.com/en-us/azure/devops/pipelines/library/connect-to-azure?view=azure-devops#create-an-azure-resource-manager-service-connection-using-workload-identity-federation",[251],[356],{"type":233,"value":357},"here",{"type":233,"value":359},").",{"type":228,"tag":229,"props":361,"children":362},{},[363],{"type":233,"value":364},"Or ... you can automate that using Infrastructure as Code 😉.",{"type":228,"tag":229,"props":366,"children":367},{},[368],{"type":233,"value":369},"Yet, who wants to manually configure things from a wizard when everything can be automated in versioned code? So let's go the IaC way.",{"type":228,"tag":311,"props":371,"children":373},{"icon":372},"i-heroicons-chat-bubble-left-20-solid",[374],{"type":228,"tag":229,"props":375,"children":376},{},[377],{"type":233,"value":378},"All kidding aside, I genuinely believe that there are many advantages to provisioning your Azure DevOps projects and their associated resources (Repos, Service Connections, policies, pipelines, ...) using Infrastructure as Code. It takes time to properly configure Azure DevOps projects, and if they are often organized similarly, it's more efficient to automate their configuration rather than doing it manually.",{"type":228,"tag":229,"props":380,"children":381},{},[382],{"type":228,"tag":302,"props":383,"children":387},{"alt":384,"className":385,"src":386},"Diagram to deploy from Azure Pipelines to Azure",[306,307],"/posts/images/azuredevopsoidc_schema_2.webp",[],{"type":228,"tag":229,"props":389,"children":390},{},[391],{"type":233,"value":392},"I will use Pulumi and its Azure DevOps provider to provision the necessary resources. The infrastructure as code will be written in C# but you could easily convert the C# code to any language that Pulumi supports (like TypeScript, I am a big fan of using TypeScript to write infrastructure code 🔥).",{"type":228,"tag":229,"props":394,"children":395},{},[396],{"type":233,"value":397},"Here is the complete solution to implement:",{"type":228,"tag":229,"props":399,"children":400},{},[401],{"type":228,"tag":302,"props":402,"children":407},{"alt":403,"className":404,"src":405,"width":406},"Schema of the complete solution",[306,307],"/posts/images/azuredevopsoidc_schema_3.webp",1000,[],{"type":228,"tag":235,"props":409,"children":411},{"id":410},"automate-the-configuration-of-workload-identity-federation-in-azure-devops",[412],{"type":233,"value":413},"Automate the configuration of Workload identity federation in Azure DevOps",{"type":228,"tag":415,"props":416,"children":418},"h3",{"id":417},"create-the-pulumi-net-project",[419],{"type":233,"value":420},"Create the Pulumi .NET project",{"type":228,"tag":229,"props":422,"children":423},{},[424],{"type":233,"value":425},"Let's start by scaffolding a new Pulumi project using .NET:",{"type":228,"tag":427,"props":428,"children":432},"pre",{"className":429,"code":430,"language":431,"meta":207,"style":207},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","pulumi new csharp -n AzureDevOpsWorkloadIdentity -s dev -d \"A program to set up an Azure-Ready Azure DevOps repository\"\n","bash",[433],{"type":228,"tag":434,"props":435,"children":436},"code",{"__ignoreMap":207},[437],{"type":228,"tag":438,"props":439,"children":442},"span",{"class":440,"line":441},"line",1,[443,449,455,460,465,470,475,480,485,491,496],{"type":228,"tag":438,"props":444,"children":446},{"style":445},"--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B",[447],{"type":233,"value":448},"pulumi",{"type":228,"tag":438,"props":450,"children":452},{"style":451},"--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D",[453],{"type":233,"value":454}," new",{"type":228,"tag":438,"props":456,"children":457},{"style":451},[458],{"type":233,"value":459}," csharp",{"type":228,"tag":438,"props":461,"children":462},{"style":451},[463],{"type":233,"value":464}," -n",{"type":228,"tag":438,"props":466,"children":467},{"style":451},[468],{"type":233,"value":469}," AzureDevOpsWorkloadIdentity",{"type":228,"tag":438,"props":471,"children":472},{"style":451},[473],{"type":233,"value":474}," -s",{"type":228,"tag":438,"props":476,"children":477},{"style":451},[478],{"type":233,"value":479}," dev",{"type":228,"tag":438,"props":481,"children":482},{"style":451},[483],{"type":233,"value":484}," -d",{"type":228,"tag":438,"props":486,"children":488},{"style":487},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF",[489],{"type":233,"value":490}," \"",{"type":228,"tag":438,"props":492,"children":493},{"style":451},[494],{"type":233,"value":495},"A program to set up an Azure-Ready Azure DevOps repository",{"type":228,"tag":438,"props":497,"children":498},{"style":487},[499],{"type":233,"value":500},"\"\n",{"type":228,"tag":229,"props":502,"children":503},{},[504,506,512],{"type":233,"value":505},"This command creates a new pulumi project and stack from the ",{"type":228,"tag":434,"props":507,"children":509},{"className":508},[],[510],{"type":233,"value":511},"csharp",{"type":233,"value":513}," template:",{"type":228,"tag":258,"props":515,"children":516},{},[517,538,555],{"type":228,"tag":262,"props":518,"children":519},{},[520,522,528,530,536],{"type":233,"value":521},"The name of the project \"",{"type":228,"tag":523,"props":524,"children":525},"em",{},[526],{"type":233,"value":527},"AzureDevOpsWorkloadIdentity",{"type":233,"value":529},"\" is specified using the ",{"type":228,"tag":434,"props":531,"children":533},{"className":532},[],[534],{"type":233,"value":535},"-n",{"type":233,"value":537}," option",{"type":228,"tag":262,"props":539,"children":540},{},[541,543,547,548,554],{"type":233,"value":542},"The description of the project \"",{"type":228,"tag":523,"props":544,"children":545},{},[546],{"type":233,"value":495},{"type":233,"value":529},{"type":228,"tag":434,"props":549,"children":551},{"className":550},[],[552],{"type":233,"value":553},"-d",{"type":233,"value":537},{"type":228,"tag":262,"props":556,"children":557},{},[558,560,565,566,572],{"type":233,"value":559},"The stack of the project \"",{"type":228,"tag":523,"props":561,"children":562},{},[563],{"type":233,"value":564},"dev",{"type":233,"value":529},{"type":228,"tag":434,"props":567,"children":569},{"className":568},[],[570],{"type":233,"value":571},"-s",{"type":233,"value":537},{"type":228,"tag":229,"props":574,"children":575},{},[576],{"type":233,"value":577},"This project will need 3 different providers:",{"type":228,"tag":258,"props":579,"children":580},{},[581,593,606],{"type":228,"tag":262,"props":582,"children":583},{},[584,586],{"type":233,"value":585},"the ",{"type":228,"tag":247,"props":587,"children":590},{"href":588,"rel":589},"https://www.pulumi.com/registry/packages/azure-native/",[251],[591],{"type":233,"value":592},"Azure Native provider",{"type":228,"tag":262,"props":594,"children":595},{},[596,597,604],{"type":233,"value":585},{"type":228,"tag":247,"props":598,"children":601},{"href":599,"rel":600},"https://www.pulumi.com/registry/packages/azuread/",[251],[602],{"type":233,"value":603},"Azure Active Directory provider",{"type":233,"value":605}," (provider for Microsoft Entra ID)",{"type":228,"tag":262,"props":607,"children":608},{},[609,610],{"type":233,"value":585},{"type":228,"tag":247,"props":611,"children":614},{"href":612,"rel":613},"https://www.pulumi.com/registry/packages/azuredevops/",[251],[615],{"type":233,"value":616},"Azure DevOps provider",{"type":228,"tag":229,"props":618,"children":619},{},[620],{"type":233,"value":621},"So we can add the following Nuget packages to our project:",{"type":228,"tag":258,"props":623,"children":624},{},[625,639,653],{"type":228,"tag":262,"props":626,"children":627},{},[628],{"type":228,"tag":247,"props":629,"children":632},{"href":630,"rel":631},"https://www.nuget.org/packages/Pulumi.AzureNative",[251],[633],{"type":228,"tag":434,"props":634,"children":636},{"className":635},[],[637],{"type":233,"value":638},"Pulumi.AzureNative",{"type":228,"tag":262,"props":640,"children":641},{},[642],{"type":228,"tag":247,"props":643,"children":646},{"href":644,"rel":645},"https://www.nuget.org/packages/Pulumi.AzureAD",[251],[647],{"type":228,"tag":434,"props":648,"children":650},{"className":649},[],[651],{"type":233,"value":652},"Pulumi.AzureAD",{"type":228,"tag":262,"props":654,"children":655},{},[656],{"type":228,"tag":247,"props":657,"children":660},{"href":658,"rel":659},"https://www.nuget.org/packages/Pulumi.AzureDevOps",[251],[661],{"type":228,"tag":434,"props":662,"children":664},{"className":663},[],[665],{"type":233,"value":666},"Pulumi.AzureDevOps",{"type":228,"tag":415,"props":668,"children":670},{"id":669},"create-the-azure-devops-project",[671],{"type":233,"value":672},"Create the Azure DevOps project",{"type":228,"tag":229,"props":674,"children":675},{},[676],{"type":233,"value":677},"First, we must select the Azure DevOps organization where we wish to create a project and set its URL in our Pulumi configuration.",{"type":228,"tag":427,"props":679,"children":681},{"className":429,"code":680,"language":431,"meta":207,"style":207},"pulumi config set azuredevops:orgServiceUrl XXXXXXXXXXXXXX --secret\n",[682],{"type":228,"tag":434,"props":683,"children":684},{"__ignoreMap":207},[685],{"type":228,"tag":438,"props":686,"children":687},{"class":440,"line":441},[688,692,697,702,707,712],{"type":228,"tag":438,"props":689,"children":690},{"style":445},[691],{"type":233,"value":448},{"type":228,"tag":438,"props":693,"children":694},{"style":451},[695],{"type":233,"value":696}," config",{"type":228,"tag":438,"props":698,"children":699},{"style":451},[700],{"type":233,"value":701}," set",{"type":228,"tag":438,"props":703,"children":704},{"style":451},[705],{"type":233,"value":706}," azuredevops:orgServiceUrl",{"type":228,"tag":438,"props":708,"children":709},{"style":451},[710],{"type":233,"value":711}," XXXXXXXXXXXXXX",{"type":228,"tag":438,"props":713,"children":714},{"style":451},[715],{"type":233,"value":716}," --secret\n",{"type":228,"tag":229,"props":718,"children":719},{},[720,722,729],{"type":233,"value":721},"Second, we need to supply the necessary Azure DevOps credentials. For that, we can ",{"type":228,"tag":247,"props":723,"children":726},{"href":724,"rel":725},"https://learn.microsoft.com/en-us/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops&tabs=Windows#create-a-pat",[251],[727],{"type":233,"value":728},"create a personal access token",{"type":233,"value":730}," and add it to our Pulumi configuration.",{"type":228,"tag":427,"props":732,"children":734},{"className":429,"code":733,"language":431,"meta":207,"style":207},"pulumi config set azuredevops:personalAccessToken YYYYYYYYYYYYYY --secret\n",[735],{"type":228,"tag":434,"props":736,"children":737},{"__ignoreMap":207},[738],{"type":228,"tag":438,"props":739,"children":740},{"class":440,"line":441},[741,745,749,753,758,763],{"type":228,"tag":438,"props":742,"children":743},{"style":445},[744],{"type":233,"value":448},{"type":228,"tag":438,"props":746,"children":747},{"style":451},[748],{"type":233,"value":696},{"type":228,"tag":438,"props":750,"children":751},{"style":451},[752],{"type":233,"value":701},{"type":228,"tag":438,"props":754,"children":755},{"style":451},[756],{"type":233,"value":757}," azuredevops:personalAccessToken",{"type":228,"tag":438,"props":759,"children":760},{"style":451},[761],{"type":233,"value":762}," YYYYYYYYYYYYYY",{"type":228,"tag":438,"props":764,"children":765},{"style":451},[766],{"type":233,"value":716},{"type":228,"tag":311,"props":768,"children":770},{"icon":769},"i-fluent-emoji-flat-locked-with-key",[771],{"type":228,"tag":229,"props":772,"children":773},{},[774,776,782,784,789],{"type":233,"value":775},"I followed the documentation but to be honest, I don't think it's necessary to include the ",{"type":228,"tag":434,"props":777,"children":779},{"className":778},[],[780],{"type":233,"value":781},"--secret",{"type":233,"value":783}," option for the organization URL as it's not really a sensitive value that needs to be encrypted. However, ",{"type":228,"tag":336,"props":785,"children":786},{},[787],{"type":233,"value":788},"it's mandatory to include it for the access token",{"type":233,"value":790}," so that we can safely commit the configuration files without creating security risks.",{"type":228,"tag":229,"props":792,"children":793},{},[794],{"type":233,"value":795},"Third, we can create the DevOps project:",{"type":228,"tag":427,"props":797,"children":800},{"className":798,"code":799,"language":511,"meta":207,"style":207},"language-csharp shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","var project = new Project(\"AzureReadyADOProject\", new()\n{\n    Description = \"New project with everything correctly configured to provision Azure resources or deploy applications to Azure\",\n    Features = new()\n    {\n        [\"boards\"] = \"disabled\",\n        [\"repositories\"] = \"enabled\",\n        [\"pipelines\"] = \"enabled\",\n        [\"testplans\"] = \"disabled\",\n        [\"artifacts\"] = \"disabled\"\n    },\n});\n",[801],{"type":228,"tag":434,"props":802,"children":803},{"__ignoreMap":207},[804,860,869,902,919,928,976,1022,1067,1112,1153,1162],{"type":228,"tag":438,"props":805,"children":806},{"class":440,"line":441},[807,812,817,822,826,831,836,841,846,850,855],{"type":228,"tag":438,"props":808,"children":809},{"style":445},[810],{"type":233,"value":811},"var",{"type":228,"tag":438,"props":813,"children":814},{"style":445},[815],{"type":233,"value":816}," project",{"type":228,"tag":438,"props":818,"children":819},{"style":487},[820],{"type":233,"value":821}," =",{"type":228,"tag":438,"props":823,"children":824},{"style":487},[825],{"type":233,"value":454},{"type":228,"tag":438,"props":827,"children":828},{"style":445},[829],{"type":233,"value":830}," Project",{"type":228,"tag":438,"props":832,"children":833},{"style":487},[834],{"type":233,"value":835},"(",{"type":228,"tag":438,"props":837,"children":838},{"style":487},[839],{"type":233,"value":840},"\"",{"type":228,"tag":438,"props":842,"children":843},{"style":451},[844],{"type":233,"value":845},"AzureReadyADOProject",{"type":228,"tag":438,"props":847,"children":848},{"style":487},[849],{"type":233,"value":840},{"type":228,"tag":438,"props":851,"children":852},{"style":487},[853],{"type":233,"value":854},",",{"type":228,"tag":438,"props":856,"children":857},{"style":487},[858],{"type":233,"value":859}," new()\n",{"type":228,"tag":438,"props":861,"children":863},{"class":440,"line":862},2,[864],{"type":228,"tag":438,"props":865,"children":866},{"style":487},[867],{"type":233,"value":868},"{\n",{"type":228,"tag":438,"props":870,"children":872},{"class":440,"line":871},3,[873,879,884,888,893,897],{"type":228,"tag":438,"props":874,"children":876},{"style":875},"--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8",[877],{"type":233,"value":878},"    Description ",{"type":228,"tag":438,"props":880,"children":881},{"style":487},[882],{"type":233,"value":883},"=",{"type":228,"tag":438,"props":885,"children":886},{"style":487},[887],{"type":233,"value":490},{"type":228,"tag":438,"props":889,"children":890},{"style":451},[891],{"type":233,"value":892},"New project with everything correctly configured to provision Azure resources or deploy applications to Azure",{"type":228,"tag":438,"props":894,"children":895},{"style":487},[896],{"type":233,"value":840},{"type":228,"tag":438,"props":898,"children":899},{"style":487},[900],{"type":233,"value":901},",\n",{"type":228,"tag":438,"props":903,"children":905},{"class":440,"line":904},4,[906,911,915],{"type":228,"tag":438,"props":907,"children":908},{"style":875},[909],{"type":233,"value":910},"    Features ",{"type":228,"tag":438,"props":912,"children":913},{"style":487},[914],{"type":233,"value":883},{"type":228,"tag":438,"props":916,"children":917},{"style":487},[918],{"type":233,"value":859},{"type":228,"tag":438,"props":920,"children":922},{"class":440,"line":921},5,[923],{"type":228,"tag":438,"props":924,"children":925},{"style":487},[926],{"type":233,"value":927},"    {\n",{"type":228,"tag":438,"props":929,"children":931},{"class":440,"line":930},6,[932,937,941,946,950,955,959,963,968,972],{"type":228,"tag":438,"props":933,"children":934},{"style":487},[935],{"type":233,"value":936},"        [",{"type":228,"tag":438,"props":938,"children":939},{"style":487},[940],{"type":233,"value":840},{"type":228,"tag":438,"props":942,"children":943},{"style":451},[944],{"type":233,"value":945},"boards",{"type":228,"tag":438,"props":947,"children":948},{"style":487},[949],{"type":233,"value":840},{"type":228,"tag":438,"props":951,"children":952},{"style":487},[953],{"type":233,"value":954},"]",{"type":228,"tag":438,"props":956,"children":957},{"style":487},[958],{"type":233,"value":821},{"type":228,"tag":438,"props":960,"children":961},{"style":487},[962],{"type":233,"value":490},{"type":228,"tag":438,"props":964,"children":965},{"style":451},[966],{"type":233,"value":967},"disabled",{"type":228,"tag":438,"props":969,"children":970},{"style":487},[971],{"type":233,"value":840},{"type":228,"tag":438,"props":973,"children":974},{"style":487},[975],{"type":233,"value":901},{"type":228,"tag":438,"props":977,"children":979},{"class":440,"line":978},7,[980,984,988,993,997,1001,1005,1009,1014,1018],{"type":228,"tag":438,"props":981,"children":982},{"style":487},[983],{"type":233,"value":936},{"type":228,"tag":438,"props":985,"children":986},{"style":487},[987],{"type":233,"value":840},{"type":228,"tag":438,"props":989,"children":990},{"style":451},[991],{"type":233,"value":992},"repositories",{"type":228,"tag":438,"props":994,"children":995},{"style":487},[996],{"type":233,"value":840},{"type":228,"tag":438,"props":998,"children":999},{"style":487},[1000],{"type":233,"value":954},{"type":228,"tag":438,"props":1002,"children":1003},{"style":487},[1004],{"type":233,"value":821},{"type":228,"tag":438,"props":1006,"children":1007},{"style":487},[1008],{"type":233,"value":490},{"type":228,"tag":438,"props":1010,"children":1011},{"style":451},[1012],{"type":233,"value":1013},"enabled",{"type":228,"tag":438,"props":1015,"children":1016},{"style":487},[1017],{"type":233,"value":840},{"type":228,"tag":438,"props":1019,"children":1020},{"style":487},[1021],{"type":233,"value":901},{"type":228,"tag":438,"props":1023,"children":1025},{"class":440,"line":1024},8,[1026,1030,1034,1039,1043,1047,1051,1055,1059,1063],{"type":228,"tag":438,"props":1027,"children":1028},{"style":487},[1029],{"type":233,"value":936},{"type":228,"tag":438,"props":1031,"children":1032},{"style":487},[1033],{"type":233,"value":840},{"type":228,"tag":438,"props":1035,"children":1036},{"style":451},[1037],{"type":233,"value":1038},"pipelines",{"type":228,"tag":438,"props":1040,"children":1041},{"style":487},[1042],{"type":233,"value":840},{"type":228,"tag":438,"props":1044,"children":1045},{"style":487},[1046],{"type":233,"value":954},{"type":228,"tag":438,"props":1048,"children":1049},{"style":487},[1050],{"type":233,"value":821},{"type":228,"tag":438,"props":1052,"children":1053},{"style":487},[1054],{"type":233,"value":490},{"type":228,"tag":438,"props":1056,"children":1057},{"style":451},[1058],{"type":233,"value":1013},{"type":228,"tag":438,"props":1060,"children":1061},{"style":487},[1062],{"type":233,"value":840},{"type":228,"tag":438,"props":1064,"children":1065},{"style":487},[1066],{"type":233,"value":901},{"type":228,"tag":438,"props":1068,"children":1070},{"class":440,"line":1069},9,[1071,1075,1079,1084,1088,1092,1096,1100,1104,1108],{"type":228,"tag":438,"props":1072,"children":1073},{"style":487},[1074],{"type":233,"value":936},{"type":228,"tag":438,"props":1076,"children":1077},{"style":487},[1078],{"type":233,"value":840},{"type":228,"tag":438,"props":1080,"children":1081},{"style":451},[1082],{"type":233,"value":1083},"testplans",{"type":228,"tag":438,"props":1085,"children":1086},{"style":487},[1087],{"type":233,"value":840},{"type":228,"tag":438,"props":1089,"children":1090},{"style":487},[1091],{"type":233,"value":954},{"type":228,"tag":438,"props":1093,"children":1094},{"style":487},[1095],{"type":233,"value":821},{"type":228,"tag":438,"props":1097,"children":1098},{"style":487},[1099],{"type":233,"value":490},{"type":228,"tag":438,"props":1101,"children":1102},{"style":451},[1103],{"type":233,"value":967},{"type":228,"tag":438,"props":1105,"children":1106},{"style":487},[1107],{"type":233,"value":840},{"type":228,"tag":438,"props":1109,"children":1110},{"style":487},[1111],{"type":233,"value":901},{"type":228,"tag":438,"props":1113,"children":1115},{"class":440,"line":1114},10,[1116,1120,1124,1129,1133,1137,1141,1145,1149],{"type":228,"tag":438,"props":1117,"children":1118},{"style":487},[1119],{"type":233,"value":936},{"type":228,"tag":438,"props":1121,"children":1122},{"style":487},[1123],{"type":233,"value":840},{"type":228,"tag":438,"props":1125,"children":1126},{"style":451},[1127],{"type":233,"value":1128},"artifacts",{"type":228,"tag":438,"props":1130,"children":1131},{"style":487},[1132],{"type":233,"value":840},{"type":228,"tag":438,"props":1134,"children":1135},{"style":487},[1136],{"type":233,"value":954},{"type":228,"tag":438,"props":1138,"children":1139},{"style":487},[1140],{"type":233,"value":821},{"type":228,"tag":438,"props":1142,"children":1143},{"style":487},[1144],{"type":233,"value":490},{"type":228,"tag":438,"props":1146,"children":1147},{"style":451},[1148],{"type":233,"value":967},{"type":228,"tag":438,"props":1150,"children":1151},{"style":487},[1152],{"type":233,"value":500},{"type":228,"tag":438,"props":1154,"children":1156},{"class":440,"line":1155},11,[1157],{"type":228,"tag":438,"props":1158,"children":1159},{"style":487},[1160],{"type":233,"value":1161},"    },\n",{"type":228,"tag":438,"props":1163,"children":1165},{"class":440,"line":1164},12,[1166],{"type":228,"tag":438,"props":1167,"children":1168},{"style":487},[1169],{"type":233,"value":1170},"});\n",{"type":228,"tag":229,"props":1172,"children":1173},{},[1174],{"type":233,"value":1175},"I intentionally disabled Azure Boards, Azure Test Plans, and Azure Artifacts as we only need Azure Repos and Azure Pipelines for this demo but you can enable what you need for your projects.",{"type":228,"tag":229,"props":1177,"children":1178},{},[1179,1181,1188],{"type":233,"value":1180},"By default, when we create an Azure DevOps project, a ",{"type":228,"tag":247,"props":1182,"children":1185},{"href":1183,"rel":1184},"https://www.pulumi.com/registry/packages/azuredevops/api-docs/git/",[251],[1186],{"type":233,"value":1187},"Git repository",{"type":233,"value":1189}," is created for us with the same name as the project. This repository can be retrieved using the following code:",{"type":228,"tag":427,"props":1191,"children":1193},{"className":798,"code":1192,"language":511,"meta":207,"style":207},"var repository = GetGitRepository.Invoke(new()\n{\n    ProjectId = project.Id,\n    Name = project.Name\n});\n",[1194],{"type":228,"tag":434,"props":1195,"children":1196},{"__ignoreMap":207},[1197,1234,1241,1270,1295],{"type":228,"tag":438,"props":1198,"children":1199},{"class":440,"line":441},[1200,1204,1209,1213,1218,1223,1229],{"type":228,"tag":438,"props":1201,"children":1202},{"style":445},[1203],{"type":233,"value":811},{"type":228,"tag":438,"props":1205,"children":1206},{"style":445},[1207],{"type":233,"value":1208}," repository",{"type":228,"tag":438,"props":1210,"children":1211},{"style":487},[1212],{"type":233,"value":821},{"type":228,"tag":438,"props":1214,"children":1215},{"style":875},[1216],{"type":233,"value":1217}," GetGitRepository",{"type":228,"tag":438,"props":1219,"children":1220},{"style":487},[1221],{"type":233,"value":1222},".",{"type":228,"tag":438,"props":1224,"children":1226},{"style":1225},"--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF",[1227],{"type":233,"value":1228},"Invoke",{"type":228,"tag":438,"props":1230,"children":1231},{"style":487},[1232],{"type":233,"value":1233},"(new()\n",{"type":228,"tag":438,"props":1235,"children":1236},{"class":440,"line":862},[1237],{"type":228,"tag":438,"props":1238,"children":1239},{"style":487},[1240],{"type":233,"value":868},{"type":228,"tag":438,"props":1242,"children":1243},{"class":440,"line":871},[1244,1249,1253,1257,1261,1266],{"type":228,"tag":438,"props":1245,"children":1246},{"style":875},[1247],{"type":233,"value":1248},"    ProjectId ",{"type":228,"tag":438,"props":1250,"children":1251},{"style":487},[1252],{"type":233,"value":883},{"type":228,"tag":438,"props":1254,"children":1255},{"style":875},[1256],{"type":233,"value":816},{"type":228,"tag":438,"props":1258,"children":1259},{"style":487},[1260],{"type":233,"value":1222},{"type":228,"tag":438,"props":1262,"children":1263},{"style":875},[1264],{"type":233,"value":1265},"Id",{"type":228,"tag":438,"props":1267,"children":1268},{"style":487},[1269],{"type":233,"value":901},{"type":228,"tag":438,"props":1271,"children":1272},{"class":440,"line":904},[1273,1278,1282,1286,1290],{"type":228,"tag":438,"props":1274,"children":1275},{"style":875},[1276],{"type":233,"value":1277},"    Name ",{"type":228,"tag":438,"props":1279,"children":1280},{"style":487},[1281],{"type":233,"value":883},{"type":228,"tag":438,"props":1283,"children":1284},{"style":875},[1285],{"type":233,"value":816},{"type":228,"tag":438,"props":1287,"children":1288},{"style":487},[1289],{"type":233,"value":1222},{"type":228,"tag":438,"props":1291,"children":1292},{"style":875},[1293],{"type":233,"value":1294},"Name\n",{"type":228,"tag":438,"props":1296,"children":1297},{"class":440,"line":921},[1298],{"type":228,"tag":438,"props":1299,"children":1300},{"style":487},[1301],{"type":233,"value":1170},{"type":228,"tag":229,"props":1303,"children":1304},{},[1305],{"type":233,"value":1306},"We can also choose to create a new Git repository like this:",{"type":228,"tag":427,"props":1308,"children":1310},{"className":798,"code":1309,"language":511,"meta":207,"style":207},"var repository = new Git(\"AzureReadyADORepository\", new()\n{\n    ProjectId = project.Id,\n    Initialization = new GitInitializationArgs()\n    {\n        InitType = \"Clean\",\n        SourceType = \"Git\",\n        SourceUrl = \"https://repo.com\",\n        ServiceConnectionId = \"\"\n    },\n    DefaultBranch = \"refs/heads/main\"\n});\n",[1311],{"type":228,"tag":434,"props":1312,"children":1313},{"__ignoreMap":207},[1314,1363,1370,1397,1423,1430,1459,1488,1517,1534,1541,1566],{"type":228,"tag":438,"props":1315,"children":1316},{"class":440,"line":441},[1317,1321,1325,1329,1333,1338,1342,1346,1351,1355,1359],{"type":228,"tag":438,"props":1318,"children":1319},{"style":445},[1320],{"type":233,"value":811},{"type":228,"tag":438,"props":1322,"children":1323},{"style":445},[1324],{"type":233,"value":1208},{"type":228,"tag":438,"props":1326,"children":1327},{"style":487},[1328],{"type":233,"value":821},{"type":228,"tag":438,"props":1330,"children":1331},{"style":487},[1332],{"type":233,"value":454},{"type":228,"tag":438,"props":1334,"children":1335},{"style":445},[1336],{"type":233,"value":1337}," Git",{"type":228,"tag":438,"props":1339,"children":1340},{"style":487},[1341],{"type":233,"value":835},{"type":228,"tag":438,"props":1343,"children":1344},{"style":487},[1345],{"type":233,"value":840},{"type":228,"tag":438,"props":1347,"children":1348},{"style":451},[1349],{"type":233,"value":1350},"AzureReadyADORepository",{"type":228,"tag":438,"props":1352,"children":1353},{"style":487},[1354],{"type":233,"value":840},{"type":228,"tag":438,"props":1356,"children":1357},{"style":487},[1358],{"type":233,"value":854},{"type":228,"tag":438,"props":1360,"children":1361},{"style":487},[1362],{"type":233,"value":859},{"type":228,"tag":438,"props":1364,"children":1365},{"class":440,"line":862},[1366],{"type":228,"tag":438,"props":1367,"children":1368},{"style":487},[1369],{"type":233,"value":868},{"type":228,"tag":438,"props":1371,"children":1372},{"class":440,"line":871},[1373,1377,1381,1385,1389,1393],{"type":228,"tag":438,"props":1374,"children":1375},{"style":875},[1376],{"type":233,"value":1248},{"type":228,"tag":438,"props":1378,"children":1379},{"style":487},[1380],{"type":233,"value":883},{"type":228,"tag":438,"props":1382,"children":1383},{"style":875},[1384],{"type":233,"value":816},{"type":228,"tag":438,"props":1386,"children":1387},{"style":487},[1388],{"type":233,"value":1222},{"type":228,"tag":438,"props":1390,"children":1391},{"style":875},[1392],{"type":233,"value":1265},{"type":228,"tag":438,"props":1394,"children":1395},{"style":487},[1396],{"type":233,"value":901},{"type":228,"tag":438,"props":1398,"children":1399},{"class":440,"line":904},[1400,1405,1409,1413,1418],{"type":228,"tag":438,"props":1401,"children":1402},{"style":875},[1403],{"type":233,"value":1404},"    Initialization ",{"type":228,"tag":438,"props":1406,"children":1407},{"style":487},[1408],{"type":233,"value":883},{"type":228,"tag":438,"props":1410,"children":1411},{"style":487},[1412],{"type":233,"value":454},{"type":228,"tag":438,"props":1414,"children":1415},{"style":445},[1416],{"type":233,"value":1417}," GitInitializationArgs",{"type":228,"tag":438,"props":1419,"children":1420},{"style":487},[1421],{"type":233,"value":1422},"()\n",{"type":228,"tag":438,"props":1424,"children":1425},{"class":440,"line":921},[1426],{"type":228,"tag":438,"props":1427,"children":1428},{"style":487},[1429],{"type":233,"value":927},{"type":228,"tag":438,"props":1431,"children":1432},{"class":440,"line":930},[1433,1438,1442,1446,1451,1455],{"type":228,"tag":438,"props":1434,"children":1435},{"style":875},[1436],{"type":233,"value":1437},"        InitType ",{"type":228,"tag":438,"props":1439,"children":1440},{"style":487},[1441],{"type":233,"value":883},{"type":228,"tag":438,"props":1443,"children":1444},{"style":487},[1445],{"type":233,"value":490},{"type":228,"tag":438,"props":1447,"children":1448},{"style":451},[1449],{"type":233,"value":1450},"Clean",{"type":228,"tag":438,"props":1452,"children":1453},{"style":487},[1454],{"type":233,"value":840},{"type":228,"tag":438,"props":1456,"children":1457},{"style":487},[1458],{"type":233,"value":901},{"type":228,"tag":438,"props":1460,"children":1461},{"class":440,"line":978},[1462,1467,1471,1475,1480,1484],{"type":228,"tag":438,"props":1463,"children":1464},{"style":875},[1465],{"type":233,"value":1466},"        SourceType ",{"type":228,"tag":438,"props":1468,"children":1469},{"style":487},[1470],{"type":233,"value":883},{"type":228,"tag":438,"props":1472,"children":1473},{"style":487},[1474],{"type":233,"value":490},{"type":228,"tag":438,"props":1476,"children":1477},{"style":451},[1478],{"type":233,"value":1479},"Git",{"type":228,"tag":438,"props":1481,"children":1482},{"style":487},[1483],{"type":233,"value":840},{"type":228,"tag":438,"props":1485,"children":1486},{"style":487},[1487],{"type":233,"value":901},{"type":228,"tag":438,"props":1489,"children":1490},{"class":440,"line":1024},[1491,1496,1500,1504,1509,1513],{"type":228,"tag":438,"props":1492,"children":1493},{"style":875},[1494],{"type":233,"value":1495},"        SourceUrl ",{"type":228,"tag":438,"props":1497,"children":1498},{"style":487},[1499],{"type":233,"value":883},{"type":228,"tag":438,"props":1501,"children":1502},{"style":487},[1503],{"type":233,"value":490},{"type":228,"tag":438,"props":1505,"children":1506},{"style":451},[1507],{"type":233,"value":1508},"https://repo.com",{"type":228,"tag":438,"props":1510,"children":1511},{"style":487},[1512],{"type":233,"value":840},{"type":228,"tag":438,"props":1514,"children":1515},{"style":487},[1516],{"type":233,"value":901},{"type":228,"tag":438,"props":1518,"children":1519},{"class":440,"line":1069},[1520,1525,1529],{"type":228,"tag":438,"props":1521,"children":1522},{"style":875},[1523],{"type":233,"value":1524},"        ServiceConnectionId ",{"type":228,"tag":438,"props":1526,"children":1527},{"style":487},[1528],{"type":233,"value":883},{"type":228,"tag":438,"props":1530,"children":1531},{"style":487},[1532],{"type":233,"value":1533}," \"\"\n",{"type":228,"tag":438,"props":1535,"children":1536},{"class":440,"line":1114},[1537],{"type":228,"tag":438,"props":1538,"children":1539},{"style":487},[1540],{"type":233,"value":1161},{"type":228,"tag":438,"props":1542,"children":1543},{"class":440,"line":1155},[1544,1549,1553,1557,1562],{"type":228,"tag":438,"props":1545,"children":1546},{"style":875},[1547],{"type":233,"value":1548},"    DefaultBranch ",{"type":228,"tag":438,"props":1550,"children":1551},{"style":487},[1552],{"type":233,"value":883},{"type":228,"tag":438,"props":1554,"children":1555},{"style":487},[1556],{"type":233,"value":490},{"type":228,"tag":438,"props":1558,"children":1559},{"style":451},[1560],{"type":233,"value":1561},"refs/heads/main",{"type":228,"tag":438,"props":1563,"children":1564},{"style":487},[1565],{"type":233,"value":500},{"type":228,"tag":438,"props":1567,"children":1568},{"class":440,"line":1164},[1569],{"type":228,"tag":438,"props":1570,"children":1571},{"style":487},[1572],{"type":233,"value":1170},{"type":228,"tag":311,"props":1574,"children":1575},{"icon":313},[1576],{"type":228,"tag":229,"props":1577,"children":1578},{},[1579,1581,1587,1589,1595,1597,1603,1605,1612],{"type":233,"value":1580},"We should not have to set the ",{"type":228,"tag":434,"props":1582,"children":1584},{"className":1583},[],[1585],{"type":233,"value":1586},"SourceType",{"type":233,"value":1588},", ",{"type":228,"tag":434,"props":1590,"children":1592},{"className":1591},[],[1593],{"type":233,"value":1594},"SourceUrl",{"type":233,"value":1596}," and ",{"type":228,"tag":434,"props":1598,"children":1600},{"className":1599},[],[1601],{"type":233,"value":1602},"ServiceConnectionId",{"type":233,"value":1604}," properties as we are initializing a clean Git repository, not importing one, but it's a workaround because of this ",{"type":228,"tag":247,"props":1606,"children":1609},{"href":1607,"rel":1608},"https://github.com/pulumi/pulumi-azuredevops/issues/66",[251],[1610],{"type":233,"value":1611},"issue",{"type":233,"value":1613}," on the provider.",{"type":228,"tag":415,"props":1615,"children":1617},{"id":1616},"configure-the-arm-service-connection-in-azure-devops",[1618],{"type":233,"value":1619},"Configure the ARM Service Connection in Azure DevOps",{"type":228,"tag":229,"props":1621,"children":1622},{},[1623,1625,1632],{"type":233,"value":1624},"In the Azure DevOps provider, the Azure Resource Manager service connection is called a ",{"type":228,"tag":247,"props":1626,"children":1629},{"href":1627,"rel":1628},"https://www.pulumi.com/registry/packages/azuredevops/api-docs/serviceendpointazurerm/#workload-identity-federation-manual-azurerm-service-endpoint-subscription-scoped",[251],[1630],{"type":233,"value":1631},"ServiceEndpointAzureRM",{"type":233,"value":1633},". We can create such a resource like this:",{"type":228,"tag":427,"props":1635,"children":1637},{"className":798,"code":1636,"language":511,"meta":207,"style":207},"var serviceConnection = new ServiceEndpointAzureRM(\"AzureServiceConnection\", new()\n{\n    ProjectId = project.Id,\n    ServiceEndpointName = \"azure-with-oidc\",\n    ServiceEndpointAuthenticationScheme = \"WorkloadIdentityFederation\",\n    AzurermSpnTenantid = tenantId,\n    AzurermSubscriptionId = subscriptionId,\n    AzurermSubscriptionName = subscriptionName,\n    Credentials = new ServiceEndpointAzureRMCredentialsArgs()\n    {\n        Serviceprincipalid = servicePrincipal.ApplicationId,\n    }\n});\n",[1638],{"type":228,"tag":434,"props":1639,"children":1640},{"__ignoreMap":207},[1641,1691,1698,1725,1754,1783,1804,1825,1846,1871,1878,1908,1916],{"type":228,"tag":438,"props":1642,"children":1643},{"class":440,"line":441},[1644,1648,1653,1657,1661,1666,1670,1674,1679,1683,1687],{"type":228,"tag":438,"props":1645,"children":1646},{"style":445},[1647],{"type":233,"value":811},{"type":228,"tag":438,"props":1649,"children":1650},{"style":445},[1651],{"type":233,"value":1652}," serviceConnection",{"type":228,"tag":438,"props":1654,"children":1655},{"style":487},[1656],{"type":233,"value":821},{"type":228,"tag":438,"props":1658,"children":1659},{"style":487},[1660],{"type":233,"value":454},{"type":228,"tag":438,"props":1662,"children":1663},{"style":445},[1664],{"type":233,"value":1665}," ServiceEndpointAzureRM",{"type":228,"tag":438,"props":1667,"children":1668},{"style":487},[1669],{"type":233,"value":835},{"type":228,"tag":438,"props":1671,"children":1672},{"style":487},[1673],{"type":233,"value":840},{"type":228,"tag":438,"props":1675,"children":1676},{"style":451},[1677],{"type":233,"value":1678},"AzureServiceConnection",{"type":228,"tag":438,"props":1680,"children":1681},{"style":487},[1682],{"type":233,"value":840},{"type":228,"tag":438,"props":1684,"children":1685},{"style":487},[1686],{"type":233,"value":854},{"type":228,"tag":438,"props":1688,"children":1689},{"style":487},[1690],{"type":233,"value":859},{"type":228,"tag":438,"props":1692,"children":1693},{"class":440,"line":862},[1694],{"type":228,"tag":438,"props":1695,"children":1696},{"style":487},[1697],{"type":233,"value":868},{"type":228,"tag":438,"props":1699,"children":1700},{"class":440,"line":871},[1701,1705,1709,1713,1717,1721],{"type":228,"tag":438,"props":1702,"children":1703},{"style":875},[1704],{"type":233,"value":1248},{"type":228,"tag":438,"props":1706,"children":1707},{"style":487},[1708],{"type":233,"value":883},{"type":228,"tag":438,"props":1710,"children":1711},{"style":875},[1712],{"type":233,"value":816},{"type":228,"tag":438,"props":1714,"children":1715},{"style":487},[1716],{"type":233,"value":1222},{"type":228,"tag":438,"props":1718,"children":1719},{"style":875},[1720],{"type":233,"value":1265},{"type":228,"tag":438,"props":1722,"children":1723},{"style":487},[1724],{"type":233,"value":901},{"type":228,"tag":438,"props":1726,"children":1727},{"class":440,"line":904},[1728,1733,1737,1741,1746,1750],{"type":228,"tag":438,"props":1729,"children":1730},{"style":875},[1731],{"type":233,"value":1732},"    ServiceEndpointName ",{"type":228,"tag":438,"props":1734,"children":1735},{"style":487},[1736],{"type":233,"value":883},{"type":228,"tag":438,"props":1738,"children":1739},{"style":487},[1740],{"type":233,"value":490},{"type":228,"tag":438,"props":1742,"children":1743},{"style":451},[1744],{"type":233,"value":1745},"azure-with-oidc",{"type":228,"tag":438,"props":1747,"children":1748},{"style":487},[1749],{"type":233,"value":840},{"type":228,"tag":438,"props":1751,"children":1752},{"style":487},[1753],{"type":233,"value":901},{"type":228,"tag":438,"props":1755,"children":1756},{"class":440,"line":921},[1757,1762,1766,1770,1775,1779],{"type":228,"tag":438,"props":1758,"children":1759},{"style":875},[1760],{"type":233,"value":1761},"    ServiceEndpointAuthenticationScheme ",{"type":228,"tag":438,"props":1763,"children":1764},{"style":487},[1765],{"type":233,"value":883},{"type":228,"tag":438,"props":1767,"children":1768},{"style":487},[1769],{"type":233,"value":490},{"type":228,"tag":438,"props":1771,"children":1772},{"style":451},[1773],{"type":233,"value":1774},"WorkloadIdentityFederation",{"type":228,"tag":438,"props":1776,"children":1777},{"style":487},[1778],{"type":233,"value":840},{"type":228,"tag":438,"props":1780,"children":1781},{"style":487},[1782],{"type":233,"value":901},{"type":228,"tag":438,"props":1784,"children":1785},{"class":440,"line":930},[1786,1791,1795,1800],{"type":228,"tag":438,"props":1787,"children":1788},{"style":875},[1789],{"type":233,"value":1790},"    AzurermSpnTenantid ",{"type":228,"tag":438,"props":1792,"children":1793},{"style":487},[1794],{"type":233,"value":883},{"type":228,"tag":438,"props":1796,"children":1797},{"style":875},[1798],{"type":233,"value":1799}," tenantId",{"type":228,"tag":438,"props":1801,"children":1802},{"style":487},[1803],{"type":233,"value":901},{"type":228,"tag":438,"props":1805,"children":1806},{"class":440,"line":978},[1807,1812,1816,1821],{"type":228,"tag":438,"props":1808,"children":1809},{"style":875},[1810],{"type":233,"value":1811},"    AzurermSubscriptionId ",{"type":228,"tag":438,"props":1813,"children":1814},{"style":487},[1815],{"type":233,"value":883},{"type":228,"tag":438,"props":1817,"children":1818},{"style":875},[1819],{"type":233,"value":1820}," subscriptionId",{"type":228,"tag":438,"props":1822,"children":1823},{"style":487},[1824],{"type":233,"value":901},{"type":228,"tag":438,"props":1826,"children":1827},{"class":440,"line":1024},[1828,1833,1837,1842],{"type":228,"tag":438,"props":1829,"children":1830},{"style":875},[1831],{"type":233,"value":1832},"    AzurermSubscriptionName ",{"type":228,"tag":438,"props":1834,"children":1835},{"style":487},[1836],{"type":233,"value":883},{"type":228,"tag":438,"props":1838,"children":1839},{"style":875},[1840],{"type":233,"value":1841}," subscriptionName",{"type":228,"tag":438,"props":1843,"children":1844},{"style":487},[1845],{"type":233,"value":901},{"type":228,"tag":438,"props":1847,"children":1848},{"class":440,"line":1069},[1849,1854,1858,1862,1867],{"type":228,"tag":438,"props":1850,"children":1851},{"style":875},[1852],{"type":233,"value":1853},"    Credentials ",{"type":228,"tag":438,"props":1855,"children":1856},{"style":487},[1857],{"type":233,"value":883},{"type":228,"tag":438,"props":1859,"children":1860},{"style":487},[1861],{"type":233,"value":454},{"type":228,"tag":438,"props":1863,"children":1864},{"style":445},[1865],{"type":233,"value":1866}," ServiceEndpointAzureRMCredentialsArgs",{"type":228,"tag":438,"props":1868,"children":1869},{"style":487},[1870],{"type":233,"value":1422},{"type":228,"tag":438,"props":1872,"children":1873},{"class":440,"line":1114},[1874],{"type":228,"tag":438,"props":1875,"children":1876},{"style":487},[1877],{"type":233,"value":927},{"type":228,"tag":438,"props":1879,"children":1880},{"class":440,"line":1155},[1881,1886,1890,1895,1899,1904],{"type":228,"tag":438,"props":1882,"children":1883},{"style":875},[1884],{"type":233,"value":1885},"        Serviceprincipalid ",{"type":228,"tag":438,"props":1887,"children":1888},{"style":487},[1889],{"type":233,"value":883},{"type":228,"tag":438,"props":1891,"children":1892},{"style":875},[1893],{"type":233,"value":1894}," servicePrincipal",{"type":228,"tag":438,"props":1896,"children":1897},{"style":487},[1898],{"type":233,"value":1222},{"type":228,"tag":438,"props":1900,"children":1901},{"style":875},[1902],{"type":233,"value":1903},"ApplicationId",{"type":228,"tag":438,"props":1905,"children":1906},{"style":487},[1907],{"type":233,"value":901},{"type":228,"tag":438,"props":1909,"children":1910},{"class":440,"line":1164},[1911],{"type":228,"tag":438,"props":1912,"children":1913},{"style":487},[1914],{"type":233,"value":1915},"    }\n",{"type":228,"tag":438,"props":1917,"children":1919},{"class":440,"line":1918},13,[1920],{"type":228,"tag":438,"props":1921,"children":1922},{"style":487},[1923],{"type":233,"value":1170},{"type":228,"tag":229,"props":1925,"children":1926},{},[1927,1929,1935],{"type":233,"value":1928},"Do not worry about the service principal, we will see in the next section how to create it. The tenant and the subscription identifiers can be retrieved from the current configuration of the Azure Native provider (using the ",{"type":228,"tag":434,"props":1930,"children":1932},{"className":1931},[],[1933],{"type":233,"value":1934},"GetClientConfig.Invoke",{"type":233,"value":1936}," function):",{"type":228,"tag":427,"props":1938,"children":1940},{"className":798,"code":1939,"language":511,"meta":207,"style":207},"var azureConfig = GetClientConfig.Invoke();\nvar tenantId = azureConfig.Apply(c => c.tenantId);\nvar subscriptionId = azureConfig.Apply(c => c.SubscriptionId);\n",[1941],{"type":228,"tag":434,"props":1942,"children":1943},{"__ignoreMap":207},[1944,1978,2039],{"type":228,"tag":438,"props":1945,"children":1946},{"class":440,"line":441},[1947,1951,1956,1960,1965,1969,1973],{"type":228,"tag":438,"props":1948,"children":1949},{"style":445},[1950],{"type":233,"value":811},{"type":228,"tag":438,"props":1952,"children":1953},{"style":445},[1954],{"type":233,"value":1955}," azureConfig",{"type":228,"tag":438,"props":1957,"children":1958},{"style":487},[1959],{"type":233,"value":821},{"type":228,"tag":438,"props":1961,"children":1962},{"style":875},[1963],{"type":233,"value":1964}," GetClientConfig",{"type":228,"tag":438,"props":1966,"children":1967},{"style":487},[1968],{"type":233,"value":1222},{"type":228,"tag":438,"props":1970,"children":1971},{"style":1225},[1972],{"type":233,"value":1228},{"type":228,"tag":438,"props":1974,"children":1975},{"style":487},[1976],{"type":233,"value":1977},"();\n",{"type":228,"tag":438,"props":1979,"children":1980},{"class":440,"line":862},[1981,1985,1989,1993,1997,2001,2006,2010,2015,2020,2025,2029,2034],{"type":228,"tag":438,"props":1982,"children":1983},{"style":445},[1984],{"type":233,"value":811},{"type":228,"tag":438,"props":1986,"children":1987},{"style":445},[1988],{"type":233,"value":1799},{"type":228,"tag":438,"props":1990,"children":1991},{"style":487},[1992],{"type":233,"value":821},{"type":228,"tag":438,"props":1994,"children":1995},{"style":875},[1996],{"type":233,"value":1955},{"type":228,"tag":438,"props":1998,"children":1999},{"style":487},[2000],{"type":233,"value":1222},{"type":228,"tag":438,"props":2002,"children":2003},{"style":1225},[2004],{"type":233,"value":2005},"Apply",{"type":228,"tag":438,"props":2007,"children":2008},{"style":487},[2009],{"type":233,"value":835},{"type":228,"tag":438,"props":2011,"children":2012},{"style":445},[2013],{"type":233,"value":2014},"c",{"type":228,"tag":438,"props":2016,"children":2017},{"style":487},[2018],{"type":233,"value":2019}," =>",{"type":228,"tag":438,"props":2021,"children":2022},{"style":875},[2023],{"type":233,"value":2024}," c",{"type":228,"tag":438,"props":2026,"children":2027},{"style":487},[2028],{"type":233,"value":1222},{"type":228,"tag":438,"props":2030,"children":2031},{"style":875},[2032],{"type":233,"value":2033},"tenantId",{"type":228,"tag":438,"props":2035,"children":2036},{"style":487},[2037],{"type":233,"value":2038},");\n",{"type":228,"tag":438,"props":2040,"children":2041},{"class":440,"line":871},[2042,2046,2050,2054,2058,2062,2066,2070,2074,2078,2082,2086,2091],{"type":228,"tag":438,"props":2043,"children":2044},{"style":445},[2045],{"type":233,"value":811},{"type":228,"tag":438,"props":2047,"children":2048},{"style":445},[2049],{"type":233,"value":1820},{"type":228,"tag":438,"props":2051,"children":2052},{"style":487},[2053],{"type":233,"value":821},{"type":228,"tag":438,"props":2055,"children":2056},{"style":875},[2057],{"type":233,"value":1955},{"type":228,"tag":438,"props":2059,"children":2060},{"style":487},[2061],{"type":233,"value":1222},{"type":228,"tag":438,"props":2063,"children":2064},{"style":1225},[2065],{"type":233,"value":2005},{"type":228,"tag":438,"props":2067,"children":2068},{"style":487},[2069],{"type":233,"value":835},{"type":228,"tag":438,"props":2071,"children":2072},{"style":445},[2073],{"type":233,"value":2014},{"type":228,"tag":438,"props":2075,"children":2076},{"style":487},[2077],{"type":233,"value":2019},{"type":228,"tag":438,"props":2079,"children":2080},{"style":875},[2081],{"type":233,"value":2024},{"type":228,"tag":438,"props":2083,"children":2084},{"style":487},[2085],{"type":233,"value":1222},{"type":228,"tag":438,"props":2087,"children":2088},{"style":875},[2089],{"type":233,"value":2090},"SubscriptionId",{"type":228,"tag":438,"props":2092,"children":2093},{"style":487},[2094],{"type":233,"value":2038},{"type":228,"tag":229,"props":2096,"children":2097},{},[2098],{"type":233,"value":2099},"For the subscription name, it's more complicated as we don't have it, and no easy way to retrieve it. To be frank, I think having to provide the subscription name while we already provide the subscription identifier is completely useless but that's how the Azure DevOps provider works.",{"type":228,"tag":229,"props":2101,"children":2102},{},[2103,2105,2112,2114,2121],{"type":233,"value":2104},"The Azure Classic provider offers a ",{"type":228,"tag":247,"props":2106,"children":2109},{"href":2107,"rel":2108},"https://www.pulumi.com/registry/packages/azure/api-docs/core/getsubscription/#azure-core-getsubscription",[251],[2110],{"type":233,"value":2111},"function",{"type":233,"value":2113}," to get a subscription by its identifier but it's not available in the Azure Native provider. I don't want to add the Azure Classic provider to my project solely for this purpose. However, it's not a big deal as it allows us to experience one of the advantages of using Pulumi: when something is not available you can just implement it or use any library that can help you, such as the ",{"type":228,"tag":247,"props":2115,"children":2118},{"href":2116,"rel":2117},"https://www.nuget.org/packages/Azure.ResourceManager",[251],[2119],{"type":233,"value":2120},"Azure SDK",{"type":233,"value":2122}," in this case.",{"type":228,"tag":427,"props":2124,"children":2126},{"className":798,"code":2125,"language":511,"meta":207,"style":207},"var subscriptionName = subscriptionId.Apply(s =>\n{\n    var armClient = new ArmClient(new DefaultAzureCredential());\n    var subscription = armClient.GetSubscriptionResource(new ResourceIdentifier($\"/subscriptions/{s}\")).Get();\n    return subscription.Value.Data.DisplayName;\n});\n",[2127],{"type":228,"tag":434,"props":2128,"children":2129},{"__ignoreMap":207},[2130,2171,2178,2219,2299,2344],{"type":228,"tag":438,"props":2131,"children":2132},{"class":440,"line":441},[2133,2137,2141,2145,2149,2153,2157,2161,2166],{"type":228,"tag":438,"props":2134,"children":2135},{"style":445},[2136],{"type":233,"value":811},{"type":228,"tag":438,"props":2138,"children":2139},{"style":445},[2140],{"type":233,"value":1841},{"type":228,"tag":438,"props":2142,"children":2143},{"style":487},[2144],{"type":233,"value":821},{"type":228,"tag":438,"props":2146,"children":2147},{"style":875},[2148],{"type":233,"value":1820},{"type":228,"tag":438,"props":2150,"children":2151},{"style":487},[2152],{"type":233,"value":1222},{"type":228,"tag":438,"props":2154,"children":2155},{"style":1225},[2156],{"type":233,"value":2005},{"type":228,"tag":438,"props":2158,"children":2159},{"style":487},[2160],{"type":233,"value":835},{"type":228,"tag":438,"props":2162,"children":2163},{"style":445},[2164],{"type":233,"value":2165},"s",{"type":228,"tag":438,"props":2167,"children":2168},{"style":487},[2169],{"type":233,"value":2170}," =>\n",{"type":228,"tag":438,"props":2172,"children":2173},{"class":440,"line":862},[2174],{"type":228,"tag":438,"props":2175,"children":2176},{"style":487},[2177],{"type":233,"value":868},{"type":228,"tag":438,"props":2179,"children":2180},{"class":440,"line":871},[2181,2186,2191,2195,2199,2204,2209,2214],{"type":228,"tag":438,"props":2182,"children":2183},{"style":445},[2184],{"type":233,"value":2185},"    var",{"type":228,"tag":438,"props":2187,"children":2188},{"style":445},[2189],{"type":233,"value":2190}," armClient",{"type":228,"tag":438,"props":2192,"children":2193},{"style":487},[2194],{"type":233,"value":821},{"type":228,"tag":438,"props":2196,"children":2197},{"style":487},[2198],{"type":233,"value":454},{"type":228,"tag":438,"props":2200,"children":2201},{"style":445},[2202],{"type":233,"value":2203}," ArmClient",{"type":228,"tag":438,"props":2205,"children":2206},{"style":487},[2207],{"type":233,"value":2208},"(new",{"type":228,"tag":438,"props":2210,"children":2211},{"style":445},[2212],{"type":233,"value":2213}," DefaultAzureCredential",{"type":228,"tag":438,"props":2215,"children":2216},{"style":487},[2217],{"type":233,"value":2218},"());\n",{"type":228,"tag":438,"props":2220,"children":2221},{"class":440,"line":904},[2222,2226,2231,2235,2239,2243,2248,2252,2257,2261,2266,2271,2276,2280,2285,2290,2295],{"type":228,"tag":438,"props":2223,"children":2224},{"style":445},[2225],{"type":233,"value":2185},{"type":228,"tag":438,"props":2227,"children":2228},{"style":445},[2229],{"type":233,"value":2230}," subscription",{"type":228,"tag":438,"props":2232,"children":2233},{"style":487},[2234],{"type":233,"value":821},{"type":228,"tag":438,"props":2236,"children":2237},{"style":875},[2238],{"type":233,"value":2190},{"type":228,"tag":438,"props":2240,"children":2241},{"style":487},[2242],{"type":233,"value":1222},{"type":228,"tag":438,"props":2244,"children":2245},{"style":1225},[2246],{"type":233,"value":2247},"GetSubscriptionResource",{"type":228,"tag":438,"props":2249,"children":2250},{"style":487},[2251],{"type":233,"value":2208},{"type":228,"tag":438,"props":2253,"children":2254},{"style":445},[2255],{"type":233,"value":2256}," ResourceIdentifier",{"type":228,"tag":438,"props":2258,"children":2259},{"style":487},[2260],{"type":233,"value":835},{"type":228,"tag":438,"props":2262,"children":2263},{"style":487},[2264],{"type":233,"value":2265},"$\"",{"type":228,"tag":438,"props":2267,"children":2268},{"style":451},[2269],{"type":233,"value":2270},"/subscriptions/",{"type":228,"tag":438,"props":2272,"children":2273},{"style":487},[2274],{"type":233,"value":2275},"{",{"type":228,"tag":438,"props":2277,"children":2278},{"style":875},[2279],{"type":233,"value":2165},{"type":228,"tag":438,"props":2281,"children":2282},{"style":487},[2283],{"type":233,"value":2284},"}\"",{"type":228,"tag":438,"props":2286,"children":2287},{"style":487},[2288],{"type":233,"value":2289},")).",{"type":228,"tag":438,"props":2291,"children":2292},{"style":1225},[2293],{"type":233,"value":2294},"Get",{"type":228,"tag":438,"props":2296,"children":2297},{"style":487},[2298],{"type":233,"value":1977},{"type":228,"tag":438,"props":2300,"children":2301},{"class":440,"line":921},[2302,2308,2312,2316,2321,2325,2330,2334,2339],{"type":228,"tag":438,"props":2303,"children":2305},{"style":2304},"--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF;--shiki-light-font-style:italic;--shiki-default-font-style:italic;--shiki-dark-font-style:italic",[2306],{"type":233,"value":2307},"    return",{"type":228,"tag":438,"props":2309,"children":2310},{"style":875},[2311],{"type":233,"value":2230},{"type":228,"tag":438,"props":2313,"children":2314},{"style":487},[2315],{"type":233,"value":1222},{"type":228,"tag":438,"props":2317,"children":2318},{"style":875},[2319],{"type":233,"value":2320},"Value",{"type":228,"tag":438,"props":2322,"children":2323},{"style":487},[2324],{"type":233,"value":1222},{"type":228,"tag":438,"props":2326,"children":2327},{"style":875},[2328],{"type":233,"value":2329},"Data",{"type":228,"tag":438,"props":2331,"children":2332},{"style":487},[2333],{"type":233,"value":1222},{"type":228,"tag":438,"props":2335,"children":2336},{"style":875},[2337],{"type":233,"value":2338},"DisplayName",{"type":228,"tag":438,"props":2340,"children":2341},{"style":487},[2342],{"type":233,"value":2343},";\n",{"type":228,"tag":438,"props":2345,"children":2346},{"class":440,"line":930},[2347],{"type":228,"tag":438,"props":2348,"children":2349},{"style":487},[2350],{"type":233,"value":1170},{"type":228,"tag":415,"props":2352,"children":2354},{"id":2353},"set-up-the-necessary-microsoft-entra-id-resources",[2355],{"type":233,"value":2356},"Set up the necessary Microsoft Entra ID resources",{"type":228,"tag":229,"props":2358,"children":2359},{},[2360],{"type":233,"value":2361},"We need to set up the following resources in Microsoft Entra ID:",{"type":228,"tag":258,"props":2363,"children":2364},{},[2365,2370,2375],{"type":228,"tag":262,"props":2366,"children":2367},{},[2368],{"type":233,"value":2369},"an Application that represents the Azure DevOps service connection identity",{"type":228,"tag":262,"props":2371,"children":2372},{},[2373],{"type":233,"value":2374},"a Service Principal (related to the application above) that has the contributor role on the Azure subscription",{"type":228,"tag":262,"props":2376,"children":2377},{},[2378],{"type":233,"value":2379},"credentials for the CI/CD pipeline to authenticate to Azure on behalf of this Microsoft Entra ID application",{"type":228,"tag":229,"props":2381,"children":2382},{},[2383],{"type":233,"value":2384},"Let's take care of the first 2 points:",{"type":228,"tag":427,"props":2386,"children":2388},{"className":798,"code":2387,"language":511,"meta":207,"style":207},"var azureConfig = GetClientConfig.Invoke();\nvar aadApplication = new Application(\"ADOAzureReadyApp\", new()\n{\n    DisplayName = \"ADO Azure Ready App\"\n});\nvar servicePrincipal  = new ServicePrincipal(\"AzureReadyServicePrincipal\", new()\n{\n    ApplicationId = aadApplication.ApplicationId,\n});\n\nvar subscriptionId = azureConfig.Apply(c => c.SubscriptionId);\nnew RoleAssignment(\"contributor\", new()\n{\n    PrincipalId= servicePrincipal.Id,\n    PrincipalType= PrincipalType.ServicePrincipal,\n    RoleDefinitionId = AzureBuiltInRoles.Contributor,\n    Scope = Output.Format($\"/subscriptions/{subscriptionId}\")\n});\n",[2389],{"type":228,"tag":434,"props":2390,"children":2391},{"__ignoreMap":207},[2392,2423,2473,2480,2505,2512,2562,2569,2597,2604,2613,2668,2707,2714,2743,2774,2805,2862],{"type":228,"tag":438,"props":2393,"children":2394},{"class":440,"line":441},[2395,2399,2403,2407,2411,2415,2419],{"type":228,"tag":438,"props":2396,"children":2397},{"style":445},[2398],{"type":233,"value":811},{"type":228,"tag":438,"props":2400,"children":2401},{"style":445},[2402],{"type":233,"value":1955},{"type":228,"tag":438,"props":2404,"children":2405},{"style":487},[2406],{"type":233,"value":821},{"type":228,"tag":438,"props":2408,"children":2409},{"style":875},[2410],{"type":233,"value":1964},{"type":228,"tag":438,"props":2412,"children":2413},{"style":487},[2414],{"type":233,"value":1222},{"type":228,"tag":438,"props":2416,"children":2417},{"style":1225},[2418],{"type":233,"value":1228},{"type":228,"tag":438,"props":2420,"children":2421},{"style":487},[2422],{"type":233,"value":1977},{"type":228,"tag":438,"props":2424,"children":2425},{"class":440,"line":862},[2426,2430,2435,2439,2443,2448,2452,2456,2461,2465,2469],{"type":228,"tag":438,"props":2427,"children":2428},{"style":445},[2429],{"type":233,"value":811},{"type":228,"tag":438,"props":2431,"children":2432},{"style":445},[2433],{"type":233,"value":2434}," aadApplication",{"type":228,"tag":438,"props":2436,"children":2437},{"style":487},[2438],{"type":233,"value":821},{"type":228,"tag":438,"props":2440,"children":2441},{"style":487},[2442],{"type":233,"value":454},{"type":228,"tag":438,"props":2444,"children":2445},{"style":445},[2446],{"type":233,"value":2447}," Application",{"type":228,"tag":438,"props":2449,"children":2450},{"style":487},[2451],{"type":233,"value":835},{"type":228,"tag":438,"props":2453,"children":2454},{"style":487},[2455],{"type":233,"value":840},{"type":228,"tag":438,"props":2457,"children":2458},{"style":451},[2459],{"type":233,"value":2460},"ADOAzureReadyApp",{"type":228,"tag":438,"props":2462,"children":2463},{"style":487},[2464],{"type":233,"value":840},{"type":228,"tag":438,"props":2466,"children":2467},{"style":487},[2468],{"type":233,"value":854},{"type":228,"tag":438,"props":2470,"children":2471},{"style":487},[2472],{"type":233,"value":859},{"type":228,"tag":438,"props":2474,"children":2475},{"class":440,"line":871},[2476],{"type":228,"tag":438,"props":2477,"children":2478},{"style":487},[2479],{"type":233,"value":868},{"type":228,"tag":438,"props":2481,"children":2482},{"class":440,"line":904},[2483,2488,2492,2496,2501],{"type":228,"tag":438,"props":2484,"children":2485},{"style":875},[2486],{"type":233,"value":2487},"    DisplayName ",{"type":228,"tag":438,"props":2489,"children":2490},{"style":487},[2491],{"type":233,"value":883},{"type":228,"tag":438,"props":2493,"children":2494},{"style":487},[2495],{"type":233,"value":490},{"type":228,"tag":438,"props":2497,"children":2498},{"style":451},[2499],{"type":233,"value":2500},"ADO Azure Ready App",{"type":228,"tag":438,"props":2502,"children":2503},{"style":487},[2504],{"type":233,"value":500},{"type":228,"tag":438,"props":2506,"children":2507},{"class":440,"line":921},[2508],{"type":228,"tag":438,"props":2509,"children":2510},{"style":487},[2511],{"type":233,"value":1170},{"type":228,"tag":438,"props":2513,"children":2514},{"class":440,"line":930},[2515,2519,2523,2528,2532,2537,2541,2545,2550,2554,2558],{"type":228,"tag":438,"props":2516,"children":2517},{"style":445},[2518],{"type":233,"value":811},{"type":228,"tag":438,"props":2520,"children":2521},{"style":445},[2522],{"type":233,"value":1894},{"type":228,"tag":438,"props":2524,"children":2525},{"style":487},[2526],{"type":233,"value":2527},"  =",{"type":228,"tag":438,"props":2529,"children":2530},{"style":487},[2531],{"type":233,"value":454},{"type":228,"tag":438,"props":2533,"children":2534},{"style":445},[2535],{"type":233,"value":2536}," ServicePrincipal",{"type":228,"tag":438,"props":2538,"children":2539},{"style":487},[2540],{"type":233,"value":835},{"type":228,"tag":438,"props":2542,"children":2543},{"style":487},[2544],{"type":233,"value":840},{"type":228,"tag":438,"props":2546,"children":2547},{"style":451},[2548],{"type":233,"value":2549},"AzureReadyServicePrincipal",{"type":228,"tag":438,"props":2551,"children":2552},{"style":487},[2553],{"type":233,"value":840},{"type":228,"tag":438,"props":2555,"children":2556},{"style":487},[2557],{"type":233,"value":854},{"type":228,"tag":438,"props":2559,"children":2560},{"style":487},[2561],{"type":233,"value":859},{"type":228,"tag":438,"props":2563,"children":2564},{"class":440,"line":978},[2565],{"type":228,"tag":438,"props":2566,"children":2567},{"style":487},[2568],{"type":233,"value":868},{"type":228,"tag":438,"props":2570,"children":2571},{"class":440,"line":1024},[2572,2577,2581,2585,2589,2593],{"type":228,"tag":438,"props":2573,"children":2574},{"style":875},[2575],{"type":233,"value":2576},"    ApplicationId ",{"type":228,"tag":438,"props":2578,"children":2579},{"style":487},[2580],{"type":233,"value":883},{"type":228,"tag":438,"props":2582,"children":2583},{"style":875},[2584],{"type":233,"value":2434},{"type":228,"tag":438,"props":2586,"children":2587},{"style":487},[2588],{"type":233,"value":1222},{"type":228,"tag":438,"props":2590,"children":2591},{"style":875},[2592],{"type":233,"value":1903},{"type":228,"tag":438,"props":2594,"children":2595},{"style":487},[2596],{"type":233,"value":901},{"type":228,"tag":438,"props":2598,"children":2599},{"class":440,"line":1069},[2600],{"type":228,"tag":438,"props":2601,"children":2602},{"style":487},[2603],{"type":233,"value":1170},{"type":228,"tag":438,"props":2605,"children":2606},{"class":440,"line":1114},[2607],{"type":228,"tag":438,"props":2608,"children":2610},{"emptyLinePlaceholder":2609},true,[2611],{"type":233,"value":2612},"\n",{"type":228,"tag":438,"props":2614,"children":2615},{"class":440,"line":1155},[2616,2620,2624,2628,2632,2636,2640,2644,2648,2652,2656,2660,2664],{"type":228,"tag":438,"props":2617,"children":2618},{"style":445},[2619],{"type":233,"value":811},{"type":228,"tag":438,"props":2621,"children":2622},{"style":445},[2623],{"type":233,"value":1820},{"type":228,"tag":438,"props":2625,"children":2626},{"style":487},[2627],{"type":233,"value":821},{"type":228,"tag":438,"props":2629,"children":2630},{"style":875},[2631],{"type":233,"value":1955},{"type":228,"tag":438,"props":2633,"children":2634},{"style":487},[2635],{"type":233,"value":1222},{"type":228,"tag":438,"props":2637,"children":2638},{"style":1225},[2639],{"type":233,"value":2005},{"type":228,"tag":438,"props":2641,"children":2642},{"style":487},[2643],{"type":233,"value":835},{"type":228,"tag":438,"props":2645,"children":2646},{"style":445},[2647],{"type":233,"value":2014},{"type":228,"tag":438,"props":2649,"children":2650},{"style":487},[2651],{"type":233,"value":2019},{"type":228,"tag":438,"props":2653,"children":2654},{"style":875},[2655],{"type":233,"value":2024},{"type":228,"tag":438,"props":2657,"children":2658},{"style":487},[2659],{"type":233,"value":1222},{"type":228,"tag":438,"props":2661,"children":2662},{"style":875},[2663],{"type":233,"value":2090},{"type":228,"tag":438,"props":2665,"children":2666},{"style":487},[2667],{"type":233,"value":2038},{"type":228,"tag":438,"props":2669,"children":2670},{"class":440,"line":1164},[2671,2677,2682,2686,2690,2695,2699,2703],{"type":228,"tag":438,"props":2672,"children":2674},{"style":2673},"--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA",[2675],{"type":233,"value":2676},"new",{"type":228,"tag":438,"props":2678,"children":2679},{"style":1225},[2680],{"type":233,"value":2681}," RoleAssignment",{"type":228,"tag":438,"props":2683,"children":2684},{"style":487},[2685],{"type":233,"value":835},{"type":228,"tag":438,"props":2687,"children":2688},{"style":487},[2689],{"type":233,"value":840},{"type":228,"tag":438,"props":2691,"children":2692},{"style":451},[2693],{"type":233,"value":2694},"contributor",{"type":228,"tag":438,"props":2696,"children":2697},{"style":487},[2698],{"type":233,"value":840},{"type":228,"tag":438,"props":2700,"children":2701},{"style":487},[2702],{"type":233,"value":854},{"type":228,"tag":438,"props":2704,"children":2705},{"style":487},[2706],{"type":233,"value":859},{"type":228,"tag":438,"props":2708,"children":2709},{"class":440,"line":1918},[2710],{"type":228,"tag":438,"props":2711,"children":2712},{"style":487},[2713],{"type":233,"value":868},{"type":228,"tag":438,"props":2715,"children":2717},{"class":440,"line":2716},14,[2718,2723,2727,2731,2735,2739],{"type":228,"tag":438,"props":2719,"children":2720},{"style":875},[2721],{"type":233,"value":2722},"    PrincipalId",{"type":228,"tag":438,"props":2724,"children":2725},{"style":487},[2726],{"type":233,"value":883},{"type":228,"tag":438,"props":2728,"children":2729},{"style":875},[2730],{"type":233,"value":1894},{"type":228,"tag":438,"props":2732,"children":2733},{"style":487},[2734],{"type":233,"value":1222},{"type":228,"tag":438,"props":2736,"children":2737},{"style":875},[2738],{"type":233,"value":1265},{"type":228,"tag":438,"props":2740,"children":2741},{"style":487},[2742],{"type":233,"value":901},{"type":228,"tag":438,"props":2744,"children":2746},{"class":440,"line":2745},15,[2747,2752,2756,2761,2765,2770],{"type":228,"tag":438,"props":2748,"children":2749},{"style":875},[2750],{"type":233,"value":2751},"    PrincipalType",{"type":228,"tag":438,"props":2753,"children":2754},{"style":487},[2755],{"type":233,"value":883},{"type":228,"tag":438,"props":2757,"children":2758},{"style":875},[2759],{"type":233,"value":2760}," PrincipalType",{"type":228,"tag":438,"props":2762,"children":2763},{"style":487},[2764],{"type":233,"value":1222},{"type":228,"tag":438,"props":2766,"children":2767},{"style":875},[2768],{"type":233,"value":2769},"ServicePrincipal",{"type":228,"tag":438,"props":2771,"children":2772},{"style":487},[2773],{"type":233,"value":901},{"type":228,"tag":438,"props":2775,"children":2777},{"class":440,"line":2776},16,[2778,2783,2787,2792,2796,2801],{"type":228,"tag":438,"props":2779,"children":2780},{"style":875},[2781],{"type":233,"value":2782},"    RoleDefinitionId ",{"type":228,"tag":438,"props":2784,"children":2785},{"style":487},[2786],{"type":233,"value":883},{"type":228,"tag":438,"props":2788,"children":2789},{"style":875},[2790],{"type":233,"value":2791}," AzureBuiltInRoles",{"type":228,"tag":438,"props":2793,"children":2794},{"style":487},[2795],{"type":233,"value":1222},{"type":228,"tag":438,"props":2797,"children":2798},{"style":875},[2799],{"type":233,"value":2800},"Contributor",{"type":228,"tag":438,"props":2802,"children":2803},{"style":487},[2804],{"type":233,"value":901},{"type":228,"tag":438,"props":2806,"children":2808},{"class":440,"line":2807},17,[2809,2814,2818,2823,2827,2832,2836,2840,2844,2848,2853,2857],{"type":228,"tag":438,"props":2810,"children":2811},{"style":875},[2812],{"type":233,"value":2813},"    Scope ",{"type":228,"tag":438,"props":2815,"children":2816},{"style":487},[2817],{"type":233,"value":883},{"type":228,"tag":438,"props":2819,"children":2820},{"style":875},[2821],{"type":233,"value":2822}," Output",{"type":228,"tag":438,"props":2824,"children":2825},{"style":487},[2826],{"type":233,"value":1222},{"type":228,"tag":438,"props":2828,"children":2829},{"style":1225},[2830],{"type":233,"value":2831},"Format",{"type":228,"tag":438,"props":2833,"children":2834},{"style":487},[2835],{"type":233,"value":835},{"type":228,"tag":438,"props":2837,"children":2838},{"style":487},[2839],{"type":233,"value":2265},{"type":228,"tag":438,"props":2841,"children":2842},{"style":451},[2843],{"type":233,"value":2270},{"type":228,"tag":438,"props":2845,"children":2846},{"style":487},[2847],{"type":233,"value":2275},{"type":228,"tag":438,"props":2849,"children":2850},{"style":875},[2851],{"type":233,"value":2852},"subscriptionId",{"type":228,"tag":438,"props":2854,"children":2855},{"style":487},[2856],{"type":233,"value":2284},{"type":228,"tag":438,"props":2858,"children":2859},{"style":487},[2860],{"type":233,"value":2861},")\n",{"type":228,"tag":438,"props":2863,"children":2865},{"class":440,"line":2864},18,[2866],{"type":228,"tag":438,"props":2867,"children":2868},{"style":487},[2869],{"type":233,"value":1170},{"type":228,"tag":311,"props":2871,"children":2872},{"icon":313},[2873],{"type":228,"tag":229,"props":2874,"children":2875},{},[2876,2878],{"type":233,"value":2877},"It's worth mentioning that using an Application and its associated Service Principal is not the only way to proceed, we could have created instead a ",{"type":228,"tag":247,"props":2879,"children":2882},{"href":2880,"rel":2881},"https://www.pulumi.com/registry/packages/azure-native/api-docs/managedidentity/userassignedidentity/",[251],[2883],{"type":233,"value":2884},"User Assigned Identity",{"type":228,"tag":229,"props":2886,"children":2887},{},[2888],{"type":233,"value":2889},"Now that everything is created, we can create the Federated identity credentials:",{"type":228,"tag":427,"props":2891,"children":2893},{"className":798,"code":2892,"language":511,"meta":207,"style":207},"new ApplicationFederatedIdentityCredential(\"ADOAzureReadyAppFederatedIdentityCredential\", new() \n{\n    ApplicationObjectId = aadApplication.ObjectId,\n    DisplayName = \"AzureReadyDeploys\",\n    Description = \"Deployments for azure-ready-repository\",\n    Audiences = new(){\"api://AzureADTokenExchange\" },\n    Issuer = serviceConnection.WorkloadIdentityFederationIssuer,\n    Subject = Output.Format($\"sc://{organisationName}/{project.Name}/{serviceConnection.ServiceEndpointName}\")\n});\n",[2894],{"type":228,"tag":434,"props":2895,"children":2896},{"__ignoreMap":207},[2897,2940,2947,2976,3004,3032,3067,3096,3204],{"type":228,"tag":438,"props":2898,"children":2899},{"class":440,"line":441},[2900,2904,2909,2913,2917,2922,2926,2930,2935],{"type":228,"tag":438,"props":2901,"children":2902},{"style":2673},[2903],{"type":233,"value":2676},{"type":228,"tag":438,"props":2905,"children":2906},{"style":1225},[2907],{"type":233,"value":2908}," ApplicationFederatedIdentityCredential",{"type":228,"tag":438,"props":2910,"children":2911},{"style":487},[2912],{"type":233,"value":835},{"type":228,"tag":438,"props":2914,"children":2915},{"style":487},[2916],{"type":233,"value":840},{"type":228,"tag":438,"props":2918,"children":2919},{"style":451},[2920],{"type":233,"value":2921},"ADOAzureReadyAppFederatedIdentityCredential",{"type":228,"tag":438,"props":2923,"children":2924},{"style":487},[2925],{"type":233,"value":840},{"type":228,"tag":438,"props":2927,"children":2928},{"style":487},[2929],{"type":233,"value":854},{"type":228,"tag":438,"props":2931,"children":2932},{"style":487},[2933],{"type":233,"value":2934}," new()",{"type":228,"tag":438,"props":2936,"children":2937},{"style":875},[2938],{"type":233,"value":2939}," \n",{"type":228,"tag":438,"props":2941,"children":2942},{"class":440,"line":862},[2943],{"type":228,"tag":438,"props":2944,"children":2945},{"style":487},[2946],{"type":233,"value":868},{"type":228,"tag":438,"props":2948,"children":2949},{"class":440,"line":871},[2950,2955,2959,2963,2967,2972],{"type":228,"tag":438,"props":2951,"children":2952},{"style":875},[2953],{"type":233,"value":2954},"    ApplicationObjectId ",{"type":228,"tag":438,"props":2956,"children":2957},{"style":487},[2958],{"type":233,"value":883},{"type":228,"tag":438,"props":2960,"children":2961},{"style":875},[2962],{"type":233,"value":2434},{"type":228,"tag":438,"props":2964,"children":2965},{"style":487},[2966],{"type":233,"value":1222},{"type":228,"tag":438,"props":2968,"children":2969},{"style":875},[2970],{"type":233,"value":2971},"ObjectId",{"type":228,"tag":438,"props":2973,"children":2974},{"style":487},[2975],{"type":233,"value":901},{"type":228,"tag":438,"props":2977,"children":2978},{"class":440,"line":904},[2979,2983,2987,2991,2996,3000],{"type":228,"tag":438,"props":2980,"children":2981},{"style":875},[2982],{"type":233,"value":2487},{"type":228,"tag":438,"props":2984,"children":2985},{"style":487},[2986],{"type":233,"value":883},{"type":228,"tag":438,"props":2988,"children":2989},{"style":487},[2990],{"type":233,"value":490},{"type":228,"tag":438,"props":2992,"children":2993},{"style":451},[2994],{"type":233,"value":2995},"AzureReadyDeploys",{"type":228,"tag":438,"props":2997,"children":2998},{"style":487},[2999],{"type":233,"value":840},{"type":228,"tag":438,"props":3001,"children":3002},{"style":487},[3003],{"type":233,"value":901},{"type":228,"tag":438,"props":3005,"children":3006},{"class":440,"line":921},[3007,3011,3015,3019,3024,3028],{"type":228,"tag":438,"props":3008,"children":3009},{"style":875},[3010],{"type":233,"value":878},{"type":228,"tag":438,"props":3012,"children":3013},{"style":487},[3014],{"type":233,"value":883},{"type":228,"tag":438,"props":3016,"children":3017},{"style":487},[3018],{"type":233,"value":490},{"type":228,"tag":438,"props":3020,"children":3021},{"style":451},[3022],{"type":233,"value":3023},"Deployments for azure-ready-repository",{"type":228,"tag":438,"props":3025,"children":3026},{"style":487},[3027],{"type":233,"value":840},{"type":228,"tag":438,"props":3029,"children":3030},{"style":487},[3031],{"type":233,"value":901},{"type":228,"tag":438,"props":3033,"children":3034},{"class":440,"line":930},[3035,3040,3044,3049,3053,3058,3062],{"type":228,"tag":438,"props":3036,"children":3037},{"style":875},[3038],{"type":233,"value":3039},"    Audiences ",{"type":228,"tag":438,"props":3041,"children":3042},{"style":487},[3043],{"type":233,"value":883},{"type":228,"tag":438,"props":3045,"children":3046},{"style":487},[3047],{"type":233,"value":3048}," new(){",{"type":228,"tag":438,"props":3050,"children":3051},{"style":487},[3052],{"type":233,"value":840},{"type":228,"tag":438,"props":3054,"children":3055},{"style":451},[3056],{"type":233,"value":3057},"api://AzureADTokenExchange",{"type":228,"tag":438,"props":3059,"children":3060},{"style":487},[3061],{"type":233,"value":840},{"type":228,"tag":438,"props":3063,"children":3064},{"style":487},[3065],{"type":233,"value":3066}," },\n",{"type":228,"tag":438,"props":3068,"children":3069},{"class":440,"line":978},[3070,3075,3079,3083,3087,3092],{"type":228,"tag":438,"props":3071,"children":3072},{"style":875},[3073],{"type":233,"value":3074},"    Issuer ",{"type":228,"tag":438,"props":3076,"children":3077},{"style":487},[3078],{"type":233,"value":883},{"type":228,"tag":438,"props":3080,"children":3081},{"style":875},[3082],{"type":233,"value":1652},{"type":228,"tag":438,"props":3084,"children":3085},{"style":487},[3086],{"type":233,"value":1222},{"type":228,"tag":438,"props":3088,"children":3089},{"style":875},[3090],{"type":233,"value":3091},"WorkloadIdentityFederationIssuer",{"type":228,"tag":438,"props":3093,"children":3094},{"style":487},[3095],{"type":233,"value":901},{"type":228,"tag":438,"props":3097,"children":3098},{"class":440,"line":1024},[3099,3104,3108,3112,3116,3120,3124,3128,3133,3137,3142,3147,3152,3156,3161,3165,3170,3174,3178,3182,3187,3191,3196,3200],{"type":228,"tag":438,"props":3100,"children":3101},{"style":875},[3102],{"type":233,"value":3103},"    Subject ",{"type":228,"tag":438,"props":3105,"children":3106},{"style":487},[3107],{"type":233,"value":883},{"type":228,"tag":438,"props":3109,"children":3110},{"style":875},[3111],{"type":233,"value":2822},{"type":228,"tag":438,"props":3113,"children":3114},{"style":487},[3115],{"type":233,"value":1222},{"type":228,"tag":438,"props":3117,"children":3118},{"style":1225},[3119],{"type":233,"value":2831},{"type":228,"tag":438,"props":3121,"children":3122},{"style":487},[3123],{"type":233,"value":835},{"type":228,"tag":438,"props":3125,"children":3126},{"style":487},[3127],{"type":233,"value":2265},{"type":228,"tag":438,"props":3129,"children":3130},{"style":451},[3131],{"type":233,"value":3132},"sc://",{"type":228,"tag":438,"props":3134,"children":3135},{"style":487},[3136],{"type":233,"value":2275},{"type":228,"tag":438,"props":3138,"children":3139},{"style":875},[3140],{"type":233,"value":3141},"organisationName",{"type":228,"tag":438,"props":3143,"children":3144},{"style":487},[3145],{"type":233,"value":3146},"}",{"type":228,"tag":438,"props":3148,"children":3149},{"style":451},[3150],{"type":233,"value":3151},"/",{"type":228,"tag":438,"props":3153,"children":3154},{"style":487},[3155],{"type":233,"value":2275},{"type":228,"tag":438,"props":3157,"children":3158},{"style":875},[3159],{"type":233,"value":3160},"project",{"type":228,"tag":438,"props":3162,"children":3163},{"style":487},[3164],{"type":233,"value":1222},{"type":228,"tag":438,"props":3166,"children":3167},{"style":875},[3168],{"type":233,"value":3169},"Name",{"type":228,"tag":438,"props":3171,"children":3172},{"style":487},[3173],{"type":233,"value":3146},{"type":228,"tag":438,"props":3175,"children":3176},{"style":451},[3177],{"type":233,"value":3151},{"type":228,"tag":438,"props":3179,"children":3180},{"style":487},[3181],{"type":233,"value":2275},{"type":228,"tag":438,"props":3183,"children":3184},{"style":875},[3185],{"type":233,"value":3186},"serviceConnection",{"type":228,"tag":438,"props":3188,"children":3189},{"style":487},[3190],{"type":233,"value":1222},{"type":228,"tag":438,"props":3192,"children":3193},{"style":875},[3194],{"type":233,"value":3195},"ServiceEndpointName",{"type":228,"tag":438,"props":3197,"children":3198},{"style":487},[3199],{"type":233,"value":2284},{"type":228,"tag":438,"props":3201,"children":3202},{"style":487},[3203],{"type":233,"value":2861},{"type":228,"tag":438,"props":3205,"children":3206},{"class":440,"line":1069},[3207],{"type":228,"tag":438,"props":3208,"children":3209},{"style":487},[3210],{"type":233,"value":1170},{"type":228,"tag":229,"props":3212,"children":3213},{},[3214,3216,3222],{"type":233,"value":3215},"You can observe that the federation subject adheres to a particular format (",{"type":228,"tag":434,"props":3217,"children":3219},{"className":3218},[],[3220],{"type":233,"value":3221},"sc://\u003Corg>/\u003Cproject>/\u003Cservice connection name>",{"type":233,"value":3223},"), which identifies the service connection authorized for authentication with Azure.",{"type":228,"tag":415,"props":3225,"children":3227},{"id":3226},"create-the-deployment-pipeline",[3228],{"type":233,"value":3229},"Create the deployment pipeline",{"type":228,"tag":229,"props":3231,"children":3232},{},[3233],{"type":233,"value":3234},"We have completed the configuration of an ARM Service Connection that employs Workload Identity Federation for authentication with Azure. While we could stop at this point, it would be nice to automate the creation of a pipeline that utilizes this service connection and seize the opportunity to ensure everything works properly.",{"type":228,"tag":229,"props":3236,"children":3237},{},[3238,3240,3246],{"type":233,"value":3239},"For this purpose, I have written a very simple YAML pipeline that runs the ",{"type":228,"tag":434,"props":3241,"children":3243},{"className":3242},[],[3244],{"type":233,"value":3245},"AzureCLI",{"type":233,"value":3247}," task to show information about the Azure subscription associated with the previously created service connection.",{"type":228,"tag":427,"props":3249,"children":3251},{"className":798,"code":3250,"language":511,"meta":207,"style":207},"trigger:\n  - main\n\npool:\n  vmImage: ubuntu-latest\n\nsteps:\n  - task: AzureCLI@2\n    inputs:\n      azureSubscription: 'azure-with-oidc'\n      scriptType: 'pscore'\n      scriptLocation: 'inlineScript'\n      inlineScript: 'az account show --query id -o tsv'\n",[3252],{"type":228,"tag":434,"props":3253,"children":3254},{"__ignoreMap":207},[3255,3268,3281,3288,3300,3328,3335,3347,3374,3386,3412,3437,3462],{"type":228,"tag":438,"props":3256,"children":3257},{"class":440,"line":441},[3258,3263],{"type":228,"tag":438,"props":3259,"children":3260},{"style":445},[3261],{"type":233,"value":3262},"trigger",{"type":228,"tag":438,"props":3264,"children":3265},{"style":487},[3266],{"type":233,"value":3267},":\n",{"type":228,"tag":438,"props":3269,"children":3270},{"class":440,"line":862},[3271,3276],{"type":228,"tag":438,"props":3272,"children":3273},{"style":487},[3274],{"type":233,"value":3275},"  -",{"type":228,"tag":438,"props":3277,"children":3278},{"style":875},[3279],{"type":233,"value":3280}," main\n",{"type":228,"tag":438,"props":3282,"children":3283},{"class":440,"line":871},[3284],{"type":228,"tag":438,"props":3285,"children":3286},{"emptyLinePlaceholder":2609},[3287],{"type":233,"value":2612},{"type":228,"tag":438,"props":3289,"children":3290},{"class":440,"line":904},[3291,3296],{"type":228,"tag":438,"props":3292,"children":3293},{"style":445},[3294],{"type":233,"value":3295},"pool",{"type":228,"tag":438,"props":3297,"children":3298},{"style":487},[3299],{"type":233,"value":3267},{"type":228,"tag":438,"props":3301,"children":3302},{"class":440,"line":921},[3303,3308,3313,3318,3323],{"type":228,"tag":438,"props":3304,"children":3305},{"style":445},[3306],{"type":233,"value":3307},"  vmImage",{"type":228,"tag":438,"props":3309,"children":3310},{"style":487},[3311],{"type":233,"value":3312},":",{"type":228,"tag":438,"props":3314,"children":3315},{"style":875},[3316],{"type":233,"value":3317}," ubuntu",{"type":228,"tag":438,"props":3319,"children":3320},{"style":487},[3321],{"type":233,"value":3322},"-",{"type":228,"tag":438,"props":3324,"children":3325},{"style":875},[3326],{"type":233,"value":3327},"latest\n",{"type":228,"tag":438,"props":3329,"children":3330},{"class":440,"line":930},[3331],{"type":228,"tag":438,"props":3332,"children":3333},{"emptyLinePlaceholder":2609},[3334],{"type":233,"value":2612},{"type":228,"tag":438,"props":3336,"children":3337},{"class":440,"line":978},[3338,3343],{"type":228,"tag":438,"props":3339,"children":3340},{"style":445},[3341],{"type":233,"value":3342},"steps",{"type":228,"tag":438,"props":3344,"children":3345},{"style":487},[3346],{"type":233,"value":3267},{"type":228,"tag":438,"props":3348,"children":3349},{"class":440,"line":1024},[3350,3354,3359,3363,3368],{"type":228,"tag":438,"props":3351,"children":3352},{"style":487},[3353],{"type":233,"value":3275},{"type":228,"tag":438,"props":3355,"children":3356},{"style":445},[3357],{"type":233,"value":3358}," task",{"type":228,"tag":438,"props":3360,"children":3361},{"style":487},[3362],{"type":233,"value":3312},{"type":228,"tag":438,"props":3364,"children":3365},{"style":875},[3366],{"type":233,"value":3367}," AzureCLI@",{"type":228,"tag":438,"props":3369,"children":3371},{"style":3370},"--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C",[3372],{"type":233,"value":3373},"2\n",{"type":228,"tag":438,"props":3375,"children":3376},{"class":440,"line":1069},[3377,3382],{"type":228,"tag":438,"props":3378,"children":3379},{"style":445},[3380],{"type":233,"value":3381},"    inputs",{"type":228,"tag":438,"props":3383,"children":3384},{"style":487},[3385],{"type":233,"value":3267},{"type":228,"tag":438,"props":3387,"children":3388},{"class":440,"line":1114},[3389,3394,3398,3403,3407],{"type":228,"tag":438,"props":3390,"children":3391},{"style":445},[3392],{"type":233,"value":3393},"      azureSubscription",{"type":228,"tag":438,"props":3395,"children":3396},{"style":487},[3397],{"type":233,"value":3312},{"type":228,"tag":438,"props":3399,"children":3400},{"style":487},[3401],{"type":233,"value":3402}," '",{"type":228,"tag":438,"props":3404,"children":3405},{"style":451},[3406],{"type":233,"value":1745},{"type":228,"tag":438,"props":3408,"children":3409},{"style":487},[3410],{"type":233,"value":3411},"'\n",{"type":228,"tag":438,"props":3413,"children":3414},{"class":440,"line":1155},[3415,3420,3424,3428,3433],{"type":228,"tag":438,"props":3416,"children":3417},{"style":445},[3418],{"type":233,"value":3419},"      scriptType",{"type":228,"tag":438,"props":3421,"children":3422},{"style":487},[3423],{"type":233,"value":3312},{"type":228,"tag":438,"props":3425,"children":3426},{"style":487},[3427],{"type":233,"value":3402},{"type":228,"tag":438,"props":3429,"children":3430},{"style":451},[3431],{"type":233,"value":3432},"pscore",{"type":228,"tag":438,"props":3434,"children":3435},{"style":487},[3436],{"type":233,"value":3411},{"type":228,"tag":438,"props":3438,"children":3439},{"class":440,"line":1164},[3440,3445,3449,3453,3458],{"type":228,"tag":438,"props":3441,"children":3442},{"style":445},[3443],{"type":233,"value":3444},"      scriptLocation",{"type":228,"tag":438,"props":3446,"children":3447},{"style":487},[3448],{"type":233,"value":3312},{"type":228,"tag":438,"props":3450,"children":3451},{"style":487},[3452],{"type":233,"value":3402},{"type":228,"tag":438,"props":3454,"children":3455},{"style":451},[3456],{"type":233,"value":3457},"inlineScript",{"type":228,"tag":438,"props":3459,"children":3460},{"style":487},[3461],{"type":233,"value":3411},{"type":228,"tag":438,"props":3463,"children":3464},{"class":440,"line":1918},[3465,3470,3474,3478,3483],{"type":228,"tag":438,"props":3466,"children":3467},{"style":445},[3468],{"type":233,"value":3469},"      inlineScript",{"type":228,"tag":438,"props":3471,"children":3472},{"style":487},[3473],{"type":233,"value":3312},{"type":228,"tag":438,"props":3475,"children":3476},{"style":487},[3477],{"type":233,"value":3402},{"type":228,"tag":438,"props":3479,"children":3480},{"style":451},[3481],{"type":233,"value":3482},"az account show --query id -o tsv",{"type":228,"tag":438,"props":3484,"children":3485},{"style":487},[3486],{"type":233,"value":3411},{"type":228,"tag":229,"props":3488,"children":3489},{},[3490],{"type":233,"value":3491},"We can add this file in the Git repository:",{"type":228,"tag":427,"props":3493,"children":3495},{"className":798,"code":3494,"language":511,"meta":207,"style":207},"var pipelineFile = new GitRepositoryFile(\"AzurePipeline\", new()\n{\n    File = \"azure-pipelines.yaml\",\n    RepositoryId = repository.Apply(r => r.Id),\n    CommitMessage = \"Add preconfigured pipeline file\",\n    Content = File.ReadAllText(\"azure-pipelines.yml\"),\n    Branch = \"refs/heads/main\"\n});\n",[3496],{"type":228,"tag":434,"props":3497,"children":3498},{"__ignoreMap":207},[3499,3549,3556,3585,3640,3669,3716,3740],{"type":228,"tag":438,"props":3500,"children":3501},{"class":440,"line":441},[3502,3506,3511,3515,3519,3524,3528,3532,3537,3541,3545],{"type":228,"tag":438,"props":3503,"children":3504},{"style":445},[3505],{"type":233,"value":811},{"type":228,"tag":438,"props":3507,"children":3508},{"style":445},[3509],{"type":233,"value":3510}," pipelineFile",{"type":228,"tag":438,"props":3512,"children":3513},{"style":487},[3514],{"type":233,"value":821},{"type":228,"tag":438,"props":3516,"children":3517},{"style":487},[3518],{"type":233,"value":454},{"type":228,"tag":438,"props":3520,"children":3521},{"style":445},[3522],{"type":233,"value":3523}," GitRepositoryFile",{"type":228,"tag":438,"props":3525,"children":3526},{"style":487},[3527],{"type":233,"value":835},{"type":228,"tag":438,"props":3529,"children":3530},{"style":487},[3531],{"type":233,"value":840},{"type":228,"tag":438,"props":3533,"children":3534},{"style":451},[3535],{"type":233,"value":3536},"AzurePipeline",{"type":228,"tag":438,"props":3538,"children":3539},{"style":487},[3540],{"type":233,"value":840},{"type":228,"tag":438,"props":3542,"children":3543},{"style":487},[3544],{"type":233,"value":854},{"type":228,"tag":438,"props":3546,"children":3547},{"style":487},[3548],{"type":233,"value":859},{"type":228,"tag":438,"props":3550,"children":3551},{"class":440,"line":862},[3552],{"type":228,"tag":438,"props":3553,"children":3554},{"style":487},[3555],{"type":233,"value":868},{"type":228,"tag":438,"props":3557,"children":3558},{"class":440,"line":871},[3559,3564,3568,3572,3577,3581],{"type":228,"tag":438,"props":3560,"children":3561},{"style":875},[3562],{"type":233,"value":3563},"    File ",{"type":228,"tag":438,"props":3565,"children":3566},{"style":487},[3567],{"type":233,"value":883},{"type":228,"tag":438,"props":3569,"children":3570},{"style":487},[3571],{"type":233,"value":490},{"type":228,"tag":438,"props":3573,"children":3574},{"style":451},[3575],{"type":233,"value":3576},"azure-pipelines.yaml",{"type":228,"tag":438,"props":3578,"children":3579},{"style":487},[3580],{"type":233,"value":840},{"type":228,"tag":438,"props":3582,"children":3583},{"style":487},[3584],{"type":233,"value":901},{"type":228,"tag":438,"props":3586,"children":3587},{"class":440,"line":904},[3588,3593,3597,3601,3605,3609,3613,3618,3622,3627,3631,3635],{"type":228,"tag":438,"props":3589,"children":3590},{"style":875},[3591],{"type":233,"value":3592},"    RepositoryId ",{"type":228,"tag":438,"props":3594,"children":3595},{"style":487},[3596],{"type":233,"value":883},{"type":228,"tag":438,"props":3598,"children":3599},{"style":875},[3600],{"type":233,"value":1208},{"type":228,"tag":438,"props":3602,"children":3603},{"style":487},[3604],{"type":233,"value":1222},{"type":228,"tag":438,"props":3606,"children":3607},{"style":1225},[3608],{"type":233,"value":2005},{"type":228,"tag":438,"props":3610,"children":3611},{"style":487},[3612],{"type":233,"value":835},{"type":228,"tag":438,"props":3614,"children":3615},{"style":445},[3616],{"type":233,"value":3617},"r",{"type":228,"tag":438,"props":3619,"children":3620},{"style":487},[3621],{"type":233,"value":2019},{"type":228,"tag":438,"props":3623,"children":3624},{"style":875},[3625],{"type":233,"value":3626}," r",{"type":228,"tag":438,"props":3628,"children":3629},{"style":487},[3630],{"type":233,"value":1222},{"type":228,"tag":438,"props":3632,"children":3633},{"style":875},[3634],{"type":233,"value":1265},{"type":228,"tag":438,"props":3636,"children":3637},{"style":487},[3638],{"type":233,"value":3639},"),\n",{"type":228,"tag":438,"props":3641,"children":3642},{"class":440,"line":921},[3643,3648,3652,3656,3661,3665],{"type":228,"tag":438,"props":3644,"children":3645},{"style":875},[3646],{"type":233,"value":3647},"    CommitMessage ",{"type":228,"tag":438,"props":3649,"children":3650},{"style":487},[3651],{"type":233,"value":883},{"type":228,"tag":438,"props":3653,"children":3654},{"style":487},[3655],{"type":233,"value":490},{"type":228,"tag":438,"props":3657,"children":3658},{"style":451},[3659],{"type":233,"value":3660},"Add preconfigured pipeline file",{"type":228,"tag":438,"props":3662,"children":3663},{"style":487},[3664],{"type":233,"value":840},{"type":228,"tag":438,"props":3666,"children":3667},{"style":487},[3668],{"type":233,"value":901},{"type":228,"tag":438,"props":3670,"children":3671},{"class":440,"line":930},[3672,3677,3681,3686,3690,3695,3699,3703,3708,3712],{"type":228,"tag":438,"props":3673,"children":3674},{"style":875},[3675],{"type":233,"value":3676},"    Content ",{"type":228,"tag":438,"props":3678,"children":3679},{"style":487},[3680],{"type":233,"value":883},{"type":228,"tag":438,"props":3682,"children":3683},{"style":875},[3684],{"type":233,"value":3685}," File",{"type":228,"tag":438,"props":3687,"children":3688},{"style":487},[3689],{"type":233,"value":1222},{"type":228,"tag":438,"props":3691,"children":3692},{"style":1225},[3693],{"type":233,"value":3694},"ReadAllText",{"type":228,"tag":438,"props":3696,"children":3697},{"style":487},[3698],{"type":233,"value":835},{"type":228,"tag":438,"props":3700,"children":3701},{"style":487},[3702],{"type":233,"value":840},{"type":228,"tag":438,"props":3704,"children":3705},{"style":451},[3706],{"type":233,"value":3707},"azure-pipelines.yml",{"type":228,"tag":438,"props":3709,"children":3710},{"style":487},[3711],{"type":233,"value":840},{"type":228,"tag":438,"props":3713,"children":3714},{"style":487},[3715],{"type":233,"value":3639},{"type":228,"tag":438,"props":3717,"children":3718},{"class":440,"line":978},[3719,3724,3728,3732,3736],{"type":228,"tag":438,"props":3720,"children":3721},{"style":875},[3722],{"type":233,"value":3723},"    Branch ",{"type":228,"tag":438,"props":3725,"children":3726},{"style":487},[3727],{"type":233,"value":883},{"type":228,"tag":438,"props":3729,"children":3730},{"style":487},[3731],{"type":233,"value":490},{"type":228,"tag":438,"props":3733,"children":3734},{"style":451},[3735],{"type":233,"value":1561},{"type":228,"tag":438,"props":3737,"children":3738},{"style":487},[3739],{"type":233,"value":500},{"type":228,"tag":438,"props":3741,"children":3742},{"class":440,"line":1024},[3743],{"type":228,"tag":438,"props":3744,"children":3745},{"style":487},[3746],{"type":233,"value":1170},{"type":228,"tag":229,"props":3748,"children":3749},{},[3750],{"type":233,"value":3751},"Now, we have to create the pipeline itself:",{"type":228,"tag":427,"props":3753,"children":3755},{"className":798,"code":3754,"language":511,"meta":207,"style":207},"var pipeline = new BuildDefinition(\"deployToAzure\", new()\n{\n    ProjectId = project.Id,\n    Repository = new BuildDefinitionRepositoryArgs()\n    {\n        RepoId = repository.Apply(r => r.Id),\n        BranchName = \"refs/heads/main\",\n        YmlPath = pipelineFile.File,\n        RepoType = \"TfsGit\"\n    }\n});\n",[3756],{"type":228,"tag":434,"props":3757,"children":3758},{"__ignoreMap":207},[3759,3809,3816,3843,3868,3875,3927,3955,3984,4009,4016],{"type":228,"tag":438,"props":3760,"children":3761},{"class":440,"line":441},[3762,3766,3771,3775,3779,3784,3788,3792,3797,3801,3805],{"type":228,"tag":438,"props":3763,"children":3764},{"style":445},[3765],{"type":233,"value":811},{"type":228,"tag":438,"props":3767,"children":3768},{"style":445},[3769],{"type":233,"value":3770}," pipeline",{"type":228,"tag":438,"props":3772,"children":3773},{"style":487},[3774],{"type":233,"value":821},{"type":228,"tag":438,"props":3776,"children":3777},{"style":487},[3778],{"type":233,"value":454},{"type":228,"tag":438,"props":3780,"children":3781},{"style":445},[3782],{"type":233,"value":3783}," BuildDefinition",{"type":228,"tag":438,"props":3785,"children":3786},{"style":487},[3787],{"type":233,"value":835},{"type":228,"tag":438,"props":3789,"children":3790},{"style":487},[3791],{"type":233,"value":840},{"type":228,"tag":438,"props":3793,"children":3794},{"style":451},[3795],{"type":233,"value":3796},"deployToAzure",{"type":228,"tag":438,"props":3798,"children":3799},{"style":487},[3800],{"type":233,"value":840},{"type":228,"tag":438,"props":3802,"children":3803},{"style":487},[3804],{"type":233,"value":854},{"type":228,"tag":438,"props":3806,"children":3807},{"style":487},[3808],{"type":233,"value":859},{"type":228,"tag":438,"props":3810,"children":3811},{"class":440,"line":862},[3812],{"type":228,"tag":438,"props":3813,"children":3814},{"style":487},[3815],{"type":233,"value":868},{"type":228,"tag":438,"props":3817,"children":3818},{"class":440,"line":871},[3819,3823,3827,3831,3835,3839],{"type":228,"tag":438,"props":3820,"children":3821},{"style":875},[3822],{"type":233,"value":1248},{"type":228,"tag":438,"props":3824,"children":3825},{"style":487},[3826],{"type":233,"value":883},{"type":228,"tag":438,"props":3828,"children":3829},{"style":875},[3830],{"type":233,"value":816},{"type":228,"tag":438,"props":3832,"children":3833},{"style":487},[3834],{"type":233,"value":1222},{"type":228,"tag":438,"props":3836,"children":3837},{"style":875},[3838],{"type":233,"value":1265},{"type":228,"tag":438,"props":3840,"children":3841},{"style":487},[3842],{"type":233,"value":901},{"type":228,"tag":438,"props":3844,"children":3845},{"class":440,"line":904},[3846,3851,3855,3859,3864],{"type":228,"tag":438,"props":3847,"children":3848},{"style":875},[3849],{"type":233,"value":3850},"    Repository ",{"type":228,"tag":438,"props":3852,"children":3853},{"style":487},[3854],{"type":233,"value":883},{"type":228,"tag":438,"props":3856,"children":3857},{"style":487},[3858],{"type":233,"value":454},{"type":228,"tag":438,"props":3860,"children":3861},{"style":445},[3862],{"type":233,"value":3863}," BuildDefinitionRepositoryArgs",{"type":228,"tag":438,"props":3865,"children":3866},{"style":487},[3867],{"type":233,"value":1422},{"type":228,"tag":438,"props":3869,"children":3870},{"class":440,"line":921},[3871],{"type":228,"tag":438,"props":3872,"children":3873},{"style":487},[3874],{"type":233,"value":927},{"type":228,"tag":438,"props":3876,"children":3877},{"class":440,"line":930},[3878,3883,3887,3891,3895,3899,3903,3907,3911,3915,3919,3923],{"type":228,"tag":438,"props":3879,"children":3880},{"style":875},[3881],{"type":233,"value":3882},"        RepoId ",{"type":228,"tag":438,"props":3884,"children":3885},{"style":487},[3886],{"type":233,"value":883},{"type":228,"tag":438,"props":3888,"children":3889},{"style":875},[3890],{"type":233,"value":1208},{"type":228,"tag":438,"props":3892,"children":3893},{"style":487},[3894],{"type":233,"value":1222},{"type":228,"tag":438,"props":3896,"children":3897},{"style":1225},[3898],{"type":233,"value":2005},{"type":228,"tag":438,"props":3900,"children":3901},{"style":487},[3902],{"type":233,"value":835},{"type":228,"tag":438,"props":3904,"children":3905},{"style":445},[3906],{"type":233,"value":3617},{"type":228,"tag":438,"props":3908,"children":3909},{"style":487},[3910],{"type":233,"value":2019},{"type":228,"tag":438,"props":3912,"children":3913},{"style":875},[3914],{"type":233,"value":3626},{"type":228,"tag":438,"props":3916,"children":3917},{"style":487},[3918],{"type":233,"value":1222},{"type":228,"tag":438,"props":3920,"children":3921},{"style":875},[3922],{"type":233,"value":1265},{"type":228,"tag":438,"props":3924,"children":3925},{"style":487},[3926],{"type":233,"value":3639},{"type":228,"tag":438,"props":3928,"children":3929},{"class":440,"line":978},[3930,3935,3939,3943,3947,3951],{"type":228,"tag":438,"props":3931,"children":3932},{"style":875},[3933],{"type":233,"value":3934},"        BranchName ",{"type":228,"tag":438,"props":3936,"children":3937},{"style":487},[3938],{"type":233,"value":883},{"type":228,"tag":438,"props":3940,"children":3941},{"style":487},[3942],{"type":233,"value":490},{"type":228,"tag":438,"props":3944,"children":3945},{"style":451},[3946],{"type":233,"value":1561},{"type":228,"tag":438,"props":3948,"children":3949},{"style":487},[3950],{"type":233,"value":840},{"type":228,"tag":438,"props":3952,"children":3953},{"style":487},[3954],{"type":233,"value":901},{"type":228,"tag":438,"props":3956,"children":3957},{"class":440,"line":1024},[3958,3963,3967,3971,3975,3980],{"type":228,"tag":438,"props":3959,"children":3960},{"style":875},[3961],{"type":233,"value":3962},"        YmlPath ",{"type":228,"tag":438,"props":3964,"children":3965},{"style":487},[3966],{"type":233,"value":883},{"type":228,"tag":438,"props":3968,"children":3969},{"style":875},[3970],{"type":233,"value":3510},{"type":228,"tag":438,"props":3972,"children":3973},{"style":487},[3974],{"type":233,"value":1222},{"type":228,"tag":438,"props":3976,"children":3977},{"style":875},[3978],{"type":233,"value":3979},"File",{"type":228,"tag":438,"props":3981,"children":3982},{"style":487},[3983],{"type":233,"value":901},{"type":228,"tag":438,"props":3985,"children":3986},{"class":440,"line":1069},[3987,3992,3996,4000,4005],{"type":228,"tag":438,"props":3988,"children":3989},{"style":875},[3990],{"type":233,"value":3991},"        RepoType ",{"type":228,"tag":438,"props":3993,"children":3994},{"style":487},[3995],{"type":233,"value":883},{"type":228,"tag":438,"props":3997,"children":3998},{"style":487},[3999],{"type":233,"value":490},{"type":228,"tag":438,"props":4001,"children":4002},{"style":451},[4003],{"type":233,"value":4004},"TfsGit",{"type":228,"tag":438,"props":4006,"children":4007},{"style":487},[4008],{"type":233,"value":500},{"type":228,"tag":438,"props":4010,"children":4011},{"class":440,"line":1114},[4012],{"type":228,"tag":438,"props":4013,"children":4014},{"style":487},[4015],{"type":233,"value":1915},{"type":228,"tag":438,"props":4017,"children":4018},{"class":440,"line":1155},[4019],{"type":228,"tag":438,"props":4020,"children":4021},{"style":487},[4022],{"type":233,"value":1170},{"type":228,"tag":229,"props":4024,"children":4025},{},[4026],{"type":233,"value":4027},"To complete the automation process, we can authorize the pipeline to utilize the service connection, eliminating the need for manual intervention through the portal:",{"type":228,"tag":427,"props":4029,"children":4031},{"className":798,"code":4030,"language":511,"meta":207,"style":207},"new PipelineAuthorization(\"azureOidcPipelineAuthorization\", new()\n{\n    ProjectId = project.Id,\n    Type = \"endpoint\",\n    PipelineId = pipeline.Id.Apply(int.Parse),\n    ResourceId = serviceConnection.Id\n});\n",[4032],{"type":228,"tag":434,"props":4033,"children":4034},{"__ignoreMap":207},[4035,4072,4079,4106,4135,4181,4206],{"type":228,"tag":438,"props":4036,"children":4037},{"class":440,"line":441},[4038,4042,4047,4051,4055,4060,4064,4068],{"type":228,"tag":438,"props":4039,"children":4040},{"style":2673},[4041],{"type":233,"value":2676},{"type":228,"tag":438,"props":4043,"children":4044},{"style":1225},[4045],{"type":233,"value":4046}," PipelineAuthorization",{"type":228,"tag":438,"props":4048,"children":4049},{"style":487},[4050],{"type":233,"value":835},{"type":228,"tag":438,"props":4052,"children":4053},{"style":487},[4054],{"type":233,"value":840},{"type":228,"tag":438,"props":4056,"children":4057},{"style":451},[4058],{"type":233,"value":4059},"azureOidcPipelineAuthorization",{"type":228,"tag":438,"props":4061,"children":4062},{"style":487},[4063],{"type":233,"value":840},{"type":228,"tag":438,"props":4065,"children":4066},{"style":487},[4067],{"type":233,"value":854},{"type":228,"tag":438,"props":4069,"children":4070},{"style":487},[4071],{"type":233,"value":859},{"type":228,"tag":438,"props":4073,"children":4074},{"class":440,"line":862},[4075],{"type":228,"tag":438,"props":4076,"children":4077},{"style":487},[4078],{"type":233,"value":868},{"type":228,"tag":438,"props":4080,"children":4081},{"class":440,"line":871},[4082,4086,4090,4094,4098,4102],{"type":228,"tag":438,"props":4083,"children":4084},{"style":875},[4085],{"type":233,"value":1248},{"type":228,"tag":438,"props":4087,"children":4088},{"style":487},[4089],{"type":233,"value":883},{"type":228,"tag":438,"props":4091,"children":4092},{"style":875},[4093],{"type":233,"value":816},{"type":228,"tag":438,"props":4095,"children":4096},{"style":487},[4097],{"type":233,"value":1222},{"type":228,"tag":438,"props":4099,"children":4100},{"style":875},[4101],{"type":233,"value":1265},{"type":228,"tag":438,"props":4103,"children":4104},{"style":487},[4105],{"type":233,"value":901},{"type":228,"tag":438,"props":4107,"children":4108},{"class":440,"line":904},[4109,4114,4118,4122,4127,4131],{"type":228,"tag":438,"props":4110,"children":4111},{"style":875},[4112],{"type":233,"value":4113},"    Type ",{"type":228,"tag":438,"props":4115,"children":4116},{"style":487},[4117],{"type":233,"value":883},{"type":228,"tag":438,"props":4119,"children":4120},{"style":487},[4121],{"type":233,"value":490},{"type":228,"tag":438,"props":4123,"children":4124},{"style":451},[4125],{"type":233,"value":4126},"endpoint",{"type":228,"tag":438,"props":4128,"children":4129},{"style":487},[4130],{"type":233,"value":840},{"type":228,"tag":438,"props":4132,"children":4133},{"style":487},[4134],{"type":233,"value":901},{"type":228,"tag":438,"props":4136,"children":4137},{"class":440,"line":921},[4138,4143,4147,4151,4155,4159,4163,4167,4172,4177],{"type":228,"tag":438,"props":4139,"children":4140},{"style":875},[4141],{"type":233,"value":4142},"    PipelineId ",{"type":228,"tag":438,"props":4144,"children":4145},{"style":487},[4146],{"type":233,"value":883},{"type":228,"tag":438,"props":4148,"children":4149},{"style":875},[4150],{"type":233,"value":3770},{"type":228,"tag":438,"props":4152,"children":4153},{"style":487},[4154],{"type":233,"value":1222},{"type":228,"tag":438,"props":4156,"children":4157},{"style":875},[4158],{"type":233,"value":1265},{"type":228,"tag":438,"props":4160,"children":4161},{"style":487},[4162],{"type":233,"value":1222},{"type":228,"tag":438,"props":4164,"children":4165},{"style":1225},[4166],{"type":233,"value":2005},{"type":228,"tag":438,"props":4168,"children":4169},{"style":487},[4170],{"type":233,"value":4171},"(int.",{"type":228,"tag":438,"props":4173,"children":4174},{"style":875},[4175],{"type":233,"value":4176},"Parse",{"type":228,"tag":438,"props":4178,"children":4179},{"style":487},[4180],{"type":233,"value":3639},{"type":228,"tag":438,"props":4182,"children":4183},{"class":440,"line":930},[4184,4189,4193,4197,4201],{"type":228,"tag":438,"props":4185,"children":4186},{"style":875},[4187],{"type":233,"value":4188},"    ResourceId ",{"type":228,"tag":438,"props":4190,"children":4191},{"style":487},[4192],{"type":233,"value":883},{"type":228,"tag":438,"props":4194,"children":4195},{"style":875},[4196],{"type":233,"value":1652},{"type":228,"tag":438,"props":4198,"children":4199},{"style":487},[4200],{"type":233,"value":1222},{"type":228,"tag":438,"props":4202,"children":4203},{"style":875},[4204],{"type":233,"value":4205},"Id\n",{"type":228,"tag":438,"props":4207,"children":4208},{"class":440,"line":978},[4209],{"type":228,"tag":438,"props":4210,"children":4211},{"style":487},[4212],{"type":233,"value":1170},{"type":228,"tag":229,"props":4214,"children":4215},{},[4216],{"type":233,"value":4217},"The last thing we can do is create a stack output to expose the URL of the created pipeline:",{"type":228,"tag":427,"props":4219,"children":4221},{"className":798,"code":4220,"language":511,"meta":207,"style":207},"return new Dictionary\u003Cstring, object?>\n{\n    [\"pipelineUrl\"] = Output.Format($\"{organizationUrl}{project.Name}/_build?definitionId={pipeline.Id}\")\n};\n",[4222],{"type":228,"tag":434,"props":4223,"children":4224},{"__ignoreMap":207},[4225,4261,4268,4374],{"type":228,"tag":438,"props":4226,"children":4227},{"class":440,"line":441},[4228,4233,4237,4242,4247,4252,4256],{"type":228,"tag":438,"props":4229,"children":4230},{"style":2304},[4231],{"type":233,"value":4232},"return",{"type":228,"tag":438,"props":4234,"children":4235},{"style":487},[4236],{"type":233,"value":454},{"type":228,"tag":438,"props":4238,"children":4239},{"style":445},[4240],{"type":233,"value":4241}," Dictionary",{"type":228,"tag":438,"props":4243,"children":4244},{"style":487},[4245],{"type":233,"value":4246},"\u003C",{"type":228,"tag":438,"props":4248,"children":4249},{"style":487},[4250],{"type":233,"value":4251},"string",{"type":228,"tag":438,"props":4253,"children":4254},{"style":487},[4255],{"type":233,"value":854},{"type":228,"tag":438,"props":4257,"children":4258},{"style":487},[4259],{"type":233,"value":4260}," object?>\n",{"type":228,"tag":438,"props":4262,"children":4263},{"class":440,"line":862},[4264],{"type":228,"tag":438,"props":4265,"children":4266},{"style":487},[4267],{"type":233,"value":868},{"type":228,"tag":438,"props":4269,"children":4270},{"class":440,"line":871},[4271,4276,4280,4285,4289,4293,4297,4301,4305,4309,4313,4318,4323,4328,4332,4336,4340,4344,4349,4353,4358,4362,4366,4370],{"type":228,"tag":438,"props":4272,"children":4273},{"style":487},[4274],{"type":233,"value":4275},"    [",{"type":228,"tag":438,"props":4277,"children":4278},{"style":487},[4279],{"type":233,"value":840},{"type":228,"tag":438,"props":4281,"children":4282},{"style":451},[4283],{"type":233,"value":4284},"pipelineUrl",{"type":228,"tag":438,"props":4286,"children":4287},{"style":487},[4288],{"type":233,"value":840},{"type":228,"tag":438,"props":4290,"children":4291},{"style":487},[4292],{"type":233,"value":954},{"type":228,"tag":438,"props":4294,"children":4295},{"style":487},[4296],{"type":233,"value":821},{"type":228,"tag":438,"props":4298,"children":4299},{"style":875},[4300],{"type":233,"value":2822},{"type":228,"tag":438,"props":4302,"children":4303},{"style":487},[4304],{"type":233,"value":1222},{"type":228,"tag":438,"props":4306,"children":4307},{"style":1225},[4308],{"type":233,"value":2831},{"type":228,"tag":438,"props":4310,"children":4311},{"style":487},[4312],{"type":233,"value":835},{"type":228,"tag":438,"props":4314,"children":4315},{"style":487},[4316],{"type":233,"value":4317},"$\"{",{"type":228,"tag":438,"props":4319,"children":4320},{"style":875},[4321],{"type":233,"value":4322},"organizationUrl",{"type":228,"tag":438,"props":4324,"children":4325},{"style":487},[4326],{"type":233,"value":4327},"}{",{"type":228,"tag":438,"props":4329,"children":4330},{"style":875},[4331],{"type":233,"value":3160},{"type":228,"tag":438,"props":4333,"children":4334},{"style":487},[4335],{"type":233,"value":1222},{"type":228,"tag":438,"props":4337,"children":4338},{"style":875},[4339],{"type":233,"value":3169},{"type":228,"tag":438,"props":4341,"children":4342},{"style":487},[4343],{"type":233,"value":3146},{"type":228,"tag":438,"props":4345,"children":4346},{"style":451},[4347],{"type":233,"value":4348},"/_build?definitionId=",{"type":228,"tag":438,"props":4350,"children":4351},{"style":487},[4352],{"type":233,"value":2275},{"type":228,"tag":438,"props":4354,"children":4355},{"style":875},[4356],{"type":233,"value":4357},"pipeline",{"type":228,"tag":438,"props":4359,"children":4360},{"style":487},[4361],{"type":233,"value":1222},{"type":228,"tag":438,"props":4363,"children":4364},{"style":875},[4365],{"type":233,"value":1265},{"type":228,"tag":438,"props":4367,"children":4368},{"style":487},[4369],{"type":233,"value":2284},{"type":228,"tag":438,"props":4371,"children":4372},{"style":487},[4373],{"type":233,"value":2861},{"type":228,"tag":438,"props":4375,"children":4376},{"class":440,"line":904},[4377],{"type":228,"tag":438,"props":4378,"children":4379},{"style":487},[4380],{"type":233,"value":4381},"};\n",{"type":228,"tag":229,"props":4383,"children":4384},{},[4385,4387,4393],{"type":233,"value":4386},"Now we can execute the ",{"type":228,"tag":434,"props":4388,"children":4390},{"className":4389},[],[4391],{"type":233,"value":4392},"pulumi up",{"type":233,"value":4394}," command to provision all these resources and then open the pipeline page in our browser to test the pipeline.",{"type":228,"tag":311,"props":4396,"children":4398},{"icon":4397},"i-heroicons-light-bulb",[4399],{"type":228,"tag":229,"props":4400,"children":4401},{},[4402,4404,4410,4412,4419,4421],{"type":233,"value":4403},"On Windows, you can use the ",{"type":228,"tag":434,"props":4405,"children":4407},{"className":4406},[],[4408],{"type":233,"value":4409},"start $(pulumi stack output pipelineUrl)",{"type":233,"value":4411}," command to directly open the browser on the pipeline page. If you are using ",{"type":228,"tag":247,"props":4413,"children":4416},{"href":4414,"rel":4415},"https://www.nushell.sh/",[251],[4417],{"type":233,"value":4418},"Nushell",{"type":233,"value":4420}," the command will be ",{"type":228,"tag":434,"props":4422,"children":4424},{"className":4423},[],[4425],{"type":233,"value":4426},"pulumi stack output pipelineUrl | start $in",{"type":228,"tag":229,"props":4428,"children":4429},{},[4430],{"type":228,"tag":302,"props":4431,"children":4435},{"alt":4432,"className":4433,"src":4434},"Results of the pipeline run in Azure DevOps",[306,307],"/posts/images/azuredevopsoidc_portal.webp",[],{"type":228,"tag":229,"props":4437,"children":4438},{},[4439],{"type":233,"value":4440},"Everything is working as expected.",{"type":228,"tag":235,"props":4442,"children":4444},{"id":4443},"to-conclude",[4445],{"type":233,"value":4446},"To conclude",{"type":228,"tag":229,"props":4448,"children":4449},{},[4450,4452,4458],{"type":233,"value":4451},"In this article, we demonstrated how to automate the configuration of an Azure DevOps project using Workload Identity Federation for secure deployments to Azure. We covered the provisioning of the Microsoft Entra ID and Azure DevOps resources necessary to make this work. It's very similar to ",{"type":228,"tag":247,"props":4453,"children":4455},{"href":291,"rel":4454},[251],[4456],{"type":233,"value":4457},"what can be done for GitHub",{"type":233,"value":4459}," but with the specificities of Azure DevOps.",{"type":228,"tag":229,"props":4461,"children":4462},{},[4463],{"type":233,"value":4464},"It was an opportunity for me to work with the Azure DevOps provider. Even if it does the job, I must admit I was somewhat disappointed with the developer experience which I found to be not very intuitive, with poorly named resources and an overreliance on strings as parameters. I assume that the Azure DevOps APIs are primarily responsible for this, as they are what the provider calls upon.",{"type":228,"tag":229,"props":4466,"children":4467},{},[4468],{"type":233,"value":4469},"One thing I find interesting with Azure DevOps is that YAML pipelines do not need to be updated to take advantage of workload identity federation as long as the Azure Pipelines tasks you are using support it and your ARM service connection has been converted to workload identity federation.",{"type":228,"tag":229,"props":4471,"children":4472},{},[4473],{"type":233,"value":4474},"Anyway, regardless of the CI/CD platform you are using, I believe that employing Workload Identity Federation to deploy code to Azure from pipelines is the right approach.",{"type":228,"tag":229,"props":4476,"children":4477},{},[4478,4480,4490],{"type":233,"value":4479},"You can find the complete source code used for this article ",{"type":228,"tag":247,"props":4481,"children":4484},{"href":4482,"rel":4483},"https://github.com/TechWatching/AzureDevOpsWorkloadIdentity",[251],[4485],{"type":228,"tag":336,"props":4486,"children":4487},{},[4488],{"type":233,"value":4489},"in this GitHub repository",{"type":233,"value":1222},{"type":228,"tag":4492,"props":4493,"children":4494},"style",{},[4495],{"type":233,"value":4496},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":207,"searchDepth":862,"depth":862,"links":4498},[4499,4500,4502,4509],{"id":237,"depth":862,"text":240},{"id":331,"depth":862,"text":4501},"How can you use Workload Identity Federation to deploy to Azure from Azure Pipelines?",{"id":410,"depth":862,"text":413,"children":4503},[4504,4505,4506,4507,4508],{"id":417,"depth":871,"text":420},{"id":669,"depth":871,"text":672},{"id":1616,"depth":871,"text":1619},{"id":2353,"depth":871,"text":2356},{"id":3226,"depth":871,"text":3229},{"id":4443,"depth":862,"text":4446},"markdown","content:1.posts:54.ado-workload-identity-federation.md","content","1.posts/54.ado-workload-identity-federation.md","md",[4516,4529],{"_path":172,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":171,"description":4517,"lead":4518,"date":4519,"image":4520,"badge":4522,"tags":4523,"_type":4510,"_id":4527,"_source":4512,"_file":4528,"_extension":4514},"What if we could script the creation and configuration of a GitHub Repository so that it is ready to provision or deploy Azure resources from a GitHub Actions pipeline? We will do that in this article using the Azure CLI and GitHub CLI.","Scripting your Azure-Ready GitHub Repository using Azure and GitHub CLI","2023-10-23T00:00:00.000Z",{"src":4521},"/images/azureOIDC_2.webp",{"label":214},[216,4524,217,4525,218,219,4526],"Azure CLI","GitHub CLI","Microsoft Entra ID","content:1.posts:55.scripting-azure-ready-github-repository.md","1.posts/55.scripting-azure-ready-github-repository.md",{"_path":166,"_dir":205,"_draft":206,"_partial":206,"_locale":207,"title":165,"description":4530,"lead":4531,"date":4532,"image":4533,"badge":4535,"tags":4536,"_type":4510,"_id":4537,"_source":4512,"_file":4538,"_extension":4514},"Creating an application and deploying it to Azure is not complicated. You write some code on your machine, do some clicks in the Azure portal, or run some Azure CLI commands from your terminal and that's it: your application is up and running in Azure.","Using Azure OpenID Connect with Pulumi in GitHub Actions","2023-07-20T00:00:00.000Z",{"src":4534},"/images/azureOIDC.webp",{"label":214},[216,217,218,219,220,221,222],"content:1.posts:53.azure-ready-github-repository.md","1.posts/53.azure-ready-github-repository.md",1716749601500]